flat_set.hpp 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_FLAT_SET_HPP
  11. #define BOOST_CONTAINER_FLAT_SET_HPP
  12. #if defined(_MSC_VER)
  13. # pragma once
  14. #endif
  15. #include <boost/container/detail/config_begin.hpp>
  16. #include <boost/container/detail/workaround.hpp>
  17. #include <boost/container/container_fwd.hpp>
  18. #include <utility>
  19. #include <functional>
  20. #include <memory>
  21. #include <boost/container/detail/flat_tree.hpp>
  22. #include <boost/container/detail/mpl.hpp>
  23. #include <boost/container/allocator_traits.hpp>
  24. #include <boost/move/utility.hpp>
  25. #include <boost/move/detail/move_helpers.hpp>
  26. namespace boost {
  27. namespace container {
  28. /// @cond
  29. // Forward declarations of operators < and ==, needed for friend declaration.
  30. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  31. template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
  32. #else
  33. template <class Key, class Compare, class Allocator>
  34. #endif
  35. class flat_set;
  36. template <class Key, class Compare, class Allocator>
  37. inline bool operator==(const flat_set<Key,Compare,Allocator>& x,
  38. const flat_set<Key,Compare,Allocator>& y);
  39. template <class Key, class Compare, class Allocator>
  40. inline bool operator<(const flat_set<Key,Compare,Allocator>& x,
  41. const flat_set<Key,Compare,Allocator>& y);
  42. /// @endcond
  43. //! flat_set is a Sorted Associative Container that stores objects of type Key.
  44. //! It is also a Unique Associative Container, meaning that no two elements are the same.
  45. //!
  46. //! flat_set is similar to std::set but it's implemented like an ordered vector.
  47. //! This means that inserting a new element into a flat_set invalidates
  48. //! previous iterators and references
  49. //!
  50. //! Erasing an element of a flat_set invalidates iterators and references
  51. //! pointing to elements that come after (their keys are bigger) the erased element.
  52. //!
  53. //! This container provides random-access iterators.
  54. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  55. template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
  56. #else
  57. template <class Key, class Compare, class Allocator>
  58. #endif
  59. class flat_set
  60. {
  61. /// @cond
  62. private:
  63. BOOST_COPYABLE_AND_MOVABLE(flat_set)
  64. typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> tree_t;
  65. tree_t m_flat_tree; // flat tree representing flat_set
  66. /// @endcond
  67. public:
  68. //////////////////////////////////////////////
  69. //
  70. // types
  71. //
  72. //////////////////////////////////////////////
  73. typedef Key key_type;
  74. typedef Key value_type;
  75. typedef Compare key_compare;
  76. typedef Compare value_compare;
  77. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  78. typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
  79. typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
  80. typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
  81. typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
  82. typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
  83. typedef Allocator allocator_type;
  84. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
  85. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator;
  86. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator;
  87. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator;
  88. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator;
  89. public:
  90. //////////////////////////////////////////////
  91. //
  92. // construct/copy/destroy
  93. //
  94. //////////////////////////////////////////////
  95. //! <b>Effects</b>: Default constructs an empty flat_set.
  96. //!
  97. //! <b>Complexity</b>: Constant.
  98. explicit flat_set()
  99. : m_flat_tree()
  100. {}
  101. //! <b>Effects</b>: Constructs an empty flat_set using the specified
  102. //! comparison object and allocator.
  103. //!
  104. //! <b>Complexity</b>: Constant.
  105. explicit flat_set(const Compare& comp,
  106. const allocator_type& a = allocator_type())
  107. : m_flat_tree(comp, a)
  108. {}
  109. //! <b>Effects</b>: Constructs an empty flat_set using the specified allocator.
  110. //!
  111. //! <b>Complexity</b>: Constant.
  112. explicit flat_set(const allocator_type& a)
  113. : m_flat_tree(a)
  114. {}
  115. //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
  116. //! allocator, and inserts elements from the range [first ,last ).
  117. //!
  118. //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
  119. //! comp and otherwise N logN, where N is last - first.
  120. template <class InputIterator>
  121. flat_set(InputIterator first, InputIterator last,
  122. const Compare& comp = Compare(),
  123. const allocator_type& a = allocator_type())
  124. : m_flat_tree(true, first, last, comp, a)
  125. {}
  126. //! <b>Effects</b>: Constructs an empty flat_set using the specified comparison object and
  127. //! allocator, and inserts elements from the ordered unique range [first ,last). This function
  128. //! is more efficient than the normal range creation for ordered ranges.
  129. //!
  130. //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
  131. //! unique values.
  132. //!
  133. //! <b>Complexity</b>: Linear in N.
  134. //!
  135. //! <b>Note</b>: Non-standard extension.
  136. template <class InputIterator>
  137. flat_set(ordered_unique_range_t, InputIterator first, InputIterator last,
  138. const Compare& comp = Compare(),
  139. const allocator_type& a = allocator_type())
  140. : m_flat_tree(ordered_range, first, last, comp, a)
  141. {}
  142. //! <b>Effects</b>: Copy constructs a set.
  143. //!
  144. //! <b>Complexity</b>: Linear in x.size().
  145. flat_set(const flat_set& x)
  146. : m_flat_tree(x.m_flat_tree)
  147. {}
  148. //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
  149. //!
  150. //! <b>Complexity</b>: Constant.
  151. //!
  152. //! <b>Postcondition</b>: x is emptied.
  153. flat_set(BOOST_RV_REF(flat_set) mx)
  154. : m_flat_tree(boost::move(mx.m_flat_tree))
  155. {}
  156. //! <b>Effects</b>: Copy constructs a set using the specified allocator.
  157. //!
  158. //! <b>Complexity</b>: Linear in x.size().
  159. flat_set(const flat_set& x, const allocator_type &a)
  160. : m_flat_tree(x.m_flat_tree, a)
  161. {}
  162. //! <b>Effects</b>: Move constructs a set using the specified allocator.
  163. //! Constructs *this using x's resources.
  164. //!
  165. //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
  166. flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a)
  167. : m_flat_tree(boost::move(mx.m_flat_tree), a)
  168. {}
  169. //! <b>Effects</b>: Makes *this a copy of x.
  170. //!
  171. //! <b>Complexity</b>: Linear in x.size().
  172. flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
  173. { m_flat_tree = x.m_flat_tree; return *this; }
  174. //! <b>Effects</b>: Makes *this a copy of the previous value of xx.
  175. //!
  176. //! <b>Complexity</b>: Linear in x.size().
  177. flat_set& operator=(BOOST_RV_REF(flat_set) mx)
  178. { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
  179. //! <b>Effects</b>: Returns a copy of the Allocator that
  180. //! was passed to the object's constructor.
  181. //!
  182. //! <b>Complexity</b>: Constant.
  183. allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
  184. { return m_flat_tree.get_allocator(); }
  185. //! <b>Effects</b>: Returns a reference to the internal allocator.
  186. //!
  187. //! <b>Throws</b>: Nothing
  188. //!
  189. //! <b>Complexity</b>: Constant.
  190. //!
  191. //! <b>Note</b>: Non-standard extension.
  192. stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
  193. { return m_flat_tree.get_stored_allocator(); }
  194. //! <b>Effects</b>: Returns a reference to the internal allocator.
  195. //!
  196. //! <b>Throws</b>: Nothing
  197. //!
  198. //! <b>Complexity</b>: Constant.
  199. //!
  200. //! <b>Note</b>: Non-standard extension.
  201. const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
  202. { return m_flat_tree.get_stored_allocator(); }
  203. //////////////////////////////////////////////
  204. //
  205. // iterators
  206. //
  207. //////////////////////////////////////////////
  208. //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
  209. //!
  210. //! <b>Throws</b>: Nothing.
  211. //!
  212. //! <b>Complexity</b>: Constant.
  213. iterator begin() BOOST_CONTAINER_NOEXCEPT
  214. { return m_flat_tree.begin(); }
  215. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
  216. //!
  217. //! <b>Throws</b>: Nothing.
  218. //!
  219. //! <b>Complexity</b>: Constant.
  220. const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
  221. { return m_flat_tree.begin(); }
  222. //! <b>Effects</b>: Returns an iterator to the end of the container.
  223. //!
  224. //! <b>Throws</b>: Nothing.
  225. //!
  226. //! <b>Complexity</b>: Constant.
  227. iterator end() BOOST_CONTAINER_NOEXCEPT
  228. { return m_flat_tree.end(); }
  229. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
  230. //!
  231. //! <b>Throws</b>: Nothing.
  232. //!
  233. //! <b>Complexity</b>: Constant.
  234. const_iterator end() const BOOST_CONTAINER_NOEXCEPT
  235. { return m_flat_tree.end(); }
  236. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  237. //! of the reversed container.
  238. //!
  239. //! <b>Throws</b>: Nothing.
  240. //!
  241. //! <b>Complexity</b>: Constant.
  242. reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
  243. { return m_flat_tree.rbegin(); }
  244. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  245. //! of the reversed container.
  246. //!
  247. //! <b>Throws</b>: Nothing.
  248. //!
  249. //! <b>Complexity</b>: Constant.
  250. const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
  251. { return m_flat_tree.rbegin(); }
  252. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  253. //! of the reversed container.
  254. //!
  255. //! <b>Throws</b>: Nothing.
  256. //!
  257. //! <b>Complexity</b>: Constant.
  258. reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
  259. { return m_flat_tree.rend(); }
  260. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  261. //! of the reversed container.
  262. //!
  263. //! <b>Throws</b>: Nothing.
  264. //!
  265. //! <b>Complexity</b>: Constant.
  266. const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
  267. { return m_flat_tree.rend(); }
  268. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
  269. //!
  270. //! <b>Throws</b>: Nothing.
  271. //!
  272. //! <b>Complexity</b>: Constant.
  273. const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
  274. { return m_flat_tree.cbegin(); }
  275. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
  276. //!
  277. //! <b>Throws</b>: Nothing.
  278. //!
  279. //! <b>Complexity</b>: Constant.
  280. const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
  281. { return m_flat_tree.cend(); }
  282. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  283. //! of the reversed container.
  284. //!
  285. //! <b>Throws</b>: Nothing.
  286. //!
  287. //! <b>Complexity</b>: Constant.
  288. const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
  289. { return m_flat_tree.crbegin(); }
  290. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  291. //! of the reversed container.
  292. //!
  293. //! <b>Throws</b>: Nothing.
  294. //!
  295. //! <b>Complexity</b>: Constant.
  296. const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
  297. { return m_flat_tree.crend(); }
  298. //////////////////////////////////////////////
  299. //
  300. // capacity
  301. //
  302. //////////////////////////////////////////////
  303. //! <b>Effects</b>: Returns true if the container contains no elements.
  304. //!
  305. //! <b>Throws</b>: Nothing.
  306. //!
  307. //! <b>Complexity</b>: Constant.
  308. bool empty() const BOOST_CONTAINER_NOEXCEPT
  309. { return m_flat_tree.empty(); }
  310. //! <b>Effects</b>: Returns the number of the elements contained in the container.
  311. //!
  312. //! <b>Throws</b>: Nothing.
  313. //!
  314. //! <b>Complexity</b>: Constant.
  315. size_type size() const BOOST_CONTAINER_NOEXCEPT
  316. { return m_flat_tree.size(); }
  317. //! <b>Effects</b>: Returns the largest possible size of the container.
  318. //!
  319. //! <b>Throws</b>: Nothing.
  320. //!
  321. //! <b>Complexity</b>: Constant.
  322. size_type max_size() const BOOST_CONTAINER_NOEXCEPT
  323. { return m_flat_tree.max_size(); }
  324. //! <b>Effects</b>: Number of elements for which memory has been allocated.
  325. //! capacity() is always greater than or equal to size().
  326. //!
  327. //! <b>Throws</b>: Nothing.
  328. //!
  329. //! <b>Complexity</b>: Constant.
  330. size_type capacity() const BOOST_CONTAINER_NOEXCEPT
  331. { return m_flat_tree.capacity(); }
  332. //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
  333. //! effect. Otherwise, it is a request for allocation of additional memory.
  334. //! If the request is successful, then capacity() is greater than or equal to
  335. //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
  336. //!
  337. //! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws.
  338. //!
  339. //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
  340. //! to values might be invalidated.
  341. void reserve(size_type cnt)
  342. { m_flat_tree.reserve(cnt); }
  343. //! <b>Effects</b>: Tries to deallocate the excess of memory created
  344. // with previous allocations. The size of the vector is unchanged
  345. //!
  346. //! <b>Throws</b>: If memory allocation throws, or Key's copy constructor throws.
  347. //!
  348. //! <b>Complexity</b>: Linear to size().
  349. void shrink_to_fit()
  350. { m_flat_tree.shrink_to_fit(); }
  351. //////////////////////////////////////////////
  352. //
  353. // modifiers
  354. //
  355. //////////////////////////////////////////////
  356. #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  357. //! <b>Effects</b>: Inserts an object x of type Key constructed with
  358. //! std::forward<Args>(args)... if and only if there is no element in the container
  359. //! with key equivalent to the key of x.
  360. //!
  361. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  362. //! if the insertion takes place, and the iterator component of the pair
  363. //! points to the element with key equivalent to the key of x.
  364. //!
  365. //! <b>Complexity</b>: Logarithmic search time plus linear insertion
  366. //! to the elements with bigger keys than x.
  367. //!
  368. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  369. template <class... Args>
  370. std::pair<iterator,bool> emplace(Args&&... args)
  371. { return m_flat_tree.emplace_unique(boost::forward<Args>(args)...); }
  372. //! <b>Effects</b>: Inserts an object of type Key constructed with
  373. //! std::forward<Args>(args)... in the container if and only if there is
  374. //! no element in the container with key equivalent to the key of x.
  375. //! p is a hint pointing to where the insert should start to search.
  376. //!
  377. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  378. //! to the key of x.
  379. //!
  380. //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
  381. //! right before p) plus insertion linear to the elements with bigger keys than x.
  382. //!
  383. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  384. template <class... Args>
  385. iterator emplace_hint(const_iterator hint, Args&&... args)
  386. { return m_flat_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
  387. #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  388. #define BOOST_PP_LOCAL_MACRO(n) \
  389. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  390. std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  391. { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
  392. \
  393. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  394. iterator emplace_hint(const_iterator hint \
  395. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  396. { return m_flat_tree.emplace_hint_unique \
  397. (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
  398. //!
  399. #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
  400. #include BOOST_PP_LOCAL_ITERATE()
  401. #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  402. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  403. //! <b>Effects</b>: Inserts x if and only if there is no element in the container
  404. //! with key equivalent to the key of x.
  405. //!
  406. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  407. //! if the insertion takes place, and the iterator component of the pair
  408. //! points to the element with key equivalent to the key of x.
  409. //!
  410. //! <b>Complexity</b>: Logarithmic search time plus linear insertion
  411. //! to the elements with bigger keys than x.
  412. //!
  413. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  414. std::pair<iterator, bool> insert(const value_type &x);
  415. //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
  416. //! only if there is no element in the container with key equivalent to the key of x.
  417. //!
  418. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  419. //! if the insertion takes place, and the iterator component of the pair
  420. //! points to the element with key equivalent to the key of x.
  421. //!
  422. //! <b>Complexity</b>: Logarithmic search time plus linear insertion
  423. //! to the elements with bigger keys than x.
  424. //!
  425. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  426. std::pair<iterator, bool> insert(value_type &&x);
  427. #else
  428. private:
  429. typedef std::pair<iterator, bool> insert_return_pair;
  430. public:
  431. BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert)
  432. #endif
  433. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  434. //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
  435. //! no element in the container with key equivalent to the key of x.
  436. //! p is a hint pointing to where the insert should start to search.
  437. //!
  438. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  439. //! to the key of x.
  440. //!
  441. //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
  442. //! right before p) plus insertion linear to the elements with bigger keys than x.
  443. //!
  444. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  445. iterator insert(const_iterator p, const value_type &x);
  446. //! <b>Effects</b>: Inserts an element move constructed from x in the container.
  447. //! p is a hint pointing to where the insert should start to search.
  448. //!
  449. //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
  450. //!
  451. //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
  452. //! right before p) plus insertion linear to the elements with bigger keys than x.
  453. //!
  454. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  455. iterator insert(const_iterator position, value_type &&x);
  456. #else
  457. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator)
  458. #endif
  459. //! <b>Requires</b>: first, last are not iterators into *this.
  460. //!
  461. //! <b>Effects</b>: inserts each element from the range [first,last) if and only
  462. //! if there is no element with key equivalent to the key of that element.
  463. //!
  464. //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
  465. //! search time plus N*size() insertion time.
  466. //!
  467. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  468. template <class InputIterator>
  469. void insert(InputIterator first, InputIterator last)
  470. { m_flat_tree.insert_unique(first, last); }
  471. //! <b>Requires</b>: first, last are not iterators into *this and
  472. //! must be ordered according to the predicate and must be
  473. //! unique values.
  474. //!
  475. //! <b>Effects</b>: inserts each element from the range [first,last) .This function
  476. //! is more efficient than the normal range creation for ordered ranges.
  477. //!
  478. //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
  479. //! search time plus N*size() insertion time.
  480. //!
  481. //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
  482. template <class InputIterator>
  483. void insert(ordered_unique_range_t, InputIterator first, InputIterator last)
  484. { m_flat_tree.insert_unique(ordered_unique_range, first, last); }
  485. //! <b>Effects</b>: Erases the element pointed to by position.
  486. //!
  487. //! <b>Returns</b>: Returns an iterator pointing to the element immediately
  488. //! following q prior to the element being erased. If no such element exists,
  489. //! returns end().
  490. //!
  491. //! <b>Complexity</b>: Linear to the elements with keys bigger than position
  492. //!
  493. //! <b>Note</b>: Invalidates elements with keys
  494. //! not less than the erased element.
  495. iterator erase(const_iterator position)
  496. { return m_flat_tree.erase(position); }
  497. //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
  498. //!
  499. //! <b>Returns</b>: Returns the number of erased elements.
  500. //!
  501. //! <b>Complexity</b>: Logarithmic search time plus erasure time
  502. //! linear to the elements with bigger keys.
  503. size_type erase(const key_type& x)
  504. { return m_flat_tree.erase(x); }
  505. //! <b>Effects</b>: Erases all the elements in the range [first, last).
  506. //!
  507. //! <b>Returns</b>: Returns last.
  508. //!
  509. //! <b>Complexity</b>: size()*N where N is the distance from first to last.
  510. //!
  511. //! <b>Complexity</b>: Logarithmic search time plus erasure time
  512. //! linear to the elements with bigger keys.
  513. iterator erase(const_iterator first, const_iterator last)
  514. { return m_flat_tree.erase(first, last); }
  515. //! <b>Effects</b>: Swaps the contents of *this and x.
  516. //!
  517. //! <b>Throws</b>: Nothing.
  518. //!
  519. //! <b>Complexity</b>: Constant.
  520. void swap(flat_set& x)
  521. { m_flat_tree.swap(x.m_flat_tree); }
  522. //! <b>Effects</b>: erase(a.begin(),a.end()).
  523. //!
  524. //! <b>Postcondition</b>: size() == 0.
  525. //!
  526. //! <b>Complexity</b>: linear in size().
  527. void clear() BOOST_CONTAINER_NOEXCEPT
  528. { m_flat_tree.clear(); }
  529. //////////////////////////////////////////////
  530. //
  531. // observers
  532. //
  533. //////////////////////////////////////////////
  534. //! <b>Effects</b>: Returns the comparison object out
  535. //! of which a was constructed.
  536. //!
  537. //! <b>Complexity</b>: Constant.
  538. key_compare key_comp() const
  539. { return m_flat_tree.key_comp(); }
  540. //! <b>Effects</b>: Returns an object of value_compare constructed out
  541. //! of the comparison object.
  542. //!
  543. //! <b>Complexity</b>: Constant.
  544. value_compare value_comp() const
  545. { return m_flat_tree.key_comp(); }
  546. //////////////////////////////////////////////
  547. //
  548. // set operations
  549. //
  550. //////////////////////////////////////////////
  551. //! <b>Returns</b>: An iterator pointing to an element with the key
  552. //! equivalent to x, or end() if such an element is not found.
  553. //!
  554. //! <b>Complexity</b>: Logarithmic.
  555. iterator find(const key_type& x)
  556. { return m_flat_tree.find(x); }
  557. //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key
  558. //! equivalent to x, or end() if such an element is not found.
  559. //!
  560. //! <b>Complexity</b>: Logarithmic.s
  561. const_iterator find(const key_type& x) const
  562. { return m_flat_tree.find(x); }
  563. //! <b>Returns</b>: The number of elements with key equivalent to x.
  564. //!
  565. //! <b>Complexity</b>: log(size())+count(k)
  566. size_type count(const key_type& x) const
  567. { return static_cast<size_type>(m_flat_tree.find(x) != m_flat_tree.end()); }
  568. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  569. //! than k, or a.end() if such an element is not found.
  570. //!
  571. //! <b>Complexity</b>: Logarithmic
  572. iterator lower_bound(const key_type& x)
  573. { return m_flat_tree.lower_bound(x); }
  574. //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
  575. //! less than k, or a.end() if such an element is not found.
  576. //!
  577. //! <b>Complexity</b>: Logarithmic
  578. const_iterator lower_bound(const key_type& x) const
  579. { return m_flat_tree.lower_bound(x); }
  580. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  581. //! than x, or end() if such an element is not found.
  582. //!
  583. //! <b>Complexity</b>: Logarithmic
  584. iterator upper_bound(const key_type& x)
  585. { return m_flat_tree.upper_bound(x); }
  586. //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
  587. //! less than x, or end() if such an element is not found.
  588. //!
  589. //! <b>Complexity</b>: Logarithmic
  590. const_iterator upper_bound(const key_type& x) const
  591. { return m_flat_tree.upper_bound(x); }
  592. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  593. //!
  594. //! <b>Complexity</b>: Logarithmic
  595. std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
  596. { return m_flat_tree.equal_range(x); }
  597. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  598. //!
  599. //! <b>Complexity</b>: Logarithmic
  600. std::pair<iterator,iterator> equal_range(const key_type& x)
  601. { return m_flat_tree.equal_range(x); }
  602. /// @cond
  603. template <class K1, class C1, class A1>
  604. friend bool operator== (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
  605. template <class K1, class C1, class A1>
  606. friend bool operator< (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
  607. private:
  608. template<class KeyType>
  609. std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
  610. { return m_flat_tree.insert_unique(::boost::forward<KeyType>(x)); }
  611. template<class KeyType>
  612. iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
  613. { return m_flat_tree.insert_unique(p, ::boost::forward<KeyType>(x)); }
  614. /// @endcond
  615. };
  616. template <class Key, class Compare, class Allocator>
  617. inline bool operator==(const flat_set<Key,Compare,Allocator>& x,
  618. const flat_set<Key,Compare,Allocator>& y)
  619. { return x.m_flat_tree == y.m_flat_tree; }
  620. template <class Key, class Compare, class Allocator>
  621. inline bool operator<(const flat_set<Key,Compare,Allocator>& x,
  622. const flat_set<Key,Compare,Allocator>& y)
  623. { return x.m_flat_tree < y.m_flat_tree; }
  624. template <class Key, class Compare, class Allocator>
  625. inline bool operator!=(const flat_set<Key,Compare,Allocator>& x,
  626. const flat_set<Key,Compare,Allocator>& y)
  627. { return !(x == y); }
  628. template <class Key, class Compare, class Allocator>
  629. inline bool operator>(const flat_set<Key,Compare,Allocator>& x,
  630. const flat_set<Key,Compare,Allocator>& y)
  631. { return y < x; }
  632. template <class Key, class Compare, class Allocator>
  633. inline bool operator<=(const flat_set<Key,Compare,Allocator>& x,
  634. const flat_set<Key,Compare,Allocator>& y)
  635. { return !(y < x); }
  636. template <class Key, class Compare, class Allocator>
  637. inline bool operator>=(const flat_set<Key,Compare,Allocator>& x,
  638. const flat_set<Key,Compare,Allocator>& y)
  639. { return !(x < y); }
  640. template <class Key, class Compare, class Allocator>
  641. inline void swap(flat_set<Key,Compare,Allocator>& x, flat_set<Key,Compare,Allocator>& y)
  642. { x.swap(y); }
  643. /// @cond
  644. } //namespace container {
  645. //!has_trivial_destructor_after_move<> == true_type
  646. //!specialization for optimizations
  647. template <class Key, class C, class Allocator>
  648. struct has_trivial_destructor_after_move<boost::container::flat_set<Key, C, Allocator> >
  649. {
  650. static const bool value = has_trivial_destructor_after_move<Allocator>::value &&has_trivial_destructor_after_move<C>::value;
  651. };
  652. namespace container {
  653. // Forward declaration of operators < and ==, needed for friend declaration.
  654. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  655. template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
  656. #else
  657. template <class Key, class Compare, class Allocator>
  658. #endif
  659. class flat_multiset;
  660. template <class Key, class Compare, class Allocator>
  661. inline bool operator==(const flat_multiset<Key,Compare,Allocator>& x,
  662. const flat_multiset<Key,Compare,Allocator>& y);
  663. template <class Key, class Compare, class Allocator>
  664. inline bool operator<(const flat_multiset<Key,Compare,Allocator>& x,
  665. const flat_multiset<Key,Compare,Allocator>& y);
  666. /// @endcond
  667. //! flat_multiset is a Sorted Associative Container that stores objects of type Key.
  668. //!
  669. //! flat_multiset can store multiple copies of the same key value.
  670. //!
  671. //! flat_multiset is similar to std::multiset but it's implemented like an ordered vector.
  672. //! This means that inserting a new element into a flat_multiset invalidates
  673. //! previous iterators and references
  674. //!
  675. //! Erasing an element invalidates iterators and references
  676. //! pointing to elements that come after (their keys are bigger) the erased element.
  677. //!
  678. //! This container provides random-access iterators.
  679. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  680. template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
  681. #else
  682. template <class Key, class Compare, class Allocator>
  683. #endif
  684. class flat_multiset
  685. {
  686. /// @cond
  687. private:
  688. BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
  689. typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> tree_t;
  690. tree_t m_flat_tree; // flat tree representing flat_multiset
  691. /// @endcond
  692. public:
  693. //////////////////////////////////////////////
  694. //
  695. // types
  696. //
  697. //////////////////////////////////////////////
  698. typedef Key key_type;
  699. typedef Key value_type;
  700. typedef Compare key_compare;
  701. typedef Compare value_compare;
  702. typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
  703. typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
  704. typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
  705. typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
  706. typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
  707. typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
  708. typedef Allocator allocator_type;
  709. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type;
  710. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator;
  711. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator;
  712. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator;
  713. typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator;
  714. //! <b>Effects</b>: Default constructs an empty flat_multiset.
  715. //!
  716. //! <b>Complexity</b>: Constant.
  717. explicit flat_multiset()
  718. : m_flat_tree()
  719. {}
  720. //! <b>Effects</b>: Constructs an empty flat_multiset using the specified
  721. //! comparison object and allocator.
  722. //!
  723. //! <b>Complexity</b>: Constant.
  724. explicit flat_multiset(const Compare& comp,
  725. const allocator_type& a = allocator_type())
  726. : m_flat_tree(comp, a)
  727. {}
  728. //! <b>Effects</b>: Constructs an empty flat_multiset using the specified allocator.
  729. //!
  730. //! <b>Complexity</b>: Constant.
  731. explicit flat_multiset(const allocator_type& a)
  732. : m_flat_tree(a)
  733. {}
  734. template <class InputIterator>
  735. flat_multiset(InputIterator first, InputIterator last,
  736. const Compare& comp = Compare(),
  737. const allocator_type& a = allocator_type())
  738. : m_flat_tree(false, first, last, comp, a)
  739. {}
  740. //! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
  741. //! allocator, and inserts elements from the ordered range [first ,last ). This function
  742. //! is more efficient than the normal range creation for ordered ranges.
  743. //!
  744. //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
  745. //!
  746. //! <b>Complexity</b>: Linear in N.
  747. //!
  748. //! <b>Note</b>: Non-standard extension.
  749. template <class InputIterator>
  750. flat_multiset(ordered_range_t, InputIterator first, InputIterator last,
  751. const Compare& comp = Compare(),
  752. const allocator_type& a = allocator_type())
  753. : m_flat_tree(ordered_range, first, last, comp, a)
  754. {}
  755. //! <b>Effects</b>: Copy constructs a flat_multiset.
  756. //!
  757. //! <b>Complexity</b>: Linear in x.size().
  758. flat_multiset(const flat_multiset& x)
  759. : m_flat_tree(x.m_flat_tree)
  760. {}
  761. //! <b>Effects</b>: Move constructs a flat_multiset. Constructs *this using x's resources.
  762. //!
  763. //! <b>Complexity</b>: Constant.
  764. //!
  765. //! <b>Postcondition</b>: x is emptied.
  766. flat_multiset(BOOST_RV_REF(flat_multiset) mx)
  767. : m_flat_tree(boost::move(mx.m_flat_tree))
  768. {}
  769. //! <b>Effects</b>: Copy constructs a flat_multiset using the specified allocator.
  770. //!
  771. //! <b>Complexity</b>: Linear in x.size().
  772. flat_multiset(const flat_multiset& x, const allocator_type &a)
  773. : m_flat_tree(x.m_flat_tree, a)
  774. {}
  775. //! <b>Effects</b>: Move constructs a flat_multiset using the specified allocator.
  776. //! Constructs *this using x's resources.
  777. //!
  778. //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
  779. flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a)
  780. : m_flat_tree(boost::move(mx.m_flat_tree), a)
  781. {}
  782. //! <b>Effects</b>: Makes *this a copy of x.
  783. //!
  784. //! <b>Complexity</b>: Linear in x.size().
  785. flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
  786. { m_flat_tree = x.m_flat_tree; return *this; }
  787. //! <b>Effects</b>: Makes *this a copy of x.
  788. //!
  789. //! <b>Complexity</b>: Linear in x.size().
  790. flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
  791. { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
  792. //! <b>Effects</b>: Returns a copy of the Allocator that
  793. //! was passed to the object's constructor.
  794. //!
  795. //! <b>Complexity</b>: Constant.
  796. allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
  797. { return m_flat_tree.get_allocator(); }
  798. //! <b>Effects</b>: Returns a reference to the internal allocator.
  799. //!
  800. //! <b>Throws</b>: Nothing
  801. //!
  802. //! <b>Complexity</b>: Constant.
  803. //!
  804. //! <b>Note</b>: Non-standard extension.
  805. stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
  806. { return m_flat_tree.get_stored_allocator(); }
  807. //! <b>Effects</b>: Returns a reference to the internal allocator.
  808. //!
  809. //! <b>Throws</b>: Nothing
  810. //!
  811. //! <b>Complexity</b>: Constant.
  812. //!
  813. //! <b>Note</b>: Non-standard extension.
  814. const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
  815. { return m_flat_tree.get_stored_allocator(); }
  816. //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
  817. //!
  818. //! <b>Throws</b>: Nothing.
  819. //!
  820. //! <b>Complexity</b>: Constant.
  821. iterator begin() BOOST_CONTAINER_NOEXCEPT
  822. { return m_flat_tree.begin(); }
  823. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
  824. //!
  825. //! <b>Throws</b>: Nothing.
  826. //!
  827. //! <b>Complexity</b>: Constant.
  828. const_iterator begin() const
  829. { return m_flat_tree.begin(); }
  830. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
  831. //!
  832. //! <b>Throws</b>: Nothing.
  833. //!
  834. //! <b>Complexity</b>: Constant.
  835. const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
  836. { return m_flat_tree.cbegin(); }
  837. //! <b>Effects</b>: Returns an iterator to the end of the container.
  838. //!
  839. //! <b>Throws</b>: Nothing.
  840. //!
  841. //! <b>Complexity</b>: Constant.
  842. iterator end() BOOST_CONTAINER_NOEXCEPT
  843. { return m_flat_tree.end(); }
  844. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
  845. //!
  846. //! <b>Throws</b>: Nothing.
  847. //!
  848. //! <b>Complexity</b>: Constant.
  849. const_iterator end() const BOOST_CONTAINER_NOEXCEPT
  850. { return m_flat_tree.end(); }
  851. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
  852. //!
  853. //! <b>Throws</b>: Nothing.
  854. //!
  855. //! <b>Complexity</b>: Constant.
  856. const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
  857. { return m_flat_tree.cend(); }
  858. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  859. //! of the reversed container.
  860. //!
  861. //! <b>Throws</b>: Nothing.
  862. //!
  863. //! <b>Complexity</b>: Constant.
  864. reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
  865. { return m_flat_tree.rbegin(); }
  866. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  867. //! of the reversed container.
  868. //!
  869. //! <b>Throws</b>: Nothing.
  870. //!
  871. //! <b>Complexity</b>: Constant.
  872. const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
  873. { return m_flat_tree.rbegin(); }
  874. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  875. //! of the reversed container.
  876. //!
  877. //! <b>Throws</b>: Nothing.
  878. //!
  879. //! <b>Complexity</b>: Constant.
  880. const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
  881. { return m_flat_tree.crbegin(); }
  882. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  883. //! of the reversed container.
  884. //!
  885. //! <b>Throws</b>: Nothing.
  886. //!
  887. //! <b>Complexity</b>: Constant.
  888. reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
  889. { return m_flat_tree.rend(); }
  890. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  891. //! of the reversed container.
  892. //!
  893. //! <b>Throws</b>: Nothing.
  894. //!
  895. //! <b>Complexity</b>: Constant.
  896. const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
  897. { return m_flat_tree.rend(); }
  898. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  899. //! of the reversed container.
  900. //!
  901. //! <b>Throws</b>: Nothing.
  902. //!
  903. //! <b>Complexity</b>: Constant.
  904. const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
  905. { return m_flat_tree.crend(); }
  906. //////////////////////////////////////////////
  907. //
  908. // capacity
  909. //
  910. //////////////////////////////////////////////
  911. //! <b>Effects</b>: Returns true if the container contains no elements.
  912. //!
  913. //! <b>Throws</b>: Nothing.
  914. //!
  915. //! <b>Complexity</b>: Constant.
  916. bool empty() const BOOST_CONTAINER_NOEXCEPT
  917. { return m_flat_tree.empty(); }
  918. //! <b>Effects</b>: Returns the number of the elements contained in the container.
  919. //!
  920. //! <b>Throws</b>: Nothing.
  921. //!
  922. //! <b>Complexity</b>: Constant.
  923. size_type size() const BOOST_CONTAINER_NOEXCEPT
  924. { return m_flat_tree.size(); }
  925. //! <b>Effects</b>: Returns the largest possible size of the container.
  926. //!
  927. //! <b>Throws</b>: Nothing.
  928. //!
  929. //! <b>Complexity</b>: Constant.
  930. size_type max_size() const BOOST_CONTAINER_NOEXCEPT
  931. { return m_flat_tree.max_size(); }
  932. //! <b>Effects</b>: Number of elements for which memory has been allocated.
  933. //! capacity() is always greater than or equal to size().
  934. //!
  935. //! <b>Throws</b>: Nothing.
  936. //!
  937. //! <b>Complexity</b>: Constant.
  938. size_type capacity() const BOOST_CONTAINER_NOEXCEPT
  939. { return m_flat_tree.capacity(); }
  940. //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
  941. //! effect. Otherwise, it is a request for allocation of additional memory.
  942. //! If the request is successful, then capacity() is greater than or equal to
  943. //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
  944. //!
  945. //! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws.
  946. //!
  947. //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
  948. //! to values might be invalidated.
  949. void reserve(size_type cnt)
  950. { m_flat_tree.reserve(cnt); }
  951. //! <b>Effects</b>: Tries to deallocate the excess of memory created
  952. // with previous allocations. The size of the vector is unchanged
  953. //!
  954. //! <b>Throws</b>: If memory allocation throws, or Key's copy constructor throws.
  955. //!
  956. //! <b>Complexity</b>: Linear to size().
  957. void shrink_to_fit()
  958. { m_flat_tree.shrink_to_fit(); }
  959. //////////////////////////////////////////////
  960. //
  961. // modifiers
  962. //
  963. //////////////////////////////////////////////
  964. #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  965. //! <b>Effects</b>: Inserts an object of type Key constructed with
  966. //! std::forward<Args>(args)... and returns the iterator pointing to the
  967. //! newly inserted element.
  968. //!
  969. //! <b>Complexity</b>: Logarithmic search time plus linear insertion
  970. //! to the elements with bigger keys than x.
  971. //!
  972. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  973. template <class... Args>
  974. iterator emplace(Args&&... args)
  975. { return m_flat_tree.emplace_equal(boost::forward<Args>(args)...); }
  976. //! <b>Effects</b>: Inserts an object of type Key constructed with
  977. //! std::forward<Args>(args)... in the container.
  978. //! p is a hint pointing to where the insert should start to search.
  979. //!
  980. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  981. //! to the key of x.
  982. //!
  983. //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
  984. //! right before p) plus insertion linear to the elements with bigger keys than x.
  985. //!
  986. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  987. template <class... Args>
  988. iterator emplace_hint(const_iterator hint, Args&&... args)
  989. { return m_flat_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
  990. #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  991. #define BOOST_PP_LOCAL_MACRO(n) \
  992. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  993. iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  994. { return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
  995. \
  996. BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
  997. iterator emplace_hint(const_iterator hint \
  998. BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
  999. { return m_flat_tree.emplace_hint_equal \
  1000. (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
  1001. //!
  1002. #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
  1003. #include BOOST_PP_LOCAL_ITERATE()
  1004. #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
  1005. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1006. //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
  1007. //! newly inserted element.
  1008. //!
  1009. //! <b>Complexity</b>: Logarithmic search time plus linear insertion
  1010. //! to the elements with bigger keys than x.
  1011. //!
  1012. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  1013. iterator insert(const value_type &x);
  1014. //! <b>Effects</b>: Inserts a new value_type move constructed from x
  1015. //! and returns the iterator pointing to the newly inserted element.
  1016. //!
  1017. //! <b>Complexity</b>: Logarithmic search time plus linear insertion
  1018. //! to the elements with bigger keys than x.
  1019. //!
  1020. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  1021. iterator insert(value_type &&x);
  1022. #else
  1023. BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert)
  1024. #endif
  1025. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  1026. //! <b>Effects</b>: Inserts a copy of x in the container.
  1027. //! p is a hint pointing to where the insert should start to search.
  1028. //!
  1029. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  1030. //! to the key of x.
  1031. //!
  1032. //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
  1033. //! right before p) plus insertion linear to the elements with bigger keys than x.
  1034. //!
  1035. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  1036. iterator insert(const_iterator p, const value_type &x);
  1037. //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
  1038. //! p is a hint pointing to where the insert should start to search.
  1039. //!
  1040. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  1041. //! to the key of x.
  1042. //!
  1043. //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
  1044. //! right before p) plus insertion linear to the elements with bigger keys than x.
  1045. //!
  1046. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  1047. iterator insert(const_iterator position, value_type &&x);
  1048. #else
  1049. BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator, const_iterator)
  1050. #endif
  1051. //! <b>Requires</b>: first, last are not iterators into *this.
  1052. //!
  1053. //! <b>Effects</b>: inserts each element from the range [first,last) .
  1054. //!
  1055. //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
  1056. //! search time plus N*size() insertion time.
  1057. //!
  1058. //! <b>Note</b>: If an element is inserted it might invalidate elements.
  1059. template <class InputIterator>
  1060. void insert(InputIterator first, InputIterator last)
  1061. { m_flat_tree.insert_equal(first, last); }
  1062. //! <b>Requires</b>: first, last are not iterators into *this and
  1063. //! must be ordered according to the predicate.
  1064. //!
  1065. //! <b>Effects</b>: inserts each element from the range [first,last) .This function
  1066. //! is more efficient than the normal range creation for ordered ranges.
  1067. //!
  1068. //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
  1069. //! search time plus N*size() insertion time.
  1070. //!
  1071. //! <b>Note</b>: Non-standard extension. If an element is inserted it might invalidate elements.
  1072. template <class InputIterator>
  1073. void insert(ordered_range_t, InputIterator first, InputIterator last)
  1074. { m_flat_tree.insert_equal(ordered_range, first, last); }
  1075. //! <b>Effects</b>: Erases the element pointed to by position.
  1076. //!
  1077. //! <b>Returns</b>: Returns an iterator pointing to the element immediately
  1078. //! following q prior to the element being erased. If no such element exists,
  1079. //! returns end().
  1080. //!
  1081. //! <b>Complexity</b>: Linear to the elements with keys bigger than position
  1082. //!
  1083. //! <b>Note</b>: Invalidates elements with keys
  1084. //! not less than the erased element.
  1085. iterator erase(const_iterator position)
  1086. { return m_flat_tree.erase(position); }
  1087. //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
  1088. //!
  1089. //! <b>Returns</b>: Returns the number of erased elements.
  1090. //!
  1091. //! <b>Complexity</b>: Logarithmic search time plus erasure time
  1092. //! linear to the elements with bigger keys.
  1093. size_type erase(const key_type& x)
  1094. { return m_flat_tree.erase(x); }
  1095. //! <b>Effects</b>: Erases all the elements in the range [first, last).
  1096. //!
  1097. //! <b>Returns</b>: Returns last.
  1098. //!
  1099. //! <b>Complexity</b>: size()*N where N is the distance from first to last.
  1100. //!
  1101. //! <b>Complexity</b>: Logarithmic search time plus erasure time
  1102. //! linear to the elements with bigger keys.
  1103. iterator erase(const_iterator first, const_iterator last)
  1104. { return m_flat_tree.erase(first, last); }
  1105. //! <b>Effects</b>: Swaps the contents of *this and x.
  1106. //!
  1107. //! <b>Throws</b>: Nothing.
  1108. //!
  1109. //! <b>Complexity</b>: Constant.
  1110. void swap(flat_multiset& x)
  1111. { m_flat_tree.swap(x.m_flat_tree); }
  1112. //! <b>Effects</b>: erase(a.begin(),a.end()).
  1113. //!
  1114. //! <b>Postcondition</b>: size() == 0.
  1115. //!
  1116. //! <b>Complexity</b>: linear in size().
  1117. void clear() BOOST_CONTAINER_NOEXCEPT
  1118. { m_flat_tree.clear(); }
  1119. //////////////////////////////////////////////
  1120. //
  1121. // observers
  1122. //
  1123. //////////////////////////////////////////////
  1124. //! <b>Effects</b>: Returns the comparison object out
  1125. //! of which a was constructed.
  1126. //!
  1127. //! <b>Complexity</b>: Constant.
  1128. key_compare key_comp() const
  1129. { return m_flat_tree.key_comp(); }
  1130. //! <b>Effects</b>: Returns an object of value_compare constructed out
  1131. //! of the comparison object.
  1132. //!
  1133. //! <b>Complexity</b>: Constant.
  1134. value_compare value_comp() const
  1135. { return m_flat_tree.key_comp(); }
  1136. //////////////////////////////////////////////
  1137. //
  1138. // set operations
  1139. //
  1140. //////////////////////////////////////////////
  1141. //! <b>Returns</b>: An iterator pointing to an element with the key
  1142. //! equivalent to x, or end() if such an element is not found.
  1143. //!
  1144. //! <b>Complexity</b>: Logarithmic.
  1145. iterator find(const key_type& x)
  1146. { return m_flat_tree.find(x); }
  1147. //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key
  1148. //! equivalent to x, or end() if such an element is not found.
  1149. //!
  1150. //! <b>Complexity</b>: Logarithmic.s
  1151. const_iterator find(const key_type& x) const
  1152. { return m_flat_tree.find(x); }
  1153. //! <b>Returns</b>: The number of elements with key equivalent to x.
  1154. //!
  1155. //! <b>Complexity</b>: log(size())+count(k)
  1156. size_type count(const key_type& x) const
  1157. { return m_flat_tree.count(x); }
  1158. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  1159. //! than k, or a.end() if such an element is not found.
  1160. //!
  1161. //! <b>Complexity</b>: Logarithmic
  1162. iterator lower_bound(const key_type& x)
  1163. { return m_flat_tree.lower_bound(x); }
  1164. //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
  1165. //! less than k, or a.end() if such an element is not found.
  1166. //!
  1167. //! <b>Complexity</b>: Logarithmic
  1168. const_iterator lower_bound(const key_type& x) const
  1169. { return m_flat_tree.lower_bound(x); }
  1170. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  1171. //! than x, or end() if such an element is not found.
  1172. //!
  1173. //! <b>Complexity</b>: Logarithmic
  1174. iterator upper_bound(const key_type& x)
  1175. { return m_flat_tree.upper_bound(x); }
  1176. //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
  1177. //! less than x, or end() if such an element is not found.
  1178. //!
  1179. //! <b>Complexity</b>: Logarithmic
  1180. const_iterator upper_bound(const key_type& x) const
  1181. { return m_flat_tree.upper_bound(x); }
  1182. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  1183. //!
  1184. //! <b>Complexity</b>: Logarithmic
  1185. std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
  1186. { return m_flat_tree.equal_range(x); }
  1187. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  1188. //!
  1189. //! <b>Complexity</b>: Logarithmic
  1190. std::pair<iterator,iterator> equal_range(const key_type& x)
  1191. { return m_flat_tree.equal_range(x); }
  1192. /// @cond
  1193. template <class K1, class C1, class A1>
  1194. friend bool operator== (const flat_multiset<K1,C1,A1>&,
  1195. const flat_multiset<K1,C1,A1>&);
  1196. template <class K1, class C1, class A1>
  1197. friend bool operator< (const flat_multiset<K1,C1,A1>&,
  1198. const flat_multiset<K1,C1,A1>&);
  1199. private:
  1200. template <class KeyType>
  1201. iterator priv_insert(BOOST_FWD_REF(KeyType) x)
  1202. { return m_flat_tree.insert_equal(::boost::forward<KeyType>(x)); }
  1203. template <class KeyType>
  1204. iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
  1205. { return m_flat_tree.insert_equal(p, ::boost::forward<KeyType>(x)); }
  1206. /// @endcond
  1207. };
  1208. template <class Key, class Compare, class Allocator>
  1209. inline bool operator==(const flat_multiset<Key,Compare,Allocator>& x,
  1210. const flat_multiset<Key,Compare,Allocator>& y)
  1211. { return x.m_flat_tree == y.m_flat_tree; }
  1212. template <class Key, class Compare, class Allocator>
  1213. inline bool operator<(const flat_multiset<Key,Compare,Allocator>& x,
  1214. const flat_multiset<Key,Compare,Allocator>& y)
  1215. { return x.m_flat_tree < y.m_flat_tree; }
  1216. template <class Key, class Compare, class Allocator>
  1217. inline bool operator!=(const flat_multiset<Key,Compare,Allocator>& x,
  1218. const flat_multiset<Key,Compare,Allocator>& y)
  1219. { return !(x == y); }
  1220. template <class Key, class Compare, class Allocator>
  1221. inline bool operator>(const flat_multiset<Key,Compare,Allocator>& x,
  1222. const flat_multiset<Key,Compare,Allocator>& y)
  1223. { return y < x; }
  1224. template <class Key, class Compare, class Allocator>
  1225. inline bool operator<=(const flat_multiset<Key,Compare,Allocator>& x,
  1226. const flat_multiset<Key,Compare,Allocator>& y)
  1227. { return !(y < x); }
  1228. template <class Key, class Compare, class Allocator>
  1229. inline bool operator>=(const flat_multiset<Key,Compare,Allocator>& x,
  1230. const flat_multiset<Key,Compare,Allocator>& y)
  1231. { return !(x < y); }
  1232. template <class Key, class Compare, class Allocator>
  1233. inline void swap(flat_multiset<Key,Compare,Allocator>& x, flat_multiset<Key,Compare,Allocator>& y)
  1234. { x.swap(y); }
  1235. /// @cond
  1236. } //namespace container {
  1237. //!has_trivial_destructor_after_move<> == true_type
  1238. //!specialization for optimizations
  1239. template <class Key, class C, class Allocator>
  1240. struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C, Allocator> >
  1241. {
  1242. static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
  1243. };
  1244. namespace container {
  1245. /// @endcond
  1246. }}
  1247. #include <boost/container/detail/config_end.hpp>
  1248. #endif /* BOOST_CONTAINER_FLAT_SET_HPP */