From eb77970646112fafb7e47af14577e63c8fd26c81 Mon Sep 17 00:00:00 2001 From: Jan Gaspar Date: Tue, 11 Apr 2006 22:20:17 +0000 Subject: [PATCH] Documentation update. [SVN r2915] --- doc/circular_buffer.html | 1470 ++++++++++------- doc/circular_buffer_space_optimized.html | 687 +++++--- .../boost/circular_buffer/space_optimized.hpp | 17 +- 3 files changed, 1268 insertions(+), 906 deletions(-) diff --git a/doc/circular_buffer.html b/doc/circular_buffer.html index 64966e3..c01040f 100644 --- a/doc/circular_buffer.html +++ b/doc/circular_buffer.html @@ -1,8 +1,7 @@ - + - + Templated Circular Buffer Container @@ -67,26 +66,31 @@

- Description + Description

- In general the term circular buffer refers to an area in memory which is used to store incoming data. When the buffer is filled, new data is written starting at the beginning - of the buffer and overwriting the old. [1] (Also see the Figure.) + In general the term circular buffer refers to an area in memory which is used to store incoming data. When + the buffer is filled, new data is written starting at the beginning of the buffer and overwriting the old. + [1] (Also see the Figure.)

- The circular_buffer is a STL compliant container. It is a kind of sequence similar to std::vector or std::deque. It supports random access - iterators, constant time insert and erase operations at the beginning or the end of the buffer and interoperability with std algorithms. The circular_buffer - is especially designed to provide fixed capacity storage. When its capacity is exhausted, newly inserted elements will cause elements either at the beginning or end of the buffer + The circular_buffer is a STL compliant container. It is a kind of sequence similar to + std::vector or std::deque. It supports random access iterators, constant time insert + and erase operations at the beginning or the end of the buffer and interoperability with std + algorithms. The circular_buffer is especially designed to provide fixed capacity storage. When its + capacity is exhausted, newly inserted elements will cause elements either at the beginning or end of the buffer (depending on what insert operation is used) to be overwritten.

- The circular_buffer only allocates memory when created, when the capacity is adjusted explicitly, or as necessary to accommodate resizing or assign operations. On the - other hand, there is also a circular_buffer_space_optimized available. It is an adaptor of the - circular_buffer which does not allocate memory at once when created, rather it allocates memory as needed. + The circular_buffer only allocates memory when created, when the capacity is adjusted explicitly, or + as necessary to accommodate resizing or assign operations. On the other hand, there is also a circular_buffer_space_optimized available. It is an adaptor of + the circular_buffer which does not allocate memory at once when created, rather it allocates memory + as needed.


- Introductory Example + Introductory Example

A brief example using the circular_buffer: @@ -131,7 +135,7 @@ }

- Synopsis + Synopsis

@@ -146,18 +150,19 @@ class circular_buffer public: typedef Alloc allocator_type; typedef implementation-definedarray_range; - typedef implementation-definedconst_array_range; - typedef implementation-definedconst_iterator; - typedef typename Alloc::const_pointer const_pointer; - typedef typename Alloc::const_reference const_reference; - typedef implementation-definedconst_reverse_iterator; - typedef typename Alloc::difference_type difference_type; - typedef implementation-definediterator; - typedef typename Alloc::pointer pointer; - typedef typename Alloc::reference reference; - typedef implementation-definedreverse_iterator; - typedef typename Alloc::size_type size_type; - typedef typename Alloc::value_type value_type; + typedef size_type capacity_control; + typedef implementation-definedconst_array_range; + typedef implementation-definedconst_iterator; + typedef typename Alloc::const_pointer const_pointer; + typedef typename Alloc::const_reference const_reference; + typedef implementation-definedconst_reverse_iterator; + typedef typename Alloc::difference_type difference_type; + typedef implementation-definediterator; + typedef typename Alloc::pointer pointer; + typedef typename Alloc::reference reference; + typedef implementation-definedreverse_iterator; + typedef typename Alloc::size_type size_type; + typedef typename Alloc::value_type value_type; template <class InputIterator> circular_buffer(size_type capacity, @@ -167,7 +172,8 @@ public: circular_buffer(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); template <class InputIterator> -circular_buffer(size_type capacity, InputIterator first, InputIterator last); +circular_buffer(size_type capacity, InputIterator first, InputIterator last); template <class InputIterator> circular_buffer(InputIterator first, InputIterator last); circular_buffer(const circular_buffer<T,Alloc>& cb); @@ -176,8 +182,10 @@ public: const allocator_type& alloc = allocator_type()); circular_buffer(size_type n, value_type item, const allocator_type& alloc = allocator_type()); - explicit circular_buffer(size_type capacity, const allocator_type& alloc = allocator_type()); - explicit circular_buffer(const allocator_type& alloc = allocator_type()); + explicit circular_buffer(size_type capacity, const allocator_type& alloc = allocator_type()); + explicit circular_buffer(const allocator_type& alloc = allocator_type()); ~circular_buffer(); const_array_range array_one() const; @@ -185,7 +193,8 @@ public: const_array_range array_two() const; array_range array_two(); template <class InputIterator> - void assign(size_type capacity, InputIterator first, InputIterator last); + void assign(size_type capacity, InputIterator first, InputIterator last); template <class InputIterator> void assign(InputIterator first, InputIterator last); void assign(size_type capacity, size_type n, value_type item); @@ -209,12 +218,14 @@ public: allocator_type& get_allocator(); allocator_type get_allocator() const; template <class InputIterator> - void insert(iterator pos, InputIterator first, InputIterator last); + void insert(iterator pos, InputIterator first, InputIterator last); void insert(iterator pos, size_type n, value_type item); iterator insert(iterator pos, value_type item = value_type()); pointer linearize(); size_type max_size() const; - circular_buffer<T,Alloc>& operator=(const circular_buffer<T,Alloc>& cb); + circular_buffer<T,Alloc>& operator=(const circular_buffer<T,Alloc>& cb); value_type operator[](size_type index) const; reference operator[](size_type index); void pop_back(); @@ -229,7 +240,8 @@ public: iterator rerase(iterator pos); void resize(size_type new_size, value_type item = value_type()); template <class InputIterator> - void rinsert(iterator pos, InputIterator first, InputIterator last); + void rinsert(iterator pos, InputIterator first, InputIterator last); void rinsert(iterator pos, size_type n, value_type item); iterator rinsert(iterator pos, value_type item = value_type()); void rresize(size_type new_size, value_type item = value_type()); @@ -240,19 +252,26 @@ public: }; template <class T, class Alloc> - bool operator!=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); + bool operator!=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); template <class T, class Alloc> - bool operator<(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); + bool operator<(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); template <class T, class Alloc> - bool operator<=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); + bool operator<=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); template <class T, class Alloc> - bool operator==(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); + bool operator==(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); template <class T, class Alloc> - bool operator>(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); + bool operator>(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); template <class T, class Alloc> - bool operator>=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); + bool operator>=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs); template <class T, class Alloc> - void swap(circular_buffer<T,Alloc>& lhs, circular_buffer<T,Alloc>& rhs); + void swap(circular_buffer<T,Alloc>& lhs, circular_buffer<T,Alloc>& rhs); } // namespace boost @@ -261,11 +280,12 @@ template <class T, class Alloc>

- Rationale + Rationale

- The basic motivation behind the circular_buffer was to create a container which would work seamlessly with STL. Additionally, the design of the - circular_buffer was guided by the following principles: + The basic motivation behind the circular_buffer was to create a container which would work + seamlessly with STL. Additionally, the design of the circular_buffer was guided by the following + principles:

  1. @@ -278,15 +298,17 @@ template <class T, class Alloc> The behaviour of the buffer as intuitive as possible.
  2. - Suitable for specialization by means of adaptors. (The circular_buffer_space_optimized is such an example of - the adaptor.) + Suitable for specialization by means of adaptors. (The circular_buffer_space_optimized is such an example of the + adaptor.)
  3. Easy to debug. (See Debug Support for details.)

- In order to achieve maximum efficiency, the circular_buffer stores its elements in a contiguous region of memory, which then enables: + In order to achieve maximum efficiency, the circular_buffer stores its elements in a contiguous + region of memory, which then enables:

  1. @@ -310,58 +332,70 @@ template <class T, class Alloc> Storage of the most recently received samples, overwriting the oldest as new samples arrive.
  2. - As an underlying container for a bounded buffer (see the Bounded Buffer Example). + As an underlying container for a bounded buffer (see the Bounded Buffer + Example).
  3. A kind of cache storing a specified number of last inserted elements.
  4. - Efficient fixed capacity FIFO (First In, First Out) or LIFO (Last In, First Out) queue which removes the oldest (inserted as first) elements when full. + Efficient fixed capacity FIFO (First In, First Out) or LIFO (Last In, First Out) queue which removes the oldest + (inserted as first) elements when full.
  5. - The following paragraphs describe issues that had to be considered during the implemenation of the circular_buffer: + The following paragraphs describe issues that had to be considered during the implemenation of the + circular_buffer:

    - Thread-Safety + Thread-Safety

    - The thread-safety of the circular_buffer is the same as the thread-safety of containers in most STL implementations. This means the circular_buffer is - thread-safe only in the sense that simultaneous accesses to distinct instances of the circular_buffer are safe, and simultaneous read accesses to a shared - circular_buffer are safe. + The thread-safety of the circular_buffer is the same as the thread-safety of containers in most STL + implementations. This means the circular_buffer is thread-safe only in the sense that simultaneous + accesses to distinct instances of the circular_buffer are safe, and simultaneous read accesses to a + shared circular_buffer are safe.

    - If multiple threads access a single circular_buffer, and at least one of the threads may potentially write, then the user is responsible for ensuring mutual exclusion - between the threads during the container accesses. The mutual exclusion between the threads can be achieved by wrapping operations of the underlying circular_buffer with - a lock acquisition and release. (See the Bounded Buffer Example.) + If multiple threads access a single circular_buffer, and at least one of the threads may potentially + write, then the user is responsible for ensuring mutual exclusion between the threads during the container + accesses. The mutual exclusion between the threads can be achieved by wrapping operations of the underlying + circular_buffer with a lock acquisition and release. (See the Bounded + Buffer Example.)

    Overwrite Operation

    - Overwrite operation occurs when an element is inserted into a full circular_buffer - the old element is being overwriten by the new one. There was a discussion what - exactly "overwriting of an element" means during the formal review. It may be either a destruction of the original element and a consequent inplace construction of a new element or it - may be an assignment of a new element into an old one. The circular_buffer implements assignment because it is more effective. + Overwrite operation occurs when an element is inserted into a full circular_buffer - the old element + is being overwriten by the new one. There was a discussion what exactly "overwriting of an element" + means during the formal review. It may be either a destruction of the original element and a consequent inplace + construction of a new element or it may be an assignment of a new element into an old one. The + circular_buffer implements assignment because it is more effective.

    - From the point of business logic of a stored element, the destruction/construction operation and assignment usually mean the same. However, in very rare cases (if in any) they may - differ. If there is a requirement for elements to be destructed/constructed instead of being assigned, consider implementing a wrapper of the element which would implement the assign - operator, and store the wrappers instead. It is necessary to note that storing such wrappers has a drawback. The destruction/construction will be invoked on every assignment of the - wrapper - not only when a wrapper is being overwritten (when the buffer is full) but also when the stored wrappers are being shifted (e.g. as a result of insertion into the middle of - container). + From the point of business logic of a stored element, the destruction/construction operation and assignment + usually mean the same. However, in very rare cases (if in any) they may differ. If there is a requirement for + elements to be destructed/constructed instead of being assigned, consider implementing a wrapper of the element + which would implement the assign operator, and store the wrappers instead. It is necessary to note that storing + such wrappers has a drawback. The destruction/construction will be invoked on every assignment of the wrapper - + not only when a wrapper is being overwritten (when the buffer is full) but also when the stored wrappers are + being shifted (e.g. as a result of insertion into the middle of container).

    Writing to a Full Buffer

    - There are several options how to cope with the case if a data source produces more data than can fit in the fixed-sized buffer: + There are several options how to cope with the case if a data source produces more data than can fit in the + fixed-sized buffer:

    1. Inform the data source to wait until there is room in the buffer (e.g. by throwing an overflow exception).
    2. - If the oldest data is the most important, ignore new data from the source until there is room in the buffer again. + If the oldest data is the most important, ignore new data from the source until there is room in the buffer + again.
    3. If the latest data is the most important, write over the oldest data. @@ -371,22 +405,26 @@ template <class T, class Alloc>

    - It is apparent that the circular_buffer implements the third option. But it may be less apparent it does not implement any other option - especially the first two. - One can get an impression that the circular_buffer should implement first three options and offer a mechanism of choosing among them. This impression is wrong. The - circular_buffer was designed and optimized to be circular (which means overwriting the oldest data when full). If such a controlling mechanism had been enabled, it would - just complicate the matters and the usage of the circular_buffer would be probably less straightforward. + It is apparent that the circular_buffer implements the third option. But it may be less apparent it + does not implement any other option - especially the first two. One can get an impression that the + circular_buffer should implement first three options and offer a mechanism of choosing among them. + This impression is wrong. The circular_buffer was designed and optimized to be circular (which means + overwriting the oldest data when full). If such a controlling mechanism had been enabled, it would just + complicate the matters and the usage of the circular_buffer would be probably less straightforward.

    - Moreover, the first two options (and the fouth option as well) do not require the buffer to be circular at all. If there is a need for the first or second option, consider - implementing an adaptor of e.g. std::vector. In this case the circular_buffer is not suitable for adapting, because, in contrary to std::vector, - it bears an overhead for its circular behavior. + Moreover, the first two options (and the fouth option as well) do not require the buffer to be circular at all. + If there is a need for the first or second option, consider implementing an adaptor of e.g. + std::vector. In this case the circular_buffer is not suitable for adapting, because, in + contrary to std::vector, it bears an overhead for its circular behavior.

    Reading/Removing from an Empty Buffer

    - When reading or removing an element from an empty buffer, the buffer should be able to notify the data consumer (e.g. by throwing underflow exception) that there are no elements - stored in it. The circular_buffer does not implement such a behaviour for two reasons: + When reading or removing an element from an empty buffer, the buffer should be able to notify the data consumer + (e.g. by throwing underflow exception) that there are no elements stored in it. The circular_buffer + does not implement such a behaviour for two reasons:

    1. @@ -397,17 +435,21 @@ template <class T, class Alloc>

    - It is considered to be a bug to read or remove an element (e.g. by calling front() or pop_back()) from an empty std container and from an emtpy - circular_buffer as well. The data consumer has to test if the container is not empty before reading/removing from it. However, when reading from the - circular_buffer, there is an option to rely on the at() method which throws an exception when the index is out of range. + It is considered to be a bug to read or remove an element (e.g. by calling front() or + pop_back()) from an empty std container and from an emtpy circular_buffer + as well. The data consumer has to test if the container is not empty before reading/removing from it. However, + when reading from the circular_buffer, there is an option to rely on the at() method + which throws an exception when the index is out of range.

    Iterator Invalidation

    - An iterator is usually considered to be invalidated if an element, the iterator pointed to, had been removed or overwritten by an another element. This definition is enforced by the - Debug Support and refered as strict in the source code documentation. However, some applications utilizing circular_buffer may require less - strict definition: an iterator is invalid only if it points to an uninitialized memory. Consider following example: + An iterator is usually considered to be invalidated if an element, the iterator pointed to, had been removed or + overwritten by an another element. This definition is enforced by the Debug Support and + refered as strict in the source code documentation. However, some applications utilizing + circular_buffer may require less strict definition: an iterator is invalid only if it points to an + uninitialized memory. Consider following example:

        #define BOOST_CB_DISABLE_DEBUG // The Debug Support has to be disabled, otherwise the code produces a runtime error.
    @@ -435,27 +477,31 @@ template <class T, class Alloc>
        }
     

    - The iterator does not point to the original element any more (and is considered to be invalid from the "strict" point of view) but it still points to the same valid place in - the memory. This meaning of iterator invalidation is then marked as loose in the source code documentation. + The iterator does not point to the original element any more (and is considered to be invalid from the + "strict" point of view) but it still points to the same valid place in the memory. This + meaning of iterator invalidation is then marked as loose in the source code documentation.

    - Header Files + Header Files

    - The circular_buffer is defined in the file boost/circular_buffer.hpp . There is also a forward declaration - for the circular_buffer in the header file boost/circular_buffer_fwd.hpp . + The circular_buffer is defined in the file boost/circular_buffer.hpp . There is also a forward declaration + for the circular_buffer in the header file boost/circular_buffer_fwd.hpp .


    - Modeled Concepts + Modeled Concepts

    - Random AccessContainer, Front Insertion - Sequence and Back Insertion Sequence. + Random AccessContainer, Front Insertion Sequence and Back Insertion Sequence.


    - Template Parameters + Template Parameters

    @@ -472,7 +518,7 @@ template <class T, class Alloc>
    - T + T The type of the elements stored in the circular buffer. @@ -481,7 +527,7 @@ template <class T, class Alloc>
    - Alloc + Alloc The allocator type used for all internal memory management. @@ -494,7 +540,7 @@ template <class T, class Alloc>

    - Public Types + Public Types

    @@ -508,7 +554,7 @@ template <class T, class Alloc> + + + +
    - allocator_type + allocator_type The type of the allocator used in the circular buffer. @@ -516,23 +562,31 @@ template <class T, class Alloc>
    - array_range + array_range - An array range. + An array range. TODO - better doc.
    - const_array_range + capacity_control - A range of a const array. + Capacity type (defined just for consistency with circular_buffer_space_optimized).
    - const_iterator + const_array_range + + A range of a const array. TODO - better doc. +
    + const_iterator Const (random access) iterator used to iterate through a circular buffer. @@ -540,7 +594,7 @@ template <class T, class Alloc>
    - const_pointer + const_pointer Const pointer to the element. @@ -548,7 +602,7 @@ template <class T, class Alloc>
    - const_reference + const_reference Const reference to the element. @@ -556,7 +610,7 @@ template <class T, class Alloc>
    - const_reverse_iterator + const_reverse_iterator Const iterator used to iterate backwards through a circular buffer. @@ -564,7 +618,7 @@ template <class T, class Alloc>
    - difference_type + difference_type Distance type. @@ -572,7 +626,7 @@ template <class T, class Alloc>
    - iterator + iterator Iterator (random access) used to iterate through a circular buffer. @@ -580,7 +634,7 @@ template <class T, class Alloc>
    - pointer + pointer Pointer to the element. @@ -588,7 +642,7 @@ template <class T, class Alloc>
    - reference + reference Reference to the element. @@ -596,7 +650,7 @@ template <class T, class Alloc>
    - reverse_iterator + reverse_iterator Iterator used to iterate backwards through a circular buffer. @@ -604,7 +658,7 @@ template <class T, class Alloc>
    - size_type + size_type Size type. @@ -612,7 +666,7 @@ template <class T, class Alloc>
    - value_type + value_type The type of the elements stored in the circular buffer. @@ -622,29 +676,30 @@ template <class T, class Alloc>

    - Constructors and Destructor + Constructors and Destructor

    - template <class InputIterator>
    - circular_buffer(size_type capacity,
    + template <class InputIterator>
    + circular_buffer(size_type capacity,
    InputIterator first, InputIterator last,
    - const allocator_type& alloc = allocator_type());

    + const allocator_type& alloc = + allocator_type());

    - +
    - +
    Create a circular buffer with a copy of a range.
    - +
    Precondition: @@ -654,15 +709,17 @@ template <class T, class Alloc>
    - +
    Postcondition: - (*this).capacity() == capacity
    - If the number of items to copy from the range [first, last) is greater than the specified capacity then only elements from the range - [last - capacity, last) will be copied. + (*this).capacity() == + capacity
    + If the number of items to copy from the range [first, last) is greater than the + specified capacity then only elements from the range [last - capacity, + last) will be copied.
    @@ -673,15 +730,16 @@ template <class T, class Alloc>
    - template <class InputIterator>
    + template <class InputIterator>
    circular_buffer(InputIterator first,
    - InputIterator last, const allocator_type& alloc = allocator_type());

    + InputIterator last, const allocator_type& alloc = + allocator_type());

    - +
    - +
    TODO doc. @@ -695,14 +753,15 @@ template <class T, class Alloc>
    - template <class InputIterator>
    - circular_buffer(size_type capacity, InputIterator first, InputIterator last);

    + template <class InputIterator>
    + circular_buffer(size_type capacity, InputIterator + first, InputIterator last);

    - +
    - +
    @@ -714,14 +773,14 @@ template <class T, class Alloc>
    - template <class InputIterator>
    + template <class InputIterator>
    circular_buffer(InputIterator first, InputIterator last);

    - +
    - +
    @@ -733,21 +792,21 @@ template <class T, class Alloc>
    - circular_buffer(const circular_buffer<T,Alloc>& - cb);
    + circular_buffer(const + circular_buffer<T,Alloc>& cb);
    - +
    - +
    Copy constructor.
    - +
    Postcondition: @@ -764,16 +823,18 @@ template <class T, class Alloc>
    - circular_buffer(size_type - capacity,
    - size_type n, value_type item,
    - const allocator_type& alloc = allocator_type());

    + circular_buffer(size_type capacity,
    + size_type n, value_type item,
    + const allocator_type& alloc = + allocator_type());

    - +
    - +
    TODO doc. @@ -787,30 +848,32 @@ template <class T, class Alloc>
    - circular_buffer(size_type - n,
    - value_type item, const allocator_type& alloc = - allocator_type());

    + circular_buffer(size_type n,
    + value_type item, const allocator_type& alloc = allocator_type());

    - +
    - +
    - Create a full circular buffer with a given capacity and filled with copies of item. + Create a full circular buffer with a given capacity and filled with copies of + item.
    - +
    Postcondition: - capacity() == n && size() == n && - (*this)[0] == (*this)[1] == ... == (*this)[n - 1] == item + capacity() == n && size() == n && (*this)[0] == (*this)[1] == + ... == (*this)[n - 1] == item
    @@ -821,28 +884,29 @@ template <class T, class Alloc>
    - explicit circular_buffer(size_type capacity, const allocator_type& alloc = - allocator_type());
    + explicit circular_buffer(size_type capacity, const allocator_type& alloc = allocator_type());
    - +
    - +
    Create an empty circular buffer with a given capacity.
    - +
    Postcondition: - (*this).capacity() == capacity && (*this).size == 0 + (*this).capacity() == capacity + && (*this).size == 0
    @@ -853,27 +917,28 @@ template <class T, class Alloc>
    - explicit circular_buffer(const explicit circular_buffer(const allocator_type& alloc = allocator_type());
    - +
    - +
    Create an empty circular buffer with a maximum capacity.
    - +
    @@ -885,13 +950,13 @@ template <class T, class Alloc>
    Postcondition: - capacity() == max_size() && capacity() == max_size() && size() == 0
    - ~circular_buffer();
    + ~circular_buffer();
    - +
    - +
    Destructor. @@ -907,20 +972,20 @@ template <class T, class Alloc>

    - Public Member Functions + Public Member Functions

    - const_array_range - array_one() const;
    + const_array_range array_one() const;
    - +
    - +
    TODO doc. @@ -934,14 +999,14 @@ template <class T, class Alloc>
    - array_range - array_one();
    + array_range array_one();
    - +
    - +
    TODO doc. @@ -955,14 +1020,14 @@ template <class T, class Alloc>
    - const_array_range - array_two() const;
    + const_array_range array_two() const;
    - +
    - +
    TODO doc. @@ -976,14 +1041,14 @@ template <class T, class Alloc>
    - array_range - array_two();
    + array_range array_two();
    - +
    - +
    TODO doc. @@ -997,14 +1062,15 @@ template <class T, class Alloc>
    - template <class InputIterator>
    - void assign(size_type capacity, InputIterator first, InputIterator last);

    + template <class InputIterator>
    + void assign(size_type capacity, InputIterator first, + InputIterator last);

    - +
    - +
    TODO doc. @@ -1018,21 +1084,21 @@ template <class T, class Alloc>
    - template <class InputIterator>
    + template <class InputIterator>
    void assign(InputIterator first, InputIterator last);

    - +
    - +
    Assign a copy of range.
    - +
    Precondition: @@ -1042,24 +1108,26 @@ template <class T, class Alloc>
    - +
    Postcondition: - (*this).capacity() == std::distance(first, last) && (*this).(*this).capacity() == + std::distance(first, last) && (*this).size() == std::distance(first, last)
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1070,14 +1138,16 @@ template <class T, class Alloc>
    - void assign(size_type - capacity, size_type n, value_type item);
    + void assign(size_type capacity, size_type n, value_type item);
    - +
    - +
    TODO doc. @@ -1091,38 +1161,42 @@ template <class T, class Alloc>
    - void assign(size_type n, - value_type item);
    + void assign(size_type n, value_type item);
    - +
    - +
    Assign n items into the circular buffer.
    - +
    Postcondition: - (*this).capacity() == n && (*this).size() == n - && (*this)[0] == (*this)[1] == ... == (*this).back() == item + (*this).capacity() == n && + (*this).size() == n && (*this)[0] == + (*this)[1] == ... == (*this).back() == + item
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1133,14 +1207,15 @@ template <class T, class Alloc>
    - value_type at(size_type index) const;
    + value_type at(size_type index) const;
    - +
    - +
    Return the element at the index position. @@ -1154,14 +1229,15 @@ template <class T, class Alloc>
    - reference at(size_type index);
    + reference at(size_type index);
    - +
    - +
    Return the element at the index position. @@ -1175,21 +1251,21 @@ template <class T, class Alloc>
    - value_type back() - const;
    + value_type back() const;
    - +
    - +
    Return the last (rightmost) element.
    - +
    Precondition: @@ -1206,21 +1282,21 @@ template <class T, class Alloc>
    - reference - back();
    + reference back();
    - +
    - +
    Return the last (rightmost) element.
    - +
    Precondition: @@ -1237,14 +1313,14 @@ template <class T, class Alloc>
    - const_iterator begin() - const;
    + const_iterator begin() const;
    - +
    - +
    Return a const iterator pointing to the beginning of the circular buffer. @@ -1258,14 +1334,14 @@ template <class T, class Alloc>
    - iterator - begin();
    + iterator begin();
    - +
    - +
    Return an iterator pointing to the beginning of the circular buffer. @@ -1279,14 +1355,14 @@ template <class T, class Alloc>
    - size_type capacity() - const;
    + size_type capacity() const;
    - +
    - +
    Return the capacity of the circular buffer. @@ -1300,20 +1376,20 @@ template <class T, class Alloc>
    - void clear();
    + void clear();
    - +
    - +
    Erase all stored elements.
    - +
    Postcondition: @@ -1323,13 +1399,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1340,26 +1417,27 @@ template <class T, class Alloc>
    - bool empty() const;
    + bool empty() const;
    - +
    - +
    Is the circular buffer empty?
    - +
    Returns: - true if there are no elements stored in the circular buffer. false otherwise. + true if there are no elements stored in the circular buffer. false + otherwise.
    @@ -1370,14 +1448,14 @@ template <class T, class Alloc>
    - const_iterator end() - const;
    + const_iterator end() const;
    - +
    - +
    Return a const iterator pointing to the end of the circular buffer. @@ -1391,14 +1469,14 @@ template <class T, class Alloc>
    - iterator - end();
    + iterator end();
    - +
    - +
    Return an iterator pointing to the end of the circular buffer. @@ -1412,59 +1490,64 @@ template <class T, class Alloc>
    - iterator erase(iterator first, iterator last);
    + iterator erase(iterator first, iterator last);
    - +
    - +
    Erase the range [first, last).
    - +
    Precondition: - Valid range [first, last). size_type old_size = (*this).size() + Valid range [first, last). size_type old_size = (*this).size()
    - +
    Postcondition: - (*this).size() == old_size - std::distance(first, last)
    + (*this).size() == old_size - + std::distance(first, last)
    Removes the elements from the range [first, last).
    - +
    Returns: - iterator to the first element remaining beyond the removed element or (*this).end() if no such - element exists. + iterator to the first element remaining beyond the removed element or (*this).end() if no such element exists.
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1475,59 +1558,63 @@ template <class T, class Alloc>
    - iterator erase(iterator pos);
    + iterator erase(iterator pos);
    - +
    - +
    Erase the element at the given position.
    - +
    Precondition: - Valid pos iterator. size_type old_size = (*this).size() + Valid pos iterator. size_type old_size = (*this).size()
    - +
    Postcondition: - (*this).size() == old_size - 1
    + (*this).size() == old_size - + 1
    Removes an element at the position pos.
    - +
    Returns: - iterator to the first element remaining beyond the removed element or (*this).end() if no such - element exists. + iterator to the first element remaining beyond the removed element or (*this).end() if no such element exists.
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1538,21 +1625,21 @@ template <class T, class Alloc>
    - value_type front() - const;
    + value_type front() const;
    - +
    - +
    Return the first (leftmost) element.
    - +
    Precondition: @@ -1569,21 +1656,21 @@ template <class T, class Alloc>
    - reference - front();
    + reference front();
    - +
    - +
    Return the first (leftmost) element.
    - +
    Precondition: @@ -1600,26 +1687,27 @@ template <class T, class Alloc>
    - bool full() const;
    + bool full() const;
    - +
    - +
    Is the circular buffer full?
    - +
    Returns: - true if the number of elements stored in the circular buffer equals the capacity of the circular buffer. false otherwise. + true if the number of elements stored in the circular buffer equals the capacity + of the circular buffer. false otherwise.
    @@ -1630,27 +1718,28 @@ template <class T, class Alloc>
    - allocator_type& - get_allocator();
    + allocator_type& get_allocator();
    - +
    - +
    Return the allocator.
    - +
    Note: - This method was added in order to optimize obtaining of the allocator with a state, although use of stateful allocators in STL is discouraged. + This method was added in order to optimize obtaining of the allocator with a state, although + use of stateful allocators in STL is discouraged.
    @@ -1661,14 +1750,14 @@ template <class T, class Alloc>
    - allocator_type - get_allocator() const;
    + allocator_type get_allocator() const;
    - +
    - +
    Return the allocator. @@ -1682,21 +1771,22 @@ template <class T, class Alloc>
    - template <class InputIterator>
    - void insert(iterator pos, InputIterator first, InputIterator last);

    + template <class InputIterator>
    + void insert(iterator pos, InputIterator first, + InputIterator last);

    - +
    - +
    Insert the range [first, last) before the given position.
    - +
    Precondition: @@ -1706,32 +1796,36 @@ template <class T, class Alloc>
    - +
    Postcondition: - This operation preserves the capacity of the circular buffer. If the insertion would result in exceeding the capacity of the circular buffer then the necessary - number of elements from the beginning (left) of the circular buffer will be removed or not the whole range will be inserted or both. In case the whole range cannot - be inserted it will be inserted just some elements from the end (right) of the range (see the example).
    + This operation preserves the capacity of the circular buffer. If the insertion would result in + exceeding the capacity of the circular buffer then the necessary number of elements from the + beginning (left) of the circular buffer will be removed or not the whole range will be inserted + or both. In case the whole range cannot be inserted it will be inserted just some elements from + the end (right) of the range (see the example).
    Example:
    array to insert: int array[] = { 5, 6, 7, 8, 9 };
    original circular buffer |1|2|3|4| | | - capacity: 6, size: 4
    position ---------------------^
    insert(position, array, array + 5);
    - (If the operation won't preserve capacity, the buffer would look like this |1|2|5|6|7|8|9|3|4|)
    + (If the operation won't preserve capacity, the buffer would look like this + |1|2|5|6|7|8|9|3|4|)
    RESULTING circular buffer |6|7|8|9|3|4| - capacity: 6, size: 6
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1742,21 +1836,23 @@ template <class T, class Alloc>
    - void insert(iterator pos, - size_type n, value_type item);
    + void insert(iterator pos, size_type n, value_type item);
    - +
    - +
    Insert n copies of the item before the given position.
    - +
    Precondition: @@ -1766,30 +1862,34 @@ template <class T, class Alloc>
    - +
    Postcondition: - This operation preserves the capacity of the circular buffer. If the insertion would result in exceeding the capacity of the circular buffer then the necessary - number of elements from the beginning (left) of the circular buffer will be removed or not all n elements will be inserted or both.
    + This operation preserves the capacity of the circular buffer. If the insertion would result in + exceeding the capacity of the circular buffer then the necessary number of elements from the + beginning (left) of the circular buffer will be removed or not all n elements will + be inserted or both.
    Example:
    original circular buffer |1|2|3|4| | | - capacity: 6, size: 4
    position ---------------------^
    insert(position, (size_t)5, 6);
    - (If the operation won't preserve capacity, the buffer would look like this |1|2|6|6|6|6|6|3|4|)
    + (If the operation won't preserve capacity, the buffer would look like this + |1|2|6|6|6|6|6|3|4|)
    RESULTING circular buffer |6|6|6|6|3|4| - capacity: 6, size: 6
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1800,21 +1900,23 @@ template <class T, class Alloc>
    - iterator - insert(iterator pos, value_type item = value_type());
    + iterator insert(iterator pos, value_type item = value_type());
    - +
    - +
    Insert the item before the given position.
    - +
    Precondition: @@ -1824,7 +1926,7 @@ template <class T, class Alloc>
    - +
    Postcondition: @@ -1835,7 +1937,7 @@ template <class T, class Alloc>
    - +
    Returns: @@ -1845,13 +1947,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1862,38 +1965,40 @@ template <class T, class Alloc>
    - pointer - linearize();
    + pointer linearize();
    - +
    - +
    - TODO doc - Return pointer to data stored in the circular buffer as a continuous array of values. + TODO doc - Return pointer to data stored in the circular buffer as a continuous array of + values.
    - +
    This method can be useful e.g. when passing the stored data into the legacy C API.
    - +
    Postcondition: - &(*this)[0] < &(*this)[1] < ... < &(*this).back() + &(*this)[0] < &(*this)[1] < ... < &(*this).back()
    - +
    Returns: @@ -1903,13 +2008,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1920,14 +2026,14 @@ template <class T, class Alloc>
    - size_type max_size() - const;
    + size_type max_size() const;
    - +
    - +
    Return the largest possible size (or capacity) of the circular buffer. @@ -1941,21 +2047,21 @@ template <class T, class Alloc>
    - circular_buffer<T,Alloc>& operator=(const - circular_buffer<T,Alloc>& cb);
    + circular_buffer<T,Alloc>& + operator=(const circular_buffer<T,Alloc>& cb);
    - +
    - +
    Assignment operator.
    - +
    Postcondition: @@ -1965,13 +2071,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -1982,21 +2089,22 @@ template <class T, class Alloc>
    - value_type - operator[](size_type index) const;
    + value_type operator[](size_type index) const;
    - +
    - +
    Return the element at the index position.
    - +
    Precondition: @@ -2013,21 +2121,22 @@ template <class T, class Alloc>
    - reference - operator[](size_type index);
    + reference operator[](size_type index);
    - +
    - +
    Return the element at the index position.
    - +
    Precondition: @@ -2044,31 +2153,31 @@ template <class T, class Alloc>
    - void pop_back();
    + void pop_back();
    - +
    - +
    Remove the last (rightmost) element.
    - +
    Precondition: - !*(this).empty() iterator it = ((*this).end() - 1) + !*(this).empty() iterator + it = ((*this).end() - 1)
    - +
    Postcondition: @@ -2078,13 +2187,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2095,31 +2205,31 @@ template <class T, class Alloc>
    - void pop_front();
    + void pop_front();
    - +
    - +
    Remove the first (leftmost) element.
    - +
    Precondition: - !*(this).empty() iterator it = (*this).begin() + !*(this).empty() iterator + it = (*this).begin()
    - +
    Postcondition: @@ -2129,13 +2239,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2146,21 +2257,21 @@ template <class T, class Alloc>
    - void push_back(value_type - item = value_type());
    + void push_back(value_type item = value_type());
    - +
    - +
    Insert a new element at the end.
    - +
    Postcondition: @@ -2171,13 +2282,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2188,21 +2300,21 @@ template <class T, class Alloc>
    - void push_front(value_type item = value_type());
    + void push_front(value_type item = value_type());
    - +
    - +
    Insert a new element at the start.
    - +
    Postcondition: @@ -2213,13 +2325,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2230,14 +2343,14 @@ template <class T, class Alloc>
    - const_reverse_iterator - rbegin() const;
    + const_reverse_iterator rbegin() const;
    - +
    - +
    Return a const reverse iterator pointing to the beginning of the reversed circular buffer. @@ -2251,14 +2364,14 @@ template <class T, class Alloc>
    - reverse_iterator - rbegin();
    + reverse_iterator rbegin();
    - +
    - +
    Return a reverse iterator pointing to the beginning of the reversed circular buffer. @@ -2272,14 +2385,14 @@ template <class T, class Alloc>
    - const_reverse_iterator - rend() const;
    + const_reverse_iterator rend() const;
    - +
    - +
    Return a const reverse iterator pointing to the end of the reversed circular buffer. @@ -2293,14 +2406,14 @@ template <class T, class Alloc>
    - reverse_iterator - rend();
    + reverse_iterator rend();
    - +
    - +
    Return a reverse iterator pointing to the end of the reversed circular buffer. @@ -2314,59 +2427,65 @@ template <class T, class Alloc>
    - iterator - rerase(iterator first, iterator last);
    + iterator rerase(iterator first, iterator last);
    - +
    - +
    Erase the range [first, last).
    - +
    Precondition: - Valid range [first, last). size_type old_size = (*this).size() + Valid range [first, last). size_type old_size = (*this).size()
    - +
    Postcondition: - (*this).size() == old_size - std::distance(first, last)
    + (*this).size() == old_size - + std::distance(first, last)
    Removes the elements from the range [first, last).
    - +
    Returns: - iterator to the first element remaining in front of the removed element or (*this).begin() if no such + iterator to the first element remaining in front of the removed element or + (*this).begin() if no such element exists.
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2377,59 +2496,64 @@ template <class T, class Alloc>
    - iterator - rerase(iterator pos);
    + iterator rerase(iterator pos);
    - +
    - +
    Erase the element at the given position.
    - +
    Precondition: - Valid pos iterator. size_type old_size = (*this).size() + Valid pos iterator. size_type old_size = (*this).size()
    - +
    Postcondition: - (*this).size() == old_size - 1
    + (*this).size() == old_size - + 1
    Removes an element at the position pos.
    - +
    Returns: - iterator to the first element remaining in front of the removed element or (*this).begin() if no such + iterator to the first element remaining in front of the removed element or + (*this).begin() if no such element exists.
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2440,40 +2564,44 @@ template <class T, class Alloc>
    - void resize(size_type - new_size, value_type item = value_type());
    + void resize(size_type new_size, value_type item = value_type());
    - +
    - +
    Change the size of the circular buffer.
    - +
    Postcondition: (*this).size() == new_size
    - If the new size is greater than the current size, the rest of the circular buffer is filled with copies of item. In case the resulting size exceeds the - current capacity the capacity is set to new_size. If the new size is lower than the current size then ((*this).size() - new_size) elements will be removed according to the remove_front parameter. + If the new size is greater than the current size, the rest of the circular buffer is filled + with copies of item. In case the resulting size exceeds the current capacity the + capacity is set to new_size. If the new size is lower than the current size then + ((*this).size() - new_size) + elements will be removed according to the remove_front parameter.
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2484,21 +2612,22 @@ template <class T, class Alloc>
    - template <class InputIterator>
    - void rinsert(iterator pos, InputIterator first, InputIterator last);

    + template <class InputIterator>
    + void rinsert(iterator pos, InputIterator first, + InputIterator last);

    - +
    - +
    Insert the range [first, last) before the given position.
    - +
    Precondition: @@ -2508,32 +2637,36 @@ template <class T, class Alloc>
    - +
    Postcondition: - This operation preserves the capacity of the circular buffer. If the insertion would result in exceeding the capacity of the circular buffer then the necessary - number of elements from the end (right) of the circular buffer will be removed or not the whole range will be inserted or both. In case the whole range cannot be - inserted it will be inserted just some elements from the beginning (left) of the range (see the example).
    + This operation preserves the capacity of the circular buffer. If the insertion would result in + exceeding the capacity of the circular buffer then the necessary number of elements from the + end (right) of the circular buffer will be removed or not the whole range will be inserted or + both. In case the whole range cannot be inserted it will be inserted just some elements from + the beginning (left) of the range (see the example).
    Example:
    array to insert: int array[] = { 5, 6, 7, 8, 9 };
    original circular buffer |1|2|3|4| | | - capacity: 6, size: 4
    position ---------------------^
    insert(position, array, array + 5);
    - (If the operation won't preserve capacity, the buffer would look like this |1|2|5|6|7|8|9|3|4|)
    + (If the operation won't preserve capacity, the buffer would look like this + |1|2|5|6|7|8|9|3|4|)
    RESULTING circular buffer |1|2|5|6|7|8| - capacity: 6, size: 6
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2544,21 +2677,23 @@ template <class T, class Alloc>
    - void rinsert(iterator pos, - size_type n, value_type item);
    + void rinsert(iterator pos, size_type n, value_type item);
    - +
    - +
    Insert n copies of the item before the given position.
    - +
    Precondition: @@ -2568,30 +2703,34 @@ template <class T, class Alloc>
    - +
    Postcondition: - This operation preserves the capacity of the circular buffer. If the insertion would result in exceeding the capacity of the circular buffer then the necessary - number of elements from the end (right) of the circular buffer will be removed or not all n elements will be inserted or both.
    + This operation preserves the capacity of the circular buffer. If the insertion would result in + exceeding the capacity of the circular buffer then the necessary number of elements from the + end (right) of the circular buffer will be removed or not all n elements will be + inserted or both.
    Example:
    original circular buffer |1|2|3|4| | | - capacity: 6, size: 4
    position ---------------------^
    insert(position, (size_t)5, 6);
    - (If the operation won't preserve capacity, the buffer would look like this |1|2|6|6|6|6|6|3|4|)
    + (If the operation won't preserve capacity, the buffer would look like this + |1|2|6|6|6|6|6|3|4|)
    RESULTING circular buffer |1|2|6|6|6|6| - capacity: 6, size: 6
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2602,21 +2741,23 @@ template <class T, class Alloc>
    - iterator - rinsert(iterator pos, value_type item = value_type());
    + iterator rinsert(iterator pos, value_type item = value_type());
    - +
    - +
    Insert an item before the given position.
    - +
    Precondition: @@ -2626,7 +2767,7 @@ template <class T, class Alloc>
    - +
    Postcondition: @@ -2637,7 +2778,7 @@ template <class T, class Alloc>
    - +
    Returns: @@ -2647,13 +2788,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2664,14 +2806,15 @@ template <class T, class Alloc>
    - void rresize(size_type - new_size, value_type item = value_type());
    + void rresize(size_type new_size, value_type item = value_type());
    - +
    - +
    TODO doc. @@ -2685,14 +2828,14 @@ template <class T, class Alloc>
    - void rset_capacity(size_type new_capacity);
    + void rset_capacity(size_type new_capacity);
    - +
    - +
    TODO doc. @@ -2706,39 +2849,43 @@ template <class T, class Alloc>
    - void set_capacity(size_type new_capacity);
    + void set_capacity(size_type new_capacity);
    - +
    - +
    Change the capacity of the circular buffer.
    - +
    Postcondition: - (*this).capacity() == new_capacity
    - If the current number of elements stored in the circular buffer is greater than the desired new capacity then ((*this).size() - new_capacity) elements will be removed according to the remove_front parameter. + (*this).capacity() == + new_capacity
    + If the current number of elements stored in the circular buffer is greater than the desired + new capacity then ((*this).size() - + new_capacity) elements will be removed according to the remove_front + parameter.
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2749,14 +2896,14 @@ template <class T, class Alloc>
    - size_type size() - const;
    + size_type size() const;
    - +
    - +
    Return the number of elements currently stored in the circular buffer. @@ -2770,20 +2917,21 @@ template <class T, class Alloc>
    - void swap(circular_buffer<T,Alloc>& cb);
    + void swap(circular_buffer<T,Alloc>& + cb);
    - +
    - +
    Swap the contents of two circular buffers.
    - +
    Postcondition: @@ -2793,13 +2941,14 @@ template <class T, class Alloc>
    - +
    Note: - For iterator invalidation see the documentation. + For iterator invalidation see the documentation.
    @@ -2812,20 +2961,21 @@ template <class T, class Alloc>

    - Standalone Functions + Standalone Functions

    - template <class T, class Alloc>
    - bool operator!=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs);

    + template <class T, class Alloc>
    + bool operator!=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& + rhs);

    - +
    Test two circular buffers for non-equality. @@ -2839,14 +2989,15 @@ template <class T, class Alloc>
    - template <class T, class Alloc>
    - bool operator<(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs);

    + template <class T, class Alloc>
    + bool operator<(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& + rhs);

    - +
    - +
    Lexicographical comparison. @@ -2860,14 +3011,15 @@ template <class T, class Alloc>
    - template <class T, class Alloc>
    - bool operator<=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs);

    + template <class T, class Alloc>
    + bool operator<=(const circular_buffer<T,Alloc>& lhs, const + circular_buffer<T,Alloc>& rhs);

    - +
    - +
    Lexicographical comparison. @@ -2881,14 +3033,15 @@ template <class T, class Alloc>
    - template <class T, class Alloc>
    - bool operator==(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs);

    + template <class T, class Alloc>
    + bool operator==(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& + rhs);

    - +
    - +
    Test two circular buffers for equality. @@ -2902,14 +3055,15 @@ template <class T, class Alloc>
    - template <class T, class Alloc>
    - bool operator>(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs);

    + template <class T, class Alloc>
    + bool operator>(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& + rhs);

    - +
    - +
    Lexicographical comparison. @@ -2923,14 +3077,15 @@ template <class T, class Alloc>
    - template <class T, class Alloc>
    - bool operator>=(const circular_buffer<T,Alloc>& lhs, const circular_buffer<T,Alloc>& rhs);

    + template <class T, class Alloc>
    + bool operator>=(const circular_buffer<T,Alloc>& lhs, const + circular_buffer<T,Alloc>& rhs);

    - +
    - +
    Lexicographical comparison. @@ -2944,14 +3099,15 @@ template <class T, class Alloc>
    - template <class T, class Alloc>
    - void swap(circular_buffer<T,Alloc>& lhs, circular_buffer<T,Alloc>& rhs);

    + template <class T, class Alloc>
    + void swap(circular_buffer<T,Alloc>& lhs, circular_buffer<T,Alloc>& + rhs);

    - +
    - +
    Swap the contents of two circular buffers. @@ -2967,7 +3123,7 @@ template <class T, class Alloc>

    - Semantics + Semantics

    TODO remove this section @@ -2977,7 +3133,8 @@ template <class T, class Alloc>

    • - The capacity of a circular_buffer remains fixed unless adjusted via set_capacity or resize . + The capacity of a circular_buffer remains fixed unless adjusted via set_capacity or + resize .
    • insert will overwrite front elements as necessary. @@ -2991,7 +3148,8 @@ template <class T, class Alloc>

      • - The capacity will be adjusted to accommodate a resize . (The capacity can be only increased, not decreased.) + The capacity will be adjusted to accommodate a resize . (The capacity can be only increased, not + decreased.)

      @@ -2999,97 +3157,113 @@ template <class T, class Alloc>

      • - The capacity will be adjusted to accommodate an assign . (The capacity can be only increased, not decreased.) + The capacity will be adjusted to accommodate an assign . (The capacity can be only increased, not + decreased.)

      - The rules for iterator (and result of data() ) invalidation for circular_buffer are as follows: + The rules for iterator (and result of data() ) invalidation for + circular_buffer are as follows:

      • - insert at the end of the circular_buffer (including push_back ) does not invalidate any iterator except the case the iterator points to the - overwritten element. + insert at the end of the circular_buffer (including push_back ) does not + invalidate any iterator except the case the iterator points to the overwritten element.
      • - rinsert at the beginning of the circular_buffer (including push_front ) does not invalidate any iterator except the case the iterator points - to the overwritten element. + rinsert at the beginning of the circular_buffer (including push_front ) + does not invalidate any iterator except the case the iterator points to the overwritten element.
      • - insert in the middle of the circular_buffer invalidates iterators pointing to the elements at the insertion point and behind the insertion point. It also - invalidates iterators pointing to the overwritten element(s). -
      • -
      • - rinsert in the middle of the circular_buffer invalidates iterators pointing to the elements before the insertion point and iterators pointing to the + insert in the middle of the circular_buffer invalidates iterators pointing to the + elements at the insertion point and behind the insertion point. It also invalidates iterators pointing to the overwritten element(s).
      • - erase at the end of the circular_buffer (including pop_back ) invalidates only iterators pointing to the erased element(s). + rinsert in the middle of the circular_buffer invalidates iterators pointing to the + elements before the insertion point and iterators pointing to the overwritten element(s). +
      • +
      • + erase at the end of the circular_buffer (including pop_back ) + invalidates only iterators pointing to the erased element(s).
      • pop_front invalidates only iterators pointing to the erased element.
      • - erase at the beginning or in the middle of the circular_buffer invalidates iterators pointing to the erased element(s) and iterators pointing to the - elements behind the erase point. + erase at the beginning or in the middle of the circular_buffer invalidates iterators + pointing to the erased element(s) and iterators pointing to the elements behind the erase point.
      • - data , set_capacity , resize , operator= , assign , swap and clear invalidate all - iterators pointing to the circular_buffer . + data , set_capacity , resize , operator= , + assign , swap and clear invalidate all iterators pointing to the + circular_buffer .

      - In addition to the preceding rules the iterators get also invalidated due to overwriting (e.g. iterator pointing to the front-most element gets invalidated when inserting into the - full circular_buffer ). They get invalidated in that sense they do not point to the same element as before but they do still point to the same valid place in the - memory. If you want to rely on this feature you have to turn of the Debug Support otherwise an assertion will report an error if such invalidated iterator is - used. + In addition to the preceding rules the iterators get also invalidated due to overwriting (e.g. iterator pointing + to the front-most element gets invalidated when inserting into the full circular_buffer ). They get + invalidated in that sense they do not point to the same element as before but they do still point to the same + valid place in the memory. If you want to rely on this feature you have to turn of the Debug Support otherwise an assertion will report an error if such invalidated iterator is used.


      - Caveats + Caveats

      - The circular_buffer should not be used for storing pointers to dynamically allocated objects. When a circular_buffer becomes full, further insertion will - overwrite the stored pointers - resulting in a memoryleak. One recommend alternative is the use of smart pointers [2]. (Any container of - std::auto_ptr is considered particularly hazardous. [3] ) + The circular_buffer should not be used for storing pointers to dynamically allocated objects. When a + circular_buffer becomes full, further insertion will overwrite the stored pointers - resulting in a + memoryleak. One recommend alternative is the use of smart pointers [2]. (Any + container of std::auto_ptr is considered particularly hazardous. [3] )

      - Elements inserted near the front of a full circular_buffer can be lost. According to the semantics of insert , insertion overwrites - front-most items as necessary - possibly including elements currently being inserted at the front of the buffer. Conversely, push_front to a full - circular_buffer is guaranteed to overwrite the back-most element. + Elements inserted near the front of a full circular_buffer can be lost. According to the semantics of insert , insertion overwrites front-most items as necessary - possibly + including elements currently being inserted at the front of the buffer. Conversely, + push_front to a full circular_buffer is guaranteed to overwrite the back-most element.

      - Elements inserted near the back of a full circular_buffer can be lost. According to the semantics of rinsert , insertion overwrites - back-most items as necessary - possibly including elements currently being inserted at the back of the buffer. Conversely, push_back to a full - circular_buffer is guaranteed to overwrite the front-most element. + Elements inserted near the back of a full circular_buffer can be lost. According to the semantics of rinsert , insertion overwrites back-most items as necessary - possibly + including elements currently being inserted at the back of the buffer. Conversely, push_back + to a full circular_buffer is guaranteed to overwrite the front-most element.

      - While internals of a circular_buffer are circular, iterators are not. Iterators of a circular_buffer are only valid for the range [begin(), - end()] . E.g. iterators (begin() - 1) and (end() + 1) are invalid. + While internals of a circular_buffer are circular, iterators are not. Iterators of a + circular_buffer are only valid for the range [begin(), end()] . E.g. iterators + (begin() - 1) and (end() + 1) are invalid.


      - Debug Support + Debug Support

      - In order to help a programmer to avoid and find common bugs, the circular_buffer contains a kind of debug support. + In order to help a programmer to avoid and find common bugs, the circular_buffer contains a kind of + debug support.

      - The circular_buffer maintains a list of valid iterators. As soon as any element gets destroyed all iterators pointing to this element are removed from this list and - explicitly invalidated (an invalidation flag is set). The debug support also consists of many assertions ( BOOST_ASSERT - macros) which ensure the circular_buffer and its iterators are used in the correct manner at runtime. In case an invalid iterator is used the assertion will report an - error. The connection of explicit iterator invalidation and assertions makes a very robust debug technique which catches most of the errors. + The circular_buffer maintains a list of valid iterators. As soon as any element gets destroyed all + iterators pointing to this element are removed from this list and explicitly invalidated (an invalidation flag is + set). The debug support also consists of many assertions ( BOOST_ASSERT macros) which ensure the + circular_buffer and its iterators are used in the correct manner at runtime. In case an invalid + iterator is used the assertion will report an error. The connection of explicit iterator invalidation and + assertions makes a very robust debug technique which catches most of the errors.

      - Moreover, the uninitialized memory allocated by circular_buffer is filled with the value 0xcc in the debug mode. This can help the programmer when debugging - the code to recognize the initialized memory from the uninitialized. For details refer the source code. + Moreover, the uninitialized memory allocated by circular_buffer is filled with the value + 0xcc in the debug mode. This can help the programmer when debugging the code to recognize the + initialized memory from the uninitialized. For details refer the source code.

      - The debug support is enabled only in the debug mode (when the NDEBUG is not defined). It can also be explicitly disabled by defining BOOST_CB_DISABLE_DEBUG - macro. + The debug support is enabled only in the debug mode (when the NDEBUG is not defined). It can also be + explicitly disabled by defining BOOST_CB_DISABLE_DEBUG macro.


      - More Examples + More Examples

      The following example includes various usage of the circular_buffer . @@ -3138,20 +3312,23 @@ template <class T, class Alloc> }

      - The circular_buffer has a capacity of three int. Therefore, the size of the buffer will not exceed three. The accumulate algorithm evaluates the sum of the stored elements. The semantics of the circular_buffer can be - inferred from the assertions. + The circular_buffer has a capacity of three int. Therefore, the size of the buffer will + not exceed three. The accumulate algorithm + evaluates the sum of the stored elements. The semantics of the circular_buffer can be inferred from + the assertions.

      - Bounded Buffer Example + Bounded Buffer Example

      - The bounded buffer is normally used in a producer-consumer mode when producer threads produce items and store them in the container and consumer threads remove these items and process - them. The bounded buffer has to guarantee that producers do not insert items into the container when the container is full, that consumers do not try to remove items when the - container is empty, and that each produced item is consumed by exactly one consumer. + The bounded buffer is normally used in a producer-consumer mode when producer threads produce items and store + them in the container and consumer threads remove these items and process them. The bounded buffer has to + guarantee that producers do not insert items into the container when the container is full, that consumers do not + try to remove items when the container is empty, and that each produced item is consumed by exactly one consumer.

      - The example below shows how the circular_buffer can be utilized as an underlying container of the bounded buffer. + The example below shows how the circular_buffer can be utilized as an underlying container of the + bounded buffer.

          #include <boost/circular_buffer.hpp>
      @@ -3203,86 +3380,113 @@ template <class T, class Alloc>
          };
       

      - The bounded_buffer uses Boost Threads and Boost Bind libraries. + The bounded_buffer uses Boost Threads and Boost Bind libraries.

      - The push_front() method is called by the producer thread in order to insert a new item into the buffer. The method locks the mutex and waits until there is a space for - the new item. (The mutex is unlocked during the waiting stage and has to be regained when the condition is met.) If there is a space in the buffer available, the execution continues - and the method inserts the item at the end of the circular_buffer. Then it increments the number of unread items and unlocks the mutex (in case an exception is thrown - before the mutex is unlocked, the mutex is unlocked automatically by the destructor of the scoped_lock). At last the method notifies one of the consumer threads waiting - for a new item to be inserted into the buffer. + The push_front() method is called by the producer thread in order to insert a new item into the + buffer. The method locks the mutex and waits until there is a space for the new item. (The mutex is unlocked + during the waiting stage and has to be regained when the condition is met.) If there is a space in the buffer + available, the execution continues and the method inserts the item at the end of the + circular_buffer. Then it increments the number of unread items and unlocks the mutex (in case an + exception is thrown before the mutex is unlocked, the mutex is unlocked automatically by the destructor of the + scoped_lock). At last the method notifies one of the consumer threads waiting for a new item to be + inserted into the buffer.

      - The pop_back() method is called by the consumer thread in order to read the next item from the buffer. The method locks the mutex and waits until there is an unread item - in the buffer. If there is at least one unread item, the method decrements the number of unread items and reads the next item from the circular_buffer. Then it unlocks - the mutex and notifies one of the producer threads waiting for the buffer to free a space for the next item. + The pop_back() method is called by the consumer thread in order to read the next item from the + buffer. The method locks the mutex and waits until there is an unread item in the buffer. If there is at least + one unread item, the method decrements the number of unread items and reads the next item from the + circular_buffer. Then it unlocks the mutex and notifies one of the producer threads waiting for the + buffer to free a space for the next item.

      - The pop_back() method does not remove the item but the item is left in the circular_buffer which then replaces it with a new one (inserted by a producer) - when the circular_buffer is full. This technique is more effective than removing the item explicitly by calling the pop_back() method of the - circular_buffer. This claim is based on the assumption that an assignment (replacement) of a new item into an old one is more effective than a destruction (removal) of an - old item and a consequent inplace construction (insertion) of a new item. + The pop_back() method does not remove the item but the item is left in the + circular_buffer which then replaces it with a new one (inserted by a producer) when the + circular_buffer is full. This technique is more effective than removing the item explicitly by + calling the pop_back() method of the circular_buffer. This claim is based on the + assumption that an assignment (replacement) of a new item into an old one is more effective than a destruction + (removal) of an old item and a consequent inplace construction (insertion) of a new item.

      - For comparison of bounded buffers based on different containers compile and run bounded_buffer_comparison.cpp. The test should - reveal the bounded buffer based on the circular_buffer is most effective closely followed by the std::deque based bounded buffer. (In praxis the result may - be different because the test is affected by external factors such as immediate CPU load.) + For comparison of bounded buffers based on different containers compile and run bounded_buffer_comparison.cpp. The test should reveal the bounded + buffer based on the circular_buffer is most effective closely followed by the + std::deque based bounded buffer. (In praxis the result may be different because the test is affected + by external factors such as immediate CPU load.)

      - Notes + Notes

      1. - +

        - An indepth definition of a circular buffer can be found at Wikipedia. + An indepth definition of a circular buffer can be found at Wikipedia.

      2. - +

        A good implementation of smart pointers is included in Boost.

      3. - +

        - Never create a circular buffer of std::auto_ptr . Refer to Scott Meyers ' excellent book Effective STL for a detailed - discussion. (Meyers S., Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library. Addison-Wesley, 2001.) + Never create a circular buffer of std::auto_ptr . Refer to Scott Meyers ' excellent book Effective STL for a detailed + discussion. (Meyers S., Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template + Library. Addison-Wesley, 2001.)


      - See also + See also

      - boost::circular_buffer_space_optimized, std::vector, std::list, std::deque + boost::circular_buffer_space_optimized, std::vector, std::list, std::deque


      - Acknowledgments + Acknowledgments

      - The circular_buffer has a short history. Its first version was a std::deque adaptor. This container was not very effective because of many reallocations when - inserting/removing an element. Thomas Wenish did a review of this version and motivated me to create a circular buffer which allocates memory at once when created. + The circular_buffer has a short history. Its first version was a std::deque adaptor. + This container was not very effective because of many reallocations when inserting/removing an element. Thomas + Wenish did a review of this version and motivated me to create a circular buffer which allocates memory at once + when created.

      - The second version adapted std::vector but it has been abandoned soon because of limited control over iterator invalidation. + The second version adapted std::vector but it has been abandoned soon because of limited control + over iterator invalidation.

      - The current version is a full-fledged STL compliant container. Pavel Vozenilek did a thorough review of this version and came with many good ideas and improvements. Also, I would like - to thank Howard Hinnant, Nigel Stewart and everyone who participated at the formal review for valuable comments and ideas. + The current version is a full-fledged STL compliant container. Pavel Vozenilek did a thorough review of this + version and came with many good ideas and improvements. Also, I would like to thank Howard Hinnant, Nigel Stewart + and everyone who participated at the formal review for valuable comments and ideas.

      -
      +
      - + diff --git a/doc/circular_buffer_space_optimized.html b/doc/circular_buffer_space_optimized.html index 0c909e3..67ed31d 100644 --- a/doc/circular_buffer_space_optimized.html +++ b/doc/circular_buffer_space_optimized.html @@ -1,8 +1,7 @@ - + - + Space Optimized Circular Buffer @@ -36,19 +35,22 @@ Acknowledgments

      - Description + Description

      - The circular_buffer_space_optimized container is an adaptor of the circular_buffer . The functionality of the - circular_buffer_space_optimized is similar to the base circular_buffer except it does not allocate memory at once when created rather it allocates memory as - needed. (The predictive memory allocation is similar to typical std::vector implementation.) Moreover the memory is automatically freed as the size of the container - decreases. + The circular_buffer_space_optimized container is an adaptor of the circular_buffer . The functionality of the + circular_buffer_space_optimized is similar to the base circular_buffer except it does + not allocate memory at once when created rather it allocates memory as needed. (The predictive memory allocation + is similar to typical std::vector implementation.) Moreover the memory is automatically freed as the + size of the container decreases.

      @@ -56,14 +58,15 @@ Figure:
      - Space Optimized Circular Buffer + Space Optimized Circular Buffer
      - The memory allocation process of the space optimized circular buffer. The min_capacity represents the minimal guaranteed amount of allocated memory. The allocated - memory will never drop under this value. By default the min_capacity is set to 0. + The memory allocation process of the space optimized circular buffer. The min_capacity + represents the minimal guaranteed amount of allocated memory. The allocated memory will never drop under this + value. By default the min_capacity is set to 0.

      - Synopsis + Synopsis

      @@ -72,58 +75,81 @@
       namespace boost {
       
      -template <class T, class Alloc>
      +template <class T, class Alloc>
       class circular_buffer_space_optimized
       {
       public:
          typedef Alloc allocator_type;
      -   typedef implementation-defined array_range;
      -   typedef implementation-defined capacity_control;
      -   typedef implementation-defined const_array_range;
      -   typedef implementation-defined const_iterator;
      -   typedef typename Alloc::const_pointer const_pointer;
      -   typedef typename Alloc::const_reference const_reference;
      -   typedef implementation-defined const_reverse_iterator;
      -   typedef typename Alloc::difference_type difference_type;
      -   typedef implementation-defined iterator;
      -   typedef typename Alloc::pointer pointer;
      -   typedef typename Alloc::reference reference;
      -   typedef implementation-defined reverse_iterator;
      -   typedef typename Alloc::size_type size_type;
      -   typedef typename Alloc::value_type value_type;
      +   typedef implementation-defined array_range;
      +   typedef size_type capacity_control;
      +   typedef implementation-defined const_array_range;
      +   typedef implementation-defined const_iterator;
      +   typedef typename Alloc::const_pointer const_pointer;
      +   typedef typename Alloc::const_reference const_reference;
      +   typedef implementation-defined const_reverse_iterator;
      +   typedef typename Alloc::difference_type difference_type;
      +   typedef implementation-defined iterator;
      +   typedef typename Alloc::pointer pointer;
      +   typedef typename Alloc::reference reference;
      +   typedef implementation-defined reverse_iterator;
      +   typedef typename Alloc::size_type size_type;
      +   typedef typename Alloc::value_type value_type;
       
          template <class InputIterator>
      -circular_buffer_space_optimized(capacity_control capacity_ctrl, 
      +circular_buffer_space_optimized(capacity_control capacity_ctrl, 
                InputIterator first, InputIterator last, 
                const allocator_type& alloc = allocator_type());
          template <class InputIterator>
      -circular_buffer_space_optimized(InputIterator first, 
      +circular_buffer_space_optimized(InputIterator first, 
                InputIterator last, const allocator_type& alloc = allocator_type());
          template <class InputIterator>
      -circular_buffer_space_optimized(capacity_control capacity_ctrl, InputIterator first, InputIterator last);
      +circular_buffer_space_optimized(capacity_control capacity_ctrl, InputIterator first, InputIterator last);
          template <class InputIterator>
      -circular_buffer_space_optimized(InputIterator first, InputIterator last);
      -circular_buffer_space_optimized(capacity_control capacity_ctrl, 
      +circular_buffer_space_optimized(InputIterator first, InputIterator last);
      +circular_buffer_space_optimized(capacity_control capacity_ctrl, 
             size_type n, value_type item, 
             const allocator_type& alloc = allocator_type());
      -circular_buffer_space_optimized(capacity_control capacity_ctrl, 
      +circular_buffer_space_optimized(capacity_control capacity_ctrl, 
             value_type item, const allocator_type& alloc = allocator_type());
          explicit circular_buffer_space_optimized(capacity_control capacity_ctrl, const allocator_type& alloc = allocator_type());
      -   explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type());
      +   explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type());
       
          const_array_range array_one() const;
          array_range array_one();
          const_array_range array_two() const;
          array_range array_two();
          template <class InputIterator>
      -      void assign(capacity_control capacity_ctrl, InputIterator first, InputIterator last);
      -   void assign(capacity_control capacity_ctrl, size_type n, value_type item);
      +      void assign(capacity_control capacity_ctrl, InputIterator first, InputIterator last);
      +   void assign(capacity_control capacity_ctrl, size_type n, value_type item);
          template <class InputIterator>
      -      void assign(size_type capacity, InputIterator first, InputIterator last);
      +      void assign(size_type capacity, InputIterator first, InputIterator last);
          template <class InputIterator>
      -      void assign(InputIterator first, InputIterator last);
      -   void assign(size_type capacity, size_type n, value_type item);
      +      void assign(InputIterator first, InputIterator last);
      +   void assign(size_type capacity, size_type n, value_type item);
          void assign(size_type n, value_type item);
          value_type at(size_type index) const;
          reference at(size_type index);
      @@ -144,9 +170,12 @@ public:
          allocator_type& get_allocator();
          allocator_type get_allocator() const;
          template <class InputIterator>
      -      void insert(iterator pos, InputIterator first, InputIterator last);
      -   void insert(iterator pos, size_type n, value_type item);
      -   iterator insert(iterator pos, value_type item = value_type());
      +      void insert(iterator pos, InputIterator first, InputIterator last);
      +   void insert(iterator pos, size_type n, value_type item);
      +   iterator insert(iterator pos, value_type item = value_type());
          pointer linearize();
          size_type max_size() const;
          size_type min_capacity() const;
      @@ -157,46 +186,61 @@ public:
          void pop_back();
          void pop_front();
          void push_back(value_type item = value_type());
      -   void push_front(value_type item = value_type());
      +   void push_front(value_type item = value_type());
          const_reverse_iterator rbegin() const;
          reverse_iterator rbegin();
          const_reverse_iterator rend() const;
          reverse_iterator rend();
          iterator rerase(iterator first, iterator last);
          iterator rerase(iterator pos);
      -   void resize(size_type new_size, value_type item = value_type());
      +   void resize(size_type new_size, value_type item = value_type());
          template <class InputIterator>
      -      void rinsert(iterator pos, InputIterator first, InputIterator last);
      -   void rinsert(iterator pos, size_type n, value_type item);
      -   iterator rinsert(iterator pos, value_type item = value_type());
      -   void rresize(size_type new_size, value_type item = value_type());
      +      void rinsert(iterator pos, InputIterator first, InputIterator last);
      +   void rinsert(iterator pos, size_type n, value_type item);
      +   iterator rinsert(iterator pos, value_type item = value_type());
      +   void rresize(size_type new_size, value_type item = value_type());
          void rset_capacity(size_type new_capacity);
          void set_capacity(size_type new_capacity);
      -   void set_min_capacity(size_type new_min_capacity);
      +   void set_min_capacity(size_type new_min_capacity);
          size_type size() const;
      -   void swap(circular_buffer_space_optimized<T,Alloc>& cb);
      +   void swap(circular_buffer_space_optimized<T,Alloc>& cb);
       };
       
       template <class T, class Alloc>
      -   bool operator!=(const circular_buffer_space_optimized<T,Alloc>& lhs, 
      +   bool operator!=(const circular_buffer_space_optimized<T,Alloc>& lhs, 
             const circular_buffer_space_optimized<T,Alloc>& rhs);
       template <class T, class Alloc>
      -   bool operator<(const circular_buffer_space_optimized<T,Alloc>& lhs, 
      +   bool operator<(const circular_buffer_space_optimized<T,Alloc>& lhs, 
             const circular_buffer_space_optimized<T,Alloc>& rhs);
       template <class T, class Alloc>
      -   bool operator<=(const circular_buffer_space_optimized<T,Alloc>& lhs, 
      +   bool operator<=(const circular_buffer_space_optimized<T,Alloc>& lhs, 
             const circular_buffer_space_optimized<T,Alloc>& rhs);
       template <class T, class Alloc>
      -   bool operator==(const circular_buffer_space_optimized<T,Alloc>& lhs, 
      +   bool operator==(const circular_buffer_space_optimized<T,Alloc>& lhs, 
             const circular_buffer_space_optimized<T,Alloc>& rhs);
       template <class T, class Alloc>
      -   bool operator>(const circular_buffer_space_optimized<T,Alloc>& lhs, 
      +   bool operator>(const circular_buffer_space_optimized<T,Alloc>& lhs, 
             const circular_buffer_space_optimized<T,Alloc>& rhs);
       template <class T, class Alloc>
      -   bool operator>=(const circular_buffer_space_optimized<T,Alloc>& lhs, 
      +   bool operator>=(const circular_buffer_space_optimized<T,Alloc>& lhs, 
             const circular_buffer_space_optimized<T,Alloc>& rhs);
       template <class T, class Alloc>
      -   void swap(circular_buffer_space_optimized<T,Alloc>& lhs, 
      +   void swap(circular_buffer_space_optimized<T,Alloc>& lhs, 
             circular_buffer_space_optimized<T,Alloc>& rhs);
       
       } // namespace boost
      @@ -206,69 +250,74 @@ template <class T, class Alloc>
             

      - Rationale + Rationale

      - The auto-resizing mode of the space optimized circular buffer can be useful in situations when the container can possibly store large number of elements but most of its lifetime the - container stores just few of them. The usage of the circular_buffer_space_optimized will result in decreased memory consumption and can improve the CPU cache - effectiveness. + The auto-resizing mode of the space optimized circular buffer can be useful in situations when the container can + possibly store large number of elements but most of its lifetime the container stores just few of them. The usage + of the circular_buffer_space_optimized will result in decreased memory consumption and can improve + the CPU cache effectiveness.


      - Header Files + Header Files

      - The circular_buffer_space_optimized is defined in the file boost/circular_buffer.hpp . There is also a - forward declaration for the circular_buffer_space_optimized in the header file circular_buffer_space_optimized is defined in the file boost/circular_buffer.hpp . There is also a forward declaration + for the circular_buffer_space_optimized in the header file boost/circular_buffer_fwd.hpp .


      - Modeled concepts + Modeled concepts

      - Random AccessContainer, Front Insertion - Sequence, Back Insertion Sequence, Assignable (SGI - specific), Equality Comparable, LessThan Comparable - (SGI specific) + Random AccessContainer, Front Insertion Sequence and Back Insertion Sequence.


      - Template Parameters, Members and Friend Functions + Template Parameters, Members and Friend Functions

      - Template parameters, members and friend functions of the circular_buffer_space_optimized are almost the same as for the base circular_buffer . Refer the - circular_buffer documentation and also its source code documentation for a detailed - description. + Template parameters, members and friend functions of the circular_buffer_space_optimized are almost + the same as for the base circular_buffer . Refer the circular_buffer documentation and also its source code + documentation for a detailed description.

      The specific methods of the circular_buffer_space_optimized are listed below.


      - Constructors + Constructors

      - template <class InputIterator>
      - circular_buffer_space_optimized(capacity_control capacity_ctrl,
      + template <class + InputIterator>
      + circular_buffer_space_optimized(capacity_control capacity_ctrl,
      InputIterator first, InputIterator last,
      - const allocator_type& alloc = allocator_type());

      + const allocator_type& alloc = + allocator_type());

      - +
      - +
      Create a space optimized circular buffer with a copy of a range.
      - +
      Precondition: @@ -278,26 +327,30 @@ template <class T, class Alloc>
      - +
      Postcondition: - (*this).capacity() == capacity
      - Allocates at least as much memory as specified by the - TODO change min_capacity parameter.
      - If the number of items to copy from the range [first, last) is greater than the specified capacity then only elements from the range - [last - capacity, last) will be copied. + (*this).capacity() + == capacity
      + Allocates at least as much memory as specified by the - TODO change min_capacity + parameter.
      + If the number of items to copy from the range [first, last) is greater than the + specified capacity then only elements from the range [last - capacity, + last) will be copied.
      - +
      Note: - It is considered as a bug if the precondition is not met (i.e. if capacity < min_capacity) and an assertion will be invoked in the debug mode. + It is considered as a bug if the precondition is not met (i.e. if capacity < + min_capacity) and an assertion will be invoked in the debug mode.
      @@ -308,15 +361,18 @@ template <class T, class Alloc>
      - template <class InputIterator>
      + template <class + InputIterator>
      circular_buffer_space_optimized(InputIterator first,
      - InputIterator last, const allocator_type& alloc = allocator_type());

      + InputIterator last, const allocator_type& alloc = + allocator_type());

      - +
      - +
      TODO doc. @@ -330,15 +386,17 @@ template <class T, class Alloc>
      - template <class InputIterator>
      - circular_buffer_space_optimized(capacity_control capacity_ctrl, InputIterator first, InputIterator - last);

      + template <class + InputIterator>
      + circular_buffer_space_optimized(capacity_control capacity_ctrl, InputIterator + first, InputIterator last);

      - +
      - +
      @@ -350,14 +408,15 @@ template <class T, class Alloc>
      - template <class InputIterator>
      + template <class + InputIterator>
      circular_buffer_space_optimized(InputIterator first, InputIterator last);

      - +
      - +
      @@ -369,17 +428,19 @@ template <class T, class Alloc>
      - - circular_buffer_space_optimized(capacity_control capacity_ctrl,
      - size_type n, + circular_buffer_space_optimized(capacity_control capacity_ctrl,
      + size_type n, value_type item,
      - const allocator_type& alloc = allocator_type());

      + const allocator_type& alloc = + allocator_type());

      - +
      - +
      TODO doc. @@ -393,23 +454,25 @@ template <class T, class Alloc>
      - - circular_buffer_space_optimized(capacity_control capacity_ctrl,
      - value_type item, const allocator_type& alloc = allocator_type());

      + + circular_buffer_space_optimized(capacity_control capacity_ctrl,
      + value_type item, + const allocator_type& alloc = + allocator_type());

      - +
      - +
      Create a full space optimized circular buffer filled with copies of item.
      - +
      Precondition: @@ -419,24 +482,26 @@ template <class T, class Alloc>
      - +
      Postcondition: - (*this).size() == capacity && (*this)[0] == (*this)[1] == ... == (*this).(*this).size() == capacity && + (*this)[0] == (*this)[1] == ... == (*this).back() == item
      - +
      Note: - It is considered as a bug if the precondition is not met (i.e. if capacity < min_capacity) and an assertion will be invoked in the debug mode. + It is considered as a bug if the precondition is not met (i.e. if capacity < + min_capacity) and an assertion will be invoked in the debug mode.
      @@ -447,22 +512,24 @@ template <class T, class Alloc>
      - explicit - circular_buffer_space_optimized(capacity_control capacity_ctrl, const allocator_type& alloc = allocator_type());
      + explicit + circular_buffer_space_optimized(capacity_control capacity_ctrl, const + allocator_type& alloc = + allocator_type());
      - +
      - +
      Create an empty space optimized circular buffer with a given capacity.
      - +
      Precondition: @@ -472,24 +539,26 @@ template <class T, class Alloc>
      - +
      Postcondition: - (*this).capacity() == capacity && (*this).size == 0
      + (*this).capacity() + == capacity && (*this).size == 0
      Allocates memory specified by the min_capacity parameter.
      - +
      Note: - It is considered as a bug if the precondition is not met (i.e. if capacity < min_capacity) and an assertion will be invoked in the debug mode. + It is considered as a bug if the precondition is not met (i.e. if capacity < + min_capacity) and an assertion will be invoked in the debug mode.
      @@ -500,21 +569,23 @@ template <class T, class Alloc>
      - explicit - circular_buffer_space_optimized(const allocator_type& alloc = allocator_type());
      + explicit + circular_buffer_space_optimized(const allocator_type& alloc = + allocator_type());
      - +
      - +
      Create an empty space optimized circular buffer with a maximum capacity.
      - +
      TODO - doc @@ -530,20 +601,22 @@ template <class T, class Alloc>

      - Public Member Functions + Public Member Functions

      - template <class InputIterator>
      - void assign(capacity_control capacity_ctrl, InputIterator first, InputIterator last);

      + template <class + InputIterator>
      + void assign(capacity_control + capacity_ctrl, InputIterator first, InputIterator last);

      - +
      - +
      See the circular_buffer source documentation. @@ -557,15 +630,17 @@ template <class T, class Alloc>
      - void assign(capacity_control capacity_ctrl, size_type n, - value_type item);
      + void assign(capacity_control capacity_ctrl, size_type n, value_type + item);
      - +
      - +
      See the circular_buffer source documentation. @@ -579,21 +654,23 @@ template <class T, class Alloc>
      - iterator erase(iterator first, iterator last);
      + iterator erase(iterator first, iterator last);
      - +
      @@ -602,20 +679,22 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - iterator erase(iterator pos);
      + iterator erase(iterator pos);
      - +
      @@ -624,20 +703,23 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - template <class InputIterator>
      - void insert(iterator pos, InputIterator first, InputIterator last);

      + template <class + InputIterator>
      + void insert(iterator pos, + InputIterator first, InputIterator last);

      - +
      @@ -646,21 +728,24 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - void insert(iterator pos, size_type n, value_type item);
      + void insert(iterator pos, size_type n, value_type + item);
      - +
      @@ -669,21 +754,24 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - iterator insert(iterator pos, value_type item = value_type());
      + iterator insert(iterator pos, value_type item = + value_type());
      - +
      @@ -692,20 +780,28 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - size_type min_capacity() const;
      + size_type min_capacity() + const;
      - +
      - +
      Return the minimal guaranteed amount of allocated memory.
      + + + + +
      + The allocated memory will never drop under this value. +
      @@ -713,19 +809,21 @@ template <class T, class Alloc>
      - void pop_back();
      + void + pop_back();
      - +
      @@ -734,19 +832,21 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - void pop_front();
      + void + pop_front();
      - +
      @@ -755,20 +855,22 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - void push_back(value_type item = value_type());
      + void push_back(value_type item = + value_type());
      - +
      @@ -777,20 +879,22 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - void push_front(value_type item = value_type());
      + void push_front(value_type item = + value_type());
      - +
      @@ -799,21 +903,23 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - iterator rerase(iterator first, iterator last);
      + iterator rerase(iterator first, iterator last);
      - +
      @@ -822,20 +928,22 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - iterator rerase(iterator pos);
      + iterator rerase(iterator pos);
      - +
      @@ -844,20 +952,23 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - template <class InputIterator>
      - void rinsert(iterator pos, InputIterator first, InputIterator last);

      + template <class + InputIterator>
      + void rinsert(iterator pos, + InputIterator first, InputIterator last);

      - +
      @@ -866,21 +977,24 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - void rinsert(iterator pos, size_type n, value_type item);
      + void rinsert(iterator pos, size_type n, value_type + item);
      - +
      @@ -889,21 +1003,24 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - iterator rinsert(iterator pos, value_type item = value_type());
      + iterator rinsert(iterator pos, value_type item = + value_type());
      - +
      @@ -912,38 +1029,41 @@ template <class T, class Alloc>
      - +
      -
      ! See the circular_buffer source documentation.
      The rules for iterator invalidation differ from the original circular_buffer. See the The rules for iterator invalidation differ from the original circular_buffer. See the documentation.
      - void rset_capacity(size_type new_capacity);
      + void + rset_capacity(size_type + new_capacity);
      - +
      - +
      ! See the circular_buffer source documentation.
      - +
      Precondition: - min_capacity() <= new_capacity + 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. + 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.
      @@ -954,38 +1074,40 @@ template <class T, class Alloc>
      - void set_capacity(size_type new_capacity);
      + void set_capacity(size_type new_capacity);
      - +
      - +
      ! See the circular_buffer source documentation.
      - +
      Precondition: - min_capacity() <= new_capacity + 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. + 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.
      @@ -996,49 +1118,55 @@ template <class T, class Alloc>
      - void set_min_capacity(size_type new_min_capacity);
      + void + set_min_capacity(size_type + new_min_capacity);
      - +
      - +
      Change the minimal guaranteed amount of allocated memory.
      - +
      Precondition: - (*this).capacity() >= new_min_capacity + (*this).capacity() + >= new_min_capacity
      - +
      Postcondition: - (*this).min_capacity() == new_min_capacity Allocates memory specified by the - new_min_capacity parameter. + (*this).min_capacity() == + new_min_capacity Allocates memory specified by the new_min_capacity + parameter.
      - +
      Note: - It is considered as a bug if the precondition is not met (i.e. if new_min_capacity > (*this).capacity()) and an assertion will be invoked in the debug mode. + It is considered as a bug if the precondition is not met (i.e. if new_min_capacity > + (*this).capacity()) and an + assertion will be invoked in the debug mode.
      @@ -1049,14 +1177,14 @@ template <class T, class Alloc>
      - void + void swap(circular_buffer_space_optimized<T,Alloc>& cb);
      - +
      - +
      See the circular_buffer source documentation. @@ -1072,7 +1200,7 @@ template <class T, class Alloc>

      - Semantics + Semantics

      TODO remove this section @@ -1085,56 +1213,73 @@ template <class T, class Alloc> Minimal capacity is allocated when an empty circular_buffer_space_optimized is created.

    • - When a non-empty circular_buffer_space_optimized container is created the allocated memory reflects the size of the container. + When a non-empty circular_buffer_space_optimized container is created the allocated memory + reflects the size of the container.
    • - push_back , push_front , insert and rinsert will predictively increase the allocated memory if necessary. (The predictive memory - allocation is similar to std::vector .) + push_back , push_front , insert and rinsert will + predictively increase the allocated memory if necessary. (The predictive memory allocation is similar to + std::vector .)
    • - set_capacity , resize , assign , insert (range or n items), rinsert (range or n items), erase (range) - and clear will accommodate the allocated memory as necessary. + set_capacity , resize , assign , insert (range or n items), + rinsert (range or n items), erase (range) and clear will accommodate the + allocated memory as necessary.
    • - pop_back , pop_front , erase and clear will predictively decrease the allocated memory. + pop_back , pop_front , erase and clear will predictively + decrease the allocated memory.
    • - The semantics of the circular_buffer_space_optimized then follows the semantics of the base circular_buffer - except the invalidation rules. + The semantics of the circular_buffer_space_optimized then follows the semantics of the base circular_buffer except the invalidation + rules.

      - The rule for iterator invalidation for circular_buffer_space_optimized is as follows: + The rule for iterator invalidation for circular_buffer_space_optimized is + as follows:

      • - data , set_capacity , resize , operator= , assign , swap , push_back , - push_front , pop_back , pop_front , insert , rinsert , erase and clear invalidate all - iterators pointing to the circular_buffer_space_optimized . + data , set_capacity , resize , operator= , + assign , swap , push_back , push_front , + pop_back , pop_front , insert , rinsert , + erase and clear invalidate all iterators pointing to the + circular_buffer_space_optimized .

      - See also + See also

      - boost::circular_buffer, std::vector + boost::circular_buffer, std::vector


      - Acknowledgments + Acknowledgments

      The idea of the space optimized circular buffer has been introduced by Pavel Vozenilek.

      -
      +
      diff --git a/include/boost/circular_buffer/space_optimized.hpp b/include/boost/circular_buffer/space_optimized.hpp index 74135a4..408f11d 100644 --- a/include/boost/circular_buffer/space_optimized.hpp +++ b/include/boost/circular_buffer/space_optimized.hpp @@ -50,7 +50,20 @@ 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. + //! Capacity controller of the space optimized circular buffer. + /*! + + struct capacity_control { + capacity_control(size_type capacity, size_type min_capacity = 0); + size_type m_capacity; + size_type m_min_capacity; + }; + + The converting constructor of the capacity_control + allows implicit conversion from size_type like types + which ensures compatibility of creating an instance of the + circular_buffer_space_optimized with other STL containers. + */ typedef cb_details::capacity_control capacity_control; // Inherited @@ -90,7 +103,7 @@ public: bool full() const { return size() == capacity(); } //! Return the minimal guaranteed amount of allocated memory. - /* + /*! The allocated memory will never drop under this value. */ size_type min_capacity() const { return m_capacity_ctrl.m_min_capacity; }