diff --git a/include/boost/circular_buffer/base.hpp b/include/boost/circular_buffer/base.hpp index 3d6d15f..020e9a6 100644 --- a/include/boost/circular_buffer/base.hpp +++ b/include/boost/circular_buffer/base.hpp @@ -538,9 +538,6 @@ public: return *this; } - // TODO - void assign(size_type capacity, size_type n, param_value_type item) {} - //! Assign n items into the circular buffer. /*! \post (*this).size() == n \&\& @@ -555,8 +552,7 @@ public: void assign(size_type n, param_value_type item) { do_assign(n, cb_details::assign_n(n, item, m_alloc)); } // TODO - template - void assign(size_type capacity, InputIterator first, InputIterator last) {} + void assign(size_type capacity, size_type n, param_value_type item) {} //! Assign a copy of range. /*! @@ -574,6 +570,10 @@ public: assign(first, last, BOOST_DEDUCED_TYPENAME cb_details::iterator_cat_traits::tag()); } + // TODO + template + void assign(size_type capacity, InputIterator first, InputIterator last) {} + //! Swap the contents of two circular buffers. /*! \post this contains elements of cb and vice versa. diff --git a/include/boost/circular_buffer/details.hpp b/include/boost/circular_buffer/details.hpp index 74ca449..7063ed3 100644 --- a/include/boost/circular_buffer/details.hpp +++ b/include/boost/circular_buffer/details.hpp @@ -80,7 +80,6 @@ template struct nonconst_traits; /*! \struct const_traits \brief Defines the data types for a const iterator. - \param Traits Defines the basic types. */ template struct const_traits { @@ -98,7 +97,6 @@ struct const_traits { /*! \struct nonconst_traits \brief Defines the data types for a non-const iterator. - \param Traits Defines the basic types. */ template struct nonconst_traits { @@ -182,11 +180,35 @@ private: assign_range& operator = (const assign_range&); // do not generate }; +/*! + \struct capacity_control + \brief Capacity controller of the space optimized circular buffer. +*/ +template +struct capacity_control { + + //! The capacity of the space optimized circular buffer. + Size m_capacity; + + //! The lowest guaranteed capacity of the adapted circular buffer. + Size m_min_capacity; + + //! Constructor. + capacity_control(Size capacity, Size min_capacity = 0) + : m_capacity(capacity), m_min_capacity(min_capacity) { + BOOST_CB_ASSERT(capacity >= min_capacity); // check for capacity lower than min_capacity + } + + // Default copy constructor. + + // Default assign operator. +}; + /*! \class iterator \brief Random access iterator for the circular buffer. \param Buff The type of the underlying circular buffer. - \param Traits Defines basic iterator types. + \param Traits Basic iterator types. \note This iterator is not circular. It was designed for iterating from begin() to end() of the circular buffer. */ diff --git a/include/boost/circular_buffer/space_optimized.hpp b/include/boost/circular_buffer/space_optimized.hpp index dfabc75..4a43440 100644 --- a/include/boost/circular_buffer/space_optimized.hpp +++ b/include/boost/circular_buffer/space_optimized.hpp @@ -51,6 +51,9 @@ public: typedef typename circular_buffer::param_value_type param_value_type; typedef typename circular_buffer::return_value_type return_value_type; + //! Capacity type of the space optimized circular buffer. + typedef cb_details::capacity_control capacity_control; + // Inherited using circular_buffer::get_allocator; @@ -78,11 +81,8 @@ public: private: // Member variables - //! The capacity of the optimized circular buffer. - size_type m_capacity; - - //! The lowest guaranteed capacity of the adapted circular buffer. - size_type m_min_capacity; + //! The capacity controller of the space optimized circular buffer. + capacity_control m_capacity_ctrl; public: // Overridden @@ -94,7 +94,7 @@ public: /* The allocated memory will never drop under this value. */ - size_type min_capacity() const { return m_min_capacity; } + size_type min_capacity() const { return m_capacity_ctrl.m_min_capacity; } //! Change the minimal guaranteed amount of allocated memory. /*! @@ -107,7 +107,7 @@ public: */ void set_min_capacity(size_type new_min_capacity) { BOOST_CB_ASSERT(capacity() >= new_min_capacity); // check for too large new min_capacity - m_min_capacity = new_min_capacity; + m_capacity_ctrl.m_min_capacity = new_min_capacity; if (new_min_capacity > circular_buffer::capacity()) circular_buffer::set_capacity(new_min_capacity); else @@ -115,7 +115,7 @@ public: } //! See the circular_buffer source documentation. - size_type capacity() const { return m_capacity; } + size_type capacity() const { return m_capacity_ctrl.m_capacity; } #if defined(BOOST_CB_TEST) @@ -130,16 +130,16 @@ public: //!! See the circular_buffer source documentation. /*! - \pre (*this).min_capacity() <= new_capacity + \pre min_capacity() <= new_capacity \note It is considered as a bug if the precondition is not met (i.e. if - new_capacity > (*this).min_capacity()) and an assertion + new_capacity > min_capacity()) and an assertion will be invoked in the debug mode. */ void set_capacity(size_type new_capacity) { BOOST_CB_ASSERT(new_capacity >= min_capacity()); // check for too low new capacity if (new_capacity < circular_buffer::capacity()) circular_buffer::set_capacity(new_capacity); - m_capacity = new_capacity; + m_capacity_ctrl.m_capacity = new_capacity; } //! See the circular_buffer source documentation. @@ -150,15 +150,21 @@ public: erase(begin(), end() - new_size); } - // TODO + //!! See the circular_buffer source documentation. + /*! + \pre min_capacity() <= new_capacity + \note It is considered as a bug if the precondition is not met (i.e. if + new_capacity > min_capacity()) and an assertion + will be invoked in the debug mode. + */ void rset_capacity(size_type new_capacity) { BOOST_CB_ASSERT(new_capacity >= min_capacity()); // check for too low new capacity if (new_capacity < circular_buffer::capacity()) circular_buffer::rset_capacity(new_capacity); - m_capacity = new_capacity; + m_capacity_ctrl.m_capacity = new_capacity; } - // TODO + //! See the circular_buffer source documentation. void rresize(size_type new_size, param_value_type item = T()) { if (new_size > size()) increase_size(new_size, item); @@ -181,14 +187,10 @@ public: in the debug mode. */ explicit circular_buffer_space_optimized( - size_type capacity, - size_type min_capacity = 0, + capacity_control capacity_ctrl, const allocator_type& alloc = allocator_type()) - : circular_buffer(min_capacity, alloc) - , m_capacity(capacity) - , m_min_capacity(min_capacity) { - BOOST_CB_ASSERT(capacity >= min_capacity); // check for capacity lower than min_capacity - } + : circular_buffer(capacity_ctrl.m_min_capacity, alloc) + , m_capacity_ctrl(capacity_ctrl) {} //! Create a full space optimized circular buffer filled with copies of item. /*! @@ -206,18 +208,30 @@ public: in the debug mode. */ circular_buffer_space_optimized( - size_type capacity, - size_type min_capacity, + capacity_control capacity_ctrl, param_value_type item, const allocator_type& alloc = allocator_type()) - : circular_buffer(capacity, item, alloc) - , m_capacity(capacity) - , m_min_capacity(min_capacity) { - BOOST_CB_ASSERT(capacity >= min_capacity); // check for capacity lower than min_capacity - } + : circular_buffer(capacity_ctrl.m_capacity, item, alloc) + , m_capacity_ctrl(capacity_ctrl) {} + + // TODO + circular_buffer_space_optimized( + capacity_control capacity_ctrl, + size_type n, + param_value_type item, + const allocator_type& alloc = allocator_type()) {} // Default copy constructor + // TODO + /*template + circular_buffer_space_optimized( + InputIterator first, + InputIterator last, + const allocator_type& alloc = allocator_type()) + : m_alloc(alloc) { + }*/ + //! Create a space optimized circular buffer with a copy of a range. /*! \param capacity The capacity of the buffer. @@ -242,15 +256,13 @@ public: */ template circular_buffer_space_optimized( - size_type capacity, - size_type min_capacity, + capacity_control capacity_ctrl, InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) : circular_buffer( - init_capacity(capacity, min_capacity, first, last), first, last, alloc) - , m_capacity(capacity) - , m_min_capacity(min_capacity) { } + init_capacity(capacity_ctrl.m_capacity, capacity_ctrl.m_min_capacity, first, last), first, last, alloc) + , m_capacity_ctrl(capacity_ctrl) {} // Default destructor @@ -267,24 +279,30 @@ public: //! See the circular_buffer source documentation. void assign(size_type n, param_value_type item) { - if (n > m_capacity) - m_capacity = n; + if (n > m_capacity_ctrl.m_capacity) + m_capacity_ctrl.m_capacity = n; circular_buffer::assign(n, item); } + // TODO + void assign(capacity_control capacity_ctrl, size_type n, param_value_type item) {} + //! See the circular_buffer source documentation. template void assign(InputIterator first, InputIterator last) { circular_buffer::assign(first, last); size_type capacity = circular_buffer::capacity(); - if (capacity > m_capacity) - m_capacity = capacity; + if (capacity > m_capacity_ctrl.m_capacity) + m_capacity_ctrl.m_capacity = capacity; } + // TODO + template + void assign(capacity_control capacity_ctrl, InputIterator first, InputIterator last) {} + //! See the circular_buffer source documentation. void swap(circular_buffer_space_optimized& cb) { - std::swap(m_capacity, cb.m_capacity); - std::swap(m_min_capacity, cb.m_min_capacity); + std::swap(m_capacity_ctrl, cb.m_capacity_ctrl); circular_buffer::swap(cb); } @@ -515,7 +533,7 @@ private: //! Increase the size of the space optimized circular buffer. void increase_size(size_type new_size, param_value_type item) { if (new_size > capacity()) - m_capacity = new_size; + m_capacity_ctrl.m_capacity = new_size; insert(end(), new_size - size(), item); } diff --git a/test/base_test.cpp b/test/base_test.cpp index 3fee06a..d686527 100644 --- a/test/base_test.cpp +++ b/test/base_test.cpp @@ -14,7 +14,6 @@ using namespace std; using unit_test_framework::test_suite; #define CB_CONTAINER circular_buffer -#define CB_MIN_CAPACITY /* none */ #include "common.cpp" diff --git a/test/common.cpp b/test/common.cpp index e5d99be..69399a4 100644 --- a/test/common.cpp +++ b/test/common.cpp @@ -97,9 +97,9 @@ void basic_test() { v.push_back(5); v.push_back(6); v.push_back(7); - CB_CONTAINER cb1(3 CB_MIN_CAPACITY, v.begin(), v.end()); - CB_CONTAINER cb2(10 CB_MIN_CAPACITY, v.begin(), v.end()); - CB_CONTAINER cb3(7 CB_MIN_CAPACITY, v.begin(), v.end()); + CB_CONTAINER cb1(3, v.begin(), v.end()); + CB_CONTAINER cb2(10, v.begin(), v.end()); + CB_CONTAINER cb3(7, v.begin(), v.end()); BOOST_CHECK(cb1.full()); BOOST_CHECK(cb1.capacity() == 3); @@ -119,7 +119,7 @@ void basic_test() { void constructor_and_element_access_test() { - CB_CONTAINER cb(5 CB_MIN_CAPACITY, 3); + CB_CONTAINER cb(5, 3); cb[1] = 10; BOOST_CHECK(cb.full()); @@ -204,7 +204,7 @@ void element_access_and_insert_test() { cb.push_back(2); cb.insert(cb.begin(), 3); cb.push_back(4); - const CB_CONTAINER ccb(3 CB_MIN_CAPACITY, 2); + const CB_CONTAINER ccb(3, 2); BOOST_CHECK(cb[0] == 1); BOOST_CHECK(cb[1] == 2); @@ -274,11 +274,11 @@ void linearize_test() { v.push_back(10); v.push_back(11); v.push_back(12); - CB_CONTAINER cb1(10 CB_MIN_CAPACITY, v.begin(), v.begin() + 10); + CB_CONTAINER cb1(10, v.begin(), v.begin() + 10); cb1.push_back(11); cb1.push_back(12); cb1.push_back(13); - CB_CONTAINER cb2(10 CB_MIN_CAPACITY, v.begin(), v.begin() + 10); + CB_CONTAINER cb2(10, v.begin(), v.begin() + 10); cb2.push_back(11); cb2.push_back(12); cb2.push_back(13); @@ -286,14 +286,14 @@ void linearize_test() { cb2.push_back(15); cb2.push_back(16); cb2.push_back(17); - CB_CONTAINER cb3(10 CB_MIN_CAPACITY, v.begin(), v.begin() + 10); + CB_CONTAINER cb3(10, v.begin(), v.begin() + 10); cb3.push_back(11); cb3.push_back(12); cb3.push_back(13); cb3.pop_front(); cb3.pop_front(); CB_CONTAINER cb4(5); - CB_CONTAINER cb5(12 CB_MIN_CAPACITY, v.begin(), v.end()); + CB_CONTAINER cb5(12, v.begin(), v.end()); cb5.push_back(13); cb5.push_back(14); cb5.push_back(15); @@ -500,9 +500,9 @@ void resize_test() { cb2.push_back(3); cb2.push_back(4); cb2.resize(2); - CB_CONTAINER cb3(10 CB_MIN_CAPACITY, 1); + CB_CONTAINER cb3(10, 1); cb3.resize(0); - CB_CONTAINER cb4(10 CB_MIN_CAPACITY, 1); + CB_CONTAINER cb4(10, 1); cb4.resize(10); BOOST_CHECK(cb1.size() == 20); @@ -548,7 +548,7 @@ void rresize_test() { void constructor_test() { CB_CONTAINER cb1(3); - CB_CONTAINER cb2(3 CB_MIN_CAPACITY, 2); + CB_CONTAINER cb2(3, 2); BOOST_CHECK(cb1.size() == 0); BOOST_CHECK(cb1.capacity() == 3); @@ -733,7 +733,7 @@ void insert_n_test() { cb1.push_back(2); cb1.push_back(3); cb1.insert(cb1.begin() + 1, 2, 10); - CB_CONTAINER cb2(2 CB_MIN_CAPACITY, 3); + CB_CONTAINER cb2(2, 3); cb2.insert(cb2.begin(), 10, 5); CB_CONTAINER cb3(4); cb3.insert(cb3.end(), 1, 6); @@ -779,7 +779,7 @@ void insert_range_test() { cb1.push_back(2); cb1.push_back(3); cb1.insert(cb1.begin() + 1, v.begin(), v.end()); - CB_CONTAINER cb2(2 CB_MIN_CAPACITY, 2); + CB_CONTAINER cb2(2, 2); cb2.insert(cb2.end(), v.begin(), v.end()); CB_CONTAINER cb3(5); cb3.insert(cb3.end(), v.end(), v.end()); @@ -943,7 +943,7 @@ void rinsert_n_test() { cb1.push_front(2); cb1.push_front(3); cb1.rinsert(cb1.begin() + 1, 2, 10); - CB_CONTAINER cb2(2 CB_MIN_CAPACITY, 3); + CB_CONTAINER cb2(2, 3); cb2.rinsert(cb2.begin(), 10, 5); CB_CONTAINER cb3(4); cb3.rinsert(cb3.end(), 1, 6); @@ -1002,7 +1002,7 @@ void rinsert_range_test() { cb1.push_back(2); cb1.push_back(3); cb1.rinsert(cb1.begin() + 1, v.begin(), v.end()); - CB_CONTAINER cb2(2 CB_MIN_CAPACITY, 2); + CB_CONTAINER cb2(2, 2); cb2.rinsert(cb2.begin(), v.begin(), v.end()); CB_CONTAINER cb3(5); cb3.rinsert(cb3.begin(), v.end(), v.end()); @@ -1034,7 +1034,7 @@ void erase_test() { cb1.push_back(3); CB_CONTAINER::iterator it1 = cb1.erase(cb1.begin() + 1); - CB_CONTAINER cb2(1 CB_MIN_CAPACITY, 1); + CB_CONTAINER cb2(1, 1); CB_CONTAINER::iterator it2 = cb2.erase(cb2.begin()); CB_CONTAINER cb3(4); @@ -1085,7 +1085,7 @@ void erase_range_test() { cb3.push_back(4); CB_CONTAINER::iterator it3 = cb3.erase(cb3.begin() + 2, cb3.end()); - CB_CONTAINER cb4(10 CB_MIN_CAPACITY, 1); + CB_CONTAINER cb4(10, 1); CB_CONTAINER::iterator it4 = cb4.erase(cb4.begin(), cb4.end()); BOOST_CHECK(cb1.size() == 2); @@ -1120,7 +1120,7 @@ void rerase_test() { cb1.push_back(3); CB_CONTAINER::iterator it1 = cb1.rerase(cb1.begin() + 1); - CB_CONTAINER cb2(1 CB_MIN_CAPACITY, 1); + CB_CONTAINER cb2(1, 1); CB_CONTAINER::iterator it2 = cb2.rerase(cb2.begin()); CB_CONTAINER cb3(4); @@ -1172,7 +1172,7 @@ void rerase_range_test() { cb3.push_back(4); CB_CONTAINER::iterator it3 = cb3.rerase(cb3.begin(), cb3.begin() + 2); - CB_CONTAINER cb4(10 CB_MIN_CAPACITY, 1); + CB_CONTAINER cb4(10, 1); CB_CONTAINER::iterator it4 = cb4.rerase(cb4.begin(), cb4.end()); BOOST_CHECK(cb1.size() == 2); @@ -1298,7 +1298,7 @@ void example_test() { BOOST_CHECK(cb1.size() == 3); BOOST_CHECK(cb1.capacity() == 3); - CB_CONTAINER cb2(5 CB_MIN_CAPACITY, 1); + CB_CONTAINER cb2(5, 1); cb2.insert(cb2.begin(), 2); BOOST_CHECK(cb2[0] == 1); @@ -1356,7 +1356,7 @@ void const_methods_test() { v.push_back(3); v.push_back(4); v.push_back(5); - const CB_CONTAINER cb(5 CB_MIN_CAPACITY, v.begin(), v.end()); + const CB_CONTAINER cb(5, v.begin(), v.end()); BOOST_CHECK(*cb.begin() == 1); BOOST_CHECK(*(cb.end() - 1) == 5); diff --git a/test/space_optimized_test.cpp b/test/space_optimized_test.cpp index 6cbfc46..3a7e663 100644 --- a/test/space_optimized_test.cpp +++ b/test/space_optimized_test.cpp @@ -16,11 +16,13 @@ using namespace std; using unit_test_framework::test_suite; #define CB_CONTAINER circular_buffer_space_optimized -#define CB_MIN_CAPACITY ,0 #include "common.cpp" -// min_capacity test (it is useful to use any debug tool) +typedef circular_buffer_space_optimized cb_space_optimized; +typedef cb_space_optimized::capacity_control capacity_ctrl; + +// min_capacity test (it is useful to use a debug tool) void min_capacity_test() { vector v; @@ -30,9 +32,9 @@ void min_capacity_test() { v.push_back(4); v.push_back(5); - circular_buffer_space_optimized cb1(10, 10); - circular_buffer_space_optimized cb2(10, 5, 1); - circular_buffer_space_optimized cb3(20, 10, v.begin(), v.end()); + cb_space_optimized cb1(capacity_ctrl(10, 10)); + cb_space_optimized cb2(capacity_ctrl(10, 5), 1); + cb_space_optimized cb3(capacity_ctrl(20, 10), v.begin(), v.end()); BOOST_CHECK(cb1.size() == 0); BOOST_CHECK(cb1.capacity() == 10);