space_optimized.hpp 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746
  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) && _MSC_VER >= 1200
  11. #pragma once
  12. #endif
  13. #include <boost/type_traits/is_same.hpp>
  14. #include <boost/detail/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. #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  385. /*! \cond */
  386. circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
  387. : circular_buffer<T, Alloc>(cb.begin(), cb.end())
  388. , m_capacity_ctrl(cb.m_capacity_ctrl) {}
  389. template <class InputIterator>
  390. circular_buffer_space_optimized(InputIterator first, InputIterator last)
  391. : circular_buffer<T, Alloc>(first, last)
  392. , m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
  393. template <class InputIterator>
  394. circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last)
  395. : circular_buffer<T, Alloc>(
  396. init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
  397. first, last)
  398. , m_capacity_ctrl(capacity_ctrl) {
  399. reduce_capacity(
  400. is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
  401. }
  402. /*! \endcond */
  403. #else
  404. //! The copy constructor.
  405. /*!
  406. Creates a copy of the specified <code>circular_buffer_space_optimized</code>.
  407. \post <code>*this == cb</code><br><br>
  408. The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
  409. \param cb The <code>circular_buffer_space_optimized</code> to be copied.
  410. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  411. used).
  412. Whatever <code>T::T(const T&)</code> throws.
  413. \par Complexity
  414. Linear (in the size of <code>cb</code>).
  415. */
  416. circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
  417. : circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator())
  418. , m_capacity_ctrl(cb.m_capacity_ctrl) {}
  419. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  420. //! The move constructor.
  421. /*! \brief Move constructs a <code>circular_buffer_space_optimized</code> from <code>cb</code>,
  422. leaving <code>cb</code> empty.
  423. \pre C++ compiler with rvalue references support.
  424. \post <code>cb.empty()</code>
  425. \param cb <code>circular_buffer</code> to 'steal' value from.
  426. \throws Nothing.
  427. \par Constant.
  428. */
  429. circular_buffer_space_optimized(circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT
  430. : circular_buffer<T, Alloc>()
  431. , m_capacity_ctrl(0) {
  432. cb.swap(*this);
  433. }
  434. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  435. //! Create a full space optimized circular buffer filled with a copy of the range.
  436. /*!
  437. \pre Valid range <code>[first, last)</code>.<br>
  438. <code>first</code> and <code>last</code> have to meet the requirements of
  439. <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
  440. \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
  441. full() \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ... \&\&
  442. (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
  443. The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
  444. \param first The beginning of the range to be copied.
  445. \param last The end of the range to be copied.
  446. \param alloc The allocator.
  447. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  448. used).
  449. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept
  450. and <code>InputIterator</code> is a move iterator.
  451. \par Complexity
  452. Linear (in the <code>std::distance(first, last)</code>).
  453. */
  454. template <class InputIterator>
  455. circular_buffer_space_optimized(InputIterator first, InputIterator last,
  456. const allocator_type& alloc = allocator_type())
  457. : circular_buffer<T, Alloc>(first, last, alloc)
  458. , m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
  459. /*! \brief Create a space optimized circular buffer with the specified capacity (and the minimal guaranteed amount
  460. of allocated memory) filled with a copy of the range.
  461. \pre Valid range <code>[first, last)</code>.<br>
  462. <code>first</code> and <code>last</code> have to meet the requirements of
  463. <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
  464. \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\& (*this)[0]==
  465. *(last - capacity_ctrl.%capacity()) \&\& (*this)[1] == *(last - capacity_ctrl.%capacity() + 1) \&\& ...
  466. \&\& (*this)[capacity_ctrl.%capacity() - 1] == *(last - 1)</code><br><br>
  467. If the number of items to be copied from the range <code>[first, last)</code> is greater than the
  468. specified <code>capacity_ctrl.%capacity()</code> then only elements from the range
  469. <code>[last - capacity_ctrl.%capacity(), last)</code> will be copied.<br><br>
  470. The amount of allocated memory in the internal buffer is <code>max[capacity_ctrl.min_capacity(),
  471. min[capacity_ctrl.%capacity(), std::distance(first, last)]]</code>.
  472. \param capacity_ctrl The capacity controller representing the maximum number of elements which can be stored in
  473. the <code>circular_buffer_space_optimized</code> and the minimal allocated size of the
  474. internal buffer.
  475. \param first The beginning of the range to be copied.
  476. \param last The end of the range to be copied.
  477. \param alloc The allocator.
  478. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  479. used).
  480. Whatever <code>T::T(const T&)</code> throws.
  481. \par Complexity
  482. Linear (in <code>std::distance(first, last)</code>; in
  483. <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
  484. is a <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  485. */
  486. template <class InputIterator>
  487. circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last,
  488. const allocator_type& alloc = allocator_type())
  489. : circular_buffer<T, Alloc>(
  490. init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
  491. first, last, alloc)
  492. , m_capacity_ctrl(capacity_ctrl) {
  493. reduce_capacity(
  494. is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
  495. }
  496. #endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  497. #if defined(BOOST_CB_NEVER_DEFINED)
  498. // This section will never be compiled - the default destructor will be generated instead.
  499. // Declared only for documentation purpose.
  500. //! The destructor.
  501. /*!
  502. Destroys the <code>circular_buffer_space_optimized</code>.
  503. \throws Nothing.
  504. \par Iterator Invalidation
  505. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (including
  506. iterators equal to <code>end()</code>).
  507. \par Complexity
  508. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  509. \sa <code>clear()</code>
  510. */
  511. ~circular_buffer_space_optimized();
  512. //! no-comment
  513. void erase_begin(size_type n);
  514. //! no-comment
  515. void erase_end(size_type n);
  516. #endif // #if defined(BOOST_CB_NEVER_DEFINED)
  517. //! The assign operator.
  518. /*!
  519. Makes this <code>circular_buffer_space_optimized</code> to become a copy of the specified
  520. <code>circular_buffer_space_optimized</code>.
  521. \post <code>*this == cb</code><br><br>
  522. The amount of allocated memory in the internal buffer is <code>cb.size()</code>.
  523. \param cb The <code>circular_buffer_space_optimized</code> to be copied.
  524. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  525. used).
  526. \throws Whatever <code>T::T(const T&)</code> throws.
  527. \par Exception Safety
  528. Strong.
  529. \par Iterator Invalidation
  530. Invalidates all iterators pointing to this <code>circular_buffer_space_optimized</code> (except iterators
  531. equal to <code>end()</code>).
  532. \par Complexity
  533. Linear (in the size of <code>cb</code>).
  534. \sa <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  535. <code>\link assign(capacity_type, size_type, param_value_type)
  536. assign(capacity_type, size_type, const_reference)\endlink</code>,
  537. <code>assign(InputIterator, InputIterator)</code>,
  538. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  539. */
  540. circular_buffer_space_optimized<T, Alloc>& operator = (const circular_buffer_space_optimized<T, Alloc>& cb) {
  541. if (this == &cb)
  542. return *this;
  543. circular_buffer<T, Alloc>::assign(cb.begin(), cb.end());
  544. m_capacity_ctrl = cb.m_capacity_ctrl;
  545. return *this;
  546. }
  547. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  548. /*! \brief Move assigns content of <code>cb</code> to <code>*this</code>, leaving <code>cb</code> empty.
  549. \pre C++ compiler with rvalue references support.
  550. \post <code>cb.empty()</code>
  551. \param cb <code>circular_buffer</code> to 'steal' value from.
  552. \throws Nothing.
  553. \par Complexity
  554. Constant.
  555. */
  556. circular_buffer_space_optimized<T, Alloc>& operator = (circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT {
  557. cb.swap(*this); // now `this` holds `cb`
  558. circular_buffer<T, Alloc>(get_allocator()) // temprary that holds initial `cb` allocator
  559. .swap(cb); // makes `cb` empty
  560. return *this;
  561. }
  562. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  563. //! Assign <code>n</code> items into the space optimized circular buffer.
  564. /*!
  565. The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with
  566. <code>n</code> copies of the <code>item</code>.
  567. \post <code>capacity().%capacity() == n \&\& capacity().min_capacity() == 0 \&\& size() == n \&\& (*this)[0] ==
  568. item \&\& (*this)[1] == item \&\& ... \&\& (*this) [n - 1] == item</code><br><br>
  569. The amount of allocated memory in the internal buffer is <code>n</code>.
  570. \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
  571. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
  572. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  573. used).
  574. Whatever <code>T::T(const T&)</code> throws.
  575. \par Exception Safety
  576. Basic.
  577. \par Iterator Invalidation
  578. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  579. equal to <code>end()</code>).
  580. \par Complexity
  581. Linear (in the <code>n</code>).
  582. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  583. <code>\link assign(capacity_type, size_type, param_value_type)
  584. assign(capacity_type, size_type, const_reference)\endlink</code>,
  585. <code>assign(InputIterator, InputIterator)</code>,
  586. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  587. */
  588. void assign(size_type n, param_value_type item) {
  589. circular_buffer<T, Alloc>::assign(n, item);
  590. m_capacity_ctrl = capacity_type(n);
  591. }
  592. //! Assign <code>n</code> items into the space optimized circular buffer specifying the capacity.
  593. /*!
  594. The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
  595. content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with <code>n</code>
  596. copies of the <code>item</code>.
  597. \pre <code>capacity_ctrl.%capacity() >= n</code>
  598. \post <code>capacity() == capacity_ctrl \&\& size() == n \&\& (*this)[0] == item \&\& (*this)[1] == item
  599. \&\& ... \&\& (*this) [n - 1] == item </code><br><br>
  600. The amount of allocated memory will be <code>max[n, capacity_ctrl.min_capacity()]</code>.
  601. \param capacity_ctrl The new capacity controller.
  602. \param n The number of elements the <code>circular_buffer_space_optimized</code> will be filled with.
  603. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
  604. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  605. used).
  606. Whatever <code>T::T(const T&)</code> throws.
  607. \par Exception Safety
  608. Basic.
  609. \par Iterator Invalidation
  610. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  611. equal to <code>end()</code>).
  612. \par Complexity
  613. Linear (in the <code>n</code>).
  614. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  615. <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  616. <code>assign(InputIterator, InputIterator)</code>,
  617. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  618. */
  619. void assign(capacity_type capacity_ctrl, size_type n, param_value_type item) {
  620. BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for new capacity lower than n
  621. circular_buffer<T, Alloc>::assign((std::max)(capacity_ctrl.min_capacity(), n), n, item);
  622. m_capacity_ctrl = capacity_ctrl;
  623. }
  624. //! Assign a copy of the range into the space optimized circular buffer.
  625. /*!
  626. The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
  627. elements from the specified range.
  628. \pre Valid range <code>[first, last)</code>.<br>
  629. <code>first</code> and <code>last</code> have to meet the requirements of
  630. <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
  631. \post <code>capacity().%capacity() == std::distance(first, last) \&\& capacity().min_capacity() == 0 \&\&
  632. size() == std::distance(first, last) \&\& (*this)[0]== *first \&\& (*this)[1] == *(first + 1) \&\& ...
  633. \&\& (*this)[std::distance(first, last) - 1] == *(last - 1)</code><br><br>
  634. The amount of allocated memory in the internal buffer is <code>std::distance(first, last)</code>.
  635. \param first The beginning of the range to be copied.
  636. \param last The end of the range to be copied.
  637. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  638. used).
  639. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
  640. <code>InputIterator</code> is a move iterator.
  641. \par Exception Safety
  642. Basic.
  643. \par Iterator Invalidation
  644. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  645. equal to <code>end()</code>).
  646. \par Complexity
  647. Linear (in the <code>std::distance(first, last)</code>).
  648. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  649. <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  650. <code>\link assign(capacity_type, size_type, param_value_type)
  651. assign(capacity_type, size_type, const_reference)\endlink</code>,
  652. <code>assign(capacity_type, InputIterator, InputIterator)</code>
  653. */
  654. template <class InputIterator>
  655. void assign(InputIterator first, InputIterator last) {
  656. circular_buffer<T, Alloc>::assign(first, last);
  657. m_capacity_ctrl = capacity_type(circular_buffer<T, Alloc>::capacity());
  658. }
  659. //! Assign a copy of the range into the space optimized circular buffer specifying the capacity.
  660. /*!
  661. The capacity of the <code>circular_buffer_space_optimized</code> will be set to the specified value and the
  662. content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with copies of
  663. elements from the specified range.
  664. \pre Valid range <code>[first, last)</code>.<br>
  665. <code>first</code> and <code>last</code> have to meet the requirements of
  666. <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
  667. \post <code>capacity() == capacity_ctrl \&\& size() \<= std::distance(first, last) \&\&
  668. (*this)[0]== *(last - capacity) \&\& (*this)[1] == *(last - capacity + 1) \&\& ... \&\&
  669. (*this)[capacity - 1] == *(last - 1)</code><br><br>
  670. If the number of items to be copied from the range <code>[first, last)</code> is greater than the
  671. specified <code>capacity</code> then only elements from the range <code>[last - capacity, last)</code>
  672. will be copied.<br><br> The amount of allocated memory in the internal buffer is
  673. <code>max[std::distance(first, last), capacity_ctrl.min_capacity()]</code>.
  674. \param capacity_ctrl The new capacity controller.
  675. \param first The beginning of the range to be copied.
  676. \param last The end of the range to be copied.
  677. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  678. used).
  679. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
  680. <code>InputIterator</code> is a move iterator.
  681. \par Exception Safety
  682. Basic.
  683. \par Iterator Invalidation
  684. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  685. equal to <code>end()</code>).
  686. \par Complexity
  687. Linear (in <code>std::distance(first, last)</code>; in
  688. <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
  689. is a <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  690. \sa <code>\link operator=(const circular_buffer_space_optimized&) operator=\endlink</code>,
  691. <code>\link assign(size_type, param_value_type) assign(size_type, const_reference)\endlink</code>,
  692. <code>\link assign(capacity_type, size_type, param_value_type)
  693. assign(capacity_type, size_type, const_reference)\endlink</code>,
  694. <code>assign(InputIterator, InputIterator)</code>
  695. */
  696. template <class InputIterator>
  697. void assign(capacity_type capacity_ctrl, InputIterator first, InputIterator last) {
  698. m_capacity_ctrl = capacity_ctrl;
  699. circular_buffer<T, Alloc>::assign(capacity_ctrl, first, last);
  700. }
  701. //! Swap the contents of two space-optimized circular-buffers.
  702. /*!
  703. \post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity and the amount of
  704. allocated memory in the internal buffer of <code>this</code> equal to the capacity and the amount of
  705. allocated memory of <code>cb</code> and vice versa.
  706. \param cb The <code>circular_buffer_space_optimized</code> whose content will be swapped.
  707. \throws Nothing.
  708. \par Exception Safety
  709. No-throw.
  710. \par Iterator Invalidation
  711. Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
  712. hand the iterators still point to the same elements but within another container. If you want to rely on
  713. this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG,
  714. otherwise an assertion will report an error if such invalidated iterator is used.)
  715. \par Complexity
  716. Constant (in the size of the <code>circular_buffer_space_optimized</code>).
  717. \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>,
  718. <code>swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)</code>
  719. */
  720. // Note link does not work right. Asked on Doxygen forum for advice 23 May 2103.
  721. void swap(circular_buffer_space_optimized<T, Alloc>& cb) BOOST_NOEXCEPT {
  722. std::swap(m_capacity_ctrl, cb.m_capacity_ctrl);
  723. circular_buffer<T, Alloc>::swap(cb);
  724. }
  725. //! Insert a new element at the end of the space optimized circular buffer.
  726. /*!
  727. \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
  728. If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
  729. capacity is <code>0</code>, nothing will be inserted.<br><br>
  730. The amount of allocated memory in the internal buffer may be predictively increased.
  731. \param item The element to be inserted.
  732. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  733. used).
  734. Whatever <code>T::T(const T&)</code> throws.
  735. \par Exception Safety
  736. Basic.
  737. \par Iterator Invalidation
  738. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  739. equal to <code>end()</code>).
  740. \par Complexity
  741. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  742. \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
  743. <code>pop_front()</code>
  744. */
  745. void push_back(param_value_type item) {
  746. check_low_capacity();
  747. circular_buffer<T, Alloc>::push_back(item);
  748. }
  749. //! Insert a new element at the end of the space optimized circular buffer.
  750. /*!
  751. \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
  752. If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
  753. capacity is <code>0</code>, nothing will be inserted.<br><br>
  754. The amount of allocated memory in the internal buffer may be predictively increased.
  755. \param item The element to be inserted.
  756. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  757. used).
  758. \par Exception Safety
  759. Basic.
  760. \par Iterator Invalidation
  761. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  762. equal to <code>end()</code>).
  763. \par Complexity
  764. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  765. \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
  766. <code>pop_front()</code>
  767. */
  768. void push_back(rvalue_type item) {
  769. check_low_capacity();
  770. circular_buffer<T, Alloc>::push_back(boost::move(item));
  771. }
  772. //! Insert a new element at the end of the space optimized circular buffer.
  773. /*!
  774. \post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
  775. If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
  776. capacity is <code>0</code>, nothing will be inserted.<br><br>
  777. The amount of allocated memory in the internal buffer may be predictively increased.
  778. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  779. used).
  780. Whatever <code>T::T()</code> throws.
  781. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  782. \par Exception Safety
  783. Basic.
  784. \par Iterator Invalidation
  785. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  786. equal to <code>end()</code>).
  787. \par Complexity
  788. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  789. \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
  790. <code>pop_front()</code>
  791. */
  792. void push_back() {
  793. check_low_capacity();
  794. circular_buffer<T, Alloc>::push_back();
  795. }
  796. //! Insert a new element at the beginning of the space optimized circular buffer.
  797. /*!
  798. \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
  799. If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
  800. capacity is <code>0</code>, nothing will be inserted.<br><br>
  801. The amount of allocated memory in the internal buffer may be predictively increased.
  802. \param item The element to be inserted.
  803. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  804. used).
  805. Whatever <code>T::T(const T&)</code> throws.
  806. \par Exception Safety
  807. Basic.
  808. \par Iterator Invalidation
  809. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  810. equal to <code>end()</code>).
  811. \par Complexity
  812. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  813. \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
  814. <code>pop_front()</code>
  815. */
  816. void push_front(param_value_type item) {
  817. check_low_capacity();
  818. circular_buffer<T, Alloc>::push_front(item);
  819. }
  820. //! Insert a new element at the beginning of the space optimized circular buffer.
  821. /*!
  822. \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
  823. If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
  824. capacity is <code>0</code>, nothing will be inserted.<br><br>
  825. The amount of allocated memory in the internal buffer may be predictively increased.
  826. \param item The element to be inserted.
  827. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  828. used).
  829. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  830. \par Exception Safety
  831. Basic.
  832. \par Iterator Invalidation
  833. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  834. equal to <code>end()</code>).
  835. \par Complexity
  836. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  837. \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
  838. <code>pop_front()</code>
  839. */
  840. void push_front(rvalue_type item) {
  841. check_low_capacity();
  842. circular_buffer<T, Alloc>::push_front(boost::move(item));
  843. }
  844. //! Insert a new element at the beginning of the space optimized circular buffer.
  845. /*!
  846. \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
  847. If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
  848. capacity is <code>0</code>, nothing will be inserted.<br><br>
  849. The amount of allocated memory in the internal buffer may be predictively increased.
  850. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  851. used).
  852. Whatever <code>T::T()</code> throws.
  853. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  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>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
  862. <code>pop_front()</code>
  863. */
  864. void push_front() {
  865. check_low_capacity();
  866. circular_buffer<T, Alloc>::push_front();
  867. }
  868. //! Remove the last element from the space optimized circular buffer.
  869. /*!
  870. \pre <code>!empty()</code>
  871. \post The last 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_front()</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_back() {
  886. circular_buffer<T, Alloc>::pop_back();
  887. check_high_capacity();
  888. }
  889. //! Remove the first element from the space optimized circular buffer.
  890. /*!
  891. \pre <code>!empty()</code>
  892. \post The first element is removed from the <code>circular_buffer_space_optimized</code>.<br><br>
  893. The amount of allocated memory in the internal buffer may be predictively decreased.
  894. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  895. used).
  896. \par Exception Safety
  897. Basic.
  898. \par Iterator Invalidation
  899. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  900. equal to <code>end()</code>).
  901. \par Complexity
  902. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  903. \sa <code>pop_back()</code>, <code>\link push_back() push_back(const_reference)\endlink</code>,
  904. <code>\link push_front() push_front(const_reference)\endlink</code>
  905. */
  906. void pop_front() {
  907. circular_buffer<T, Alloc>::pop_front();
  908. check_high_capacity();
  909. }
  910. //! Insert an element at the specified position.
  911. /*!
  912. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  913. end.
  914. \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
  915. If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
  916. the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  917. <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  918. nothing will be inserted.<br><br>
  919. The amount of allocated memory in the internal buffer may be predictively increased.
  920. \param pos An iterator specifying the position where the <code>item</code> will be inserted.
  921. \param item The element to be inserted.
  922. \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
  923. the <i>Effect</i>.)
  924. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  925. used).
  926. Whatever <code>T::T(const T&)</code> throws.
  927. Whatever <code>T::operator = (const T&)</code> throws.
  928. \par Exception Safety
  929. Basic.
  930. \par Iterator Invalidation
  931. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  932. equal to <code>end()</code>).
  933. \par Complexity
  934. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  935. \sa <code>\link insert(iterator, size_type, param_value_type)
  936. insert(iterator, size_type, value_type)\endlink</code>,
  937. <code>insert(iterator, InputIterator, InputIterator)</code>,
  938. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  939. <code>\link rinsert(iterator, size_type, param_value_type)
  940. rinsert(iterator, size_type, value_type)\endlink</code>,
  941. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  942. */
  943. iterator insert(iterator pos, param_value_type item) {
  944. size_type index = pos - begin();
  945. check_low_capacity();
  946. return circular_buffer<T, Alloc>::insert(begin() + index, item);
  947. }
  948. //! Insert an element at the specified position.
  949. /*!
  950. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  951. end.
  952. \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
  953. If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
  954. the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  955. <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  956. nothing will be inserted.<br><br>
  957. The amount of allocated memory in the internal buffer may be predictively increased.
  958. \param pos An iterator specifying the position where the <code>item</code> will be inserted.
  959. \param item The element to be inserted.
  960. \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
  961. the <i>Effect</i>.)
  962. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  963. used).
  964. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  965. \par Exception Safety
  966. Basic.
  967. \par Iterator Invalidation
  968. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  969. equal to <code>end()</code>).
  970. \par Complexity
  971. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  972. \sa <code>\link insert(iterator, size_type, param_value_type)
  973. insert(iterator, size_type, value_type)\endlink</code>,
  974. <code>insert(iterator, InputIterator, InputIterator)</code>,
  975. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  976. <code>\link rinsert(iterator, size_type, param_value_type)
  977. rinsert(iterator, size_type, value_type)\endlink</code>,
  978. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  979. */
  980. iterator insert(iterator pos, rvalue_type item) {
  981. size_type index = pos - begin();
  982. check_low_capacity();
  983. return circular_buffer<T, Alloc>::insert(begin() + index, boost::move(item));
  984. }
  985. //! Insert an element at the specified position.
  986. /*!
  987. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  988. end.
  989. \post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
  990. If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
  991. the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  992. <code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  993. nothing will be inserted.<br><br>
  994. The amount of allocated memory in the internal buffer may be predictively increased.
  995. \param pos An iterator specifying the position where the <code>item</code> will be inserted.
  996. \return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
  997. the <i>Effect</i>.)
  998. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  999. used).
  1000. Whatever <code>T::T()</code> throws.
  1001. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  1002. \par Exception Safety
  1003. Basic.
  1004. \par Iterator Invalidation
  1005. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1006. equal to <code>end()</code>).
  1007. \par Complexity
  1008. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1009. \sa <code>\link insert(iterator, size_type, param_value_type)
  1010. insert(iterator, size_type, value_type)\endlink</code>,
  1011. <code>insert(iterator, InputIterator, InputIterator)</code>,
  1012. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  1013. <code>\link rinsert(iterator, size_type, param_value_type)
  1014. rinsert(iterator, size_type, value_type)\endlink</code>,
  1015. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  1016. */
  1017. iterator insert(iterator pos) {
  1018. size_type index = pos - begin();
  1019. check_low_capacity();
  1020. return circular_buffer<T, Alloc>::insert(begin() + index);
  1021. }
  1022. //! Insert <code>n</code> copies of the <code>item</code> at the specified position.
  1023. /*!
  1024. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1025. end.
  1026. \post The number of <code>min[n, (pos - begin()) + reserve()]</code> elements will be inserted at the position
  1027. <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0, n - reserve()]]</code> elements will
  1028. be overwritten at the beginning of the <code>circular_buffer_space_optimized</code>.<br>(See
  1029. <i>Example</i> for the explanation.)<br><br>
  1030. The amount of allocated memory in the internal buffer may be predictively increased.
  1031. \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
  1032. \param n The number of <code>item</code>s the to be inserted.
  1033. \param item The element whose copies will be inserted.
  1034. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1035. used).
  1036. Whatever <code>T::T(const T&)</code> throws.
  1037. Whatever <code>T::operator = (const T&)</code> throws.
  1038. \par Exception Safety
  1039. Basic.
  1040. \par Iterator Invalidation
  1041. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1042. equal to <code>end()</code>).
  1043. \par Complexity
  1044. Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
  1045. \par Example
  1046. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1047. internal buffer may look like the one below.<br><br>
  1048. <code>|1|2|3|4| | |</code><br>
  1049. <code>p ___^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
  1050. <code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
  1051. <code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves
  1052. the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br>
  1053. <br>For comparison if the capacity would not be preserved the internal buffer would then result in
  1054. <code>|1|2|0|0|0|0|0|3|4|</code>.
  1055. \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1056. <code>insert(iterator, InputIterator, InputIterator)</code>,
  1057. <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  1058. <code>\link rinsert(iterator, size_type, param_value_type)
  1059. rinsert(iterator, size_type, value_type)\endlink</code>,
  1060. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  1061. */
  1062. void insert(iterator pos, size_type n, param_value_type item) {
  1063. size_type index = pos - begin();
  1064. check_low_capacity(n);
  1065. circular_buffer<T, Alloc>::insert(begin() + index, n, item);
  1066. }
  1067. //! Insert the range <code>[first, last)</code> at the specified position.
  1068. /*!
  1069. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1070. end.<br>Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
  1071. requirements of an <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
  1072. \post Elements from the range
  1073. <code>[first + max[0, distance(first, last) - (pos - begin()) - reserve()], last)</code> will be
  1074. inserted at the position <code>pos</code>.<br>The number of <code>min[pos - begin(), max[0,
  1075. distance(first, last) - reserve()]]</code> elements will be overwritten at the beginning of the
  1076. <code>circular_buffer_space_optimized</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
  1077. The amount of allocated memory in the internal buffer may be predictively increased.
  1078. \param pos An iterator specifying the position where the range will be inserted.
  1079. \param first The beginning of the range to be inserted.
  1080. \param last The end of the range to be inserted.
  1081. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1082. used).
  1083. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  1084. \par Exception Safety
  1085. Basic.
  1086. \par Iterator Invalidation
  1087. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1088. equal to <code>end()</code>).
  1089. \par Complexity
  1090. Linear (in <code>[size() + std::distance(first, last)]</code>; in
  1091. <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
  1092. <code>InputIterator</code> is a
  1093. <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  1094. \par Example
  1095. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1096. internal buffer may look like the one below.<br><br>
  1097. <code>|1|2|3|4| | |</code><br>
  1098. <code>p ___^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
  1099. <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
  1100. actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the
  1101. specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due
  1102. to the fact the insert operation preserves the capacity. After insertion the internal buffer looks like
  1103. this:<br><br><code>|6|7|8|9|3|4|</code><br><br>For comparison if the capacity would not be preserved the
  1104. internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
  1105. \sa <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1106. <code>\link insert(iterator, size_type, param_value_type)
  1107. insert(iterator, size_type, value_type)\endlink</code>, <code>\link rinsert(iterator, param_value_type)
  1108. rinsert(iterator, value_type)\endlink</code>, <code>\link rinsert(iterator, size_type, param_value_type)
  1109. rinsert(iterator, size_type, value_type)\endlink</code>,
  1110. <code>rinsert(iterator, InputIterator, InputIterator)</code>
  1111. */
  1112. template <class InputIterator>
  1113. void insert(iterator pos, InputIterator first, InputIterator last) {
  1114. insert(pos, first, last, is_integral<InputIterator>());
  1115. }
  1116. //! Insert an element before the specified position.
  1117. /*!
  1118. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1119. end.
  1120. \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
  1121. If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
  1122. <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  1123. <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  1124. nothing will be inserted.<br><br>
  1125. The amount of allocated memory in the internal buffer may be predictively increased.
  1126. \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
  1127. \param item The element to be inserted.
  1128. \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
  1129. the <i>Effect</i>.)
  1130. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1131. used).
  1132. Whatever <code>T::T(const T&)</code> throws.
  1133. Whatever <code>T::operator = (const T&)</code> throws.
  1134. \par Exception Safety
  1135. Basic.
  1136. \par Iterator Invalidation
  1137. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1138. equal to <code>end()</code>).
  1139. \par Complexity
  1140. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1141. \sa <code>\link rinsert(iterator, size_type, param_value_type)
  1142. rinsert(iterator, size_type, value_type)\endlink</code>,
  1143. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1144. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1145. <code>\link insert(iterator, size_type, param_value_type)
  1146. insert(iterator, size_type, value_type)\endlink</code>,
  1147. <code>insert(iterator, InputIterator, InputIterator)</code>
  1148. */
  1149. iterator rinsert(iterator pos, param_value_type item) {
  1150. size_type index = pos - begin();
  1151. check_low_capacity();
  1152. return circular_buffer<T, Alloc>::rinsert(begin() + index, item);
  1153. }
  1154. //! Insert an element before the specified position.
  1155. /*!
  1156. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1157. end.
  1158. \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
  1159. If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
  1160. <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  1161. <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  1162. nothing will be inserted.<br><br>
  1163. The amount of allocated memory in the internal buffer may be predictively increased.
  1164. \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
  1165. \param item The element to be inserted.
  1166. \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
  1167. the <i>Effect</i>.)
  1168. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1169. used).
  1170. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  1171. \par Exception Safety
  1172. Basic.
  1173. \par Iterator Invalidation
  1174. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1175. equal to <code>end()</code>).
  1176. \par Complexity
  1177. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1178. \sa <code>\link rinsert(iterator, size_type, param_value_type)
  1179. rinsert(iterator, size_type, value_type)\endlink</code>,
  1180. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1181. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1182. <code>\link insert(iterator, size_type, param_value_type)
  1183. insert(iterator, size_type, value_type)\endlink</code>,
  1184. <code>insert(iterator, InputIterator, InputIterator)</code>
  1185. */
  1186. iterator rinsert(iterator pos, rvalue_type item) {
  1187. size_type index = pos - begin();
  1188. check_low_capacity();
  1189. return circular_buffer<T, Alloc>::rinsert(begin() + index, boost::move(item));
  1190. }
  1191. //! Insert an element before the specified position.
  1192. /*!
  1193. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1194. end.
  1195. \post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
  1196. If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
  1197. <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
  1198. <code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
  1199. nothing will be inserted.<br><br>
  1200. The amount of allocated memory in the internal buffer may be predictively increased.
  1201. \param pos An iterator specifying the position before which the <code>item</code> will be inserted.
  1202. \return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
  1203. the <i>Effect</i>.)
  1204. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1205. used).
  1206. Whatever <code>T::T()</code> throws.
  1207. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
  1208. \par Exception Safety
  1209. Basic.
  1210. \par Iterator Invalidation
  1211. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1212. equal to <code>end()</code>).
  1213. \par Complexity
  1214. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1215. \sa <code>\link rinsert(iterator, size_type, param_value_type)
  1216. rinsert(iterator, size_type, value_type)\endlink</code>,
  1217. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1218. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1219. <code>\link insert(iterator, size_type, param_value_type)
  1220. insert(iterator, size_type, value_type)\endlink</code>,
  1221. <code>insert(iterator, InputIterator, InputIterator)</code>
  1222. */
  1223. iterator rinsert(iterator pos) {
  1224. size_type index = pos - begin();
  1225. check_low_capacity();
  1226. return circular_buffer<T, Alloc>::rinsert(begin() + index);
  1227. }
  1228. //! Insert <code>n</code> copies of the <code>item</code> before the specified position.
  1229. /*!
  1230. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1231. end.
  1232. \post The number of <code>min[n, (end() - pos) + reserve()]</code> elements will be inserted before the
  1233. position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0, n - reserve()]]</code> elements
  1234. will be overwritten at the end of the <code>circular_buffer_space_optimized</code>.<br>(See
  1235. <i>Example</i> for the explanation.)<br><br>
  1236. The amount of allocated memory in the internal buffer may be predictively increased.
  1237. \param pos An iterator specifying the position where the <code>item</code>s will be inserted.
  1238. \param n The number of <code>item</code>s the to be inserted.
  1239. \param item The element whose copies will be inserted.
  1240. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1241. used).
  1242. Whatever <code>T::T(const T&)</code> throws.
  1243. Whatever <code>T::operator = (const T&)</code> throws.
  1244. \par Exception Safety
  1245. Basic.
  1246. \par Iterator Invalidation
  1247. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1248. equal to <code>end()</code>).
  1249. \par Complexity
  1250. Linear (in <code>min[capacity().%capacity(), size() + n]</code>).
  1251. \par Example
  1252. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1253. internal buffer may look like the one below.<br><br>
  1254. <code>|1|2|3|4| | |</code><br>
  1255. <code>p ___^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
  1256. <code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
  1257. <code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves
  1258. the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br>
  1259. <br>For comparison if the capacity would not be preserved the internal buffer would then result in
  1260. <code>|1|2|0|0|0|0|0|3|4|</code>.
  1261. \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  1262. <code>rinsert(iterator, InputIterator, InputIterator)</code>,
  1263. <code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
  1264. <code>\link insert(iterator, size_type, param_value_type)
  1265. insert(iterator, size_type, value_type)\endlink</code>,
  1266. <code>insert(iterator, InputIterator, InputIterator)</code>
  1267. */
  1268. void rinsert(iterator pos, size_type n, param_value_type item) {
  1269. size_type index = pos - begin();
  1270. check_low_capacity(n);
  1271. circular_buffer<T, Alloc>::rinsert(begin() + index, n, item);
  1272. }
  1273. //! Insert the range <code>[first, last)</code> before the specified position.
  1274. /*!
  1275. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
  1276. end.<br>
  1277. Valid range <code>[first, last)</code> where <code>first</code> and <code>last</code> meet the
  1278. requirements of an <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.
  1279. \post Elements from the range
  1280. <code>[first, last - max[0, distance(first, last) - (end() - pos) - reserve()])</code> will be inserted
  1281. before the position <code>pos</code>.<br>The number of <code>min[end() - pos, max[0,
  1282. distance(first, last) - reserve()]]</code> elements will be overwritten at the end of the
  1283. <code>circular_buffer</code>.<br>(See <i>Example</i> for the explanation.)<br><br>
  1284. The amount of allocated memory in the internal buffer may be predictively increased.
  1285. \param pos An iterator specifying the position where the range will be inserted.
  1286. \param first The beginning of the range to be inserted.
  1287. \param last The end of the range to be inserted.
  1288. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1289. used).
  1290. Whatever <code>T::T(const T&)</code> throws.
  1291. Whatever <code>T::operator = (const T&)</code> throws.
  1292. \par Exception Safety
  1293. Basic.
  1294. \par Iterator Invalidation
  1295. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1296. equal to <code>end()</code>).
  1297. \par Complexity
  1298. Linear (in <code>[size() + std::distance(first, last)]</code>; in
  1299. <code>min[capacity().%capacity(), size() + std::distance(first, last)]</code> if the
  1300. <code>InputIterator</code> is a
  1301. <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  1302. \par Example
  1303. Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
  1304. internal buffer may look like the one below.<br><br>
  1305. <code>|1|2|3|4| | |</code><br>
  1306. <code>p ___^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
  1307. <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
  1308. actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the
  1309. specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due
  1310. to the fact the rinsert operation preserves the capacity. After insertion the internal buffer looks like
  1311. this:<br><br><code>|1|2|5|6|7|8|</code><br><br>For comparison if the capacity would not be preserved the
  1312. internal buffer would then result in <code>|1|2|5|6|7|8|9|3|4|</code>.
  1313. \sa <code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
  1314. <code>\link rinsert(iterator, size_type, param_value_type)
  1315. rinsert(iterator, size_type, value_type)\endlink</code>, <code>\link insert(iterator, param_value_type)
  1316. insert(iterator, value_type)\endlink</code>, <code>\link insert(iterator, size_type, param_value_type)
  1317. insert(iterator, size_type, value_type)\endlink</code>,
  1318. <code>insert(iterator, InputIterator, InputIterator)</code>
  1319. */
  1320. template <class InputIterator>
  1321. void rinsert(iterator pos, InputIterator first, InputIterator last) {
  1322. rinsert(pos, first, last, is_integral<InputIterator>());
  1323. }
  1324. //! Remove an element at the specified position.
  1325. /*!
  1326. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
  1327. an <code>end()</code>).
  1328. \post The element at the position <code>pos</code> is removed.<br><br>
  1329. The amount of allocated memory in the internal buffer may be predictively decreased.
  1330. \param pos An iterator pointing at the element to be removed.
  1331. \return Iterator to the first element remaining beyond the removed element or <code>end()</code> if no such
  1332. element exists.
  1333. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1334. used).
  1335. Whatever <code>T::operator = (const T&)</code> throws or
  1336. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1337. \par Exception Safety
  1338. Basic.
  1339. \par Iterator Invalidation
  1340. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1341. equal to <code>end()</code>).
  1342. \par Complexity
  1343. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1344. \sa <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
  1345. <code>rerase(iterator, iterator)</code>, <code>clear()</code>
  1346. */
  1347. iterator erase(iterator pos) {
  1348. iterator it = circular_buffer<T, Alloc>::erase(pos);
  1349. size_type index = it - begin();
  1350. check_high_capacity();
  1351. return begin() + index;
  1352. }
  1353. //! Erase the range <code>[first, last)</code>.
  1354. /*!
  1355. \pre Valid range <code>[first, last)</code>.
  1356. \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
  1357. nothing is removed.)<br><br>
  1358. The amount of allocated memory in the internal buffer may be predictively decreased.
  1359. \param first The beginning of the range to be removed.
  1360. \param last The end of the range to be removed.
  1361. \return Iterator to the first element remaining beyond the removed elements or <code>end()</code> if no such
  1362. element exists.
  1363. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1364. used).
  1365. Whatever <code>T::operator = (const T&)</code> throws or
  1366. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1367. \par Exception Safety
  1368. Basic.
  1369. \par Iterator Invalidation
  1370. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1371. equal to <code>end()</code>).
  1372. \par Complexity
  1373. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1374. \sa <code>erase(iterator)</code>, <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
  1375. <code>clear()</code>
  1376. */
  1377. iterator erase(iterator first, iterator last) {
  1378. iterator it = circular_buffer<T, Alloc>::erase(first, last);
  1379. size_type index = it - begin();
  1380. check_high_capacity();
  1381. return begin() + index;
  1382. }
  1383. //! Remove an element at the specified position.
  1384. /*!
  1385. \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> (but not
  1386. an <code>end()</code>).<br><br>
  1387. The amount of allocated memory in the internal buffer may be predictively decreased.
  1388. \post The element at the position <code>pos</code> is removed.
  1389. \param pos An iterator pointing at the element to be removed.
  1390. \return Iterator to the first element remaining in front of the removed element or <code>begin()</code> if no
  1391. such element exists.
  1392. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1393. used).
  1394. Whatever <code>T::operator = (const T&)</code> throws or
  1395. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1396. \par Exception Safety
  1397. Basic.
  1398. \par Iterator Invalidation
  1399. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1400. equal to <code>end()</code>).
  1401. \par Complexity
  1402. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1403. \note Basically there is no difference between <code>erase(iterator)</code> and this method. It is implemented
  1404. only for consistency with the base <code>circular_buffer</code>.
  1405. \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
  1406. <code>rerase(iterator, iterator)</code>, <code>clear()</code>
  1407. */
  1408. iterator rerase(iterator pos) {
  1409. iterator it = circular_buffer<T, Alloc>::rerase(pos);
  1410. size_type index = it - begin();
  1411. check_high_capacity();
  1412. return begin() + index;
  1413. }
  1414. //! Erase the range <code>[first, last)</code>.
  1415. /*!
  1416. \pre Valid range <code>[first, last)</code>.
  1417. \post The elements from the range <code>[first, last)</code> are removed. (If <code>first == last</code>
  1418. nothing is removed.)<br><br>
  1419. The amount of allocated memory in the internal buffer may be predictively decreased.
  1420. \param first The beginning of the range to be removed.
  1421. \param last The end of the range to be removed.
  1422. \return Iterator to the first element remaining in front of the removed elements or <code>begin()</code> if no
  1423. such element exists.
  1424. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1425. used).
  1426. Whatever <code>T::operator = (const T&)</code> throws or
  1427. nothing if <code>T::operator = (T&&)</code> is noexcept.
  1428. \par Exception Safety
  1429. Basic.
  1430. \par Iterator Invalidation
  1431. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1432. equal to <code>end()</code>).
  1433. \par Complexity
  1434. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1435. \note Basically there is no difference between <code>erase(iterator, iterator)</code> and this method. It is
  1436. implemented only for consistency with the base
  1437. <code><circular_buffer</code>.
  1438. \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
  1439. <code>clear()</code>
  1440. */
  1441. iterator rerase(iterator first, iterator last) {
  1442. iterator it = circular_buffer<T, Alloc>::rerase(first, last);
  1443. size_type index = it - begin();
  1444. check_high_capacity();
  1445. return begin() + index;
  1446. }
  1447. //! Remove all stored elements from the space optimized circular buffer.
  1448. /*!
  1449. \post <code>size() == 0</code><br><br>
  1450. The amount of allocated memory in the internal buffer may be predictively decreased.
  1451. \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
  1452. used).
  1453. \par Exception Safety
  1454. Basic.
  1455. \par Iterator Invalidation
  1456. Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
  1457. equal to <code>end()</code>).
  1458. \par Complexity
  1459. Linear (in the size of the <code>circular_buffer_space_optimized</code>).
  1460. \sa <code>~circular_buffer_space_optimized()</code>, <code>erase(iterator)</code>,
  1461. <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
  1462. <code>rerase(iterator, iterator)</code>
  1463. */
  1464. void clear() { erase(begin(), end()); }
  1465. private:
  1466. // Helper methods
  1467. //! Adjust the amount of allocated memory.
  1468. void adjust_min_capacity() {
  1469. if (m_capacity_ctrl.min_capacity() > circular_buffer<T, Alloc>::capacity())
  1470. circular_buffer<T, Alloc>::set_capacity(m_capacity_ctrl.min_capacity());
  1471. else
  1472. check_high_capacity();
  1473. }
  1474. //! Ensure the reserve for possible growth up.
  1475. size_type ensure_reserve(size_type new_capacity, size_type buffer_size) const {
  1476. if (buffer_size + new_capacity / 5 >= new_capacity)
  1477. new_capacity *= 2; // ensure at least 20% reserve
  1478. if (new_capacity > m_capacity_ctrl)
  1479. return m_capacity_ctrl;
  1480. return new_capacity;
  1481. }
  1482. //! Check for low capacity.
  1483. /*
  1484. \post If the capacity is low it will be increased.
  1485. */
  1486. void check_low_capacity(size_type n = 1) {
  1487. size_type new_size = size() + n;
  1488. size_type new_capacity = circular_buffer<T, Alloc>::capacity();
  1489. if (new_size > new_capacity) {
  1490. if (new_capacity == 0)
  1491. new_capacity = 1;
  1492. for (; new_size > new_capacity; new_capacity *= 2) {}
  1493. circular_buffer<T, Alloc>::set_capacity(
  1494. ensure_reserve(new_capacity, new_size));
  1495. }
  1496. #if BOOST_CB_ENABLE_DEBUG
  1497. this->invalidate_iterators_except(end());
  1498. #endif
  1499. }
  1500. //! Check for high capacity.
  1501. /*
  1502. \post If the capacity is high it will be decreased.
  1503. */
  1504. void check_high_capacity() {
  1505. size_type new_capacity = circular_buffer<T, Alloc>::capacity();
  1506. while (new_capacity / 3 >= size()) { // (new_capacity / 3) -> avoid oscillations
  1507. new_capacity /= 2;
  1508. if (new_capacity <= m_capacity_ctrl.min_capacity()) {
  1509. new_capacity = m_capacity_ctrl.min_capacity();
  1510. break;
  1511. }
  1512. }
  1513. circular_buffer<T, Alloc>::set_capacity(
  1514. ensure_reserve(new_capacity, size()));
  1515. #if BOOST_CB_ENABLE_DEBUG
  1516. this->invalidate_iterators_except(end());
  1517. #endif
  1518. }
  1519. //! Specialized method for reducing the capacity.
  1520. void reduce_capacity(const true_type&) {
  1521. circular_buffer<T, Alloc>::set_capacity((std::max)(m_capacity_ctrl.min_capacity(), size()));
  1522. }
  1523. //! Specialized method for reducing the capacity.
  1524. void reduce_capacity(const false_type&) {}
  1525. //! Determine the initial capacity.
  1526. static size_type init_capacity(const capacity_type& capacity_ctrl, size_type n) {
  1527. BOOST_CB_ASSERT(capacity_ctrl.capacity() >= n); // check for capacity lower than n
  1528. return (std::max)(capacity_ctrl.min_capacity(), n);
  1529. }
  1530. //! Specialized method for determining the initial capacity.
  1531. template <class IntegralType>
  1532. static size_type init_capacity(const capacity_type& capacity_ctrl, IntegralType n, IntegralType,
  1533. const true_type&) {
  1534. return init_capacity(capacity_ctrl, static_cast<size_type>(n));
  1535. }
  1536. //! Specialized method for determining the initial capacity.
  1537. template <class Iterator>
  1538. static size_type init_capacity(const capacity_type& capacity_ctrl, Iterator first, Iterator last,
  1539. const false_type&) {
  1540. BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
  1541. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
  1542. return init_capacity(capacity_ctrl, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
  1543. #else
  1544. return init_capacity(
  1545. capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
  1546. #endif
  1547. }
  1548. //! Specialized method for determining the initial capacity.
  1549. template <class InputIterator>
  1550. static size_type init_capacity(const capacity_type& capacity_ctrl, InputIterator, InputIterator,
  1551. const std::input_iterator_tag&) {
  1552. return capacity_ctrl.capacity();
  1553. }
  1554. //! Specialized method for determining the initial capacity.
  1555. template <class ForwardIterator>
  1556. static size_type init_capacity(const capacity_type& capacity_ctrl, ForwardIterator first, ForwardIterator last,
  1557. const std::forward_iterator_tag&) {
  1558. BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
  1559. return (std::max)(capacity_ctrl.min_capacity(),
  1560. (std::min)(capacity_ctrl.capacity(), static_cast<size_type>(std::distance(first, last))));
  1561. }
  1562. //! Specialized insert method.
  1563. template <class IntegralType>
  1564. void insert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
  1565. insert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
  1566. }
  1567. //! Specialized insert method.
  1568. template <class Iterator>
  1569. void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
  1570. size_type index = pos - begin();
  1571. check_low_capacity(std::distance(first, last));
  1572. circular_buffer<T, Alloc>::insert(begin() + index, first, last);
  1573. }
  1574. //! Specialized rinsert method.
  1575. template <class IntegralType>
  1576. void rinsert(const iterator& pos, IntegralType n, IntegralType item, const true_type&) {
  1577. rinsert(pos, static_cast<size_type>(n), static_cast<value_type>(item));
  1578. }
  1579. //! Specialized rinsert method.
  1580. template <class Iterator>
  1581. void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
  1582. size_type index = pos - begin();
  1583. check_low_capacity(std::distance(first, last));
  1584. circular_buffer<T, Alloc>::rinsert(begin() + index, first, last);
  1585. }
  1586. };
  1587. // Non-member functions
  1588. //! Test two space optimized circular buffers for equality.
  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 lhs.size() == rhs.size() &&
  1593. std::equal(lhs.begin(), lhs.end(), rhs.begin());
  1594. }
  1595. //! Lexicographical comparison.
  1596. template <class T, class Alloc>
  1597. inline bool operator < (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1598. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1599. return std::lexicographical_compare(
  1600. lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  1601. }
  1602. #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
  1603. //! Test two space optimized circular buffers for non-equality.
  1604. template <class T, class Alloc>
  1605. inline bool operator != (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1606. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1607. return !(lhs == rhs);
  1608. }
  1609. //! Lexicographical comparison.
  1610. template <class T, class Alloc>
  1611. inline bool operator > (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1612. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1613. return rhs < lhs;
  1614. }
  1615. //! Lexicographical comparison.
  1616. template <class T, class Alloc>
  1617. inline bool operator <= (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1618. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1619. return !(rhs < lhs);
  1620. }
  1621. //! Lexicographical comparison.
  1622. template <class T, class Alloc>
  1623. inline bool operator >= (const circular_buffer_space_optimized<T, Alloc>& lhs,
  1624. const circular_buffer_space_optimized<T, Alloc>& rhs) {
  1625. return !(lhs < rhs);
  1626. }
  1627. //! Swap the contents of two space optimized circular buffers.
  1628. template <class T, class Alloc>
  1629. inline void swap(circular_buffer_space_optimized<T, Alloc>& lhs,
  1630. circular_buffer_space_optimized<T, Alloc>& rhs) BOOST_NOEXCEPT {
  1631. lhs.swap(rhs);
  1632. }
  1633. #endif // #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
  1634. } // namespace boost
  1635. #endif // #if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)