space_optimized.hpp 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713
  1. // Implementation of the circular buffer adaptor.
  2. // Copyright (c) 2003-2008 Jan Gaspar
  3. // Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed for new version of documentation.
  4. // Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
  5. // Use, modification, and distribution is subject to the Boost Software
  6. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)
  9. #define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/type_traits/is_same.hpp>
  14. #include <boost/config/workaround.hpp>
  15. namespace boost {
  16. /*!
  17. \class circular_buffer_space_optimized
  18. \brief Space optimized circular buffer container adaptor.
  19. <code>T</code> must be a copyable class or must have an noexcept move constructor
  20. and move assignment operator.
  21. */
  22. template <class T, class Alloc>
  23. class circular_buffer_space_optimized :
  24. /*! \cond */
  25. #if BOOST_CB_ENABLE_DEBUG
  26. public
  27. #endif
  28. /*! \endcond */
  29. circular_buffer<T, Alloc> {
  30. public:
  31. // Typedefs
  32. typedef typename circular_buffer<T, Alloc>::value_type value_type;
  33. typedef typename circular_buffer<T, Alloc>::pointer pointer;
  34. typedef typename circular_buffer<T, Alloc>::const_pointer const_pointer;
  35. typedef typename circular_buffer<T, Alloc>::reference reference;
  36. typedef typename circular_buffer<T, Alloc>::const_reference const_reference;
  37. typedef typename circular_buffer<T, Alloc>::size_type size_type;
  38. typedef typename circular_buffer<T, Alloc>::difference_type difference_type;
  39. typedef typename circular_buffer<T, Alloc>::allocator_type allocator_type;
  40. typedef typename circular_buffer<T, Alloc>::const_iterator const_iterator;
  41. typedef typename circular_buffer<T, Alloc>::iterator iterator;
  42. typedef typename circular_buffer<T, Alloc>::const_reverse_iterator const_reverse_iterator;
  43. typedef typename circular_buffer<T, Alloc>::reverse_iterator reverse_iterator;
  44. typedef typename circular_buffer<T, Alloc>::array_range array_range;
  45. typedef typename circular_buffer<T, Alloc>::const_array_range const_array_range;
  46. typedef typename circular_buffer<T, Alloc>::param_value_type param_value_type;
  47. typedef typename circular_buffer<T, Alloc>::rvalue_type rvalue_type;
  48. //typedef typename circular_buffer<T, Alloc>::return_value_type return_value_type;
  49. /* <pre> is not passed through to html or pdf. So <br> is used in code section below. Ugly :-(
  50. Ideally want a link to capacity_control, but this would require include details
  51. and this would expose all the functions in details.
  52. There must be a better way of doing this.
  53. */
  54. /*! Capacity controller of the space optimized circular buffer.
  55. \see capacity_control in details.hpp.
  56. <p>
  57. <code>
  58. class capacity_control<br>
  59. {<br>
  60. size_type m_capacity; // Available capacity.<br>
  61. size_type m_min_capacity; // Minimum capacity.<br>
  62. public:<br>
  63. capacity_control(size_type capacity, size_type min_capacity = 0)<br>
  64. : m_capacity(capacity), m_min_capacity(min_capacity)<br>
  65. {};<br>
  66. size_type %capacity() const { return m_capacity; }<br>
  67. size_type min_capacity() const { return m_min_capacity; }<br>
  68. operator size_type() const { return m_capacity; }<br>
  69. };<br>
  70. </code>
  71. </p>
  72. <p>Always
  73. <code>capacity >= min_capacity</code>.
  74. </p>
  75. <p>
  76. The <code>capacity()</code> represents the capacity
  77. of the <code>circular_buffer_space_optimized</code> and
  78. the <code>min_capacity()</code> determines the minimal allocated size of its internal buffer.
  79. </p>
  80. <p>The converting constructor of the <code>capacity_control</code> allows implicit conversion from
  81. <code>size_type</code>-like types which ensures compatibility of creating an instance of the
  82. <code>circular_buffer_space_optimized</code> with other STL containers.
  83. On the other hand the operator <code>%size_type()</code>
  84. provides implicit conversion to the <code>size_type</code> which allows to treat the
  85. capacity of the <code>circular_buffer_space_optimized</code> the same way as in the
  86. <code>circular_buffer</a></code>.
  87. </p>
  88. */
  89. typedef cb_details::capacity_control<size_type> capacity_type;
  90. // Inherited
  91. using circular_buffer<T, Alloc>::get_allocator;
  92. using circular_buffer<T, Alloc>::begin;
  93. using circular_buffer<T, Alloc>::end;
  94. using circular_buffer<T, Alloc>::rbegin;
  95. using circular_buffer<T, Alloc>::rend;
  96. using circular_buffer<T, Alloc>::at;
  97. using circular_buffer<T, Alloc>::front;
  98. using circular_buffer<T, Alloc>::back;
  99. using circular_buffer<T, Alloc>::array_one;
  100. using circular_buffer<T, Alloc>::array_two;
  101. using circular_buffer<T, Alloc>::linearize;
  102. using circular_buffer<T, Alloc>::is_linearized;
  103. using circular_buffer<T, Alloc>::rotate;
  104. using circular_buffer<T, Alloc>::size;
  105. using circular_buffer<T, Alloc>::max_size;
  106. using circular_buffer<T, Alloc>::empty;
  107. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  108. reference operator [] (size_type n) { return circular_buffer<T, Alloc>::operator[](n); }
  109. const_reference operator [] (size_type n) const { return circular_buffer<T, Alloc>::operator[](n); }
  110. #else
  111. using circular_buffer<T, Alloc>::operator[];
  112. #endif
  113. private:
  114. // Member variables
  115. //! The capacity controller of the space optimized circular buffer.
  116. capacity_type m_capacity_ctrl;
  117. public:
  118. // Overridden
  119. //! Is the <code>circular_buffer_space_optimized</code> full?
  120. /*!
  121. \return <code>true</code> if the number of elements stored in the <code>circular_buffer_space_optimized</code>
  122. equals the capacity of the <code>circular_buffer_space_optimized</code>; <code>false</code> otherwise.
  123. \throws Nothing.
  124. \par Exception Safety
  125. No-throw.
  126. \par Iterator Invalidation
  127. Does not invalidate any iterators.
  128. \par Complexity
  129. Constant (in the size of the <code>circular_buffer_space_optimized</code>).
  130. \sa <code>empty()</code>
  131. */
  132. bool full() const BOOST_NOEXCEPT { return m_capacity_ctrl == size(); }
  133. /*! \brief Get the maximum number of elements which can be inserted into the
  134. <code>circular_buffer_space_optimized</code> without overwriting any of already stored elements.
  135. \return <code>capacity().%capacity() - size()</code>
  136. \throws Nothing.
  137. \par Exception Safety
  138. No-throw.
  139. \par Iterator Invalidation
  140. Does not invalidate any iterators.
  141. \par Complexity
  142. Constant (in the size of the <code>circular_buffer_space_optimized</code>).
  143. \sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code>
  144. */
  145. size_type reserve() const BOOST_NOEXCEPT { return m_capacity_ctrl - size(); }
  146. //! Get the capacity of the <code>circular_buffer_space_optimized</code>.
  147. /*!
  148. \return The capacity controller representing the maximum number of elements which can be stored in the
  149. <code>circular_buffer_space_optimized</code> and the minimal allocated size of the internal buffer.
  150. \throws Nothing.
  151. \par Exception Safety
  152. No-throw.
  153. \par Iterator Invalidation
  154. Does not invalidate any iterators.
  155. \par Complexity
  156. Constant (in the size of the <code>circular_buffer_space_optimized</code>).
  157. \sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>,
  158. <code>set_capacity(const capacity_type&)</code>
  159. */
  160. const capacity_type& capacity() const BOOST_NOEXCEPT { return m_capacity_ctrl; }
  161. #if defined(BOOST_CB_TEST)
  162. // Return the current capacity of the adapted circular buffer.
  163. /*
  164. \note This method is not intended to be used directly by the user.
  165. It is defined only for testing purposes.
  166. */
  167. size_type internal_capacity() const BOOST_NOEXCEPT { return circular_buffer<T, Alloc>::capacity(); }
  168. #endif // #if defined(BOOST_CB_TEST)
  169. /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the
  170. <code>circular_buffer_space_optimized</code>.
  171. \post <code>capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl.capacity()</code><br><br>
  172. If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
  173. than the desired new capacity then number of <code>[size() - capacity_ctrl.capacity()]</code> <b>last</b>
  174. elements will be removed and the new size will be equal to <code>capacity_ctrl.capacity()</code>.<br><br>
  175. If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is lower
  176. than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
  177. necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
  178. \param capacity_ctrl The new capacity controller.
  179. \throws "An allocation error" if memory is exhausted, (<code>std::bad_alloc</code> if the standard allocator is
  180. used).
  181. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  182. \par Exception Safety
  183. Strong.
  184. \par Iterator Invalidation
  185. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  186. equal to <code>end()</code>).
  187. \par Complexity
  188. Linear (in <code>min[size(), capacity_ctrl.%capacity()]</code>).
  189. \note To explicitly clear the extra allocated memory use the <b>shrink-to-fit</b> technique:<br><br>
  190. <code>%boost::%circular_buffer_space_optimized\<int\> cb(1000);<br>
  191. ...<br>
  192. %boost::%circular_buffer_space_optimized\<int\>(cb).swap(cb);</code><br><br>
  193. For more information about the shrink-to-fit technique in STL see
  194. <a href="http://www.gotw.ca/gotw/054.htm">http://www.gotw.ca/gotw/054.htm</a>.
  195. \sa <code>rset_capacity(const capacity_type&)</code>,
  196. <code>\link resize() resize(size_type, const_reference)\endlink</code>
  197. */
  198. void set_capacity(const capacity_type& capacity_ctrl) {
  199. m_capacity_ctrl = capacity_ctrl;
  200. if (capacity_ctrl < size()) {
  201. iterator e = end();
  202. circular_buffer<T, Alloc>::erase(e - (size() - capacity_ctrl), e);
  203. }
  204. adjust_min_capacity();
  205. }
  206. //! Change the size of the <code>circular_buffer_space_optimized</code>.
  207. /*!
  208. \post <code>size() == new_size \&\& capacity().%capacity() >= new_size</code><br><br>
  209. If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
  210. <b>back</b> of the of the <code>circular_buffer_space_optimized</code> in order to achieve the desired
  211. size. In the case the resulting size exceeds the current capacity the capacity will be set to
  212. <code>new_size</code>.<br><br>
  213. If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
  214. than the desired new size then number of <code>[size() - new_size]</code> <b>last</b> elements will be
  215. removed. (The capacity will remain unchanged.)<br><br>
  216. The amount of allocated memory in the internal buffer may be accommodated as necessary.
  217. \param new_size The new size.
  218. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with in order to gain
  219. the requested size. (See the <i>Effect</i>.)
  220. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  221. used).
  222. Whatever <code>T::T(const T&)</code> throws.
  223. \par Exception Safety
  224. Basic.
  225. \par Iterator Invalidation
  226. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  227. equal to <code>end()</code>).
  228. \par Complexity
  229. Linear (in the new size of the <code>circular_buffer_space_optimized</code>).
  230. \sa <code>\link rresize() rresize(size_type, const_reference)\endlink</code>,
  231. <code>set_capacity(const capacity_type&)</code>
  232. */
  233. void resize(size_type new_size, param_value_type item = value_type()) {
  234. if (new_size > size()) {
  235. if (new_size > m_capacity_ctrl)
  236. m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity());
  237. insert(end(), new_size - size(), item);
  238. } else {
  239. iterator e = end();
  240. erase(e - (size() - new_size), e);
  241. }
  242. }
  243. /*! \brief Change the capacity (and the minimal guaranteed amount of allocated memory) of the
  244. <code>circular_buffer_space_optimized</code>.
  245. \post <code>capacity() == capacity_ctrl \&\& size() \<= capacity_ctrl</code><br><br>
  246. If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
  247. than the desired new capacity then number of <code>[size() - capacity_ctrl.capacity()]</code>
  248. <b>first</b> elements will be removed and the new size will be equal to
  249. <code>capacity_ctrl.capacity()</code>.<br><br>
  250. If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is lower
  251. than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
  252. necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
  253. \param capacity_ctrl The new capacity controller.
  254. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  255. used).
  256. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  257. \par Exception Safety
  258. Strong.
  259. \par Iterator Invalidation
  260. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  261. equal to <code>end()</code>).
  262. \par Complexity
  263. Linear (in <code>min[size(), capacity_ctrl.%capacity()]</code>).
  264. \sa <code>set_capacity(const capacity_type&)</code>,
  265. <code>\link rresize() rresize(size_type, const_reference)\endlink</code>
  266. */
  267. void rset_capacity(const capacity_type& capacity_ctrl) {
  268. m_capacity_ctrl = capacity_ctrl;
  269. if (capacity_ctrl < size()) {
  270. iterator b = begin();
  271. circular_buffer<T, Alloc>::rerase(b, b + (size() - capacity_ctrl));
  272. }
  273. adjust_min_capacity();
  274. }
  275. //! Change the size of the <code>circular_buffer_space_optimized</code>.
  276. /*!
  277. \post <code>size() == new_size \&\& capacity().%capacity() >= new_size</code><br><br>
  278. If the new size is greater than the current size, copies of <code>item</code> will be inserted at the
  279. <b>front</b> of the of the <code>circular_buffer_space_optimized</code> in order to achieve the desired
  280. size. In the case the resulting size exceeds the current capacity the capacity will be set to
  281. <code>new_size</code>.<br><br>
  282. If the current number of elements stored in the <code>circular_buffer_space_optimized</code> is greater
  283. than the desired new size then number of <code>[size() - new_size]</code> <b>first</b> elements will be
  284. removed. (The capacity will remain unchanged.)<br><br>
  285. The amount of allocated memory in the internal buffer may be accommodated as necessary.
  286. \param new_size The new size.
  287. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with in order to gain
  288. the requested size. (See the <i>Effect</i>.)
  289. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  290. used).
  291. Whatever <code>T::T(const T&)</code> throws.
  292. \par Exception Safety
  293. Basic.
  294. \par Iterator Invalidation
  295. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  296. equal to <code>end()</code>).
  297. \par Complexity
  298. Linear (in the new size of the <code>circular_buffer_space_optimized</code>).
  299. \sa <code>\link resize() resize(size_type, const_reference)\endlink</code>,
  300. <code>rset_capacity(const capacity_type&)</code>
  301. */
  302. void rresize(size_type new_size, param_value_type item = value_type()) {
  303. if (new_size > size()) {
  304. if (new_size > m_capacity_ctrl)
  305. m_capacity_ctrl = capacity_type(new_size, m_capacity_ctrl.min_capacity());
  306. rinsert(begin(), new_size - size(), item);
  307. } else {
  308. rerase(begin(), end() - new_size);
  309. }
  310. }
  311. //! Create an empty space optimized circular buffer with zero capacity.
  312. /*!
  313. \post <code>capacity().%capacity() == 0 \&\& capacity().min_capacity() == 0 \&\& size() == 0</code>
  314. \param alloc The allocator.
  315. \throws Nothing.
  316. \par Complexity
  317. Constant.
  318. \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space
  319. optimized circular buffer with zero capacity.
  320. */
  321. explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT
  322. : circular_buffer<T, Alloc>(0, alloc)
  323. , m_capacity_ctrl(0) {}
  324. //! Create an empty space optimized circular buffer with the specified capacity.
  325. /*!
  326. \post <code>capacity() == capacity_ctrl \&\& size() == 0</code><br><br>
  327. The amount of allocated memory in the internal buffer is <code>capacity_ctrl.min_capacity()</code>.
  328. \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
  329. the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
  330. internal buffer.
  331. \param alloc The allocator.
  332. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  333. used).
  334. \par Complexity
  335. Constant.
  336. */
  337. explicit circular_buffer_space_optimized(capacity_type capacity_ctrl,
  338. const allocator_type& alloc = allocator_type())
  339. : circular_buffer<T, Alloc>(capacity_ctrl.min_capacity(), alloc)
  340. , m_capacity_ctrl(capacity_ctrl) {}
  341. /*! \brief Create a full space optimized circular buffer with the specified capacity filled with
  342. <code>capacity_ctrl.%capacity()</code> copies of <code>item</code>.
  343. \post <code>capacity() == capacity_ctrl \&\& full() \&\& (*this)[0] == item \&\& (*this)[1] == item \&\& ...
  344. \&\& (*this) [capacity_ctrl.%capacity() - 1] == item </code><br><br>
  345. The amount of allocated memory in the internal buffer is <code>capacity_ctrl.capacity()</code>.
  346. \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
  347. the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
  348. internal buffer.
  349. \param item The element the created <code>circular_buffer_space_optimized</code> will be filled with.
  350. \param alloc The allocator.
  351. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  352. used).
  353. \throws Whatever <code>T::T(const T&)</code> throws.
  354. \par Complexity
  355. Linear (in the <code>capacity_ctrl.%capacity()</code>).
  356. */
  357. circular_buffer_space_optimized(capacity_type capacity_ctrl, param_value_type item,
  358. const allocator_type& alloc = allocator_type())
  359. : circular_buffer<T, Alloc>(capacity_ctrl.capacity(), item, alloc)
  360. , m_capacity_ctrl(capacity_ctrl) {}
  361. /*! \brief Create a space optimized circular buffer with the specified capacity filled with <code>n</code> copies
  362. of <code>item</code>.
  363. \pre <code>capacity_ctrl.%capacity() >= n</code>
  364. \post <code>capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
  365. \&\& ... \&\& (*this)[n - 1] == item</code><br><br>
  366. The amount of allocated memory in the internal buffer is
  367. <code>max[n, capacity_ctrl.min_capacity()]</code>.
  368. \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
  369. the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
  370. internal buffer.
  371. \param n The number of elements the created <code>circular_buffer_space_optimized</code> will be filled with.
  372. \param item The element the created <code>circular_buffer_space_optimized</code> will be filled with.
  373. \param alloc The allocator.
  374. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  375. used).
  376. Whatever <code>T::T(const T&)</code> throws.
  377. \par Complexity
  378. Linear (in the <code>n</code>).
  379. */
  380. circular_buffer_space_optimized(capacity_type capacity_ctrl, size_type n, param_value_type item,
  381. const allocator_type& alloc = allocator_type())
  382. : circular_buffer<T, Alloc>(init_capacity(capacity_ctrl, n), n, item, alloc)
  383. , m_capacity_ctrl(capacity_ctrl) {}
  384. //! The copy constructor.
  385. /*!
  386. Creates a copy of the specified <code>circular_buffer_space_optimized</code>.
  387. \post <code>*this == cb</code><br><br>
  388. The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
  389. \param cb The <code>circular_buffer_space_optimized</code> to be copied.
  390. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  391. used).
  392. Whatever <code>T::T(const T&)</code> throws.
  393. \par Complexity
  394. Linear (in the size of <code>cb</code>).
  395. */
  396. circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
  397. : circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator())
  398. , m_capacity_ctrl(cb.m_capacity_ctrl) {}
  399. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  400. //! The move constructor.
  401. /*! \brief Move constructs a <code>circular_buffer_space_optimized</code> from <code>cb</code>,
  402. leaving <code>cb</code> empty.
  403. \pre C++ compiler with rvalue references support.
  404. \post <code>cb.empty()</code>
  405. \param cb <code>circular_buffer</code> to 'steal' value from.
  406. \throws Nothing.
  407. \par Constant.
  408. */
  409. circular_buffer_space_optimized(circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT
  410. : circular_buffer<T, Alloc>()
  411. , m_capacity_ctrl(0) {
  412. cb.swap(*this);
  413. }
  414. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  415. //! Create a full space optimized circular buffer filled with a copy of the range.
  416. /*!
  417. \pre Valid range <code>[first, last)</code>.<br>
  418. <code>first</code> and <code>last</code> have to meet the requirements of
  419. <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
  420. \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
  421. full() \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... \&\&
  422. (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
  423. The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
  424. \param first The beginning of the range to be copied.
  425. \param last The end of the range to be copied.
  426. \param alloc The allocator.
  427. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  428. used).
  429. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept
  430. and <code>InputIterator</code> is a move iterator.
  431. \par Complexity
  432. Linear (in the <code>std::distance(first, last)</code>).
  433. */
  434. template <class InputIterator>
  435. circular_buffer_space_optimized(InputIterator first, InputIterator last,
  436. const allocator_type& alloc = allocator_type())
  437. : circular_buffer<T, Alloc>(first, last, alloc)
  438. , m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
  439. /*! \brief Create a space optimized circular buffer with the specified capacity (and the minimal guaranteed amount
  440. of allocated memory) filled with a copy of the range.
  441. \pre Valid range <code>[first, last)</code>.<br>
  442. <code>first</code> and <code>last</code> have to meet the requirements of
  443. <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
  444. \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\& (*this)[0]==
  445. *(last - capacity_ctrl.%capacity()) \&\& (*this)[1] == *(last - capacity_ctrl.%capacity() + 1) \&\& ...
  446. \&\& (*this)[capacity_ctrl.%capacity() - 1] == *(last - 1)</code><br><br>
  447. If the number of items to be copied from the range <code>[first, last)</code> is greater than the
  448. specified <code>capacity_ctrl.%capacity()</code> then only elements from the range
  449. <code>[last - capacity_ctrl.%capacity(), last)</code> will be copied.<br><br>
  450. The amount of allocated memory in the internal buffer is <code>max[capacity_ctrl.min_capacity(),
  451. min[capacity_ctrl.%capacity(), std::distance(first, last)]]</code>.
  452. \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
  453. the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
  454. internal buffer.
  455. \param first The beginning of the range to be copied.
  456. \param last The end of the range to be copied.
  457. \param alloc The allocator.
  458. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  459. used).
  460. Whatever <code>T::T(const T&)</code> throws.
  461. \par Complexity
  462. Linear (in <code>std::distance(first, last)</code>; in
  463. <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
  464. is a <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  465. */
  466. template <class InputIterator>
  467. circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last,
  468. const allocator_type& alloc = allocator_type())
  469. : circular_buffer<T, Alloc>(
  470. init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
  471. first, last, alloc)
  472. , m_capacity_ctrl(capacity_ctrl) {
  473. reduce_capacity(
  474. is_same< BOOST_DEDUCED_TYPENAME std::iterator_traits<InputIterator>::iterator_category, std::input_iterator_tag >());
  475. }
  476. #if defined(BOOST_CB_NEVER_DEFINED)
  477. // This section will never be compiled - the default destructor will be generated instead.
  478. // Declared only for documentation purpose.
  479. //! The destructor.
  480. /*!
  481. Destroys the <code>circular_buffer_space_optimized</code>.
  482. \throws Nothing.
  483. \par Iterator Invalidation
  484. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (including
  485. iterators equal to <code>end()</code>).
  486. \par Complexity
  487. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  488. \sa <code>clear()</code>
  489. */
  490. ~circular_buffer_space_optimized();
  491. //! no-comment
  492. void erase_begin(size_type n);
  493. //! no-comment
  494. void erase_end(size_type n);
  495. #endif // #if defined(BOOST_CB_NEVER_DEFINED)
  496. //! The assign operator.
  497. /*!
  498. Makes this <code>circular_buffer_space_optimized</code> to become a copy of the specified
  499. <code>circular_buffer_space_optimized</code>.
  500. \post <code>*this == cb</code><br><br>
  501. The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
  502. \param cb The <code>circular_buffer_space_optimized</code> to be copied.
  503. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  504. used).
  505. \throws Whatever <code>T::T(const T&)</code> throws.
  506. \par Exception Safety
  507. Strong.
  508. \par Iterator Invalidation
  509. Invalidates all iterators pointing to this <code>circular_buffer_space_optimized</code> (except iterators
  510. equal to <code>end()</code>).
  511. \par Complexity
  512. Linear (in the size of <code>cb</code>).
  513. \sa <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  514. <code>\link assign(capacity_type, size_type, param_value_type)
  515. assign(capacity_type, size_type, const_reference)\endlink</code>,
  516. <code>assign(InputIterator, InputIterator)</code>,
  517. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  518. */
  519. circular_buffer_space_optimized<T, Alloc>& operator = (const circular_buffer_space_optimized<T, Alloc>& cb) {
  520. if (this == &cb)
  521. return *this;
  522. circular_buffer<T, Alloc>::assign(cb.begin(), cb.end());
  523. m_capacity_ctrl = cb.m_capacity_ctrl;
  524. return *this;
  525. }
  526. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  527. /*! \brief Move assigns content of <code>cb</code> to <code>*this</code>, leaving <code>cb</code> empty.
  528. \pre C++ compiler with rvalue references support.
  529. \post <code>cb.empty()</code>
  530. \param cb <code>circular_buffer</code> to 'steal' value from.
  531. \throws Nothing.
  532. \par Complexity
  533. Constant.
  534. */
  535. circular_buffer_space_optimized<T, Alloc>& operator = (circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT {
  536. cb.swap(*this); // now `this` holds `cb`
  537. circular_buffer<T, Alloc>(get_allocator()) // temporary that holds initial `cb` allocator
  538. .swap(cb); // makes `cb` empty
  539. return *this;
  540. }
  541. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  542. //! Assign <code>n</code> items into the space optimized circular buffer.
  543. /*!
  544. The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with
  545. <code>n</code> copies of the <code>item</code>.
  546. \post <code>capacity().%capacity() == n \&\& capacity().min_capacity() == 0 \&\& size() == n \&\& (*this)[0] ==
  547. item \&\& (*this)[1] == item \&\& ... \&\& (*this) [n - 1] == item</code><br><br>
  548. The amount of allocated memory in the internal buffer is <code>n</code>.
  549. \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
  550. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
  551. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  552. used).
  553. Whatever <code>T::T(const T&)</code> throws.
  554. \par Exception Safety
  555. Basic.
  556. \par Iterator Invalidation
  557. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  558. equal to <code>end()</code>).
  559. \par Complexity
  560. Linear (in the <code>n</code>).
  561. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  562. <code>\link assign(capacity_type, size_type, param_value_type)
  563. assign(capacity_type, size_type, const_reference)\endlink</code>,
  564. <code>assign(InputIterator, InputIterator)</code>,
  565. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  566. */
  567. void assign(size_type n, param_value_type item) {
  568. circular_buffer<T, Alloc>::assign(n, item);
  569. m_capacity_ctrl = capacity_type(n);
  570. }
  571. //! Assign <code>n</code> items into the space optimized circular buffer specifying the capacity.
  572. /*!
  573. The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
  574. content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with <code>n</code>
  575. copies of the <code>item</code>.
  576. \pre <code>capacity_ctrl.%capacity() >= n</code>
  577. \post <code>capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
  578. \&\& ... \&\& (*this) [n - 1] == item </code><br><br>
  579. The amount of allocated memory will be <code>max[n, capacity_ctrl.min_capacity()]</code>.
  580. \param capacity_ctrl The new capacity controller.
  581. \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
  582. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
  583. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  584. used).
  585. Whatever <code>T::T(const T&)</code> throws.
  586. \par Exception Safety
  587. Basic.
  588. \par Iterator Invalidation
  589. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  590. equal to <code>end()</code>).
  591. \par Complexity
  592. Linear (in the <code>n</code>).
  593. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  594. <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  595. <code>assign(InputIterator, InputIterator)</code>,
  596. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  597. */
  598. void assign(capacity_type capacity_ctrl, size_type n, param_value_type item) {
  599. BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for new capacity lower than n
  600. circular_buffer<T, Alloc>::assign((std::max)(capacity_ctrl.min_capacity(), n), n, item);
  601. m_capacity_ctrl = capacity_ctrl;
  602. }
  603. //! Assign a copy of the range into the space optimized circular buffer.
  604. /*!
  605. The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
  606. elements from the specified range.
  607. \pre Valid range <code>[first, last)</code>.<br>
  608. <code>first</code> and <code>last</code> have to meet the requirements of
  609. <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
  610. \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
  611. size() == std::distance(first, last) \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ...
  612. \&\& (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
  613. The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
  614. \param first The beginning of the range to be copied.
  615. \param last The end of the range to be copied.
  616. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  617. used).
  618. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
  619. <code>InputIterator</code> is a move iterator.
  620. \par Exception Safety
  621. Basic.
  622. \par Iterator Invalidation
  623. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  624. equal to <code>end()</code>).
  625. \par Complexity
  626. Linear (in the <code>std::distance(first, last)</code>).
  627. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  628. <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  629. <code>\link assign(capacity_type, size_type, param_value_type)
  630. assign(capacity_type, size_type, const_reference)\endlink</code>,
  631. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  632. */
  633. template <class InputIterator>
  634. void assign(InputIterator first, InputIterator last) {
  635. circular_buffer<T, Alloc>::assign(first, last);
  636. m_capacity_ctrl = capacity_type(circular_buffer<T, Alloc>::capacity());
  637. }
  638. //! Assign a copy of the range into the space optimized circular buffer specifying the capacity.
  639. /*!
  640. The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
  641. content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
  642. elements from the specified range.
  643. \pre Valid range <code>[first, last)</code>.<br>
  644. <code>first</code> and <code>last</code> have to meet the requirements of
  645. <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
  646. \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\&
  647. (*this)[0]== *(last - capacity) \&\& (*this)[1] == *(last - capacity + 1) \&\& ... \&\&
  648. (*this)[capacity - 1] == *(last - 1)</code><br><br>
  649. If the number of items to be copied from the range <code>[first, last)</code> is greater than the
  650. specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
  651. will be copied.<br><br> The amount of allocated memory in the internal buffer is
  652. <code>max[std::distance(first, last), capacity_ctrl.min_capacity()]</code>.
  653. \param capacity_ctrl The new capacity controller.
  654. \param first The beginning of the range to be copied.
  655. \param last The end of the range to be copied.
  656. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  657. used).
  658. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
  659. <code>InputIterator</code> is a move iterator.
  660. \par Exception Safety
  661. Basic.
  662. \par Iterator Invalidation
  663. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  664. equal to <code>end()</code>).
  665. \par Complexity
  666. Linear (in <code>std::distance(first, last)</code>; in
  667. <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
  668. is a <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  669. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  670. <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  671. <code>\link assign(capacity_type, size_type, param_value_type)
  672. assign(capacity_type, size_type, const_reference)\endlink</code>,
  673. <code>assign(InputIterator, InputIterator)</code>
  674. */
  675. template <class InputIterator>
  676. void assign(capacity_type capacity_ctrl, InputIterator first, InputIterator last) {
  677. m_capacity_ctrl = capacity_ctrl;
  678. circular_buffer<T, Alloc>::assign(capacity_ctrl, first, last);
  679. }
  680. //! Swap the contents of two space-optimized circular-buffers.
  681. /*!
  682. \post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity and the amount of
  683. allocated memory in the internal buffer of <code>this</code> equal to the capacity and the amount of
  684. allocated memory of <code>cb</code> and vice versa.
  685. \param cb The <code>circular_buffer_space_optimized</code> whose content will be swapped.
  686. \throws Nothing.
  687. \par Exception Safety
  688. No-throw.
  689. \par Iterator Invalidation
  690. Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
  691. hand the iterators still point to the same elements but within another container. If you want to rely on
  692. this feature you have to turn the __debug_support off,
  693. otherwise an assertion will report an error if such invalidated iterator is used.)
  694. \par Complexity
  695. Constant (in the size of the <code>circular_buffer_space_optimized</code>).
  696. \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>,
  697. <code>swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)</code>
  698. */
  699. // Note link does not work right. Asked on Doxygen forum for advice 23 May 2103.
  700. void swap(circular_buffer_space_optimized<T, Alloc>& cb) BOOST_NOEXCEPT {
  701. std::swap(m_capacity_ctrl, cb.m_capacity_ctrl);
  702. circular_buffer<T, Alloc>::swap(cb);
  703. }
  704. //! Insert a new element at the end of the space optimized circular buffer.
  705. /*!
  706. \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
  707. If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
  708. capacity is <code>0</code>, nothing will be inserted.<br><br>
  709. The amount of allocated memory in the internal buffer may be predictively increased.
  710. \param item The element to be inserted.
  711. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  712. used).
  713. Whatever <code>T::T(const T&)</code> throws.
  714. \par Exception Safety
  715. Basic.
  716. \par Iterator Invalidation
  717. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  718. equal to <code>end()</code>).
  719. \par Complexity
  720. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  721. \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
  722. <code>pop_front()</code>
  723. */
  724. void push_back(param_value_type item) {
  725. check_low_capacity();
  726. circular_buffer<T, Alloc>::push_back(item);
  727. }
  728. //! Insert a new element at the end of the space optimized circular buffer.
  729. /*!
  730. \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
  731. If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
  732. capacity is <code>0</code>, nothing will be inserted.<br><br>
  733. The amount of allocated memory in the internal buffer may be predictively increased.
  734. \param item The element to be inserted.
  735. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  736. used).
  737. \par Exception Safety
  738. Basic.
  739. \par Iterator Invalidation
  740. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  741. equal to <code>end()</code>).
  742. \par Complexity
  743. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  744. \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
  745. <code>pop_front()</code>
  746. */
  747. void push_back(rvalue_type item) {
  748. check_low_capacity();
  749. circular_buffer<T, Alloc>::push_back(boost::move(item));
  750. }
  751. //! Insert a new element at the end of the space optimized circular buffer.
  752. /*!
  753. \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
  754. If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
  755. capacity is <code>0</code>, nothing will be inserted.<br><br>
  756. The amount of allocated memory in the internal buffer may be predictively increased.
  757. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  758. used).
  759. Whatever <code>T::T()</code> throws.
  760. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  761. \par Exception Safety
  762. Basic.
  763. \par Iterator Invalidation
  764. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  765. equal to <code>end()</code>).
  766. \par Complexity
  767. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  768. \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
  769. <code>pop_front()</code>
  770. */
  771. void push_back() {
  772. check_low_capacity();
  773. circular_buffer<T, Alloc>::push_back();
  774. }
  775. //! Insert a new element at the beginning of the space optimized circular buffer.
  776. /*!
  777. \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
  778. If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
  779. capacity is <code>0</code>, nothing will be inserted.<br><br>
  780. The amount of allocated memory in the internal buffer may be predictively increased.
  781. \param item The element to be inserted.
  782. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  783. used).
  784. Whatever <code>T::T(const T&)</code> throws.
  785. \par Exception Safety
  786. Basic.
  787. \par Iterator Invalidation
  788. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  789. equal to <code>end()</code>).
  790. \par Complexity
  791. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  792. \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
  793. <code>pop_front()</code>
  794. */
  795. void push_front(param_value_type item) {
  796. check_low_capacity();
  797. circular_buffer<T, Alloc>::push_front(item);
  798. }
  799. //! Insert a new element at the beginning of the space optimized circular buffer.
  800. /*!
  801. \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
  802. If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
  803. capacity is <code>0</code>, nothing will be inserted.<br><br>
  804. The amount of allocated memory in the internal buffer may be predictively increased.
  805. \param item The element to be inserted.
  806. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  807. used).
  808. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  809. \par Exception Safety
  810. Basic.
  811. \par Iterator Invalidation
  812. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  813. equal to <code>end()</code>).
  814. \par Complexity
  815. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  816. \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
  817. <code>pop_front()</code>
  818. */
  819. void push_front(rvalue_type item) {
  820. check_low_capacity();
  821. circular_buffer<T, Alloc>::push_front(boost::move(item));
  822. }
  823. //! Insert a new element at the beginning of the space optimized circular buffer.
  824. /*!
  825. \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
  826. If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
  827. capacity is <code>0</code>, nothing will be inserted.<br><br>
  828. The amount of allocated memory in the internal buffer may be predictively increased.
  829. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  830. used).
  831. Whatever <code>T::T()</code> throws.
  832. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  833. \par Exception Safety
  834. Basic.
  835. \par Iterator Invalidation
  836. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  837. equal to <code>end()</code>).
  838. \par Complexity
  839. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  840. \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
  841. <code>pop_front()</code>
  842. */
  843. void push_front() {
  844. check_low_capacity();
  845. circular_buffer<T, Alloc>::push_front();
  846. }
  847. //! Remove the last element from the space optimized circular buffer.
  848. /*!
  849. \pre <code>!empty()</code>
  850. \post The last element is removed from the <code>circular_buffer_space_optimized</code>.<br><br>
  851. The amount of allocated memory in the internal buffer may be predictively decreased.
  852. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  853. used).
  854. \par Exception Safety
  855. Basic.
  856. \par Iterator Invalidation
  857. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  858. equal to <code>end()</code>).
  859. \par Complexity
  860. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  861. \sa <code>pop_front()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
  862. <code>\link push_front() push_front(const_reference)\endlink</code>
  863. */
  864. void pop_back() {
  865. circular_buffer<T, Alloc>::pop_back();
  866. check_high_capacity();
  867. }
  868. //! Remove the first element from the space optimized circular buffer.
  869. /*!
  870. \pre <code>!empty()</code>
  871. \post The first element is removed from the <code>circular_buffer_space_optimized</code>.<br><br>
  872. The amount of allocated memory in the internal buffer may be predictively decreased.
  873. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  874. used).
  875. \par Exception Safety
  876. Basic.
  877. \par Iterator Invalidation
  878. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  879. equal to <code>end()</code>).
  880. \par Complexity
  881. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  882. \sa <code>pop_back()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
  883. <code>\link push_front() push_front(const_reference)\endlink</code>
  884. */
  885. void pop_front() {
  886. circular_buffer<T, Alloc>::pop_front();
  887. check_high_capacity();
  888. }
  889. //! Insert an element at the specified position.
  890. /*!
  891. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  892. end.
  893. \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
  894. If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
  895. the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  896. <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  897. nothing will be inserted.<br><br>
  898. The amount of allocated memory in the internal buffer may be predictively increased.
  899. \param pos An iterator specifying the position where the <code>item</code> will be inserted.
  900. \param item The element to be inserted.
  901. \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
  902. the <i>Effect</i>.)
  903. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  904. used).
  905. Whatever <code>T::T(const T&)</code> throws.
  906. Whatever <code>T::operator = (const T&)</code> throws.
  907. \par Exception Safety
  908. Basic.
  909. \par Iterator Invalidation
  910. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  911. equal to <code>end()</code>).
  912. \par Complexity
  913. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  914. \sa <code>\link insert(iterator, size_type, param_value_type)
  915. insert(iterator, size_type, value_type)\endlink</code>,
  916. <code>insert(iterator, InputIterator, InputIterator)</code>,
  917. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  918. <code>\link rinsert(iterator, size_type, param_value_type)
  919. rinsert(iterator, size_type, value_type)\endlink</code>,
  920. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  921. */
  922. iterator insert(iterator pos, param_value_type item) {
  923. size_type index = pos - begin();
  924. check_low_capacity();
  925. return circular_buffer<T, Alloc>::insert(begin() + index, item);
  926. }
  927. //! Insert an element at the specified position.
  928. /*!
  929. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  930. end.
  931. \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
  932. If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
  933. the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  934. <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  935. nothing will be inserted.<br><br>
  936. The amount of allocated memory in the internal buffer may be predictively increased.
  937. \param pos An iterator specifying the position where the <code>item</code> will be inserted.
  938. \param item The element to be inserted.
  939. \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
  940. the <i>Effect</i>.)
  941. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  942. used).
  943. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  944. \par Exception Safety
  945. Basic.
  946. \par Iterator Invalidation
  947. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  948. equal to <code>end()</code>).
  949. \par Complexity
  950. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  951. \sa <code>\link insert(iterator, size_type, param_value_type)
  952. insert(iterator, size_type, value_type)\endlink</code>,
  953. <code>insert(iterator, InputIterator, InputIterator)</code>,
  954. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  955. <code>\link rinsert(iterator, size_type, param_value_type)
  956. rinsert(iterator, size_type, value_type)\endlink</code>,
  957. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  958. */
  959. iterator insert(iterator pos, rvalue_type item) {
  960. size_type index = pos - begin();
  961. check_low_capacity();
  962. return circular_buffer<T, Alloc>::insert(begin() + index, boost::move(item));
  963. }
  964. //! Insert an element at the specified position.
  965. /*!
  966. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  967. end.
  968. \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
  969. If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
  970. the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  971. <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  972. nothing will be inserted.<br><br>
  973. The amount of allocated memory in the internal buffer may be predictively increased.
  974. \param pos An iterator specifying the position where the <code>item</code> will be inserted.
  975. \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
  976. the <i>Effect</i>.)
  977. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  978. used).
  979. Whatever <code>T::T()</code> throws.
  980. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  981. \par Exception Safety
  982. Basic.
  983. \par Iterator Invalidation
  984. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  985. equal to <code>end()</code>).
  986. \par Complexity
  987. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  988. \sa <code>\link insert(iterator, size_type, param_value_type)
  989. insert(iterator, size_type, value_type)\endlink</code>,
  990. <code>insert(iterator, InputIterator, InputIterator)</code>,
  991. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  992. <code>\link rinsert(iterator, size_type, param_value_type)
  993. rinsert(iterator, size_type, value_type)\endlink</code>,
  994. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  995. */
  996. iterator insert(iterator pos) {
  997. size_type index = pos - begin();
  998. check_low_capacity();
  999. return circular_buffer<T, Alloc>::insert(begin() + index);
  1000. }
  1001. //! Insert <code>n</code> copies of the <code>item</code> at the specified position.
  1002. /*!
  1003. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1004. end.
  1005. \post The number of <code>min[n, (pos - begin()) + reserve()]</code> elements will be inserted at the position
  1006. <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0, n - reserve()]]</code> elements will
  1007. be overwritten at the beginning of the <code>circular_buffer_space_optimized</code>.<br>(See
  1008. <i>Example</i> for the explanation.)<br><br>
  1009. The amount of allocated memory in the internal buffer may be predictively increased.
  1010. \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
  1011. \param n The number of <code>item</code>s the to be inserted.
  1012. \param item The element whose copies will be inserted.
  1013. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1014. used).
  1015. Whatever <code>T::T(const T&)</code> throws.
  1016. Whatever <code>T::operator = (const T&)</code> throws.
  1017. \par Exception Safety
  1018. Basic.
  1019. \par Iterator Invalidation
  1020. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1021. equal to <code>end()</code>).
  1022. \par Complexity
  1023. Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
  1024. \par Example
  1025. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1026. internal buffer may look like the one below.<br><br>
  1027. <code>|1|2|3|4| | |</code><br>
  1028. <code>p ___^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
  1029. <code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
  1030. <code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves
  1031. the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br>
  1032. <br>For comparison if the capacity would not be preserved the internal buffer would then result in
  1033. <code>|1|2|0|0|0|0|0|3|4|</code>.
  1034. \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1035. <code>insert(iterator, InputIterator, InputIterator)</code>,
  1036. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  1037. <code>\link rinsert(iterator, size_type, param_value_type)
  1038. rinsert(iterator, size_type, value_type)\endlink</code>,
  1039. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  1040. */
  1041. void insert(iterator pos, size_type n, param_value_type item) {
  1042. size_type index = pos - begin();
  1043. check_low_capacity(n);
  1044. circular_buffer<T, Alloc>::insert(begin() + index, n, item);
  1045. }
  1046. //! Insert the range <code>[first, last)</code> at the specified position.
  1047. /*!
  1048. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1049. end.<br>Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
  1050. requirements of an <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
  1051. \post Elements from the range
  1052. <code>[first + max[0, distance(first, last) - (pos - begin()) - reserve()], last)</code> will be
  1053. inserted at the position <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0,
  1054. distance(first, last) - reserve()]]</code> elements will be overwritten at the beginning of the
  1055. <code>circular_buffer_space_optimized</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
  1056. The amount of allocated memory in the internal buffer may be predictively increased.
  1057. \param pos An iterator specifying the position where the range will be inserted.
  1058. \param first The beginning of the range to be inserted.
  1059. \param last The end of the range to be inserted.
  1060. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1061. used).
  1062. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  1063. \par Exception Safety
  1064. Basic.
  1065. \par Iterator Invalidation
  1066. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1067. equal to <code>end()</code>).
  1068. \par Complexity
  1069. Linear (in <code>[size() + std::distance(first, last)]</code>; in
  1070. <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
  1071. <code>InputIterator</code> is a
  1072. <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  1073. \par Example
  1074. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1075. internal buffer may look like the one below.<br><br>
  1076. <code>|1|2|3|4| | |</code><br>
  1077. <code>p ___^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
  1078. <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
  1079. actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the
  1080. specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due
  1081. to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like
  1082. this:<br><br><code>|6|7|8|9|3|4|</code><br><br>For comparison if the capacity would not be preserved the
  1083. internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
  1084. \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1085. <code>\link insert(iterator, size_type, param_value_type)
  1086. insert(iterator, size_type, value_type)\endlink</code>, <code>\link rinsert(iterator, param_value_type)
  1087. rinsert(iterator, value_type)\endlink</code>, <code>\link rinsert(iterator, size_type, param_value_type)
  1088. rinsert(iterator, size_type, value_type)\endlink</code>,
  1089. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  1090. */
  1091. template <class InputIterator>
  1092. void insert(iterator pos, InputIterator first, InputIterator last) {
  1093. insert(pos, first, last, is_integral<InputIterator>());
  1094. }
  1095. //! Insert an element before the specified position.
  1096. /*!
  1097. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1098. end.
  1099. \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
  1100. If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
  1101. <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  1102. <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  1103. nothing will be inserted.<br><br>
  1104. The amount of allocated memory in the internal buffer may be predictively increased.
  1105. \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
  1106. \param item The element to be inserted.
  1107. \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
  1108. the <i>Effect</i>.)
  1109. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1110. used).
  1111. Whatever <code>T::T(const T&)</code> throws.
  1112. Whatever <code>T::operator = (const T&)</code> throws.
  1113. \par Exception Safety
  1114. Basic.
  1115. \par Iterator Invalidation
  1116. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1117. equal to <code>end()</code>).
  1118. \par Complexity
  1119. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1120. \sa <code>\link rinsert(iterator, size_type, param_value_type)
  1121. rinsert(iterator, size_type, value_type)\endlink</code>,
  1122. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1123. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1124. <code>\link insert(iterator, size_type, param_value_type)
  1125. insert(iterator, size_type, value_type)\endlink</code>,
  1126. <code>insert(iterator, InputIterator, InputIterator)</code>
  1127. */
  1128. iterator rinsert(iterator pos, param_value_type item) {
  1129. size_type index = pos - begin();
  1130. check_low_capacity();
  1131. return circular_buffer<T, Alloc>::rinsert(begin() + index, item);
  1132. }
  1133. //! Insert an element before the specified position.
  1134. /*!
  1135. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1136. end.
  1137. \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
  1138. If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
  1139. <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  1140. <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  1141. nothing will be inserted.<br><br>
  1142. The amount of allocated memory in the internal buffer may be predictively increased.
  1143. \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
  1144. \param item The element to be inserted.
  1145. \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
  1146. the <i>Effect</i>.)
  1147. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1148. used).
  1149. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  1150. \par Exception Safety
  1151. Basic.
  1152. \par Iterator Invalidation
  1153. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1154. equal to <code>end()</code>).
  1155. \par Complexity
  1156. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1157. \sa <code>\link rinsert(iterator, size_type, param_value_type)
  1158. rinsert(iterator, size_type, value_type)\endlink</code>,
  1159. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1160. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1161. <code>\link insert(iterator, size_type, param_value_type)
  1162. insert(iterator, size_type, value_type)\endlink</code>,
  1163. <code>insert(iterator, InputIterator, InputIterator)</code>
  1164. */
  1165. iterator rinsert(iterator pos, rvalue_type item) {
  1166. size_type index = pos - begin();
  1167. check_low_capacity();
  1168. return circular_buffer<T, Alloc>::rinsert(begin() + index, boost::move(item));
  1169. }
  1170. //! Insert an element before the specified position.
  1171. /*!
  1172. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1173. end.
  1174. \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
  1175. If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
  1176. <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  1177. <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  1178. nothing will be inserted.<br><br>
  1179. The amount of allocated memory in the internal buffer may be predictively increased.
  1180. \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
  1181. \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
  1182. the <i>Effect</i>.)
  1183. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1184. used).
  1185. Whatever <code>T::T()</code> throws.
  1186. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  1187. \par Exception Safety
  1188. Basic.
  1189. \par Iterator Invalidation
  1190. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1191. equal to <code>end()</code>).
  1192. \par Complexity
  1193. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1194. \sa <code>\link rinsert(iterator, size_type, param_value_type)
  1195. rinsert(iterator, size_type, value_type)\endlink</code>,
  1196. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1197. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1198. <code>\link insert(iterator, size_type, param_value_type)
  1199. insert(iterator, size_type, value_type)\endlink</code>,
  1200. <code>insert(iterator, InputIterator, InputIterator)</code>
  1201. */
  1202. iterator rinsert(iterator pos) {
  1203. size_type index = pos - begin();
  1204. check_low_capacity();
  1205. return circular_buffer<T, Alloc>::rinsert(begin() + index);
  1206. }
  1207. //! Insert <code>n</code> copies of the <code>item</code> before the specified position.
  1208. /*!
  1209. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1210. end.
  1211. \post The number of <code>min[n, (end() - pos) + reserve()]</code> elements will be inserted before the
  1212. position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0, n - reserve()]]</code> elements
  1213. will be overwritten at the end of the <code>circular_buffer_space_optimized</code>.<br>(See
  1214. <i>Example</i> for the explanation.)<br><br>
  1215. The amount of allocated memory in the internal buffer may be predictively increased.
  1216. \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
  1217. \param n The number of <code>item</code>s the to be inserted.
  1218. \param item The element whose copies will be inserted.
  1219. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1220. used).
  1221. Whatever <code>T::T(const T&)</code> throws.
  1222. Whatever <code>T::operator = (const T&)</code> throws.
  1223. \par Exception Safety
  1224. Basic.
  1225. \par Iterator Invalidation
  1226. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1227. equal to <code>end()</code>).
  1228. \par Complexity
  1229. Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
  1230. \par Example
  1231. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1232. internal buffer may look like the one below.<br><br>
  1233. <code>|1|2|3|4| | |</code><br>
  1234. <code>p ___^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
  1235. <code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
  1236. <code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves
  1237. the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br>
  1238. <br>For comparison if the capacity would not be preserved the internal buffer would then result in
  1239. <code>|1|2|0|0|0|0|0|3|4|</code>.
  1240. \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  1241. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1242. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1243. <code>\link insert(iterator, size_type, param_value_type)
  1244. insert(iterator, size_type, value_type)\endlink</code>,
  1245. <code>insert(iterator, InputIterator, InputIterator)</code>
  1246. */
  1247. void rinsert(iterator pos, size_type n, param_value_type item) {
  1248. size_type index = pos - begin();
  1249. check_low_capacity(n);
  1250. circular_buffer<T, Alloc>::rinsert(begin() + index, n, item);
  1251. }
  1252. //! Insert the range <code>[first, last)</code> before the specified position.
  1253. /*!
  1254. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1255. end.<br>
  1256. Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
  1257. requirements of an <a href="https://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>.
  1258. \post Elements from the range
  1259. <code>[first, last - max[0, distance(first, last) - (end() - pos) - reserve()])</code> will be inserted
  1260. before the position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0,
  1261. distance(first, last) - reserve()]]</code> elements will be overwritten at the end of the
  1262. <code>circular_buffer</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
  1263. The amount of allocated memory in the internal buffer may be predictively increased.
  1264. \param pos An iterator specifying the position where the range will be inserted.
  1265. \param first The beginning of the range to be inserted.
  1266. \param last The end of the range to be inserted.
  1267. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1268. used).
  1269. Whatever <code>T::T(const T&)</code> throws.
  1270. Whatever <code>T::operator = (const T&)</code> throws.
  1271. \par Exception Safety
  1272. Basic.
  1273. \par Iterator Invalidation
  1274. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1275. equal to <code>end()</code>).
  1276. \par Complexity
  1277. Linear (in <code>[size() + std::distance(first, last)]</code>; in
  1278. <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
  1279. <code>InputIterator</code> is a
  1280. <a href="https://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  1281. \par Example
  1282. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1283. internal buffer may look like the one below.<br><br>
  1284. <code>|1|2|3|4| | |</code><br>
  1285. <code>p ___^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
  1286. <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
  1287. actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the
  1288. specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due
  1289. to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like
  1290. this:<br><br><code>|1|2|5|6|7|8|</code><br><br>For comparison if the capacity would not be preserved the
  1291. internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
  1292. \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  1293. <code>\link rinsert(iterator, size_type, param_value_type)
  1294. rinsert(iterator, size_type, value_type)\endlink</code>, <code>\link insert(iterator, param_value_type)
  1295. insert(iterator, value_type)\endlink</code>, <code>\link insert(iterator, size_type, param_value_type)
  1296. insert(iterator, size_type, value_type)\endlink</code>,
  1297. <code>insert(iterator, InputIterator, InputIterator)</code>
  1298. */
  1299. template <class InputIterator>
  1300. void rinsert(iterator pos, InputIterator first, InputIterator last) {
  1301. rinsert(pos, first, last, is_integral<InputIterator>());
  1302. }
  1303. //! Remove an element at the specified position.
  1304. /*!
  1305. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
  1306. an <code>end()</code>).
  1307. \post The element at the position <code>pos</code> is removed.<br><br>
  1308. The amount of allocated memory in the internal buffer may be predictively decreased.
  1309. \param pos An iterator pointing at the element to be removed.
  1310. \return Iterator to the first element remaining beyond the removed element or <code>end()</code> if no such
  1311. element exists.
  1312. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1313. used).
  1314. Whatever <code>T::operator = (const T&)</code> throws or
  1315. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1316. \par Exception Safety
  1317. Basic.
  1318. \par Iterator Invalidation
  1319. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1320. equal to <code>end()</code>).
  1321. \par Complexity
  1322. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1323. \sa <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
  1324. <code>rerase(iterator, iterator)</code>, <code>clear()</code>
  1325. */
  1326. iterator erase(iterator pos) {
  1327. iterator it = circular_buffer<T, Alloc>::erase(pos);
  1328. size_type index = it - begin();
  1329. check_high_capacity();
  1330. return begin() + index;
  1331. }
  1332. //! Erase the range <code>[first, last)</code>.
  1333. /*!
  1334. \pre Valid range <code>[first, last)</code>.
  1335. \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
  1336. nothing is removed.)<br><br>
  1337. The amount of allocated memory in the internal buffer may be predictively decreased.
  1338. \param first The beginning of the range to be removed.
  1339. \param last The end of the range to be removed.
  1340. \return Iterator to the first element remaining beyond the removed elements or <code>end()</code> if no such
  1341. element exists.
  1342. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1343. used).
  1344. Whatever <code>T::operator = (const T&)</code> throws or
  1345. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1346. \par Exception Safety
  1347. Basic.
  1348. \par Iterator Invalidation
  1349. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1350. equal to <code>end()</code>).
  1351. \par Complexity
  1352. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1353. \sa <code>erase(iterator)</code>, <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
  1354. <code>clear()</code>
  1355. */
  1356. iterator erase(iterator first, iterator last) {
  1357. iterator it = circular_buffer<T, Alloc>::erase(first, last);
  1358. size_type index = it - begin();
  1359. check_high_capacity();
  1360. return begin() + index;
  1361. }
  1362. //! Remove an element at the specified position.
  1363. /*!
  1364. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
  1365. an <code>end()</code>).<br><br>
  1366. The amount of allocated memory in the internal buffer may be predictively decreased.
  1367. \post The element at the position <code>pos</code> is removed.
  1368. \param pos An iterator pointing at the element to be removed.
  1369. \return Iterator to the first element remaining in front of the removed element or <code>begin()</code> if no
  1370. such element exists.
  1371. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1372. used).
  1373. Whatever <code>T::operator = (const T&)</code> throws or
  1374. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1375. \par Exception Safety
  1376. Basic.
  1377. \par Iterator Invalidation
  1378. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1379. equal to <code>end()</code>).
  1380. \par Complexity
  1381. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1382. \note Basically there is no difference between <code>erase(iterator)</code> and this method. It is implemented
  1383. only for consistency with the base <code>circular_buffer</code>.
  1384. \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
  1385. <code>rerase(iterator, iterator)</code>, <code>clear()</code>
  1386. */
  1387. iterator rerase(iterator pos) {
  1388. iterator it = circular_buffer<T, Alloc>::rerase(pos);
  1389. size_type index = it - begin();
  1390. check_high_capacity();
  1391. return begin() + index;
  1392. }
  1393. //! Erase the range <code>[first, last)</code>.
  1394. /*!
  1395. \pre Valid range <code>[first, last)</code>.
  1396. \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
  1397. nothing is removed.)<br><br>
  1398. The amount of allocated memory in the internal buffer may be predictively decreased.
  1399. \param first The beginning of the range to be removed.
  1400. \param last The end of the range to be removed.
  1401. \return Iterator to the first element remaining in front of the removed elements or <code>begin()</code> if no
  1402. such element exists.
  1403. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1404. used).
  1405. Whatever <code>T::operator = (const T&)</code> throws or
  1406. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1407. \par Exception Safety
  1408. Basic.
  1409. \par Iterator Invalidation
  1410. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1411. equal to <code>end()</code>).
  1412. \par Complexity
  1413. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1414. \note Basically there is no difference between <code>erase(iterator, iterator)</code> and this method. It is
  1415. implemented only for consistency with the base
  1416. <code><circular_buffer</code>.
  1417. \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
  1418. <code>clear()</code>
  1419. */
  1420. iterator rerase(iterator first, iterator last) {
  1421. iterator it = circular_buffer<T, Alloc>::rerase(first, last);
  1422. size_type index = it - begin();
  1423. check_high_capacity();
  1424. return begin() + index;
  1425. }
  1426. //! Remove all stored elements from the space optimized circular buffer.
  1427. /*!
  1428. \post <code>size() == 0</code><br><br>
  1429. The amount of allocated memory in the internal buffer may be predictively decreased.
  1430. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1431. used).
  1432. \par Exception Safety
  1433. Basic.
  1434. \par Iterator Invalidation
  1435. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1436. equal to <code>end()</code>).
  1437. \par Complexity
  1438. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1439. \sa <code>~circular_buffer_space_optimized()</code>, <code>erase(iterator)</code>,
  1440. <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
  1441. <code>rerase(iterator, iterator)</code>
  1442. */
  1443. void clear() { erase(begin(), end()); }
  1444. private:
  1445. // Helper methods
  1446. /*! INTERNAL ONLY */
  1447. void adjust_min_capacity() {
  1448. if (m_capacity_ctrl.min_capacity() > circular_buffer<T, Alloc>::capacity())
  1449. circular_buffer<T, Alloc>::set_capacity(m_capacity_ctrl.min_capacity());
  1450. else
  1451. check_high_capacity();
  1452. }
  1453. /*! INTERNAL ONLY */
  1454. size_type ensure_reserve(size_type new_capacity, size_type buffer_size) const {
  1455. if (buffer_size + new_capacity / 5 >= new_capacity)
  1456. new_capacity *= 2; // ensure at least 20% reserve
  1457. if (new_capacity > m_capacity_ctrl)
  1458. return m_capacity_ctrl;
  1459. return new_capacity;
  1460. }
  1461. /*! INTERNAL ONLY */
  1462. void check_low_capacity(size_type n = 1) {
  1463. size_type new_size = size() + n;
  1464. size_type new_capacity = circular_buffer<T, Alloc>::capacity();
  1465. if (new_size > new_capacity) {
  1466. if (new_capacity == 0)
  1467. new_capacity = 1;
  1468. for (; new_size > new_capacity; new_capacity *= 2) {}
  1469. circular_buffer<T, Alloc>::set_capacity(
  1470. ensure_reserve(new_capacity, new_size));
  1471. }
  1472. #if BOOST_CB_ENABLE_DEBUG
  1473. this->invalidate_iterators_except(end());
  1474. #endif
  1475. }
  1476. /*! INTERNAL ONLY */
  1477. void check_high_capacity() {
  1478. size_type new_capacity = circular_buffer<T, Alloc>::capacity();
  1479. while (new_capacity / 3 >= size()) { // (new_capacity / 3) -> avoid oscillations
  1480. new_capacity /= 2;
  1481. if (new_capacity <= m_capacity_ctrl.min_capacity()) {
  1482. new_capacity = m_capacity_ctrl.min_capacity();
  1483. break;
  1484. }
  1485. }
  1486. circular_buffer<T, Alloc>::set_capacity(
  1487. ensure_reserve(new_capacity, size()));
  1488. #if BOOST_CB_ENABLE_DEBUG
  1489. this->invalidate_iterators_except(end());
  1490. #endif
  1491. }
  1492. /*! INTERNAL ONLY */
  1493. void reduce_capacity(const true_type&) {
  1494. circular_buffer<T, Alloc>::set_capacity((std::max)(m_capacity_ctrl.min_capacity(), size()));
  1495. }
  1496. /*! INTERNAL ONLY */
  1497. void reduce_capacity(const false_type&) {}
  1498. /*! INTERNAL ONLY */
  1499. static size_type init_capacity(const capacity_type& capacity_ctrl, size_type n) {
  1500. BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for capacity lower than n
  1501. return (std::max)(capacity_ctrl.min_capacity(), n);
  1502. }
  1503. /*! INTERNAL ONLY */
  1504. template <class IntegralType>
  1505. static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType,
  1506. const true_type&) {
  1507. return init_capacity(capacity_ctrl, static_cast<size_type>(n));
  1508. }
  1509. /*! INTERNAL ONLY */
  1510. template <class Iterator>
  1511. static size_type init_capacity(const capacity_type& capacity_ctrl, Iterator first, Iterator last,
  1512. const false_type&) {
  1513. BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
  1514. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
  1515. return init_capacity(capacity_ctrl, first, last, std::iterator_traits<Iterator>::iterator_category());
  1516. #else
  1517. return init_capacity(
  1518. capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::iterator_category());
  1519. #endif
  1520. }
  1521. /*! INTERNAL ONLY */
  1522. template <class InputIterator>
  1523. static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator, InputIterator,
  1524. const std::input_iterator_tag&) {
  1525. return capacity_ctrl.capacity();
  1526. }
  1527. /*! INTERNAL ONLY */
  1528. template <class ForwardIterator>
  1529. static size_type init_capacity(const capacity_type& capacity_ctrl, ForwardIterator first, ForwardIterator last,
  1530. const std::forward_iterator_tag&) {
  1531. BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
  1532. return (std::max)(capacity_ctrl.min_capacity(),
  1533. (std::min)(capacity_ctrl.capacity(), static_cast<size_type>(std::distance(first, last))));
  1534. }
  1535. /*! INTERNAL ONLY */
  1536. template <class IntegralType>
  1537. void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
  1538. insert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
  1539. }
  1540. /*! INTERNAL ONLY */
  1541. template <class Iterator>
  1542. void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
  1543. size_type index = pos - begin();
  1544. check_low_capacity(std::distance(first, last));
  1545. circular_buffer<T, Alloc>::insert(begin() + index, first, last);
  1546. }
  1547. /*! INTERNAL ONLY */
  1548. template <class IntegralType>
  1549. void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
  1550. rinsert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
  1551. }
  1552. /*! INTERNAL ONLY */
  1553. template <class Iterator>
  1554. void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
  1555. size_type index = pos - begin();
  1556. check_low_capacity(std::distance(first, last));
  1557. circular_buffer<T, Alloc>::rinsert(begin() + index, first, last);
  1558. }
  1559. };
  1560. // Non-member functions
  1561. //! Test two space optimized circular buffers for equality.
  1562. template <class T, class Alloc>
  1563. inline bool operator == (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1564. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1565. return lhs.size() == rhs.size() &&
  1566. std::equal(lhs.begin(), lhs.end(), rhs.begin());
  1567. }
  1568. //! Lexicographical comparison.
  1569. template <class T, class Alloc>
  1570. inline bool operator < (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1571. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1572. return std::lexicographical_compare(
  1573. lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  1574. }
  1575. #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
  1576. //! Test two space optimized circular buffers for non-equality.
  1577. template <class T, class Alloc>
  1578. inline bool operator != (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1579. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1580. return !(lhs == rhs);
  1581. }
  1582. //! Lexicographical comparison.
  1583. template <class T, class Alloc>
  1584. inline bool operator > (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1585. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1586. return rhs < lhs;
  1587. }
  1588. //! Lexicographical comparison.
  1589. template <class T, class Alloc>
  1590. inline bool operator <= (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1591. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1592. return !(rhs < lhs);
  1593. }
  1594. //! Lexicographical comparison.
  1595. template <class T, class Alloc>
  1596. inline bool operator >= (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1597. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1598. return !(lhs < rhs);
  1599. }
  1600. //! Swap the contents of two space optimized circular buffers.
  1601. template <class T, class Alloc>
  1602. inline void swap(circular_buffer_space_optimized<T, Alloc>& lhs,
  1603. circular_buffer_space_optimized<T, Alloc>& rhs) BOOST_NOEXCEPT {
  1604. lhs.swap(rhs);
  1605. }
  1606. #endif // #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
  1607. } // namespace boost
  1608. #endif // #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)