map.hpp 60 KB

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