Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:49

0001 // Implementation of the base circular buffer.
0002 
0003 // Copyright (c) 2003-2008 Jan Gaspar
0004 // Copyright (c) 2013 Paul A. Bristow  // Doxygen comments changed.
0005 // Copyright (c) 2013 Antony Polukhin  // Move semantics implementation.
0006 
0007 // Copyright 2014,2018 Glen Joseph Fernandes
0008 // (glenjofe@gmail.com)
0009 
0010 // Use, modification, and distribution is subject to the Boost Software
0011 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
0013 
0014 #if !defined(BOOST_CIRCULAR_BUFFER_BASE_HPP)
0015 #define BOOST_CIRCULAR_BUFFER_BASE_HPP
0016 
0017 #if defined(_MSC_VER)
0018     #pragma once
0019 #endif
0020 
0021 #include <boost/config.hpp>
0022 #include <boost/concept_check.hpp>
0023 #include <boost/limits.hpp>
0024 #include <boost/core/allocator_access.hpp>
0025 #include <boost/core/empty_value.hpp>
0026 #include <boost/type_traits/is_stateless.hpp>
0027 #include <boost/type_traits/is_integral.hpp>
0028 #include <boost/type_traits/is_scalar.hpp>
0029 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0030 #include <boost/type_traits/is_nothrow_move_assignable.hpp>
0031 #include <boost/type_traits/is_copy_constructible.hpp>
0032 #include <boost/type_traits/conditional.hpp>
0033 #include <boost/move/adl_move_swap.hpp>
0034 #include <boost/move/move.hpp>
0035 #include <algorithm>
0036 #include <iterator>
0037 #include <utility>
0038 #include <deque>
0039 #include <stdexcept>
0040 
0041 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
0042     #include <stddef.h>
0043 #endif
0044 
0045 namespace boost {
0046 
0047 /*!
0048     \class circular_buffer
0049     \brief Circular buffer - a STL compliant container.
0050     \tparam T The type of the elements stored in the <code>circular_buffer</code>.
0051     \par Type Requirements T
0052          The <code>T</code> has to be <a href="https://www.boost.org/sgi/stl/Assignable.html">
0053          SGIAssignable</a> (SGI STL defined combination of <a href="../../../utility/Assignable.html">
0054          Assignable</a> and <a href="../../../utility/CopyConstructible.html">CopyConstructible</a>).
0055          Moreover <code>T</code> has to be <a href="https://www.boost.org/sgi/stl/DefaultConstructible.html">
0056          DefaultConstructible</a> if supplied as a default parameter when invoking some of the
0057          <code>circular_buffer</code>'s methods e.g.
0058          <code>insert(iterator pos, const value_type& item = %value_type())</code>. And
0059          <a href="https://www.boost.org/sgi/stl/EqualityComparable.html">EqualityComparable</a> and/or
0060          <a href="../../../utility/LessThanComparable.html">LessThanComparable</a> if the <code>circular_buffer</code>
0061          will be compared with another container.
0062     \tparam Alloc The allocator type used for all internal memory management.
0063     \par Type Requirements Alloc
0064          The <code>Alloc</code> has to meet the allocator requirements imposed by STL.
0065     \par Default Alloc
0066          std::allocator<T>
0067 
0068     For detailed documentation of the circular_buffer visit:
0069     http://www.boost.org/libs/circular_buffer/doc/circular_buffer.html
0070 */
0071 template <class T, class Alloc>
0072 class circular_buffer
0073 :
0074 /*! \cond */
0075 #if BOOST_CB_ENABLE_DEBUG
0076 public cb_details::debug_iterator_registry,
0077 #endif
0078 /*! \endcond */
0079 private empty_value<Alloc>
0080 {
0081     typedef empty_value<Alloc> base;
0082 
0083   // Requirements
0084     //BOOST_CLASS_REQUIRE(T, boost, SGIAssignableConcept);
0085 
0086 
0087     //BOOST_CONCEPT_ASSERT((Assignable<T>));
0088     //BOOST_CONCEPT_ASSERT((CopyConstructible<T>));
0089     //BOOST_CONCEPT_ASSERT((DefaultConstructible<T>));
0090 
0091     // Required if the circular_buffer will be compared with anther container.
0092     //BOOST_CONCEPT_ASSERT((EqualityComparable<T>));
0093     //BOOST_CONCEPT_ASSERT((LessThanComparable<T>));
0094 
0095 public:
0096 // Basic types
0097     
0098     //! The type of this <code>circular_buffer</code>.
0099     typedef circular_buffer<T, Alloc> this_type;
0100 
0101     //! The type of elements stored in the <code>circular_buffer</code>.
0102     typedef typename Alloc::value_type value_type;
0103 
0104     //! A pointer to an element.
0105     typedef typename allocator_pointer<Alloc>::type pointer;
0106 
0107     //! A const pointer to the element.
0108     typedef typename allocator_const_pointer<Alloc>::type const_pointer;
0109 
0110     //! A reference to an element.
0111     typedef value_type& reference;
0112 
0113     //! A const reference to an element.
0114     typedef const value_type& const_reference;
0115 
0116     //! The distance type.
0117     /*!
0118         (A signed integral type used to represent the distance between two iterators.)
0119     */
0120     typedef typename allocator_difference_type<Alloc>::type difference_type;
0121 
0122     //! The size type.
0123     /*!
0124         (An unsigned integral type that can represent any non-negative value of the container's distance type.)
0125     */
0126     typedef typename allocator_size_type<Alloc>::type size_type;
0127 
0128     //! The type of an allocator used in the <code>circular_buffer</code>.
0129     typedef Alloc allocator_type;
0130 
0131 // Iterators
0132 
0133     //! A const (random access) iterator used to iterate through the <code>circular_buffer</code>.
0134     typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<Alloc> > const_iterator;
0135 
0136     //! A (random access) iterator used to iterate through the <code>circular_buffer</code>.
0137     typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<Alloc> > iterator;
0138 
0139     //! A const iterator used to iterate backwards through a <code>circular_buffer</code>.
0140     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0141 
0142     //! An iterator used to iterate backwards through a <code>circular_buffer</code>.
0143     typedef std::reverse_iterator<iterator> reverse_iterator;
0144 
0145 // Container specific types
0146 
0147     //! An array range.
0148     /*!
0149         (A typedef for the <a href="https://www.boost.org/sgi/stl/pair.html"><code>std::pair</code></a> where
0150         its first element is a pointer to a beginning of an array and its second element represents
0151         a size of the array.)
0152     */
0153     typedef std::pair<pointer, size_type> array_range;
0154 
0155     //! A range of a const array.
0156     /*!
0157         (A typedef for the <a href="https://www.boost.org/sgi/stl/pair.html"><code>std::pair</code></a> where
0158         its first element is a pointer to a beginning of a const array and its second element represents
0159         a size of the const array.)
0160     */
0161     typedef std::pair<const_pointer, size_type> const_array_range;
0162 
0163     //! The capacity type.
0164     /*!
0165         (Same as <code>size_type</code> - defined for consistency with the  __cbso class.
0166 
0167     */
0168     // <a href="space_optimized.html"><code>circular_buffer_space_optimized</code></a>.)
0169 
0170     typedef size_type capacity_type;
0171 
0172 // Helper types
0173 
0174     //! A type representing the "best" way to pass the value_type to a method.
0175     typedef const value_type& param_value_type;
0176 
0177     //! A type representing rvalue from param type.
0178     //! On compilers without rvalue references support this type is the Boost.Moves type used for emulation.
0179     typedef BOOST_RV_REF(value_type) rvalue_type;
0180 
0181 private:
0182 // Member variables
0183 
0184     //! The internal buffer used for storing elements in the circular buffer.
0185     pointer m_buff;
0186 
0187     //! The internal buffer's end (end of the storage space).
0188     pointer m_end;
0189 
0190     //! The virtual beginning of the circular buffer.
0191     pointer m_first;
0192 
0193     //! The virtual end of the circular buffer (one behind the last element).
0194     pointer m_last;
0195 
0196     //! The number of items currently stored in the circular buffer.
0197     size_type m_size;
0198 
0199 // Friends
0200 #if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
0201     friend iterator;
0202     friend const_iterator;
0203 #else
0204     template <class Buff, class Traits> friend struct cb_details::iterator;
0205 #endif
0206 
0207 public:
0208 // Allocator
0209 
0210     //! Get the allocator.
0211     /*!
0212         \return The allocator.
0213         \throws Nothing.
0214         \par Exception Safety
0215              No-throw.
0216         \par Iterator Invalidation
0217              Does not invalidate any iterators.
0218         \par Complexity
0219              Constant (in the size of the <code>circular_buffer</code>).
0220         \sa <code>get_allocator()</code> for obtaining an allocator %reference.
0221     */
0222     allocator_type get_allocator() const BOOST_NOEXCEPT { return alloc(); }
0223 
0224     //! Get the allocator reference.
0225     /*!
0226         \return A reference to the allocator.
0227         \throws Nothing.
0228         \par Exception Safety
0229              No-throw.
0230         \par Iterator Invalidation
0231              Does not invalidate any iterators.
0232         \par Complexity
0233              Constant (in the size of the <code>circular_buffer</code>).
0234         \note This method was added in order to optimize obtaining of the allocator with a state,
0235               although use of stateful allocators in STL is discouraged.
0236         \sa <code>get_allocator() const</code>
0237     */
0238     allocator_type& get_allocator() BOOST_NOEXCEPT { return alloc(); }
0239 
0240 // Element access
0241 
0242     //! Get the iterator pointing to the beginning of the <code>circular_buffer</code>.
0243     /*!
0244         \return A random access iterator pointing to the first element of the <code>circular_buffer</code>. If the
0245                 <code>circular_buffer</code> is empty it returns an iterator equal to the one returned by
0246                 <code>end()</code>.
0247         \throws Nothing.
0248         \par Exception Safety
0249              No-throw.
0250         \par Iterator Invalidation
0251              Does not invalidate any iterators.
0252         \par Complexity
0253              Constant (in the size of the <code>circular_buffer</code>).
0254         \sa <code>end()</code>, <code>rbegin()</code>, <code>rend()</code>
0255     */
0256     iterator begin() BOOST_NOEXCEPT { return iterator(this, empty() ? 0 : m_first); }
0257 
0258     //! Get the iterator pointing to the end of the <code>circular_buffer</code>.
0259     /*!
0260         \return A random access iterator pointing to the element "one behind" the last element of the <code>
0261                 circular_buffer</code>. If the <code>circular_buffer</code> is empty it returns an iterator equal to
0262                 the one returned by <code>begin()</code>.
0263         \throws Nothing.
0264         \par Exception Safety
0265              No-throw.
0266         \par Iterator Invalidation
0267              Does not invalidate any iterators.
0268         \par Complexity
0269              Constant (in the size of the <code>circular_buffer</code>).
0270         \sa <code>begin()</code>, <code>rbegin()</code>, <code>rend()</code>
0271     */
0272     iterator end() BOOST_NOEXCEPT { return iterator(this, 0); }
0273 
0274     //! Get the const iterator pointing to the beginning of the <code>circular_buffer</code>.
0275     /*!
0276         \return A const random access iterator pointing to the first element of the <code>circular_buffer</code>. If
0277                 the <code>circular_buffer</code> is empty it returns an iterator equal to the one returned by
0278                 <code>end() const</code>.
0279         \throws Nothing.
0280         \par Exception Safety
0281              No-throw.
0282         \par Iterator Invalidation
0283              Does not invalidate any iterators.
0284         \par Complexity
0285              Constant (in the size of the <code>circular_buffer</code>).
0286         \sa <code>end() const</code>, <code>rbegin() const</code>, <code>rend() const</code>
0287     */
0288     const_iterator begin() const BOOST_NOEXCEPT { return const_iterator(this, empty() ? 0 : m_first); }
0289 
0290     const_iterator cbegin() const BOOST_NOEXCEPT { return begin(); }
0291     //! Get the const iterator pointing to the end of the <code>circular_buffer</code>.
0292     /*!
0293         \return A const random access iterator pointing to the element "one behind" the last element of the <code>
0294                 circular_buffer</code>. If the <code>circular_buffer</code> is empty it returns an iterator equal to
0295                 the one returned by <code>begin() const</code> const.
0296         \throws Nothing.
0297         \par Exception Safety
0298              No-throw.
0299         \par Iterator Invalidation
0300              Does not invalidate any iterators.
0301         \par Complexity
0302              Constant (in the size of the <code>circular_buffer</code>).
0303         \sa <code>begin() const</code>, <code>rbegin() const</code>, <code>rend() const</code>
0304     */
0305     const_iterator end() const BOOST_NOEXCEPT { return const_iterator(this, 0); }
0306 
0307     const_iterator cend() const BOOST_NOEXCEPT { return end(); }
0308     //! Get the iterator pointing to the beginning of the "reversed" <code>circular_buffer</code>.
0309     /*!
0310         \return A reverse random access iterator pointing to the last element of the <code>circular_buffer</code>.
0311                 If the <code>circular_buffer</code> is empty it returns an iterator equal to the one returned by
0312                 <code>rend()</code>.
0313         \throws Nothing.
0314         \par Exception Safety
0315              No-throw.
0316         \par Iterator Invalidation
0317              Does not invalidate any iterators.
0318         \par Complexity
0319              Constant (in the size of the <code>circular_buffer</code>).
0320         \sa <code>rend()</code>, <code>begin()</code>, <code>end()</code>
0321     */
0322     reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
0323 
0324     //! Get the iterator pointing to the end of the "reversed" <code>circular_buffer</code>.
0325     /*!
0326         \return A reverse random access iterator pointing to the element "one before" the first element of the <code>
0327                 circular_buffer</code>. If the <code>circular_buffer</code> is empty it returns an iterator equal to
0328                 the one returned by <code>rbegin()</code>.
0329         \throws Nothing.
0330         \par Exception Safety
0331              No-throw.
0332         \par Iterator Invalidation
0333              Does not invalidate any iterators.
0334         \par Complexity
0335              Constant (in the size of the <code>circular_buffer</code>).
0336         \sa <code>rbegin()</code>, <code>begin()</code>, <code>end()</code>
0337     */
0338     reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); }
0339 
0340     //! Get the const iterator pointing to the beginning of the "reversed" <code>circular_buffer</code>.
0341     /*!
0342         \return A const reverse random access iterator pointing to the last element of the
0343                 <code>circular_buffer</code>. If the <code>circular_buffer</code> is empty it returns an iterator equal
0344                 to the one returned by <code>rend() const</code>.
0345         \throws Nothing.
0346         \par Exception Safety
0347              No-throw.
0348         \par Iterator Invalidation
0349              Does not invalidate any iterators.
0350         \par Complexity
0351              Constant (in the size of the <code>circular_buffer</code>).
0352         \sa <code>rend() const</code>, <code>begin() const</code>, <code>end() const</code>
0353     */
0354     const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
0355 
0356     //! Get the const iterator pointing to the end of the "reversed" <code>circular_buffer</code>.
0357     /*!
0358         \return A const reverse random access iterator pointing to the element "one before" the first element of the
0359                 <code>circular_buffer</code>. If the <code>circular_buffer</code> is empty it returns an iterator equal
0360                 to the one returned by <code>rbegin() const</code>.
0361         \throws Nothing.
0362         \par Exception Safety
0363              No-throw.
0364         \par Iterator Invalidation
0365              Does not invalidate any iterators.
0366         \par Complexity
0367              Constant (in the size of the <code>circular_buffer</code>).
0368         \sa <code>rbegin() const</code>, <code>begin() const</code>, <code>end() const</code>
0369     */
0370     const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
0371 
0372     //! Get the element at the <code>index</code> position.
0373     /*!
0374         \pre <code>0 \<= index \&\& index \< size()</code>
0375         \param index The position of the element.
0376         \return A reference to the element at the <code>index</code> position.
0377         \throws Nothing.
0378         \par Exception Safety
0379              No-throw.
0380         \par Iterator Invalidation
0381              Does not invalidate any iterators.
0382         \par Complexity
0383              Constant (in the size of the <code>circular_buffer</code>).
0384         \sa <code>at()</code>
0385     */
0386     reference operator [] (size_type index) {
0387         BOOST_CB_ASSERT(index < size()); // check for invalid index
0388         return *add(m_first, index);
0389     }
0390 
0391     //! Get the element at the <code>index</code> position.
0392     /*!
0393         \pre <code>0 \<= index \&\& index \< size()</code>
0394         \param index The position of the element.
0395         \return A const reference to the element at the <code>index</code> position.
0396         \throws Nothing.
0397         \par Exception Safety
0398              No-throw.
0399         \par Iterator Invalidation
0400              Does not invalidate any iterators.
0401         \par Complexity
0402              Constant (in the size of the <code>circular_buffer</code>).
0403         \sa <code>\link at(size_type)const at() const \endlink</code>
0404     */
0405     const_reference operator [] (size_type index) const {
0406         BOOST_CB_ASSERT(index < size()); // check for invalid index
0407         return *add(m_first, index);
0408     }
0409 
0410     //! Get the element at the <code>index</code> position.
0411     /*!
0412         \param index The position of the element.
0413         \return A reference to the element at the <code>index</code> position.
0414         \throws <code>std::out_of_range</code> when the <code>index</code> is invalid (when
0415                 <code>index >= size()</code>).
0416         \par Exception Safety
0417              Strong.
0418         \par Iterator Invalidation
0419              Does not invalidate any iterators.
0420         \par Complexity
0421              Constant (in the size of the <code>circular_buffer</code>).
0422         \sa <code>\link operator[](size_type) operator[] \endlink</code>
0423     */
0424     reference at(size_type index) {
0425         check_position(index);
0426         return (*this)[index];
0427     }
0428 
0429     //! Get the element at the <code>index</code> position.
0430     /*!
0431         \param index The position of the element.
0432         \return A const reference to the element at the <code>index</code> position.
0433         \throws <code>std::out_of_range</code> when the <code>index</code> is invalid (when
0434                 <code>index >= size()</code>).
0435         \par Exception Safety
0436              Strong.
0437         \par Iterator Invalidation
0438              Does not invalidate any iterators.
0439         \par Complexity
0440              Constant (in the size of the <code>circular_buffer</code>).
0441         \sa <code>\link operator[](size_type)const operator[] const \endlink</code>
0442     */
0443     const_reference at(size_type index) const {
0444         check_position(index);
0445         return (*this)[index];
0446     }
0447 
0448     //! Get the first element.
0449     /*!
0450         \pre <code>!empty()</code>
0451         \return A reference to the first element of the <code>circular_buffer</code>.
0452         \throws Nothing.
0453         \par Exception Safety
0454              No-throw.
0455         \par Iterator Invalidation
0456              Does not invalidate any iterators.
0457         \par Complexity
0458              Constant (in the size of the <code>circular_buffer</code>).
0459         \sa <code>back()</code>
0460     */
0461     reference front() {
0462         BOOST_CB_ASSERT(!empty()); // check for empty buffer (front element not available)
0463         return *m_first;
0464     }
0465 
0466     //! Get the last element.
0467     /*!
0468         \pre <code>!empty()</code>
0469         \return A reference to the last element of the <code>circular_buffer</code>.
0470         \throws Nothing.
0471         \par Exception Safety
0472              No-throw.
0473         \par Iterator Invalidation
0474              Does not invalidate any iterators.
0475         \par Complexity
0476              Constant (in the size of the <code>circular_buffer</code>).
0477         \sa <code>front()</code>
0478     */
0479     reference back() {
0480         BOOST_CB_ASSERT(!empty()); // check for empty buffer (back element not available)
0481         return *((m_last == m_buff ? m_end : m_last) - 1);
0482     }
0483 
0484     //! Get the first element.
0485     /*!
0486         \pre <code>!empty()</code>
0487         \return A const reference to the first element of the <code>circular_buffer</code>.
0488         \throws Nothing.
0489         \par Exception Safety
0490              No-throw.
0491         \par Iterator Invalidation
0492              Does not invalidate any iterators.
0493         \par Complexity
0494              Constant (in the size of the <code>circular_buffer</code>).
0495         \sa <code>back() const</code>
0496     */
0497     const_reference front() const {
0498         BOOST_CB_ASSERT(!empty()); // check for empty buffer (front element not available)
0499         return *m_first;
0500     }
0501 
0502     //! Get the last element.
0503     /*!
0504         \pre <code>!empty()</code>
0505         \return A const reference to the last element of the <code>circular_buffer</code>.
0506         \throws Nothing.
0507         \par Exception Safety
0508              No-throw.
0509         \par Iterator Invalidation
0510              Does not invalidate any iterators.
0511         \par Complexity
0512              Constant (in the size of the <code>circular_buffer</code>).
0513         \sa <code>front() const</code>
0514     */
0515     const_reference back() const {
0516         BOOST_CB_ASSERT(!empty()); // check for empty buffer (back element not available)
0517         return *((m_last == m_buff ? m_end : m_last) - 1);
0518     }
0519 
0520     //! Get the first continuous array of the internal buffer.
0521     /*!
0522         This method in combination with <code>array_two()</code> can be useful when passing the stored data into
0523         a legacy C API as an array. Suppose there is a <code>circular_buffer</code> of capacity 10, containing 7
0524         characters <code>'a', 'b', ..., 'g'</code> where <code>buff[0] == 'a'</code>, <code>buff[1] == 'b'</code>,
0525         ... and <code>buff[6] == 'g'</code>:<br><br>
0526         <code>circular_buffer<char> buff(10);</code><br><br>
0527         The internal representation is often not linear and the state of the internal buffer may look like this:<br>
0528         <br><code>
0529         |e|f|g| | | |a|b|c|d|<br>
0530         end ___^<br>
0531         begin _______^</code><br><br>
0532 
0533         where <code>|a|b|c|d|</code> represents the "array one", <code>|e|f|g|</code> represents the "array two" and
0534         <code>| | | |</code> is a free space.<br>
0535         Now consider a typical C style function for writing data into a file:<br><br>
0536         <code>int write(int file_desc, char* buff, int num_bytes);</code><br><br>
0537         There are two ways how to write the content of the <code>circular_buffer</code> into a file. Either relying
0538         on <code>array_one()</code> and <code>array_two()</code> methods and calling the write function twice:<br><br>
0539         <code>array_range ar = buff.array_one();<br>
0540         write(file_desc, ar.first, ar.second);<br>
0541         ar = buff.array_two();<br>
0542         write(file_desc, ar.first, ar.second);</code><br><br>
0543         Or relying on the <code>linearize()</code> method:<br><br><code>
0544         write(file_desc, buff.linearize(), buff.size());</code><br><br>
0545         Since the complexity of <code>array_one()</code> and <code>array_two()</code> methods is constant the first
0546         option is suitable when calling the write method is "cheap". On the other hand the second option is more
0547         suitable when calling the write method is more "expensive" than calling the <code>linearize()</code> method
0548         whose complexity is linear.
0549         \return The array range of the first continuous array of the internal buffer. In the case the
0550                 <code>circular_buffer</code> is empty the size of the returned array is <code>0</code>.
0551         \throws Nothing.
0552         \par Exception Safety
0553              No-throw.
0554         \par Iterator Invalidation
0555              Does not invalidate any iterators.
0556         \par Complexity
0557              Constant (in the size of the <code>circular_buffer</code>).
0558         \warning In general invoking any method which modifies the internal state of the circular_buffer  may
0559                  delinearize the internal buffer and invalidate the array ranges returned by <code>array_one()</code>
0560                  and <code>array_two()</code> (and their const versions).
0561         \note In the case the internal buffer is linear e.g. <code>|a|b|c|d|e|f|g| | | |</code> the "array one" is
0562               represented by <code>|a|b|c|d|e|f|g|</code> and the "array two" does not exist (the
0563               <code>array_two()</code> method returns an array with the size <code>0</code>).
0564         \sa <code>array_two()</code>, <code>linearize()</code>
0565     */
0566     array_range array_one() {
0567         return array_range(m_first, (m_last <= m_first && !empty() ? m_end : m_last) - m_first);
0568     }
0569 
0570     //! Get the second continuous array of the internal buffer.
0571     /*!
0572         This method in combination with <code>array_one()</code> can be useful when passing the stored data into
0573         a legacy C API as an array.
0574         \return The array range of the second continuous array of the internal buffer. In the case the internal buffer
0575                 is linear or the <code>circular_buffer</code> is empty the size of the returned array is
0576                 <code>0</code>.
0577         \throws Nothing.
0578         \par Exception Safety
0579              No-throw.
0580         \par Iterator Invalidation
0581              Does not invalidate any iterators.
0582         \par Complexity
0583              Constant (in the size of the <code>circular_buffer</code>).
0584         \sa <code>array_one()</code>
0585     */
0586     array_range array_two() {
0587         return array_range(m_buff, m_last <= m_first && !empty() ? m_last - m_buff : 0);
0588     }
0589 
0590     //! Get the first continuous array of the internal buffer.
0591     /*!
0592         This method in combination with <code>array_two() const</code> can be useful when passing the stored data into
0593         a legacy C API as an array.
0594         \return The array range of the first continuous array of the internal buffer. In the case the
0595                 <code>circular_buffer</code> is empty the size of the returned array is <code>0</code>.
0596         \throws Nothing.
0597         \par Exception Safety
0598              No-throw.
0599         \par Iterator Invalidation
0600              Does not invalidate any iterators.
0601         \par Complexity
0602              Constant (in the size of the <code>circular_buffer</code>).
0603         \sa <code>array_two() const</code>; <code>array_one()</code> for more details how to pass data into a legacy C
0604             API.
0605     */
0606     const_array_range array_one() const {
0607         return const_array_range(m_first, (m_last <= m_first && !empty() ? m_end : m_last) - m_first);
0608     }
0609 
0610     //! Get the second continuous array of the internal buffer.
0611     /*!
0612         This method in combination with <code>array_one() const</code> can be useful when passing the stored data into
0613         a legacy C API as an array.
0614         \return The array range of the second continuous array of the internal buffer. In the case the internal buffer
0615                 is linear or the <code>circular_buffer</code> is empty the size of the returned array is
0616                 <code>0</code>.
0617         \throws Nothing.
0618         \par Exception Safety
0619              No-throw.
0620         \par Iterator Invalidation
0621              Does not invalidate any iterators.
0622         \par Complexity
0623              Constant (in the size of the <code>circular_buffer</code>).
0624         \sa <code>array_one() const</code>
0625     */
0626     const_array_range array_two() const {
0627         return const_array_range(m_buff, m_last <= m_first && !empty() ? m_last - m_buff : 0);
0628     }
0629 
0630     //! Linearize the internal buffer into a continuous array.
0631     /*!
0632         This method can be useful when passing the stored data into a legacy C API as an array.
0633         \post <code>\&(*this)[0] \< \&(*this)[1] \< ... \< \&(*this)[size() - 1]</code>
0634         \return A pointer to the beginning of the array or <code>0</code> if empty.
0635         \throws <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
0636         \par Exception Safety
0637              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
0638         \par Iterator Invalidation
0639              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
0640              <code>end()</code>); does not invalidate any iterators if the postcondition (the <i>Effect</i>) is already
0641              met prior calling this method.
0642         \par Complexity
0643              Linear (in the size of the <code>circular_buffer</code>); constant if the postcondition (the
0644              <i>Effect</i>) is already met.
0645         \warning In general invoking any method which modifies the internal state of the <code>circular_buffer</code>
0646                  may delinearize the internal buffer and invalidate the returned pointer.
0647         \sa <code>array_one()</code> and <code>array_two()</code> for the other option how to pass data into a legacy
0648             C API; <code>is_linearized()</code>, <code>rotate(const_iterator)</code>
0649     */
0650     pointer linearize() {
0651         if (empty())
0652             return 0;
0653         if (m_first < m_last || m_last == m_buff)
0654             return m_first;
0655         pointer src = m_first;
0656         pointer dest = m_buff;
0657         size_type moved = 0;
0658         size_type constructed = 0;
0659         BOOST_TRY {
0660             for (pointer first = m_first; dest < src; src = first) {
0661                 for (size_type ii = 0; src < m_end; ++src, ++dest, ++moved, ++ii) {
0662                     if (moved == size()) {
0663                         first = dest;
0664                         break;
0665                     }
0666                     if (dest == first) {
0667                         first += ii;
0668                         break;
0669                     }
0670                     if (is_uninitialized(dest)) {
0671                         boost::allocator_construct(alloc(), boost::to_address(dest), boost::move_if_noexcept(*src));
0672                         ++constructed;
0673                     } else {
0674                         value_type tmp = boost::move_if_noexcept(*src); 
0675                         replace(src, boost::move_if_noexcept(*dest));
0676                         replace(dest, boost::move(tmp));
0677                     }
0678                 }
0679             }
0680         } BOOST_CATCH(...) {
0681             m_last += constructed;
0682             m_size += constructed;
0683             BOOST_RETHROW
0684         }
0685         BOOST_CATCH_END
0686         for (src = m_end - constructed; src < m_end; ++src)
0687             destroy_item(src);
0688         m_first = m_buff;
0689         m_last = add(m_buff, size());
0690 #if BOOST_CB_ENABLE_DEBUG
0691         invalidate_iterators_except(end());
0692 #endif
0693         return m_buff;
0694     }
0695 
0696     //! Is the <code>circular_buffer</code> linearized?
0697     /*!
0698         \return <code>true</code> if the internal buffer is linearized into a continuous array (i.e. the
0699                 <code>circular_buffer</code> meets a condition
0700                 <code>\&(*this)[0] \< \&(*this)[1] \< ... \< \&(*this)[size() - 1]</code>);
0701                 <code>false</code> otherwise.
0702         \throws Nothing.
0703         \par Exception Safety
0704              No-throw.
0705         \par Iterator Invalidation
0706              Does not invalidate any iterators.
0707         \par Complexity
0708              Constant (in the size of the <code>circular_buffer</code>).
0709         \sa <code>linearize()</code>, <code>array_one()</code>, <code>array_two()</code>
0710     */
0711     bool is_linearized() const BOOST_NOEXCEPT { return m_first < m_last || m_last == m_buff; }
0712 
0713     //! Rotate elements in the <code>circular_buffer</code>.
0714     /*!
0715         A more effective implementation of
0716         <code><a href="https://www.boost.org/sgi/stl/rotate.html">std::rotate</a></code>.
0717         \pre <code>new_begin</code> is a valid iterator pointing to the <code>circular_buffer</code> <b>except</b> its
0718              end.
0719         \post Before calling the method suppose:<br><br>
0720               <code>m == std::distance(new_begin, end())</code><br><code>n == std::distance(begin(), new_begin)</code>
0721               <br><code>val_0 == *new_begin, val_1 == *(new_begin + 1), ... val_m == *(new_begin + m)</code><br>
0722               <code>val_r1 == *(new_begin - 1), val_r2 == *(new_begin - 2), ... val_rn == *(new_begin - n)</code><br>
0723               <br>then after call to the method:<br><br>
0724               <code>val_0 == (*this)[0] \&\& val_1 == (*this)[1] \&\& ... \&\& val_m == (*this)[m - 1] \&\& val_r1 ==
0725               (*this)[m + n - 1] \&\& val_r2 == (*this)[m + n - 2] \&\& ... \&\& val_rn == (*this)[m]</code>
0726         \param new_begin The new beginning.
0727         \throws See <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
0728         \par Exception Safety
0729              Basic; no-throw if the <code>circular_buffer</code> is full or <code>new_begin</code> points to
0730              <code>begin()</code> or if the operations in the <i>Throws</i> section do not throw anything.
0731         \par Iterator Invalidation
0732              If <code>m \< n</code> invalidates iterators pointing to the last <code>m</code> elements
0733              (<b>including</b> <code>new_begin</code>, but not iterators equal to <code>end()</code>) else invalidates
0734              iterators pointing to the first <code>n</code> elements; does not invalidate any iterators if the
0735              <code>circular_buffer</code> is full.
0736         \par Complexity
0737              Linear (in <code>(std::min)(m, n)</code>); constant if the <code>circular_buffer</code> is full.
0738         \sa <code><a href="https://www.boost.org/sgi/stl/rotate.html">std::rotate</a></code>
0739     */
0740     void rotate(const_iterator new_begin) {
0741         BOOST_CB_ASSERT(new_begin.is_valid(this)); // check for uninitialized or invalidated iterator
0742         BOOST_CB_ASSERT(new_begin.m_it != 0);      // check for iterator pointing to end()
0743         if (full()) {
0744             m_first = m_last = const_cast<pointer>(new_begin.m_it);
0745         } else {
0746             difference_type m = end() - new_begin;
0747             difference_type n = new_begin - begin();
0748             if (m < n) {
0749                 for (; m > 0; --m) {
0750                     push_front(boost::move_if_noexcept(back()));
0751                     pop_back();
0752                 }
0753             } else {
0754                 for (; n > 0; --n) {
0755                     push_back(boost::move_if_noexcept(front()));
0756                     pop_front();
0757                 }
0758             }
0759         }
0760     }
0761 
0762 // Size and capacity
0763 
0764     //! Get the number of elements currently stored in the <code>circular_buffer</code>.
0765     /*!
0766         \return The number of elements stored in the <code>circular_buffer</code>.
0767         \throws Nothing.
0768         \par Exception Safety
0769              No-throw.
0770         \par Iterator Invalidation
0771              Does not invalidate any iterators.
0772         \par Complexity
0773              Constant (in the size of the <code>circular_buffer</code>).
0774         \sa <code>capacity()</code>, <code>max_size()</code>, <code>reserve()</code>,
0775             <code>\link resize() resize(size_type, const_reference)\endlink</code>
0776     */
0777     size_type size() const BOOST_NOEXCEPT { return m_size; }
0778 
0779     /*! \brief Get the largest possible size or capacity of the <code>circular_buffer</code>. (It depends on
0780                allocator's %max_size()).
0781         \return The maximum size/capacity the <code>circular_buffer</code> can be set to.
0782         \throws Nothing.
0783         \par Exception Safety
0784              No-throw.
0785         \par Iterator Invalidation
0786              Does not invalidate any iterators.
0787         \par Complexity
0788              Constant (in the size of the <code>circular_buffer</code>).
0789         \sa <code>size()</code>, <code>capacity()</code>, <code>reserve()</code>
0790     */
0791     size_type max_size() const BOOST_NOEXCEPT {
0792         return (std::min<size_type>)(boost::allocator_max_size(alloc()), (std::numeric_limits<difference_type>::max)());
0793     }
0794 
0795     //! Is the <code>circular_buffer</code> empty?
0796     /*!
0797         \return <code>true</code> if there are no elements stored in the <code>circular_buffer</code>;
0798                 <code>false</code> otherwise.
0799         \throws Nothing.
0800         \par Exception Safety
0801              No-throw.
0802         \par Iterator Invalidation
0803              Does not invalidate any iterators.
0804         \par Complexity
0805              Constant (in the size of the <code>circular_buffer</code>).
0806         \sa <code>full()</code>
0807     */
0808     bool empty() const BOOST_NOEXCEPT { return size() == 0; }
0809 
0810     //! Is the <code>circular_buffer</code> full?
0811     /*!
0812         \return <code>true</code> if the number of elements stored in the <code>circular_buffer</code>
0813                 equals the capacity of the <code>circular_buffer</code>; <code>false</code> otherwise.
0814         \throws Nothing.
0815         \par Exception Safety
0816              No-throw.
0817         \par Iterator Invalidation
0818              Does not invalidate any iterators.
0819         \par Complexity
0820              Constant (in the size of the <code>circular_buffer</code>).
0821         \sa <code>empty()</code>
0822     */
0823     bool full() const BOOST_NOEXCEPT { return capacity() == size(); }
0824 
0825     /*! \brief Get the maximum number of elements which can be inserted into the <code>circular_buffer</code> without
0826                overwriting any of already stored elements.
0827         \return <code>capacity() - size()</code>
0828         \throws Nothing.
0829         \par Exception Safety
0830              No-throw.
0831         \par Iterator Invalidation
0832              Does not invalidate any iterators.
0833         \par Complexity
0834              Constant (in the size of the <code>circular_buffer</code>).
0835         \sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code>
0836     */
0837     size_type reserve() const BOOST_NOEXCEPT { return capacity() - size(); }
0838 
0839     //! Get the capacity of the <code>circular_buffer</code>.
0840     /*!
0841         \return The maximum number of elements which can be stored in the <code>circular_buffer</code>.
0842         \throws Nothing.
0843         \par Exception Safety
0844              No-throw.
0845         \par Iterator Invalidation
0846              Does not invalidate any iterators.
0847         \par Complexity
0848              Constant (in the size of the <code>circular_buffer</code>).
0849         \sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>,
0850             <code>set_capacity(capacity_type)</code>
0851     */
0852     capacity_type capacity() const BOOST_NOEXCEPT { return m_end - m_buff; }
0853 
0854     //! Change the capacity of the <code>circular_buffer</code>.
0855     /*! 
0856         \pre If <code>T</code> is a move only type, then compiler shall support <code>noexcept</code> modifiers
0857                 and move constructor of <code>T</code> must be marked with it (must not throw exceptions).
0858         \post <code>capacity() == new_capacity \&\& size() \<= new_capacity</code><br><br>
0859               If the current number of elements stored in the <code>circular_buffer</code> is greater than the desired
0860               new capacity then number of <code>[size() - new_capacity]</code> <b>last</b> elements will be removed and
0861               the new size will be equal to <code>new_capacity</code>.
0862         \param new_capacity The new capacity.
0863         \throws "An allocation error" if memory is exhausted, (<code>std::bad_alloc</code> if the standard allocator is
0864                 used).
0865                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0866         \par Exception Safety
0867              Strong.
0868         \par Iterator Invalidation
0869              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
0870              <code>end()</code>) if the new capacity is different from the original.
0871         \par Complexity
0872              Linear (in <code>min[size(), new_capacity]</code>).
0873         \sa <code>rset_capacity(capacity_type)</code>,
0874             <code>\link resize() resize(size_type, const_reference)\endlink</code>
0875     */
0876     void set_capacity(capacity_type new_capacity) {
0877         if (new_capacity == capacity())
0878             return;
0879         pointer buff = allocate(new_capacity);
0880         iterator b = begin();
0881         BOOST_TRY {
0882             reset(buff,
0883                 cb_details::uninitialized_move_if_noexcept(b, b + (std::min)(new_capacity, size()), buff, alloc()),
0884                 new_capacity);
0885         } BOOST_CATCH(...) {
0886             deallocate(buff, new_capacity);
0887             BOOST_RETHROW
0888         }
0889         BOOST_CATCH_END
0890     }
0891 
0892     //! Change the size of the <code>circular_buffer</code>.
0893     /*!
0894         \post <code>size() == new_size \&\& capacity() >= new_size</code><br><br>
0895               If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
0896               <b>back</b> of the of the <code>circular_buffer</code> in order to achieve the desired size. In the case
0897               the resulting size exceeds the current capacity the capacity will be set to <code>new_size</code>.<br>
0898               If the current number of elements stored in the <code>circular_buffer</code> is greater than the desired
0899               new size then number of <code>[size() - new_size]</code> <b>last</b> elements will be removed. (The
0900               capacity will remain unchanged.)
0901         \param new_size The new size.
0902         \param item The element the <code>circular_buffer</code> will be filled with in order to gain the requested
0903                     size. (See the <i>Effect</i>.)
0904         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0905                 used).
0906                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0907         \par Exception Safety
0908              Basic.
0909         \par Iterator Invalidation
0910              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
0911              <code>end()</code>) if the new size is greater than the current capacity. Invalidates iterators pointing
0912              to the removed elements if the new size is lower that the original size. Otherwise it does not invalidate
0913              any iterator.
0914         \par Complexity
0915              Linear (in the new size of the <code>circular_buffer</code>).
0916         \sa <code>\link rresize() rresize(size_type, const_reference)\endlink</code>,
0917             <code>set_capacity(capacity_type)</code>
0918     */
0919     void resize(size_type new_size, param_value_type item = value_type()) {
0920         if (new_size > size()) {
0921             if (new_size > capacity())
0922                 set_capacity(new_size);
0923             insert(end(), new_size - size(), item);
0924         } else {
0925             iterator e = end();
0926             erase(e - (size() - new_size), e);
0927         }
0928     }
0929 
0930     //! Change the capacity of the <code>circular_buffer</code>.
0931     /*! 
0932         \pre If <code>T</code> is a move only type, then compiler shall support <code>noexcept</code> modifiers
0933                 and move constructor of <code>T</code> must be marked with it (must not throw exceptions).
0934         \post <code>capacity() == new_capacity \&\& size() \<= new_capacity</code><br><br>
0935               If the current number of elements stored in the <code>circular_buffer</code> is greater than the desired
0936               new capacity then number of <code>[size() - new_capacity]</code> <b>first</b> elements will be removed
0937               and the new size will be equal to <code>new_capacity</code>.
0938         \param new_capacity The new capacity.
0939         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0940                 used).
0941                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0942         \par Exception Safety
0943              Strong.
0944         \par Iterator Invalidation
0945              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
0946              <code>end()</code>) if the new capacity is different from the original.
0947         \par Complexity
0948              Linear (in <code>min[size(), new_capacity]</code>).
0949         \sa <code>set_capacity(capacity_type)</code>,
0950             <code>\link rresize() rresize(size_type, const_reference)\endlink</code>
0951     */
0952     void rset_capacity(capacity_type new_capacity) {
0953         if (new_capacity == capacity())
0954             return;
0955         pointer buff = allocate(new_capacity);
0956         iterator e = end();
0957         BOOST_TRY {
0958             reset(buff, cb_details::uninitialized_move_if_noexcept(e - (std::min)(new_capacity, size()),
0959                 e, buff, alloc()), new_capacity);
0960         } BOOST_CATCH(...) {
0961             deallocate(buff, new_capacity);
0962             BOOST_RETHROW
0963         }
0964         BOOST_CATCH_END
0965     }
0966 
0967     //! Change the size of the <code>circular_buffer</code>.
0968     /*!
0969         \post <code>size() == new_size \&\& capacity() >= new_size</code><br><br>
0970               If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
0971               <b>front</b> of the of the <code>circular_buffer</code> in order to achieve the desired size. In the case
0972               the resulting size exceeds the current capacity the capacity will be set to <code>new_size</code>.<br>
0973               If the current number of elements stored in the <code>circular_buffer</code> is greater than the desired
0974               new size then number of <code>[size() - new_size]</code> <b>first</b> elements will be removed. (The
0975               capacity will remain unchanged.)
0976         \param new_size The new size.
0977         \param item The element the <code>circular_buffer</code> will be filled with in order to gain the requested
0978                     size. (See the <i>Effect</i>.)
0979         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
0980                 used).
0981                 Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
0982         \par Exception Safety
0983              Basic.
0984         \par Iterator Invalidation
0985              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
0986              <code>end()</code>) if the new size is greater than the current capacity. Invalidates iterators pointing
0987              to the removed elements if the new size is lower that the original size. Otherwise it does not invalidate
0988              any iterator.
0989         \par Complexity
0990              Linear (in the new size of the <code>circular_buffer</code>).
0991         \sa <code>\link resize() resize(size_type, const_reference)\endlink</code>,
0992             <code>rset_capacity(capacity_type)</code>
0993     */
0994     void rresize(size_type new_size, param_value_type item = value_type()) {
0995         if (new_size > size()) {
0996             if (new_size > capacity())
0997                 set_capacity(new_size);
0998             rinsert(begin(), new_size - size(), item);
0999         } else {
1000             rerase(begin(), end() - new_size);
1001         }
1002     }
1003 
1004 // Construction/Destruction
1005 
1006     //! Create an empty <code>circular_buffer</code> with zero capacity.
1007     /*!
1008         \post <code>capacity() == 0 \&\& size() == 0</code>
1009         \param alloc The allocator.
1010         \throws Nothing.
1011         \par Complexity
1012              Constant.
1013         \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now the constructor does not
1014                  allocate any memory and both capacity and size are set to zero. Also note when inserting an element
1015                  into a <code>circular_buffer</code> with zero capacity (e.g. by
1016                  <code>\link push_back() push_back(const_reference)\endlink</code> or
1017                  <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>) nothing
1018                  will be inserted and the size (as well as capacity) remains zero.
1019         \note You can explicitly set the capacity by calling the <code>set_capacity(capacity_type)</code> method or you
1020               can use the other constructor with the capacity specified.
1021         \sa <code>circular_buffer(capacity_type, const allocator_type& alloc)</code>,
1022             <code>set_capacity(capacity_type)</code>
1023     */
1024     explicit circular_buffer(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT
1025     : base(boost::empty_init_t(), alloc), m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0) {}
1026 
1027     //! Create an empty <code>circular_buffer</code> with the specified capacity.
1028     /*!
1029         \post <code>capacity() == buffer_capacity \&\& size() == 0</code>
1030         \param buffer_capacity The maximum number of elements which can be stored in the <code>circular_buffer</code>.
1031         \param alloc The allocator.
1032         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1033                 used).
1034         \par Complexity
1035              Constant.
1036     */
1037     explicit circular_buffer(capacity_type buffer_capacity, const allocator_type& alloc = allocator_type())
1038     : base(boost::empty_init_t(), alloc), m_size(0) {
1039         initialize_buffer(buffer_capacity);
1040         m_first = m_last = m_buff;
1041     }
1042 
1043     /*! \brief Create a full <code>circular_buffer</code> with the specified capacity and filled with <code>n</code>
1044                copies of <code>item</code>.
1045         \post <code>capacity() == n \&\& full() \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ... \&\&
1046               (*this)[n - 1] == item </code>
1047         \param n The number of elements the created <code>circular_buffer</code> will be filled with.
1048         \param item The element the created <code>circular_buffer</code> will be filled with.
1049         \param alloc The allocator.
1050         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1051                 used).
1052                 Whatever <code>T::T(const T&)</code> throws.
1053         \par Complexity
1054              Linear (in the <code>n</code>).
1055     */
1056     circular_buffer(size_type n, param_value_type item, const allocator_type& alloc = allocator_type())
1057     : base(boost::empty_init_t(), alloc), m_size(n) {
1058         initialize_buffer(n, item);
1059         m_first = m_last = m_buff;
1060     }
1061 
1062     /*! \brief Create a <code>circular_buffer</code> with the specified capacity and filled with <code>n</code>
1063                copies of <code>item</code>.
1064         \pre <code>buffer_capacity >= n</code>
1065         \post <code>capacity() == buffer_capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
1066               \&\& ... \&\& (*this)[n - 1] == item</code>
1067         \param buffer_capacity The capacity of the created <code>circular_buffer</code>.
1068         \param n The number of elements the created <code>circular_buffer</code> will be filled with.
1069         \param item The element the created <code>circular_buffer</code> will be filled with.
1070         \param alloc The allocator.
1071         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1072                 used).
1073                 Whatever <code>T::T(const T&)</code> throws.
1074         \par Complexity
1075              Linear (in the <code>n</code>).
1076     */
1077     circular_buffer(capacity_type buffer_capacity, size_type n, param_value_type item,
1078         const allocator_type& alloc = allocator_type())
1079     : base(boost::empty_init_t(), alloc), m_size(n) {
1080         BOOST_CB_ASSERT(buffer_capacity >= size()); // check for capacity lower than size
1081         initialize_buffer(buffer_capacity, item);
1082         m_first = m_buff;
1083         m_last = buffer_capacity == n ? m_buff : m_buff + n;
1084     }
1085 
1086     //! The copy constructor.
1087     /*!
1088         Creates a copy of the specified <code>circular_buffer</code>.
1089         \post <code>*this == cb</code>
1090         \param cb The <code>circular_buffer</code> to be copied.
1091         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1092                 used).
1093                 Whatever <code>T::T(const T&)</code> throws.
1094         \par Complexity
1095              Linear (in the size of <code>cb</code>).
1096     */
1097     circular_buffer(const circular_buffer<T, Alloc>& cb)
1098     :
1099 #if BOOST_CB_ENABLE_DEBUG
1100     debug_iterator_registry(),
1101 #endif
1102     base(boost::empty_init_t(), cb.get_allocator()),
1103     m_size(cb.size()) {
1104         initialize_buffer(cb.capacity());
1105         m_first = m_buff;
1106         BOOST_TRY {
1107             m_last = cb_details::uninitialized_copy(cb.begin(), cb.end(), m_buff, alloc());
1108         } BOOST_CATCH(...) {
1109             deallocate(m_buff, cb.capacity());
1110             BOOST_RETHROW
1111         }
1112         BOOST_CATCH_END
1113         if (m_last == m_end)
1114             m_last = m_buff;
1115     }
1116     
1117 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1118     //! The move constructor.
1119     /*! \brief Move constructs a <code>circular_buffer</code> from <code>cb</code>, leaving <code>cb</code> empty.
1120         \pre C++ compiler with rvalue references support.
1121         \post <code>cb.empty()</code>
1122         \param cb <code>circular_buffer</code> to 'steal' value from.
1123         \throws Nothing.
1124         \par Constant.
1125     */
1126     circular_buffer(circular_buffer<T, Alloc>&& cb) BOOST_NOEXCEPT
1127     : base(boost::empty_init_t(), cb.get_allocator()), m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0) {
1128         cb.swap(*this);
1129     }
1130 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
1131 
1132     //! Create a full <code>circular_buffer</code> filled with a copy of the range.
1133     /*!
1134         \pre Valid range <code>[first, last)</code>.<br>
1135              <code>first</code> and <code>last</code> have to meet the requirements of
1136              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
1137         \post <code>capacity() == std::distance(first, last) \&\& full() \&\& (*this)[0]== *first \&\&
1138               (*this)[1] == *(first + 1) \&\& ... \&\& (*this)[std::distance(first, last) - 1] == *(last - 1)</code>
1139         \param first The beginning of the range to be copied.
1140         \param last The end of the range to be copied.
1141         \param alloc The allocator.
1142         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1143                 used).
1144                 Whatever <code>T::T(const T&)</code> throws.
1145         \par Complexity
1146              Linear (in the <code>std::distance(first, last)</code>).
1147     */
1148     template <class InputIterator>
1149     circular_buffer(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())
1150     : base(boost::empty_init_t(), alloc) {
1151         initialize(first, last, is_integral<InputIterator>());
1152     }
1153 
1154     //! Create a <code>circular_buffer</code> with the specified capacity and filled with a copy of the range.
1155     /*!
1156         \pre Valid range <code>[first, last)</code>.<br>
1157              <code>first</code> and <code>last</code> have to meet the requirements of
1158              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
1159         \post <code>capacity() == buffer_capacity \&\& size() \<= std::distance(first, last) \&\&
1160              (*this)[0]== *(last - buffer_capacity) \&\& (*this)[1] == *(last - buffer_capacity + 1) \&\& ... \&\&
1161              (*this)[buffer_capacity - 1] == *(last - 1)</code><br><br>
1162              If the number of items to be copied from the range <code>[first, last)</code> is greater than the
1163              specified <code>buffer_capacity</code> then only elements from the range
1164              <code>[last - buffer_capacity, last)</code> will be copied.
1165         \param buffer_capacity The capacity of the created <code>circular_buffer</code>.
1166         \param first The beginning of the range to be copied.
1167         \param last The end of the range to be copied.
1168         \param alloc The allocator.
1169         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1170                 used).
1171                 Whatever <code>T::T(const T&)</code> throws.
1172         \par Complexity
1173              Linear (in <code>std::distance(first, last)</code>; in
1174              <code>min[capacity, std::distance(first, last)]</code> if the <code>InputIterator</code> is a
1175              <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
1176     */
1177     template <class InputIterator>
1178     circular_buffer(capacity_type buffer_capacity, InputIterator first, InputIterator last,
1179         const allocator_type& alloc = allocator_type())
1180     : base(boost::empty_init_t(), alloc) {
1181         initialize(buffer_capacity, first, last, is_integral<InputIterator>());
1182     }
1183 
1184     //! The destructor.
1185     /*!
1186         Destroys the <code>circular_buffer</code>.
1187         \throws Nothing.
1188         \par Iterator Invalidation
1189              Invalidates all iterators pointing to the <code>circular_buffer</code> (including iterators equal to
1190              <code>end()</code>).
1191         \par Complexity
1192              Constant (in the size of the <code>circular_buffer</code>) for scalar types; linear for other types.
1193         \sa <code>clear()</code>
1194     */
1195     ~circular_buffer() BOOST_NOEXCEPT {
1196         destroy();
1197 #if BOOST_CB_ENABLE_DEBUG
1198         invalidate_all_iterators();
1199 #endif
1200     }
1201 
1202 public:
1203 // Assign methods
1204 
1205     //! The assign operator.
1206     /*!
1207         Makes this <code>circular_buffer</code> to become a copy of the specified <code>circular_buffer</code>.
1208         \post <code>*this == cb</code>
1209         \param cb The <code>circular_buffer</code> to be copied.
1210         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1211                 used).
1212                 Whatever <code>T::T(const T&)</code> throws.
1213         \par Exception Safety
1214              Strong.
1215         \par Iterator Invalidation
1216              Invalidates all iterators pointing to this <code>circular_buffer</code> (except iterators equal to
1217              <code>end()</code>).
1218         \par Complexity
1219              Linear (in the size of <code>cb</code>).
1220         \sa <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
1221             <code>\link assign(capacity_type, size_type, param_value_type)
1222             assign(capacity_type, size_type, const_reference)\endlink</code>,
1223             <code>assign(InputIterator, InputIterator)</code>,
1224             <code>assign(capacity_type, InputIterator, InputIterator)</code>
1225     */
1226     circular_buffer<T, Alloc>& operator = (const circular_buffer<T, Alloc>& cb) {
1227         if (this == &cb)
1228             return *this;
1229         pointer buff = allocate(cb.capacity());
1230         BOOST_TRY {
1231             reset(buff, cb_details::uninitialized_copy(cb.begin(), cb.end(), buff, alloc()), cb.capacity());
1232         } BOOST_CATCH(...) {
1233             deallocate(buff, cb.capacity());
1234             BOOST_RETHROW
1235         }
1236         BOOST_CATCH_END
1237         return *this;
1238     }
1239 
1240 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1241     /*! \brief Move assigns content of <code>cb</code> to <code>*this</code>, leaving <code>cb</code> empty.
1242         \pre C++ compiler with rvalue references support.
1243         \post <code>cb.empty()</code>
1244         \param cb <code>circular_buffer</code> to 'steal' value from.
1245         \throws Nothing.
1246         \par Complexity
1247              Constant.
1248     */
1249     circular_buffer<T, Alloc>& operator = (circular_buffer<T, Alloc>&& cb) BOOST_NOEXCEPT {
1250         cb.swap(*this); // now `this` holds `cb`
1251         circular_buffer<T, Alloc>(get_allocator()) // temporary that holds initial `cb` allocator
1252             .swap(cb); // makes `cb` empty
1253         return *this;
1254     }
1255 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
1256 
1257     //! Assign <code>n</code> items into the <code>circular_buffer</code>.
1258     /*!
1259         The content of the <code>circular_buffer</code> will be removed and replaced with <code>n</code> copies of the
1260         <code>item</code>.
1261         \post <code>capacity() == n \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ... \&\&
1262               (*this) [n - 1] == item</code>
1263         \param n The number of elements the <code>circular_buffer</code> will be filled with.
1264         \param item The element the <code>circular_buffer</code> will be filled with.
1265         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1266                 used).
1267                 Whatever <code>T::T(const T&)</code> throws.
1268         \par Exception Safety
1269              Basic.
1270         \par Iterator Invalidation
1271              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
1272              <code>end()</code>).
1273         \par Complexity
1274              Linear (in the <code>n</code>).
1275         \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
1276             <code>\link assign(capacity_type, size_type, param_value_type)
1277             assign(capacity_type, size_type, const_reference)\endlink</code>,
1278             <code>assign(InputIterator, InputIterator)</code>,
1279             <code>assign(capacity_type, InputIterator, InputIterator)</code>
1280     */
1281     void assign(size_type n, param_value_type item) {
1282         assign_n(n, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, alloc()));
1283     }
1284 
1285     //! Assign <code>n</code> items into the <code>circular_buffer</code> specifying the capacity.
1286     /*!
1287         The capacity of the <code>circular_buffer</code> will be set to the specified value and the content of the
1288         <code>circular_buffer</code> will be removed and replaced with <code>n</code> copies of the <code>item</code>.
1289         \pre <code>capacity >= n</code>
1290         \post <code>capacity() == buffer_capacity \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
1291               \&\& ... \&\& (*this) [n - 1] == item </code>
1292         \param buffer_capacity The new capacity.
1293         \param n The number of elements the <code>circular_buffer</code> will be filled with.
1294         \param item The element the <code>circular_buffer</code> will be filled with.
1295         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1296                 used).
1297                 Whatever <code>T::T(const T&)</code> throws.
1298         \par Exception Safety
1299              Basic.
1300         \par Iterator Invalidation
1301              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
1302              <code>end()</code>).
1303         \par Complexity
1304              Linear (in the <code>n</code>).
1305         \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
1306             <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
1307             <code>assign(InputIterator, InputIterator)</code>,
1308             <code>assign(capacity_type, InputIterator, InputIterator)</code>
1309     */
1310     void assign(capacity_type buffer_capacity, size_type n, param_value_type item) {
1311         BOOST_CB_ASSERT(buffer_capacity >= n); // check for new capacity lower than n
1312         assign_n(buffer_capacity, n, cb_details::assign_n<param_value_type, allocator_type>(n, item, alloc()));
1313     }
1314 
1315     //! Assign a copy of the range into the <code>circular_buffer</code>.
1316     /*!
1317         The content of the <code>circular_buffer</code> will be removed and replaced with copies of elements from the
1318         specified range.
1319         \pre Valid range <code>[first, last)</code>.<br>
1320              <code>first</code> and <code>last</code> have to meet the requirements of
1321              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
1322         \post <code>capacity() == std::distance(first, last) \&\& size() == std::distance(first, last) \&\&
1323              (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... \&\& (*this)[std::distance(first, last) - 1]
1324              == *(last - 1)</code>
1325         \param first The beginning of the range to be copied.
1326         \param last The end of the range to be copied.
1327         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1328                 used).
1329                 Whatever <code>T::T(const T&)</code> throws.
1330         \par Exception Safety
1331              Basic.
1332         \par Iterator Invalidation
1333              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
1334              <code>end()</code>).
1335         \par Complexity
1336              Linear (in the <code>std::distance(first, last)</code>).
1337         \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
1338             <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
1339             <code>\link assign(capacity_type, size_type, param_value_type)
1340             assign(capacity_type, size_type, const_reference)\endlink</code>,
1341             <code>assign(capacity_type, InputIterator, InputIterator)</code>
1342     */
1343     template <class InputIterator>
1344     void assign(InputIterator first, InputIterator last) {
1345         assign(first, last, is_integral<InputIterator>());
1346     }
1347 
1348     //! Assign a copy of the range into the <code>circular_buffer</code> specifying the capacity.
1349     /*!
1350         The capacity of the <code>circular_buffer</code> will be set to the specified value and the content of the
1351         <code>circular_buffer</code> will be removed and replaced with copies of elements from the specified range.
1352         \pre Valid range <code>[first, last)</code>.<br>
1353              <code>first</code> and <code>last</code> have to meet the requirements of
1354              <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
1355         \post <code>capacity() == buffer_capacity \&\& size() \<= std::distance(first, last) \&\&
1356              (*this)[0]== *(last - buffer_capacity) \&\& (*this)[1] == *(last - buffer_capacity + 1) \&\& ... \&\&
1357              (*this)[buffer_capacity - 1] == *(last - 1)</code><br><br>
1358              If the number of items to be copied from the range <code>[first, last)</code> is greater than the
1359              specified <code>buffer_capacity</code> then only elements from the range
1360              <code>[last - buffer_capacity, last)</code> will be copied.
1361         \param buffer_capacity The new capacity.
1362         \param first The beginning of the range to be copied.
1363         \param last The end of the range to be copied.
1364         \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
1365                 used).
1366                 Whatever <code>T::T(const T&)</code> throws.
1367         \par Exception Safety
1368              Basic.
1369         \par Iterator Invalidation
1370              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
1371              <code>end()</code>).
1372         \par Complexity
1373              Linear (in <code>std::distance(first, last)</code>; in
1374              <code>min[capacity, std::distance(first, last)]</code> if the <code>InputIterator</code> is a
1375              <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
1376         \sa <code>\link operator=(const circular_buffer&) operator=\endlink</code>,
1377             <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
1378             <code>\link assign(capacity_type, size_type, param_value_type)
1379             assign(capacity_type, size_type, const_reference)\endlink</code>,
1380             <code>assign(InputIterator, InputIterator)</code>
1381     */
1382     template <class InputIterator>
1383     void assign(capacity_type buffer_capacity, InputIterator first, InputIterator last) {
1384         assign(buffer_capacity, first, last, is_integral<InputIterator>());
1385     }
1386 
1387     //! Swap the contents of two <code>circular_buffer</code>s.
1388     /*!
1389         \post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity of <code>this</code>
1390               equals to the capacity of <code>cb</code> and vice versa.
1391         \param cb The <code>circular_buffer</code> whose content will be swapped.
1392         \throws Nothing.
1393         \par Exception Safety
1394              No-throw.
1395         \par Iterator Invalidation
1396              Invalidates all iterators of both <code>circular_buffer</code>s. (On the other hand the iterators still
1397              point to the same elements but within another container. If you want to rely on this feature you have to
1398              turn the <a href="#debug">Debug Support</a> off otherwise an assertion will report an error if such
1399              invalidated iterator is used.)
1400         \par Complexity
1401              Constant (in the size of the <code>circular_buffer</code>).
1402         \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>
1403     */
1404     void swap(circular_buffer<T, Alloc>& cb) BOOST_NOEXCEPT {
1405         swap_allocator(cb, is_stateless<allocator_type>());
1406         adl_move_swap(m_buff, cb.m_buff);
1407         adl_move_swap(m_end, cb.m_end);
1408         adl_move_swap(m_first, cb.m_first);
1409         adl_move_swap(m_last, cb.m_last);
1410         adl_move_swap(m_size, cb.m_size);
1411 #if BOOST_CB_ENABLE_DEBUG
1412         invalidate_all_iterators();
1413         cb.invalidate_all_iterators();
1414 #endif
1415     }
1416 
1417 // push and pop
1418 private:
1419     /*! INTERNAL ONLY */
1420     template <class ValT>
1421     void push_back_impl(ValT item) {
1422         if (full()) {
1423             if (empty())
1424                 return;
1425             replace(m_last, static_cast<ValT>(item));
1426             increment(m_last);
1427             m_first = m_last;
1428         } else {
1429             boost::allocator_construct(alloc(), boost::to_address(m_last), static_cast<ValT>(item));
1430             increment(m_last);
1431             ++m_size;
1432         }        
1433     }
1434 
1435     /*! INTERNAL ONLY */
1436     template <class ValT>
1437     void push_front_impl(ValT item) {
1438         BOOST_TRY {
1439             if (full()) {
1440                 if (empty())
1441                     return;
1442                 decrement(m_first);
1443                 replace(m_first, static_cast<ValT>(item));
1444                 m_last = m_first;
1445             } else {
1446                 decrement(m_first);
1447                 boost::allocator_construct(alloc(), boost::to_address(m_first), static_cast<ValT>(item));
1448                 ++m_size;
1449             }
1450         } BOOST_CATCH(...) {
1451             increment(m_first);
1452             BOOST_RETHROW
1453         }
1454         BOOST_CATCH_END
1455     }
1456 
1457 public:
1458     //! Insert a new element at the end of the <code>circular_buffer</code>.
1459     /*!
1460         \post if <code>capacity() > 0</code> then <code>back() == item</code><br>
1461               If the <code>circular_buffer</code> is full, the first element will be removed. If the capacity is
1462               <code>0</code>, nothing will be inserted.
1463         \param item The element to be inserted.
1464         \throws Whatever <code>T::T(const T&)</code> throws.
1465                 Whatever <code>T::operator = (const T&)</code> throws.
1466         \par Exception Safety
1467              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1468         \par Iterator Invalidation
1469              Does not invalidate any iterators with the exception of iterators pointing to the overwritten element.
1470         \par Complexity
1471              Constant (in the size of the <code>circular_buffer</code>).
1472         \sa <code>\link push_front() push_front(const_reference)\endlink</code>,
1473             <code>pop_back()</code>, <code>pop_front()</code>
1474     */
1475     void push_back(param_value_type item) {
1476         push_back_impl<param_value_type>(item);
1477     }
1478 
1479     //! Insert a new element at the end of the <code>circular_buffer</code> using rvalue references or rvalues references emulation.
1480     /*!
1481         \post if <code>capacity() > 0</code> then <code>back() == item</code><br>
1482               If the <code>circular_buffer</code> is full, the first element will be removed. If the capacity is
1483               <code>0</code>, nothing will be inserted.
1484         \param item The element to be inserted.
1485         \throws Whatever <code>T::T(T&&)</code> throws.
1486                 Whatever <code>T::operator = (T&&)</code> throws.
1487         \par Exception Safety
1488              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1489         \par Iterator Invalidation
1490              Does not invalidate any iterators with the exception of iterators pointing to the overwritten element.
1491         \par Complexity
1492              Constant (in the size of the <code>circular_buffer</code>).
1493         \sa <code>\link push_front() push_front(const_reference)\endlink</code>,
1494             <code>pop_back()</code>, <code>pop_front()</code>
1495     */
1496     void push_back(rvalue_type item) {
1497         push_back_impl<rvalue_type>(boost::move(item));
1498     }
1499 
1500     //! Insert a new default-constructed element at the end of the <code>circular_buffer</code>.
1501     /*!
1502         \post if <code>capacity() > 0</code> then <code>back() == item</code><br>
1503               If the <code>circular_buffer</code> is full, the first element will be removed. If the capacity is
1504               <code>0</code>, nothing will be inserted.
1505         \throws Whatever <code>T::T()</code> throws.
1506                 Whatever <code>T::T(T&&)</code> throws.
1507                 Whatever <code>T::operator = (T&&)</code> throws.
1508         \par Exception Safety
1509              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1510         \par Iterator Invalidation
1511              Does not invalidate any iterators with the exception of iterators pointing to the overwritten element.
1512         \par Complexity
1513              Constant (in the size of the <code>circular_buffer</code>).
1514         \sa <code>\link push_front() push_front(const_reference)\endlink</code>,
1515             <code>pop_back()</code>, <code>pop_front()</code>
1516     */
1517     void push_back() {
1518         value_type temp;
1519         push_back(boost::move(temp));
1520     }
1521 
1522     //! Insert a new element at the beginning of the <code>circular_buffer</code>.
1523     /*!
1524         \post if <code>capacity() > 0</code> then <code>front() == item</code><br>
1525               If the <code>circular_buffer</code> is full, the last element will be removed. If the capacity is
1526               <code>0</code>, nothing will be inserted.
1527         \param item The element to be inserted.
1528         \throws Whatever <code>T::T(const T&)</code> throws.
1529                 Whatever <code>T::operator = (const T&)</code> throws.
1530         \par Exception Safety
1531              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1532         \par Iterator Invalidation
1533              Does not invalidate any iterators with the exception of iterators pointing to the overwritten element.
1534         \par Complexity
1535              Constant (in the size of the <code>circular_buffer</code>).
1536         \sa <code>\link push_back() push_back(const_reference)\endlink</code>,
1537             <code>pop_back()</code>, <code>pop_front()</code>
1538     */
1539     void push_front(param_value_type item) {
1540         push_front_impl<param_value_type>(item);
1541     }
1542 
1543     //! Insert a new element at the beginning of the <code>circular_buffer</code> using rvalue references or rvalues references emulation.
1544     /*!
1545         \post if <code>capacity() > 0</code> then <code>front() == item</code><br>
1546               If the <code>circular_buffer</code> is full, the last element will be removed. If the capacity is
1547               <code>0</code>, nothing will be inserted.
1548         \param item The element to be inserted.
1549         \throws Whatever <code>T::T(T&&)</code> throws.
1550                 Whatever <code>T::operator = (T&&)</code> throws.
1551         \par Exception Safety
1552              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1553         \par Iterator Invalidation
1554              Does not invalidate any iterators with the exception of iterators pointing to the overwritten element.
1555         \par Complexity
1556              Constant (in the size of the <code>circular_buffer</code>).
1557         \sa <code>\link push_back() push_back(const_reference)\endlink</code>,
1558             <code>pop_back()</code>, <code>pop_front()</code>
1559     */
1560     void push_front(rvalue_type item) {
1561         push_front_impl<rvalue_type>(boost::move(item));
1562     }
1563 
1564     //! Insert a new default-constructed element at the beginning of the <code>circular_buffer</code>.
1565     /*!
1566         \post if <code>capacity() > 0</code> then <code>front() == item</code><br>
1567               If the <code>circular_buffer</code> is full, the last element will be removed. If the capacity is
1568               <code>0</code>, nothing will be inserted.
1569         \throws Whatever <code>T::T()</code> throws.
1570                 Whatever <code>T::T(T&&)</code> throws.
1571                 Whatever <code>T::operator = (T&&)</code> throws.
1572         \par Exception Safety
1573              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1574         \par Iterator Invalidation
1575              Does not invalidate any iterators with the exception of iterators pointing to the overwritten element.
1576         \par Complexity
1577              Constant (in the size of the <code>circular_buffer</code>).
1578         \sa <code>\link push_back() push_back(const_reference)\endlink</code>,
1579             <code>pop_back()</code>, <code>pop_front()</code>
1580     */
1581     void push_front() {
1582         value_type temp;
1583         push_front(boost::move(temp));
1584     }
1585 
1586     //! Remove the last element from the <code>circular_buffer</code>.
1587     /*!
1588         \pre <code>!empty()</code>
1589         \post The last element is removed from the <code>circular_buffer</code>.
1590         \throws Nothing.
1591         \par Exception Safety
1592              No-throw.
1593         \par Iterator Invalidation
1594              Invalidates only iterators pointing to the removed element.
1595         \par Complexity
1596              Constant (in the size of the <code>circular_buffer</code>).
1597         \sa <code>pop_front()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
1598             <code>\link push_front() push_front(const_reference)\endlink</code>
1599     */
1600     void pop_back() {
1601         BOOST_CB_ASSERT(!empty()); // check for empty buffer (back element not available)
1602         decrement(m_last);
1603         destroy_item(m_last);
1604         --m_size;
1605     }
1606 
1607     //! Remove the first element from the <code>circular_buffer</code>.
1608     /*!
1609         \pre <code>!empty()</code>
1610         \post The first element is removed from the <code>circular_buffer</code>.
1611         \throws Nothing.
1612         \par Exception Safety
1613              No-throw.
1614         \par Iterator Invalidation
1615              Invalidates only iterators pointing to the removed element.
1616         \par Complexity
1617              Constant (in the size of the <code>circular_buffer</code>).
1618         \sa <code>pop_back()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
1619             <code>\link push_front() push_front(const_reference)\endlink</code>
1620     */
1621     void pop_front() {
1622         BOOST_CB_ASSERT(!empty()); // check for empty buffer (front element not available)
1623         destroy_item(m_first);
1624         increment(m_first);
1625         --m_size;
1626     }
1627 private:
1628     /*! INTERNAL ONLY */
1629     template <class ValT>
1630     iterator insert_impl(iterator pos, ValT item) {
1631         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
1632         iterator b = begin();
1633         if (full() && pos == b)
1634             return b;
1635         return insert_item<ValT>(pos, static_cast<ValT>(item));
1636     }
1637 
1638 public:
1639 // Insert
1640 
1641     //! Insert an element at the specified position.
1642     /*!
1643         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
1644         \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
1645               If the <code>circular_buffer</code> is full, the first element will be overwritten. If the
1646               <code>circular_buffer</code> is full and the <code>pos</code> points to <code>begin()</code>, then the
1647               <code>item</code> will not be inserted. If the capacity is <code>0</code>, nothing will be inserted.
1648         \param pos An iterator specifying the position where the <code>item</code> will be inserted.
1649         \param item The element to be inserted.
1650         \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
1651                 the <i>Effect</i>.)
1652         \throws Whatever <code>T::T(const T&)</code> throws.
1653                 Whatever <code>T::operator = (const T&)</code> throws.
1654                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
1655          
1656         \par Exception Safety
1657              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1658         \par Iterator Invalidation
1659              Invalidates iterators pointing to the elements at the insertion point (including <code>pos</code>) and
1660              iterators behind the insertion point (towards the end; except iterators equal to <code>end()</code>). It
1661              also invalidates iterators pointing to the overwritten element.
1662         \par Complexity
1663              Linear (in <code>std::distance(pos, end())</code>).
1664         \sa <code>\link insert(iterator, size_type, param_value_type)
1665             insert(iterator, size_type, value_type)\endlink</code>,
1666             <code>insert(iterator, InputIterator, InputIterator)</code>,
1667             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1668             <code>\link rinsert(iterator, size_type, param_value_type)
1669             rinsert(iterator, size_type, value_type)\endlink</code>,
1670             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1671     */
1672     iterator insert(iterator pos, param_value_type item) {
1673         return insert_impl<param_value_type>(pos, item);
1674     }
1675 
1676     //! Insert an element at the specified position.
1677     /*!
1678         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
1679         \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
1680               If the <code>circular_buffer</code> is full, the first element will be overwritten. If the
1681               <code>circular_buffer</code> is full and the <code>pos</code> points to <code>begin()</code>, then the
1682               <code>item</code> will not be inserted. If the capacity is <code>0</code>, nothing will be inserted.
1683         \param pos An iterator specifying the position where the <code>item</code> will be inserted.
1684         \param item The element to be inserted.
1685         \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
1686                 the <i>Effect</i>.)
1687         \throws Whatever <code>T::T(T&&)</code> throws.
1688                 Whatever <code>T::operator = (T&&)</code> throws.
1689                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
1690         \par Exception Safety
1691              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1692         \par Iterator Invalidation
1693              Invalidates iterators pointing to the elements at the insertion point (including <code>pos</code>) and
1694              iterators behind the insertion point (towards the end; except iterators equal to <code>end()</code>). It
1695              also invalidates iterators pointing to the overwritten element.
1696         \par Complexity
1697              Linear (in <code>std::distance(pos, end())</code>).
1698         \sa <code>\link insert(iterator, size_type, param_value_type)
1699             insert(iterator, size_type, value_type)\endlink</code>,
1700             <code>insert(iterator, InputIterator, InputIterator)</code>,
1701             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1702             <code>\link rinsert(iterator, size_type, param_value_type)
1703             rinsert(iterator, size_type, value_type)\endlink</code>,
1704             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1705     */
1706     iterator insert(iterator pos, rvalue_type item) {
1707         return insert_impl<rvalue_type>(pos, boost::move(item));
1708     }
1709 
1710     //! Insert a default-constructed element at the specified position.
1711     /*!
1712         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
1713         \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
1714               If the <code>circular_buffer</code> is full, the first element will be overwritten. If the
1715               <code>circular_buffer</code> is full and the <code>pos</code> points to <code>begin()</code>, then the
1716               <code>item</code> will not be inserted. If the capacity is <code>0</code>, nothing will be inserted.
1717         \param pos An iterator specifying the position where the <code>item</code> will be inserted.
1718         \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
1719                 the <i>Effect</i>.)
1720         \throws Whatever <code>T::T()</code> throws.
1721                 Whatever <code>T::T(T&&)</code> throws.
1722                 Whatever <code>T::operator = (T&&)</code> throws.
1723                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
1724         \par Exception Safety
1725              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
1726         \par Iterator Invalidation
1727              Invalidates iterators pointing to the elements at the insertion point (including <code>pos</code>) and
1728              iterators behind the insertion point (towards the end; except iterators equal to <code>end()</code>). It
1729              also invalidates iterators pointing to the overwritten element.
1730         \par Complexity
1731              Linear (in <code>std::distance(pos, end())</code>).
1732         \sa <code>\link insert(iterator, size_type, param_value_type)
1733             insert(iterator, size_type, value_type)\endlink</code>,
1734             <code>insert(iterator, InputIterator, InputIterator)</code>,
1735             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1736             <code>\link rinsert(iterator, size_type, param_value_type)
1737             rinsert(iterator, size_type, value_type)\endlink</code>,
1738             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1739     */
1740     iterator insert(iterator pos) {
1741         value_type temp;
1742         return insert(pos, boost::move(temp));
1743     }
1744 
1745     //! Insert <code>n</code> copies of the <code>item</code> at the specified position.
1746     /*!
1747         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
1748         \post The number of <code>min[n, (pos - begin()) + reserve()]</code> elements will be inserted at the position
1749               <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0, n - reserve()]]</code> elements will
1750               be overwritten at the beginning of the <code>circular_buffer</code>.<br>(See <i>Example</i> for the
1751               explanation.)
1752         \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
1753         \param n The number of <code>item</code>s the to be inserted.
1754         \param item The element whose copies will be inserted.
1755         \throws Whatever <code>T::T(const T&)</code> throws.
1756                 Whatever <code>T::operator = (const T&)</code> throws.
1757                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
1758         \par Exception Safety
1759              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
1760         \par Iterator Invalidation
1761              Invalidates iterators pointing to the elements at the insertion point (including <code>pos</code>) and
1762              iterators behind the insertion point (towards the end; except iterators equal to <code>end()</code>). It
1763              also invalidates iterators pointing to the overwritten elements.
1764         \par Complexity
1765              Linear (in <code>min[capacity(), std::distance(pos, end()) + n]</code>).
1766         \par Example
1767              Consider a <code>circular_buffer</code> with the capacity of 6 and the size of 4. Its internal buffer may
1768              look like the one below.<br><br>
1769              <code>|1|2|3|4| | |</code><br>
1770              <code>p ___^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
1771              <code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
1772              <code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves
1773              the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br>
1774              <br>For comparison if the capacity would not be preserved the internal buffer would then result in
1775              <code>|1|2|0|0|0|0|0|3|4|</code>.
1776         \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1777             <code>insert(iterator, InputIterator, InputIterator)</code>,
1778             <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
1779             <code>\link rinsert(iterator, size_type, param_value_type)
1780             rinsert(iterator, size_type, value_type)\endlink</code>,
1781             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1782     */
1783     void insert(iterator pos, size_type n, param_value_type item) {
1784         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
1785         if (n == 0)
1786             return;
1787         size_type copy = capacity() - (end() - pos);
1788         if (copy == 0)
1789             return;
1790         if (n > copy)
1791             n = copy;
1792         insert_n(pos, n, cb_details::item_wrapper<const_pointer, param_value_type>(item));
1793     }
1794 
1795     //! Insert the range <code>[first, last)</code> at the specified position.
1796     /*!
1797         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.<br>
1798              Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
1799              requirements of an <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
1800         \post Elements from the range
1801               <code>[first + max[0, distance(first, last) - (pos - begin()) - reserve()], last)</code> will be
1802               inserted at the position <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0,
1803               distance(first, last) - reserve()]]</code> elements will be overwritten at the beginning of the
1804               <code>circular_buffer</code>.<br>(See <i>Example</i> for the explanation.)
1805         \param pos An iterator specifying the position where the range will be inserted.
1806         \param first The beginning of the range to be inserted.
1807         \param last The end of the range to be inserted.
1808         \throws Whatever <code>T::T(const T&)</code> throws if the <code>InputIterator</code> is not a move iterator.
1809                 Whatever <code>T::operator = (const T&)</code> throws if the <code>InputIterator</code> is not a move iterator.
1810                 Whatever <code>T::T(T&&)</code> throws if the <code>InputIterator</code> is a move iterator.
1811                 Whatever <code>T::operator = (T&&)</code> throws if the <code>InputIterator</code> is a move iterator.
1812         \par Exception Safety
1813              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
1814         \par Iterator Invalidation
1815              Invalidates iterators pointing to the elements at the insertion point (including <code>pos</code>) and
1816              iterators behind the insertion point (towards the end; except iterators equal to <code>end()</code>). It
1817              also invalidates iterators pointing to the overwritten elements.
1818         \par Complexity
1819              Linear (in <code>[std::distance(pos, end()) + std::distance(first, last)]</code>; in
1820              <code>min[capacity(), std::distance(pos, end()) + std::distance(first, last)]</code> if the
1821              <code>InputIterator</code> is a
1822              <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
1823         \par Example
1824              Consider a <code>circular_buffer</code> with the capacity of 6 and the size of 4. Its internal buffer may
1825              look like the one below.<br><br>
1826              <code>|1|2|3|4| | |</code><br>
1827              <code>p ___^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
1828              <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
1829              actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the
1830              specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due
1831              to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like
1832              this:<br><br><code>|6|7|8|9|3|4|</code><br><br>For comparison if the capacity would not be preserved the
1833              internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
1834         \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1835             <code>\link insert(iterator, size_type, param_value_type)
1836             insert(iterator, size_type, value_type)\endlink</code>, <code>\link rinsert(iterator, param_value_type)
1837             rinsert(iterator, value_type)\endlink</code>, <code>\link rinsert(iterator, size_type, param_value_type)
1838             rinsert(iterator, size_type, value_type)\endlink</code>,
1839             <code>rinsert(iterator, InputIterator, InputIterator)</code>
1840     */
1841     template <class InputIterator>
1842     void insert(iterator pos, InputIterator first, InputIterator last) {
1843         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
1844         insert(pos, first, last, is_integral<InputIterator>());
1845     }
1846 
1847 private:
1848     /*! INTERNAL ONLY */
1849     template <class ValT>
1850     iterator rinsert_impl(iterator pos, ValT item) {
1851         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
1852         if (full() && pos.m_it == 0)
1853             return end();
1854         if (pos == begin()) {
1855             BOOST_TRY {
1856                 decrement(m_first);
1857                 construct_or_replace(!full(), m_first, static_cast<ValT>(item));
1858             } BOOST_CATCH(...) {
1859                 increment(m_first);
1860                 BOOST_RETHROW
1861             }
1862             BOOST_CATCH_END
1863             pos.m_it = m_first;
1864         } else {
1865             pointer src = m_first;
1866             pointer dest = m_first;
1867             decrement(dest);
1868             pos.m_it = map_pointer(pos.m_it);
1869             bool construct = !full();
1870             BOOST_TRY {
1871                 while (src != pos.m_it) {
1872                     construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
1873                     increment(src);
1874                     increment(dest);
1875                     construct = false;
1876                 }
1877                 decrement(pos.m_it);
1878                 replace(pos.m_it, static_cast<ValT>(item));
1879             } BOOST_CATCH(...) {
1880                 if (!construct && !full()) {
1881                     decrement(m_first);
1882                     ++m_size;
1883                 }
1884                 BOOST_RETHROW
1885             }
1886             BOOST_CATCH_END
1887             decrement(m_first);
1888         }
1889         if (full())
1890             m_last = m_first;
1891         else
1892             ++m_size;
1893         return iterator(this, pos.m_it);
1894     }
1895 
1896 public:
1897    
1898     //! Insert an element before the specified position.
1899     /*!
1900         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
1901         \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1902               If the <code>circular_buffer</code> is full, the last element will be overwritten. If the
1903               <code>circular_buffer</code> is full and the <code>pos</code> points to <code>end()</code>, then the
1904               <code>item</code> will not be inserted. If the capacity is <code>0</code>, nothing will be inserted.
1905         \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1906         \param item The element to be inserted.
1907         \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1908                 the <i>Effect</i>.)
1909         \throws Whatever <code>T::T(const T&)</code> throws.
1910                 Whatever <code>T::operator = (const T&)</code> throws.
1911                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
1912         \par Exception Safety
1913              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
1914         \par Iterator Invalidation
1915              Invalidates iterators pointing to the elements before the insertion point (towards the beginning and
1916              excluding <code>pos</code>). It also invalidates iterators pointing to the overwritten element.
1917         \par Complexity
1918              Linear (in <code>std::distance(begin(), pos)</code>).
1919         \sa <code>\link rinsert(iterator, size_type, param_value_type)
1920             rinsert(iterator, size_type, value_type)\endlink</code>,
1921             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1922             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1923             <code>\link insert(iterator, size_type, param_value_type)
1924             insert(iterator, size_type, value_type)\endlink</code>,
1925             <code>insert(iterator, InputIterator, InputIterator)</code>
1926     */
1927     iterator rinsert(iterator pos, param_value_type item) {
1928         return rinsert_impl<param_value_type>(pos, item);
1929     }
1930 
1931     //! Insert an element before the specified position.
1932     /*!
1933         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
1934         \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1935               If the <code>circular_buffer</code> is full, the last element will be overwritten. If the
1936               <code>circular_buffer</code> is full and the <code>pos</code> points to <code>end()</code>, then the
1937               <code>item</code> will not be inserted. If the capacity is <code>0</code>, nothing will be inserted.
1938         \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1939         \param item The element to be inserted.
1940         \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1941                 the <i>Effect</i>.)
1942         \throws Whatever <code>T::T(T&&)</code> throws.
1943                 Whatever <code>T::operator = (T&&)</code> throws.
1944                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
1945         \par Exception Safety
1946              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
1947         \par Iterator Invalidation
1948              Invalidates iterators pointing to the elements before the insertion point (towards the beginning and
1949              excluding <code>pos</code>). It also invalidates iterators pointing to the overwritten element.
1950         \par Complexity
1951              Linear (in <code>std::distance(begin(), pos)</code>).
1952         \sa <code>\link rinsert(iterator, size_type, param_value_type)
1953             rinsert(iterator, size_type, value_type)\endlink</code>,
1954             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1955             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1956             <code>\link insert(iterator, size_type, param_value_type)
1957             insert(iterator, size_type, value_type)\endlink</code>,
1958             <code>insert(iterator, InputIterator, InputIterator)</code>
1959     */
1960     iterator rinsert(iterator pos, rvalue_type item) {
1961         return rinsert_impl<rvalue_type>(pos, boost::move(item));
1962     }
1963 
1964     //! Insert an element before the specified position.
1965     /*!
1966         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
1967         \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
1968               If the <code>circular_buffer</code> is full, the last element will be overwritten. If the
1969               <code>circular_buffer</code> is full and the <code>pos</code> points to <code>end()</code>, then the
1970               <code>item</code> will not be inserted. If the capacity is <code>0</code>, nothing will be inserted.
1971         \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
1972         \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
1973                 the <i>Effect</i>.)
1974         \throws Whatever <code>T::T()</code> throws.
1975                 Whatever <code>T::T(T&&)</code> throws.
1976                 Whatever <code>T::operator = (T&&)</code> throws.
1977                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
1978         \par Exception Safety
1979              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
1980         \par Iterator Invalidation
1981              Invalidates iterators pointing to the elements before the insertion point (towards the beginning and
1982              excluding <code>pos</code>). It also invalidates iterators pointing to the overwritten element.
1983         \par Complexity
1984              Linear (in <code>std::distance(begin(), pos)</code>).
1985         \sa <code>\link rinsert(iterator, size_type, param_value_type)
1986             rinsert(iterator, size_type, value_type)\endlink</code>,
1987             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
1988             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
1989             <code>\link insert(iterator, size_type, param_value_type)
1990             insert(iterator, size_type, value_type)\endlink</code>,
1991             <code>insert(iterator, InputIterator, InputIterator)</code>
1992     */
1993     iterator rinsert(iterator pos) {
1994         value_type temp;
1995         return rinsert(pos, boost::move(temp));
1996     }
1997 
1998     //! Insert <code>n</code> copies of the <code>item</code> before the specified position.
1999     /*!
2000         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.
2001         \post The number of <code>min[n, (end() - pos) + reserve()]</code> elements will be inserted before the
2002               position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0, n - reserve()]]</code> elements
2003               will be overwritten at the end of the <code>circular_buffer</code>.<br>(See <i>Example</i> for the
2004               explanation.)
2005         \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
2006         \param n The number of <code>item</code>s the to be inserted.
2007         \param item The element whose copies will be inserted.
2008         \throws Whatever <code>T::T(const T&)</code> throws.
2009                 Whatever <code>T::operator = (const T&)</code> throws.
2010                 <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
2011         \par Exception Safety
2012              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
2013         \par Iterator Invalidation
2014              Invalidates iterators pointing to the elements before the insertion point (towards the beginning and
2015              excluding <code>pos</code>). It also invalidates iterators pointing to the overwritten elements.
2016         \par Complexity
2017              Linear (in <code>min[capacity(), std::distance(begin(), pos) + n]</code>).
2018         \par Example
2019              Consider a <code>circular_buffer</code> with the capacity of 6 and the size of 4. Its internal buffer may
2020              look like the one below.<br><br>
2021              <code>|1|2|3|4| | |</code><br>
2022              <code>p ___^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
2023              <code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
2024              <code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves
2025              the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br>
2026              <br>For comparison if the capacity would not be preserved the internal buffer would then result in
2027              <code>|1|2|0|0|0|0|0|3|4|</code>.
2028         \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
2029             <code>rinsert(iterator, InputIterator, InputIterator)</code>,
2030             <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
2031             <code>\link insert(iterator, size_type, param_value_type)
2032             insert(iterator, size_type, value_type)\endlink</code>,
2033             <code>insert(iterator, InputIterator, InputIterator)</code>
2034     */
2035     void rinsert(iterator pos, size_type n, param_value_type item) {
2036         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
2037         rinsert_n(pos, n, cb_details::item_wrapper<const_pointer, param_value_type>(item));
2038     }
2039 
2040     //! Insert the range <code>[first, last)</code> before the specified position.
2041     /*!
2042         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> or its end.<br>
2043              Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
2044              requirements of an <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
2045         \post Elements from the range
2046               <code>[first, last - max[0, distance(first, last) - (end() - pos) - reserve()])</code> will be inserted
2047               before the position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0,
2048               distance(first, last) - reserve()]]</code> elements will be overwritten at the end of the
2049               <code>circular_buffer</code>.<br>(See <i>Example</i> for the explanation.)
2050         \param pos An iterator specifying the position where the range will be inserted.
2051         \param first The beginning of the range to be inserted.
2052         \param last The end of the range to be inserted.
2053         \throws Whatever <code>T::T(const T&)</code> throws if the <code>InputIterator</code> is not a move iterator.
2054                 Whatever <code>T::operator = (const T&)</code> throws if the <code>InputIterator</code> is not a move iterator.
2055                 Whatever <code>T::T(T&&)</code> throws if the <code>InputIterator</code> is a move iterator.
2056                 Whatever <code>T::operator = (T&&)</code> throws if the <code>InputIterator</code> is a move iterator.
2057         \par Exception Safety
2058              Basic; no-throw if the operations in the <i>Throws</i> section do not throw anything.
2059         \par Iterator Invalidation
2060              Invalidates iterators pointing to the elements before the insertion point (towards the beginning and
2061              excluding <code>pos</code>). It also invalidates iterators pointing to the overwritten elements.
2062         \par Complexity
2063              Linear (in <code>[std::distance(begin(), pos) + std::distance(first, last)]</code>; in
2064              <code>min[capacity(), std::distance(begin(), pos) + std::distance(first, last)]</code> if the
2065              <code>InputIterator</code> is a
2066              <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
2067         \par Example
2068              Consider a <code>circular_buffer</code> with the capacity of 6 and the size of 4. Its internal buffer may
2069              look like the one below.<br><br>
2070              <code>|1|2|3|4| | |</code><br>
2071              <code>p ___^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
2072              <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
2073              actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the
2074              specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due
2075              to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like
2076              this:<br><br><code>|1|2|5|6|7|8|</code><br><br>For comparison if the capacity would not be preserved the
2077              internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
2078         \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
2079             <code>\link rinsert(iterator, size_type, param_value_type)
2080             rinsert(iterator, size_type, value_type)\endlink</code>, <code>\link insert(iterator, param_value_type)
2081             insert(iterator, value_type)\endlink</code>, <code>\link insert(iterator, size_type, param_value_type)
2082             insert(iterator, size_type, value_type)\endlink</code>,
2083             <code>insert(iterator, InputIterator, InputIterator)</code>
2084     */
2085     template <class InputIterator>
2086     void rinsert(iterator pos, InputIterator first, InputIterator last) {
2087         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
2088         rinsert(pos, first, last, is_integral<InputIterator>());
2089     }
2090 
2091 // Erase
2092 
2093     //! Remove an element at the specified position.
2094     /*!
2095         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> (but not an
2096              <code>end()</code>).
2097         \post The element at the position <code>pos</code> is removed.
2098         \param pos An iterator pointing at the element to be removed.
2099         \return Iterator to the first element remaining beyond the removed element or <code>end()</code> if no such
2100                 element exists.
2101         \throws <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
2102         \par Exception Safety
2103              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
2104         \par Iterator Invalidation
2105              Invalidates iterators pointing to the erased element and iterators pointing to the elements behind
2106              the erased element (towards the end; except iterators equal to <code>end()</code>).
2107         \par Complexity
2108              Linear (in <code>std::distance(pos, end())</code>).
2109         \sa <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
2110             <code>rerase(iterator, iterator)</code>, <code>erase_begin(size_type)</code>,
2111             <code>erase_end(size_type)</code>, <code>clear()</code>
2112     */
2113     iterator erase(iterator pos) {
2114         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
2115         BOOST_CB_ASSERT(pos.m_it != 0);      // check for iterator pointing to end()
2116         pointer next = pos.m_it;
2117         increment(next);
2118         for (pointer p = pos.m_it; next != m_last; p = next, increment(next))
2119             replace(p, boost::move_if_noexcept(*next));
2120         decrement(m_last);
2121         destroy_item(m_last);
2122         --m_size;
2123 #if BOOST_CB_ENABLE_DEBUG
2124         return m_last == pos.m_it ? end() : iterator(this, pos.m_it);
2125 #else
2126         return m_last == pos.m_it ? end() : pos;
2127 #endif
2128     }
2129 
2130     //! Erase the range <code>[first, last)</code>.
2131     /*!
2132         \pre Valid range <code>[first, last)</code>.
2133         \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
2134               nothing is removed.)
2135         \param first The beginning of the range to be removed.
2136         \param last The end of the range to be removed.
2137         \return Iterator to the first element remaining beyond the removed elements or <code>end()</code> if no such
2138                 element exists.
2139         \throws <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
2140         \par Exception Safety
2141              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
2142         \par Iterator Invalidation
2143              Invalidates iterators pointing to the erased elements and iterators pointing to the elements behind
2144              the erased range (towards the end; except iterators equal to <code>end()</code>).
2145         \par Complexity
2146              Linear (in <code>std::distance(first, end())</code>).
2147         \sa <code>erase(iterator)</code>, <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
2148             <code>erase_begin(size_type)</code>, <code>erase_end(size_type)</code>, <code>clear()</code>
2149     */
2150     iterator erase(iterator first, iterator last) {
2151         BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator
2152         BOOST_CB_ASSERT(last.is_valid(this));  // check for uninitialized or invalidated iterator
2153         BOOST_CB_ASSERT(first <= last);        // check for wrong range
2154         if (first == last)
2155             return first;
2156         pointer p = first.m_it;
2157         while (last.m_it != 0)
2158             replace((first++).m_it, boost::move_if_noexcept(*last++));
2159         do {
2160             decrement(m_last);
2161             destroy_item(m_last);
2162             --m_size;
2163         } while(m_last != first.m_it);
2164         return m_last == p ? end() : iterator(this, p);
2165     }
2166 
2167     //! Remove an element at the specified position.
2168     /*!
2169         \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer</code> (but not an
2170              <code>end()</code>).
2171         \post The element at the position <code>pos</code> is removed.
2172         \param pos An iterator pointing at the element to be removed.
2173         \return Iterator to the first element remaining in front of the removed element or <code>begin()</code> if no
2174                 such element exists.
2175         \throws <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
2176         \par Exception Safety
2177              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
2178         \par Iterator Invalidation
2179              Invalidates iterators pointing to the erased element and iterators pointing to the elements in front of
2180              the erased element (towards the beginning).
2181         \par Complexity
2182              Linear (in <code>std::distance(begin(), pos)</code>).
2183         \note This method is symmetric to the <code>erase(iterator)</code> method and is more effective than
2184               <code>erase(iterator)</code> if the iterator <code>pos</code> is close to the beginning of the
2185               <code>circular_buffer</code>. (See the <i>Complexity</i>.)
2186         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
2187             <code>rerase(iterator, iterator)</code>, <code>erase_begin(size_type)</code>,
2188             <code>erase_end(size_type)</code>, <code>clear()</code>
2189     */
2190     iterator rerase(iterator pos) {
2191         BOOST_CB_ASSERT(pos.is_valid(this)); // check for uninitialized or invalidated iterator
2192         BOOST_CB_ASSERT(pos.m_it != 0);      // check for iterator pointing to end()
2193         pointer prev = pos.m_it;
2194         pointer p = prev;
2195         for (decrement(prev); p != m_first; p = prev, decrement(prev))
2196             replace(p, boost::move_if_noexcept(*prev));
2197         destroy_item(m_first);
2198         increment(m_first);
2199         --m_size;
2200 #if BOOST_CB_ENABLE_DEBUG
2201         return p == pos.m_it ? begin() : iterator(this, pos.m_it);
2202 #else
2203         return p == pos.m_it ? begin() : pos;
2204 #endif
2205     }
2206 
2207     //! Erase the range <code>[first, last)</code>.
2208     /*!
2209         \pre Valid range <code>[first, last)</code>.
2210         \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
2211               nothing is removed.)
2212         \param first The beginning of the range to be removed.
2213         \param last The end of the range to be removed.
2214         \return Iterator to the first element remaining in front of the removed elements or <code>begin()</code> if no
2215                 such element exists.
2216         \throws <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
2217         \par Exception Safety
2218              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything.
2219         \par Iterator Invalidation
2220              Invalidates iterators pointing to the erased elements and iterators pointing to the elements in front of
2221              the erased range (towards the beginning).
2222         \par Complexity
2223              Linear (in <code>std::distance(begin(), last)</code>).
2224         \note This method is symmetric to the <code>erase(iterator, iterator)</code> method and is more effective than
2225               <code>erase(iterator, iterator)</code> if <code>std::distance(begin(), first)</code> is lower that
2226               <code>std::distance(last, end())</code>.
2227         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
2228             <code>erase_begin(size_type)</code>, <code>erase_end(size_type)</code>, <code>clear()</code>
2229     */
2230     iterator rerase(iterator first, iterator last) {
2231         BOOST_CB_ASSERT(first.is_valid(this)); // check for uninitialized or invalidated iterator
2232         BOOST_CB_ASSERT(last.is_valid(this));  // check for uninitialized or invalidated iterator
2233         BOOST_CB_ASSERT(first <= last);        // check for wrong range
2234         if (first == last)
2235             return first;
2236         pointer p = map_pointer(last.m_it);
2237         last.m_it = p;
2238         while (first.m_it != m_first) {
2239             decrement(first.m_it);
2240             decrement(p);
2241             replace(p, boost::move_if_noexcept(*first.m_it));
2242         }
2243         do {
2244             destroy_item(m_first);
2245             increment(m_first);
2246             --m_size;
2247         } while(m_first != p);
2248         if (m_first == last.m_it)
2249             return begin();
2250         decrement(last.m_it);
2251         return iterator(this, last.m_it);
2252     }
2253 
2254     //! Remove first <code>n</code> elements (with constant complexity for scalar types).
2255     /*!
2256         \pre <code>n \<= size()</code>
2257         \post The <code>n</code> elements at the beginning of the <code>circular_buffer</code> will be removed.
2258         \param n The number of elements to be removed.
2259         \throws <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
2260         \par Exception Safety
2261              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything. (I.e. no throw in
2262              case of scalars.)
2263         \par Iterator Invalidation
2264              Invalidates iterators pointing to the first <code>n</code> erased elements.
2265         \par Complexity
2266              Constant (in <code>n</code>) for scalar types; linear for other types.
2267         \note This method has been specially designed for types which do not require an explicit destructruction (e.g.
2268               integer, float or a pointer). For these scalar types a call to a destructor is not required which makes
2269               it possible to implement the "erase from beginning" operation with a constant complexity. For non-sacalar
2270               types the complexity is linear (hence the explicit destruction is needed) and the implementation is
2271               actually equivalent to
2272               <code>\link circular_buffer::rerase(iterator, iterator) rerase(begin(), begin() + n)\endlink</code>.
2273         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
2274             <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
2275             <code>erase_end(size_type)</code>, <code>clear()</code>
2276     */
2277     void erase_begin(size_type n) {
2278         BOOST_CB_ASSERT(n <= size()); // check for n greater than size
2279 #if BOOST_CB_ENABLE_DEBUG
2280         erase_begin(n, false_type());
2281 #else
2282         erase_begin(n, is_scalar<value_type>());
2283 #endif
2284     }
2285 
2286     //! Remove last <code>n</code> elements (with constant complexity for scalar types).
2287     /*!
2288         \pre <code>n \<= size()</code>
2289         \post The <code>n</code> elements at the end of the <code>circular_buffer</code> will be removed.
2290         \param n The number of elements to be removed.
2291         \throws <a href="circular_buffer/implementation.html#circular_buffer.implementation.exceptions_of_move_if_noexcept_t">Exceptions of move_if_noexcept(T&)</a>.
2292         \par Exception Safety
2293              Basic; no-throw if the operation in the <i>Throws</i> section does not throw anything. (I.e. no throw in
2294              case of scalars.)
2295         \par Iterator Invalidation
2296              Invalidates iterators pointing to the last <code>n</code> erased elements.
2297         \par Complexity
2298              Constant (in <code>n</code>) for scalar types; linear for other types.
2299         \note This method has been specially designed for types which do not require an explicit destructruction (e.g.
2300               integer, float or a pointer). For these scalar types a call to a destructor is not required which makes
2301               it possible to implement the "erase from end" operation with a constant complexity. For non-sacalar
2302               types the complexity is linear (hence the explicit destruction is needed) and the implementation is
2303               actually equivalent to
2304               <code>\link circular_buffer::erase(iterator, iterator) erase(end() - n, end())\endlink</code>.
2305         \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
2306             <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
2307             <code>erase_begin(size_type)</code>, <code>clear()</code>
2308     */
2309     void erase_end(size_type n) {
2310         BOOST_CB_ASSERT(n <= size()); // check for n greater than size
2311 #if BOOST_CB_ENABLE_DEBUG
2312         erase_end(n, false_type());
2313 #else
2314         erase_end(n, is_scalar<value_type>());
2315 #endif
2316     }
2317 
2318     //! Remove all stored elements from the <code>circular_buffer</code>.
2319     /*!
2320         \post <code>size() == 0</code>
2321         \throws Nothing.
2322         \par Exception Safety
2323              No-throw.
2324         \par Iterator Invalidation
2325              Invalidates all iterators pointing to the <code>circular_buffer</code> (except iterators equal to
2326              <code>end()</code>).
2327         \par Complexity
2328              Constant (in the size of the <code>circular_buffer</code>) for scalar types; linear for other types.
2329         \sa <code>~circular_buffer()</code>, <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
2330             <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
2331             <code>erase_begin(size_type)</code>, <code>erase_end(size_type)</code>
2332     */
2333     void clear() BOOST_NOEXCEPT {
2334         destroy_content();
2335         m_size = 0;
2336     }
2337 
2338 private:
2339 // Helper methods
2340 
2341     /*! INTERNAL ONLY */
2342     void check_position(size_type index) const {
2343         if (index >= size())
2344             throw_exception(std::out_of_range("circular_buffer"));
2345     }
2346 
2347     /*! INTERNAL ONLY */
2348     template <class Pointer>
2349     void increment(Pointer& p) const {
2350         if (++p == m_end)
2351             p = m_buff;
2352     }
2353 
2354     /*! INTERNAL ONLY */
2355     template <class Pointer>
2356     void decrement(Pointer& p) const {
2357         if (p == m_buff)
2358             p = m_end;
2359         --p;
2360     }
2361 
2362     /*! INTERNAL ONLY */
2363     template <class Pointer>
2364     Pointer add(Pointer p, difference_type n) const {
2365         return p + (n < (m_end - p) ? n : n - (m_end - m_buff));
2366     }
2367 
2368     /*! INTERNAL ONLY */
2369     template <class Pointer>
2370     Pointer sub(Pointer p, difference_type n) const {
2371         return p - (n > (p - m_buff) ? n - (m_end - m_buff) : n);
2372     }
2373 
2374     /*! INTERNAL ONLY */
2375     pointer map_pointer(pointer p) const { return p == 0 ? m_last : p; }
2376 
2377     /*! INTERNAL ONLY */
2378     const Alloc& alloc() const {
2379         return base::get();
2380     }
2381 
2382     /*! INTERNAL ONLY */
2383     Alloc& alloc() {
2384         return base::get();
2385     }
2386 
2387     /*! INTERNAL ONLY */
2388     pointer allocate(size_type n) {
2389         if (n > max_size())
2390             throw_exception(std::length_error("circular_buffer"));
2391 #if BOOST_CB_ENABLE_DEBUG
2392         pointer p = (n == 0) ? 0 : alloc().allocate(n);
2393         cb_details::do_fill_uninitialized_memory(p, sizeof(value_type) * n);
2394         return p;
2395 #else
2396         return (n == 0) ? 0 : alloc().allocate(n);
2397 #endif
2398     }
2399 
2400     /*! INTERNAL ONLY */
2401     void deallocate(pointer p, size_type n) {
2402         if (p != 0)
2403             alloc().deallocate(p, n);
2404     }
2405 
2406     /*! INTERNAL ONLY */
2407     bool is_uninitialized(const_pointer p) const BOOST_NOEXCEPT {
2408         return (m_first < m_last)
2409             ? (p >= m_last || p < m_first)
2410             : (p >= m_last && p < m_first);
2411     }
2412 
2413     /*! INTERNAL ONLY */
2414     void replace(pointer pos, param_value_type item) {
2415         *pos = item;
2416 #if BOOST_CB_ENABLE_DEBUG
2417         invalidate_iterators(iterator(this, pos));
2418 #endif
2419     }
2420 
2421     /*! INTERNAL ONLY */
2422     void replace(pointer pos, rvalue_type item) {
2423         *pos = boost::move(item);
2424 #if BOOST_CB_ENABLE_DEBUG
2425         invalidate_iterators(iterator(this, pos));
2426 #endif
2427     }
2428 
2429     /*! INTERNAL ONLY */
2430     void construct_or_replace(bool construct, pointer pos, param_value_type item) {
2431         if (construct)
2432             boost::allocator_construct(alloc(), boost::to_address(pos), item);
2433         else
2434             replace(pos, item);
2435     }
2436 
2437     /*! INTERNAL ONLY */
2438     void construct_or_replace(bool construct, pointer pos, rvalue_type item) {
2439         if (construct)
2440             boost::allocator_construct(alloc(), boost::to_address(pos), boost::move(item));
2441         else
2442             replace(pos, boost::move(item));
2443     }
2444 
2445     /*! INTERNAL ONLY */
2446     void destroy_item(pointer p) {
2447         boost::allocator_destroy(alloc(), boost::to_address(p));
2448 #if BOOST_CB_ENABLE_DEBUG
2449         invalidate_iterators(iterator(this, p));
2450         cb_details::do_fill_uninitialized_memory(p, sizeof(value_type));
2451 #endif
2452     }
2453 
2454     /*! INTERNAL ONLY */
2455     void destroy_if_constructed(pointer pos) {
2456         if (is_uninitialized(pos))
2457             destroy_item(pos);
2458     }
2459 
2460     /*! INTERNAL ONLY */
2461     void destroy_content() {
2462 #if BOOST_CB_ENABLE_DEBUG
2463         destroy_content(false_type());
2464 #else
2465         destroy_content(is_scalar<value_type>());
2466 #endif
2467     }
2468 
2469     /*! INTERNAL ONLY */
2470     void destroy_content(const true_type&) {
2471         m_first = add(m_first, size());
2472     }
2473 
2474     /*! INTERNAL ONLY */
2475     void destroy_content(const false_type&) {
2476         for (size_type ii = 0; ii < size(); ++ii, increment(m_first))
2477             destroy_item(m_first);
2478     }
2479 
2480     /*! INTERNAL ONLY */
2481     void destroy() BOOST_NOEXCEPT {
2482         destroy_content();
2483         deallocate(m_buff, capacity());
2484 #if BOOST_CB_ENABLE_DEBUG
2485         m_buff = 0;
2486         m_first = 0;
2487         m_last = 0;
2488         m_end = 0;
2489 #endif
2490     }
2491 
2492     /*! INTERNAL ONLY */
2493     void initialize_buffer(capacity_type buffer_capacity) {
2494         m_buff = allocate(buffer_capacity);
2495         m_end = m_buff + buffer_capacity;
2496     }
2497 
2498     /*! INTERNAL ONLY */
2499     void initialize_buffer(capacity_type buffer_capacity, param_value_type item) {
2500         initialize_buffer(buffer_capacity);
2501         BOOST_TRY {
2502             cb_details::uninitialized_fill_n_with_alloc(m_buff, size(), item, alloc());
2503         } BOOST_CATCH(...) {
2504             deallocate(m_buff, size());
2505             BOOST_RETHROW
2506         }
2507         BOOST_CATCH_END
2508     }
2509 
2510     /*! INTERNAL ONLY */
2511     template <class IntegralType>
2512     void initialize(IntegralType n, IntegralType item, const true_type&) {
2513         m_size = static_cast<size_type>(n);
2514         initialize_buffer(size(), item);
2515         m_first = m_last = m_buff;
2516     }
2517 
2518     /*! INTERNAL ONLY */
2519     template <class Iterator>
2520     void initialize(Iterator first, Iterator last, const false_type&) {
2521         BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
2522 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
2523         initialize(first, last, std::iterator_traits<Iterator>::iterator_category());
2524 #else
2525         initialize(first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
2526 #endif
2527     }
2528 
2529     /*! INTERNAL ONLY */
2530     template <class InputIterator>
2531     void initialize(InputIterator first, InputIterator last, const std::input_iterator_tag&) {
2532         BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors
2533                                                         // for containers
2534         std::deque<value_type, allocator_type> tmp(first, last, alloc());
2535         size_type distance = tmp.size();
2536         initialize(distance, boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), distance);
2537     }
2538 
2539     /*! INTERNAL ONLY */
2540     template <class ForwardIterator>
2541     void initialize(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) {
2542         BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
2543         size_type distance = std::distance(first, last);
2544         initialize(distance, first, last, distance);
2545     }
2546 
2547     /*! INTERNAL ONLY */
2548     template <class IntegralType>
2549     void initialize(capacity_type buffer_capacity, IntegralType n, IntegralType item, const true_type&) {
2550         BOOST_CB_ASSERT(buffer_capacity >= static_cast<size_type>(n)); // check for capacity lower than n
2551         m_size = static_cast<size_type>(n);
2552         initialize_buffer(buffer_capacity, item);
2553         m_first = m_buff;
2554         m_last = buffer_capacity == size() ? m_buff : m_buff + size();
2555     }
2556 
2557     /*! INTERNAL ONLY */
2558     template <class Iterator>
2559     void initialize(capacity_type buffer_capacity, Iterator first, Iterator last, const false_type&) {
2560         BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
2561 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
2562         initialize(buffer_capacity, first, last, std::iterator_traits<Iterator>::iterator_category());
2563 #else
2564         initialize(buffer_capacity, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
2565 #endif
2566     }
2567 
2568     /*! INTERNAL ONLY */
2569     template <class InputIterator>
2570     void initialize(capacity_type buffer_capacity,
2571         InputIterator first,
2572         InputIterator last,
2573         const std::input_iterator_tag&) {
2574         initialize_buffer(buffer_capacity);
2575         m_first = m_last = m_buff;
2576         m_size = 0;
2577         if (buffer_capacity == 0)
2578             return;
2579         while (first != last && !full()) {
2580             boost::allocator_construct(alloc(), boost::to_address(m_last), *first++);
2581             increment(m_last);
2582             ++m_size;
2583         }
2584         while (first != last) {
2585             replace(m_last, *first++);
2586             increment(m_last);
2587             m_first = m_last;
2588         }
2589     }
2590 
2591     /*! INTERNAL ONLY */
2592     template <class ForwardIterator>
2593     void initialize(capacity_type buffer_capacity,
2594         ForwardIterator first,
2595         ForwardIterator last,
2596         const std::forward_iterator_tag&) {
2597         BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
2598         initialize(buffer_capacity, first, last, std::distance(first, last));
2599     }
2600 
2601     /*! INTERNAL ONLY */
2602     template <class ForwardIterator>
2603     void initialize(capacity_type buffer_capacity,
2604         ForwardIterator first,
2605         ForwardIterator last,
2606         size_type distance) {
2607         initialize_buffer(buffer_capacity);
2608         m_first = m_buff;
2609         if (distance > buffer_capacity) {
2610             std::advance(first, distance - buffer_capacity);
2611             m_size = buffer_capacity;
2612         } else {
2613             m_size = distance;
2614         }
2615         BOOST_TRY {
2616             m_last = cb_details::uninitialized_copy(first, last, m_buff, alloc());
2617         } BOOST_CATCH(...) {
2618             deallocate(m_buff, buffer_capacity);
2619             BOOST_RETHROW
2620         }
2621         BOOST_CATCH_END
2622         if (m_last == m_end)
2623             m_last = m_buff;
2624     }
2625 
2626     /*! INTERNAL ONLY */
2627     void reset(pointer buff, pointer last, capacity_type new_capacity) {
2628         destroy();
2629         m_size = last - buff;
2630         m_first = m_buff = buff;
2631         m_end = m_buff + new_capacity;
2632         m_last = last == m_end ? m_buff : last;
2633     }
2634 
2635     /*! INTERNAL ONLY */
2636     void swap_allocator(circular_buffer<T, Alloc>&, const true_type&) {
2637         // Swap is not needed because allocators have no state.
2638     }
2639 
2640     /*! INTERNAL ONLY */
2641     void swap_allocator(circular_buffer<T, Alloc>& cb, const false_type&) {
2642         adl_move_swap(alloc(), cb.alloc());
2643     }
2644 
2645     /*! INTERNAL ONLY */
2646     template <class IntegralType>
2647     void assign(IntegralType n, IntegralType item, const true_type&) {
2648         assign(static_cast<size_type>(n), static_cast<value_type>(item));
2649     }
2650 
2651     /*! INTERNAL ONLY */
2652     template <class Iterator>
2653     void assign(Iterator first, Iterator last, const false_type&) {
2654         BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
2655 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
2656         assign(first, last, std::iterator_traits<Iterator>::iterator_category());
2657 #else
2658         assign(first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
2659 #endif
2660     }
2661 
2662     /*! INTERNAL ONLY */
2663     template <class InputIterator>
2664     void assign(InputIterator first, InputIterator last, const std::input_iterator_tag&) {
2665         BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS // check if the STL provides templated iterator constructors
2666                                                         // for containers
2667         std::deque<value_type, allocator_type> tmp(first, last, alloc());
2668         size_type distance = tmp.size();
2669         assign_n(distance, distance,
2670             cb_details::make_assign_range
2671                 (boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), alloc()));
2672     }
2673 
2674     /*! INTERNAL ONLY */
2675     template <class ForwardIterator>
2676     void assign(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) {
2677         BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
2678         size_type distance = std::distance(first, last);
2679         assign_n(distance, distance, cb_details::make_assign_range(first, last, alloc()));
2680     }
2681 
2682     /*! INTERNAL ONLY */
2683     template <class IntegralType>
2684     void assign(capacity_type new_capacity, IntegralType n, IntegralType item, const true_type&) {
2685         assign(new_capacity, static_cast<size_type>(n), static_cast<value_type>(item));
2686     }
2687 
2688     /*! INTERNAL ONLY */
2689     template <class Iterator>
2690     void assign(capacity_type new_capacity, Iterator first, Iterator last, const false_type&) {
2691         BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
2692 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
2693         assign(new_capacity, first, last, std::iterator_traits<Iterator>::iterator_category());
2694 #else
2695         assign(new_capacity, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
2696 #endif
2697     }
2698 
2699     /*! INTERNAL ONLY */
2700     template <class InputIterator>
2701     void assign(capacity_type new_capacity, InputIterator first, InputIterator last, const std::input_iterator_tag&) {
2702         if (new_capacity == capacity()) {
2703             clear();
2704             insert(begin(), first, last);
2705         } else {
2706             circular_buffer<value_type, allocator_type> tmp(new_capacity, first, last, alloc());
2707             tmp.swap(*this);
2708         }
2709     }
2710 
2711     /*! INTERNAL ONLY */
2712     template <class ForwardIterator>
2713     void assign(capacity_type new_capacity, ForwardIterator first, ForwardIterator last,
2714         const std::forward_iterator_tag&) {
2715         BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
2716         size_type distance = std::distance(first, last);
2717         if (distance > new_capacity) {
2718             std::advance(first, distance - new_capacity);
2719             distance = new_capacity;
2720         }
2721         assign_n(new_capacity, distance,
2722             cb_details::make_assign_range(first, last, alloc()));
2723     }
2724 
2725     /*! INTERNAL ONLY */
2726     template <class Functor>
2727     void assign_n(capacity_type new_capacity, size_type n, const Functor& fnc) {
2728         if (new_capacity == capacity()) {
2729             destroy_content();
2730             BOOST_TRY {
2731                 fnc(m_buff);
2732             } BOOST_CATCH(...) {
2733                 m_size = 0;
2734                 BOOST_RETHROW
2735             }
2736             BOOST_CATCH_END
2737         } else {
2738             pointer buff = allocate(new_capacity);
2739             BOOST_TRY {
2740                 fnc(buff);
2741             } BOOST_CATCH(...) {
2742                 deallocate(buff, new_capacity);
2743                 BOOST_RETHROW
2744             }
2745             BOOST_CATCH_END
2746             destroy();
2747             m_buff = buff;
2748             m_end = m_buff + new_capacity;
2749         }
2750         m_size = n;
2751         m_first = m_buff;
2752         m_last = add(m_buff, size());
2753     }
2754 
2755     /*! INTERNAL ONLY */
2756     template <class ValT>
2757     iterator insert_item(const iterator& pos, ValT item) {
2758         pointer p = pos.m_it;
2759         if (p == 0) {
2760             construct_or_replace(!full(), m_last, static_cast<ValT>(item));
2761             p = m_last;
2762         } else {
2763             pointer src = m_last;
2764             pointer dest = m_last;
2765             bool construct = !full();
2766             BOOST_TRY {
2767                 while (src != p) {
2768                     decrement(src);
2769                     construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
2770                     decrement(dest);
2771                     construct = false;
2772                 }
2773                 replace(p, static_cast<ValT>(item));
2774             } BOOST_CATCH(...) {
2775                 if (!construct && !full()) {
2776                     increment(m_last);
2777                     ++m_size;
2778                 }
2779                 BOOST_RETHROW
2780             }
2781             BOOST_CATCH_END
2782         }
2783         increment(m_last);
2784         if (full())
2785             m_first = m_last;
2786         else
2787             ++m_size;
2788         return iterator(this, p);
2789     }
2790 
2791     /*! INTERNAL ONLY */
2792     template <class IntegralType>
2793     void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
2794         insert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
2795     }
2796 
2797     /*! INTERNAL ONLY */
2798     template <class Iterator>
2799     void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
2800         BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
2801 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
2802         insert(pos, first, last, std::iterator_traits<Iterator>::iterator_category());
2803 #else
2804         insert(pos, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
2805 #endif
2806     }
2807 
2808     /*! INTERNAL ONLY */
2809     template <class InputIterator>
2810     void insert(iterator pos, InputIterator first, InputIterator last, const std::input_iterator_tag&) {
2811         if (!full() || pos != begin()) {
2812             for (;first != last; ++pos)
2813                 pos = insert(pos, *first++);
2814         }
2815     }
2816 
2817     /*! INTERNAL ONLY */
2818     template <class ForwardIterator>
2819     void insert(const iterator& pos, ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) {
2820         BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
2821         size_type n = std::distance(first, last);
2822         if (n == 0)
2823             return;
2824         size_type copy = capacity() - (end() - pos);
2825         if (copy == 0)
2826             return;
2827         if (n > copy) {
2828             std::advance(first, n - copy);
2829             n = copy;
2830         }
2831         insert_n(pos, n, cb_details::iterator_wrapper<ForwardIterator>(first));
2832     }
2833 
2834     /*! INTERNAL ONLY */
2835     template <class Wrapper>
2836     void insert_n(const iterator& pos, size_type n, const Wrapper& wrapper) {
2837         size_type construct = reserve();
2838         if (construct > n)
2839             construct = n;
2840         if (pos.m_it == 0) {
2841             size_type ii = 0;
2842             pointer p = m_last;
2843             BOOST_TRY {
2844                 for (; ii < construct; ++ii, increment(p))
2845                     boost::allocator_construct(alloc(), boost::to_address(p), *wrapper());
2846                 for (;ii < n; ++ii, increment(p))
2847                     replace(p, *wrapper());
2848             } BOOST_CATCH(...) {
2849                 size_type constructed = (std::min)(ii, construct);
2850                 m_last = add(m_last, constructed);
2851                 m_size += constructed;
2852                 BOOST_RETHROW
2853             }
2854             BOOST_CATCH_END
2855         } else {
2856             pointer src = m_last;
2857             pointer dest = add(m_last, n - 1);
2858             pointer p = pos.m_it;
2859             size_type ii = 0;
2860             BOOST_TRY {
2861                 while (src != pos.m_it) {
2862                     decrement(src);
2863                     construct_or_replace(is_uninitialized(dest), dest, *src);
2864                     decrement(dest);
2865                 }
2866                 for (; ii < n; ++ii, increment(p))
2867                     construct_or_replace(is_uninitialized(p), p, *wrapper());
2868             } BOOST_CATCH(...) {
2869                 for (p = add(m_last, n - 1); p != dest; decrement(p))
2870                     destroy_if_constructed(p);
2871                 for (n = 0, p = pos.m_it; n < ii; ++n, increment(p))
2872                     destroy_if_constructed(p);
2873                 BOOST_RETHROW
2874             }
2875             BOOST_CATCH_END
2876         }
2877         m_last = add(m_last, n);
2878         m_first = add(m_first, n - construct);
2879         m_size += construct;
2880     }
2881 
2882     /*! INTERNAL ONLY */
2883     template <class IntegralType>
2884     void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
2885         rinsert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
2886     }
2887 
2888     /*! INTERNAL ONLY */
2889     template <class Iterator>
2890     void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
2891         BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
2892 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x581))
2893         rinsert(pos, first, last, std::iterator_traits<Iterator>::iterator_category());
2894 #else
2895         rinsert(pos, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
2896 #endif
2897     }
2898 
2899     /*! INTERNAL ONLY */
2900     template <class InputIterator>
2901     void rinsert(iterator pos, InputIterator first, InputIterator last, const std::input_iterator_tag&) {
2902         if (!full() || pos.m_it != 0) {
2903             for (;first != last; ++pos) {
2904                 pos = rinsert(pos, *first++);
2905                 if (pos.m_it == 0)
2906                     break;
2907             }
2908         }
2909     }
2910 
2911     /*! INTERNAL ONLY */
2912     template <class ForwardIterator>
2913     void rinsert(const iterator& pos, ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) {
2914         BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
2915         rinsert_n(pos, std::distance(first, last), cb_details::iterator_wrapper<ForwardIterator>(first));
2916     }
2917 
2918     /*! INTERNAL ONLY */
2919     template <class Wrapper>
2920     void rinsert_n(const iterator& pos, size_type n, const Wrapper& wrapper) {
2921         if (n == 0)
2922             return;
2923         iterator b = begin();
2924         size_type copy = capacity() - (pos - b);
2925         if (copy == 0)
2926             return;
2927         if (n > copy)
2928             n = copy;
2929         size_type construct = reserve();
2930         if (construct > n)
2931             construct = n;
2932         if (pos == b) {
2933             pointer p = sub(m_first, n);
2934             size_type ii = n;
2935             BOOST_TRY {
2936                 for (;ii > construct; --ii, increment(p))
2937                     replace(p, *wrapper());
2938                 for (; ii > 0; --ii, increment(p))
2939                     boost::allocator_construct(alloc(), boost::to_address(p), *wrapper());
2940             } BOOST_CATCH(...) {
2941                 size_type constructed = ii < construct ? construct - ii : 0;
2942                 m_last = add(m_last, constructed);
2943                 m_size += constructed;
2944                 BOOST_RETHROW
2945             }
2946             BOOST_CATCH_END
2947         } else {
2948             pointer src = m_first;
2949             pointer dest = sub(m_first, n);
2950             pointer p = map_pointer(pos.m_it);
2951             BOOST_TRY {
2952                 while (src != p) {
2953                     construct_or_replace(is_uninitialized(dest), dest, *src);
2954                     increment(src);
2955                     increment(dest);
2956                 }
2957                 for (size_type ii = 0; ii < n; ++ii, increment(dest))
2958                     construct_or_replace(is_uninitialized(dest), dest, *wrapper());
2959             } BOOST_CATCH(...) {
2960                 for (src = sub(m_first, n); src != dest; increment(src))
2961                     destroy_if_constructed(src);
2962                 BOOST_RETHROW
2963             }
2964             BOOST_CATCH_END
2965         }
2966         m_first = sub(m_first, n);
2967         m_last = sub(m_last, n - construct);
2968         m_size += construct;
2969     }
2970 
2971     /*! INTERNAL ONLY */
2972     void erase_begin(size_type n, const true_type&) {
2973         m_first = add(m_first, n);
2974         m_size -= n;
2975     }
2976 
2977     /*! INTERNAL ONLY */
2978     void erase_begin(size_type n, const false_type&) {
2979         iterator b = begin();
2980         rerase(b, b + n);
2981     }
2982 
2983     /*! INTERNAL ONLY */
2984     void erase_end(size_type n, const true_type&) {
2985         m_last = sub(m_last, n);
2986         m_size -= n;
2987     }
2988 
2989     /*! INTERNAL ONLY */
2990     void erase_end(size_type n, const false_type&) {
2991         iterator e = end();
2992         erase(e - n, e);
2993     }
2994 };
2995 
2996 // Non-member functions
2997 
2998 //! Compare two <code>circular_buffer</code>s element-by-element to determine if they are equal.
2999 /*!
3000     \param lhs The <code>circular_buffer</code> to compare.
3001     \param rhs The <code>circular_buffer</code> to compare.
3002     \return <code>lhs.\link circular_buffer::size() size()\endlink == rhs.\link circular_buffer::size() size()\endlink
3003             && <a href="https://www.boost.org/sgi/stl/equal.html">std::equal</a>(lhs.\link circular_buffer::begin()
3004             begin()\endlink, lhs.\link circular_buffer::end() end()\endlink,
3005             rhs.\link circular_buffer::begin() begin()\endlink)</code>
3006     \throws Nothing.
3007     \par Complexity
3008          Linear (in the size of the <code>circular_buffer</code>s).
3009     \par Iterator Invalidation
3010          Does not invalidate any iterators.
3011 */
3012 template <class T, class Alloc>
3013 inline bool operator == (const circular_buffer<T, Alloc>& lhs, const circular_buffer<T, Alloc>& rhs) {
3014     return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
3015 }
3016 
3017 /*!
3018     \brief Compare two <code>circular_buffer</code>s element-by-element to determine if the left one is lesser than the
3019            right one.
3020     \param lhs The <code>circular_buffer</code> to compare.
3021     \param rhs The <code>circular_buffer</code> to compare.
3022     \return <code><a href="https://www.boost.org/sgi/stl/lexicographical_compare.html">
3023             std::lexicographical_compare</a>(lhs.\link circular_buffer::begin() begin()\endlink,
3024             lhs.\link circular_buffer::end() end()\endlink, rhs.\link circular_buffer::begin() begin()\endlink,
3025             rhs.\link circular_buffer::end() end()\endlink)</code>
3026     \throws Nothing.
3027     \par Complexity
3028          Linear (in the size of the <code>circular_buffer</code>s).
3029     \par Iterator Invalidation
3030          Does not invalidate any iterators.
3031 */
3032 template <class T, class Alloc>
3033 inline bool operator < (const circular_buffer<T, Alloc>& lhs, const circular_buffer<T, Alloc>& rhs) {
3034     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
3035 }
3036 
3037 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_MSVC)
3038 
3039 //! Compare two <code>circular_buffer</code>s element-by-element to determine if they are non-equal.
3040 /*!
3041     \param lhs The <code>circular_buffer</code> to compare.
3042     \param rhs The <code>circular_buffer</code> to compare.
3043     \return <code>!(lhs == rhs)</code>
3044     \throws Nothing.
3045     \par Complexity
3046          Linear (in the size of the <code>circular_buffer</code>s).
3047     \par Iterator Invalidation
3048          Does not invalidate any iterators.
3049     \sa <code>operator==(const circular_buffer<T,Alloc>&, const circular_buffer<T,Alloc>&)</code>
3050 */
3051 template <class T, class Alloc>
3052 inline bool operator != (const circular_buffer<T, Alloc>& lhs, const circular_buffer<T, Alloc>& rhs) {
3053     return !(lhs == rhs);
3054 }
3055 
3056 /*!
3057     \brief Compare two <code>circular_buffer</code>s element-by-element to determine if the left one is greater than
3058            the right one.
3059     \param lhs The <code>circular_buffer</code> to compare.
3060     \param rhs The <code>circular_buffer</code> to compare.
3061     \return <code>rhs \< lhs</code>
3062     \throws Nothing.
3063     \par Complexity
3064          Linear (in the size of the <code>circular_buffer</code>s).
3065     \par Iterator Invalidation
3066          Does not invalidate any iterators.
3067     \sa <code>operator<(const circular_buffer<T,Alloc>&, const circular_buffer<T,Alloc>&)</code>
3068 */
3069 template <class T, class Alloc>
3070 inline bool operator > (const circular_buffer<T, Alloc>& lhs, const circular_buffer<T, Alloc>& rhs) {
3071     return rhs < lhs;
3072 }
3073 
3074 /*!
3075     \brief Compare two <code>circular_buffer</code>s element-by-element to determine if the left one is lesser or equal
3076            to the right one.
3077     \param lhs The <code>circular_buffer</code> to compare.
3078     \param rhs The <code>circular_buffer</code> to compare.
3079     \return <code>!(rhs \< lhs)</code>
3080     \throws Nothing.
3081     \par Complexity
3082          Linear (in the size of the <code>circular_buffer</code>s).
3083     \par Iterator Invalidation
3084          Does not invalidate any iterators.
3085     \sa <code>operator<(const circular_buffer<T,Alloc>&, const circular_buffer<T,Alloc>&)</code>
3086 */
3087 template <class T, class Alloc>
3088 inline bool operator <= (const circular_buffer<T, Alloc>& lhs, const circular_buffer<T, Alloc>& rhs) {
3089     return !(rhs < lhs);
3090 }
3091 
3092 /*!
3093     \brief Compare two <code>circular_buffer</code>s element-by-element to determine if the left one is greater or
3094            equal to the right one.
3095     \param lhs The <code>circular_buffer</code> to compare.
3096     \param rhs The <code>circular_buffer</code> to compare.
3097     \return <code>!(lhs < rhs)</code>
3098     \throws Nothing.
3099     \par Complexity
3100          Linear (in the size of the <code>circular_buffer</code>s).
3101     \par Iterator Invalidation
3102          Does not invalidate any iterators.
3103     \sa <code>operator<(const circular_buffer<T,Alloc>&, const circular_buffer<T,Alloc>&)</code>
3104 */
3105 template <class T, class Alloc>
3106 inline bool operator >= (const circular_buffer<T, Alloc>& lhs, const circular_buffer<T, Alloc>& rhs) {
3107     return !(lhs < rhs);
3108 }
3109 
3110 //! Swap the contents of two <code>circular_buffer</code>s.
3111 /*!
3112     \post <code>lhs</code> contains elements of <code>rhs</code> and vice versa.
3113     \param lhs The <code>circular_buffer</code> whose content will be swapped with <code>rhs</code>.
3114     \param rhs The <code>circular_buffer</code> whose content will be swapped with <code>lhs</code>.
3115     \throws Nothing.
3116     \par Complexity
3117          Constant (in the size of the <code>circular_buffer</code>s).
3118     \par Iterator Invalidation
3119          Invalidates all iterators of both <code>circular_buffer</code>s. (On the other hand the iterators still
3120          point to the same elements but within another container. If you want to rely on this feature you have to
3121          turn the <a href="#debug">Debug Support</a> off otherwise an assertion will report an error if such
3122          invalidated iterator is used.)
3123     \sa <code>\link circular_buffer::swap(circular_buffer<T, Alloc>&) swap(circular_buffer<T, Alloc>&)\endlink</code>
3124 */
3125 template <class T, class Alloc>
3126 inline void swap(circular_buffer<T, Alloc>& lhs, circular_buffer<T, Alloc>& rhs) BOOST_NOEXCEPT {
3127     lhs.swap(rhs);
3128 }
3129 
3130 #endif // #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_MSVC)
3131 
3132 } // namespace boost
3133 
3134 #endif // #if !defined(BOOST_CIRCULAR_BUFFER_BASE_HPP)