PageRenderTime 341ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/interprocess/containers/container/map.hpp

http://hadesmem.googlecode.com/
C++ Header | 1286 lines | 495 code | 160 blank | 631 comment | 18 complexity | 1b04b86ffd130e26d92384ade6f401ab MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.0, Apache-2.0, LGPL-3.0
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2009. 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. //
  11. // This file comes from SGI's stl_map/stl_multimap files. Modified by Ion Gaztanaga.
  12. // Renaming, isolating and porting to generic algorithms. Pointer typedef
  13. // set to allocator::pointer to allow placing it in shared memory.
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. /*
  17. *
  18. * Copyright (c) 1994
  19. * Hewlett-Packard Company
  20. *
  21. * Permission to use, copy, modify, distribute and sell this software
  22. * and its documentation for any purpose is hereby granted without fee,
  23. * provided that the above copyright notice appear in all copies and
  24. * that both that copyright notice and this permission notice appear
  25. * in supporting documentation. Hewlett-Packard Company makes no
  26. * representations about the suitability of this software for any
  27. * purpose. It is provided "as is" without express or implied warranty.
  28. *
  29. *
  30. * Copyright (c) 1996
  31. * Silicon Graphics Computer Systems, Inc.
  32. *
  33. * Permission to use, copy, modify, distribute and sell this software
  34. * and its documentation for any purpose is hereby granted without fee,
  35. * provided that the above copyright notice appear in all copies and
  36. * that both that copyright notice and this permission notice appear
  37. * in supporting documentation. Silicon Graphics makes no
  38. * representations about the suitability of this software for any
  39. * purpose. It is provided "as is" without express or implied warranty.
  40. *
  41. */
  42. #ifndef BOOST_CONTAINERS_MAP_HPP
  43. #define BOOST_CONTAINERS_MAP_HPP
  44. #if (defined _MSC_VER) && (_MSC_VER >= 1200)
  45. # pragma once
  46. #endif
  47. #include "detail/config_begin.hpp"
  48. #include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
  49. #include INCLUDE_BOOST_CONTAINER_CONTAINER_FWD_HPP
  50. #include <utility>
  51. #include <functional>
  52. #include <memory>
  53. #include <stdexcept>
  54. #include INCLUDE_BOOST_CONTAINER_DETAIL_TREE_HPP
  55. #include INCLUDE_BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
  56. #include <boost/type_traits/has_trivial_destructor.hpp>
  57. #include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
  58. #include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
  59. #include INCLUDE_BOOST_CONTAINER_DETAIL_PAIR_HPP
  60. #include INCLUDE_BOOST_CONTAINER_MOVE_HPP
  61. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
  62. namespace boost {
  63. namespace container {
  64. #else
  65. namespace boost {
  66. namespace container {
  67. #endif
  68. /// @cond
  69. // Forward declarations of operators == and <, needed for friend declarations.
  70. template <class Key, class T, class Pred, class Alloc>
  71. inline bool operator==(const map<Key,T,Pred,Alloc>& x,
  72. const map<Key,T,Pred,Alloc>& y);
  73. template <class Key, class T, class Pred, class Alloc>
  74. inline bool operator<(const map<Key,T,Pred,Alloc>& x,
  75. const map<Key,T,Pred,Alloc>& y);
  76. /// @endcond
  77. //! A map is a kind of associative container that supports unique keys (contains at
  78. //! most one of each key value) and provides for fast retrieval of values of another
  79. //! type T based on the keys. The map class supports bidirectional iterators.
  80. //!
  81. //! A map satisfies all of the requirements of a container and of a reversible
  82. //! container and of an associative container. For a
  83. //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
  84. //!
  85. //! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
  86. //!
  87. //! Alloc is the allocator to allocate the value_types
  88. //! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
  89. template <class Key, class T, class Pred, class Alloc>
  90. class map
  91. {
  92. /// @cond
  93. private:
  94. BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(map)
  95. typedef containers_detail::rbtree<Key,
  96. std::pair<const Key, T>,
  97. containers_detail::select1st< std::pair<const Key, T> >,
  98. Pred,
  99. Alloc> tree_t;
  100. tree_t m_tree; // red-black tree representing map
  101. /// @endcond
  102. public:
  103. // typedefs:
  104. typedef typename tree_t::key_type key_type;
  105. typedef typename tree_t::value_type value_type;
  106. typedef typename tree_t::pointer pointer;
  107. typedef typename tree_t::const_pointer const_pointer;
  108. typedef typename tree_t::reference reference;
  109. typedef typename tree_t::const_reference const_reference;
  110. typedef T mapped_type;
  111. typedef Pred key_compare;
  112. typedef typename tree_t::iterator iterator;
  113. typedef typename tree_t::const_iterator const_iterator;
  114. typedef typename tree_t::reverse_iterator reverse_iterator;
  115. typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
  116. typedef typename tree_t::size_type size_type;
  117. typedef typename tree_t::difference_type difference_type;
  118. typedef typename tree_t::allocator_type allocator_type;
  119. typedef typename tree_t::stored_allocator_type stored_allocator_type;
  120. typedef std::pair<key_type, mapped_type> nonconst_value_type;
  121. typedef containers_detail::pair
  122. <key_type, mapped_type> nonconst_impl_value_type;
  123. /// @cond
  124. class value_compare_impl
  125. : public Pred,
  126. public std::binary_function<value_type, value_type, bool>
  127. {
  128. friend class map<Key,T,Pred,Alloc>;
  129. protected :
  130. value_compare_impl(const Pred &c) : Pred(c) {}
  131. public:
  132. bool operator()(const value_type& x, const value_type& y) const {
  133. return Pred::operator()(x.first, y.first);
  134. }
  135. };
  136. /// @endcond
  137. typedef value_compare_impl value_compare;
  138. //! <b>Effects</b>: Constructs an empty map using the specified comparison object
  139. //! and allocator.
  140. //!
  141. //! <b>Complexity</b>: Constant.
  142. explicit map(const Pred& comp = Pred(),
  143. const allocator_type& a = allocator_type())
  144. : m_tree(comp, a)
  145. {}
  146. //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
  147. //! allocator, and inserts elements from the range [first ,last ).
  148. //!
  149. //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
  150. //! comp and otherwise N logN, where N is last - first.
  151. template <class InputIterator>
  152. map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
  153. const allocator_type& a = allocator_type())
  154. : m_tree(first, last, comp, a, true)
  155. {}
  156. //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
  157. //! allocator, and inserts elements from the ordered unique range [first ,last). This function
  158. //! is more efficient than the normal range creation for ordered ranges.
  159. //!
  160. //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
  161. //! unique values.
  162. //!
  163. //! <b>Complexity</b>: Linear in N.
  164. template <class InputIterator>
  165. map( ordered_unique_range_t, InputIterator first, InputIterator last
  166. , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
  167. : m_tree(ordered_range, first, last, comp, a)
  168. {}
  169. //! <b>Effects</b>: Copy constructs a map.
  170. //!
  171. //! <b>Complexity</b>: Linear in x.size().
  172. map(const map<Key,T,Pred,Alloc>& x)
  173. : m_tree(x.m_tree)
  174. {}
  175. //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
  176. //!
  177. //! <b>Complexity</b>: Construct.
  178. //!
  179. //! <b>Postcondition</b>: x is emptied.
  180. map(BOOST_MOVE_MACRO_RV_REF(map) x)
  181. : m_tree(BOOST_CONTAINER_MOVE_NAMESPACE::move(x.m_tree))
  182. {}
  183. //! <b>Effects</b>: Makes *this a copy of x.
  184. //!
  185. //! <b>Complexity</b>: Linear in x.size().
  186. map& operator=(BOOST_MOVE_MACRO_COPY_ASSIGN_REF(map) x)
  187. { m_tree = x.m_tree; return *this; }
  188. //! <b>Effects</b>: this->swap(x.get()).
  189. //!
  190. //! <b>Complexity</b>: Constant.
  191. map& operator=(BOOST_MOVE_MACRO_RV_REF(map) x)
  192. { m_tree = BOOST_CONTAINER_MOVE_NAMESPACE::move(x.m_tree); return *this; }
  193. //! <b>Effects</b>: Returns the comparison object out
  194. //! of which a was constructed.
  195. //!
  196. //! <b>Complexity</b>: Constant.
  197. key_compare key_comp() const
  198. { return m_tree.key_comp(); }
  199. //! <b>Effects</b>: Returns an object of value_compare constructed out
  200. //! of the comparison object.
  201. //!
  202. //! <b>Complexity</b>: Constant.
  203. value_compare value_comp() const
  204. { return value_compare(m_tree.key_comp()); }
  205. //! <b>Effects</b>: Returns a copy of the Allocator that
  206. //! was passed to the object's constructor.
  207. //!
  208. //! <b>Complexity</b>: Constant.
  209. allocator_type get_allocator() const
  210. { return m_tree.get_allocator(); }
  211. const stored_allocator_type &get_stored_allocator() const
  212. { return m_tree.get_stored_allocator(); }
  213. stored_allocator_type &get_stored_allocator()
  214. { return m_tree.get_stored_allocator(); }
  215. //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
  216. //!
  217. //! <b>Throws</b>: Nothing.
  218. //!
  219. //! <b>Complexity</b>: Constant.
  220. iterator begin()
  221. { return m_tree.begin(); }
  222. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
  223. //!
  224. //! <b>Throws</b>: Nothing.
  225. //!
  226. //! <b>Complexity</b>: Constant.
  227. const_iterator begin() const
  228. { return m_tree.begin(); }
  229. //! <b>Effects</b>: Returns an iterator to the end of the container.
  230. //!
  231. //! <b>Throws</b>: Nothing.
  232. //!
  233. //! <b>Complexity</b>: Constant.
  234. iterator end()
  235. { return m_tree.end(); }
  236. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
  237. //!
  238. //! <b>Throws</b>: Nothing.
  239. //!
  240. //! <b>Complexity</b>: Constant.
  241. const_iterator end() const
  242. { return m_tree.end(); }
  243. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  244. //! of the reversed container.
  245. //!
  246. //! <b>Throws</b>: Nothing.
  247. //!
  248. //! <b>Complexity</b>: Constant.
  249. reverse_iterator rbegin()
  250. { return m_tree.rbegin(); }
  251. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  252. //! of the reversed container.
  253. //!
  254. //! <b>Throws</b>: Nothing.
  255. //!
  256. //! <b>Complexity</b>: Constant.
  257. const_reverse_iterator rbegin() const
  258. { return m_tree.rbegin(); }
  259. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  260. //! of the reversed container.
  261. //!
  262. //! <b>Throws</b>: Nothing.
  263. //!
  264. //! <b>Complexity</b>: Constant.
  265. reverse_iterator rend()
  266. { return m_tree.rend(); }
  267. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  268. //! of the reversed container.
  269. //!
  270. //! <b>Throws</b>: Nothing.
  271. //!
  272. //! <b>Complexity</b>: Constant.
  273. const_reverse_iterator rend() const
  274. { return m_tree.rend(); }
  275. //! <b>Effects</b>: Returns true if the container contains no elements.
  276. //!
  277. //! <b>Throws</b>: Nothing.
  278. //!
  279. //! <b>Complexity</b>: Constant.
  280. bool empty() const
  281. { return m_tree.empty(); }
  282. //! <b>Effects</b>: Returns the number of the elements contained in the container.
  283. //!
  284. //! <b>Throws</b>: Nothing.
  285. //!
  286. //! <b>Complexity</b>: Constant.
  287. size_type size() const
  288. { return m_tree.size(); }
  289. //! <b>Effects</b>: Returns the largest possible size of the container.
  290. //!
  291. //! <b>Throws</b>: Nothing.
  292. //!
  293. //! <b>Complexity</b>: Constant.
  294. size_type max_size() const
  295. { return m_tree.max_size(); }
  296. //! Effects: If there is no key equivalent to x in the map, inserts
  297. //! value_type(x, T()) into the map.
  298. //!
  299. //! Returns: A reference to the mapped_type corresponding to x in *this.
  300. //!
  301. //! Complexity: Logarithmic.
  302. T& operator[](const key_type& k)
  303. {
  304. //we can optimize this
  305. iterator i = lower_bound(k);
  306. // i->first is greater than or equivalent to k.
  307. if (i == end() || key_comp()(k, (*i).first)){
  308. containers_detail::value_init<T> v;
  309. value_type val(k, BOOST_CONTAINER_MOVE_NAMESPACE::move(v.m_t));
  310. i = insert(i, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
  311. }
  312. return (*i).second;
  313. }
  314. //! Effects: If there is no key equivalent to x in the map, inserts
  315. //! value_type(BOOST_CONTAINER_MOVE_NAMESPACE::move(x), T()) into the map (the key is move-constructed)
  316. //!
  317. //! Returns: A reference to the mapped_type corresponding to x in *this.
  318. //!
  319. //! Complexity: Logarithmic.
  320. T& operator[](BOOST_MOVE_MACRO_RV_REF(key_type) mk)
  321. {
  322. key_type &k = mk;
  323. //we can optimize this
  324. iterator i = lower_bound(k);
  325. // i->first is greater than or equivalent to k.
  326. if (i == end() || key_comp()(k, (*i).first)){
  327. value_type val(BOOST_CONTAINER_MOVE_NAMESPACE::move(k), BOOST_CONTAINER_MOVE_NAMESPACE::move(T()));
  328. i = insert(i, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
  329. }
  330. return (*i).second;
  331. }
  332. //! Returns: A reference to the element whose key is equivalent to x.
  333. //! Throws: An exception object of type out_of_range if no such element is present.
  334. //! Complexity: logarithmic.
  335. T& at(const key_type& k)
  336. {
  337. iterator i = this->find(k);
  338. if(i == this->end()){
  339. throw std::out_of_range("key not found");
  340. }
  341. return i->second;
  342. }
  343. //! Returns: A reference to the element whose key is equivalent to x.
  344. //! Throws: An exception object of type out_of_range if no such element is present.
  345. //! Complexity: logarithmic.
  346. const T& at(const key_type& k) const
  347. {
  348. const_iterator i = this->find(k);
  349. if(i == this->end()){
  350. throw std::out_of_range("key not found");
  351. }
  352. return i->second;
  353. }
  354. //! <b>Effects</b>: Swaps the contents of *this and x.
  355. //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
  356. //!
  357. //! <b>Throws</b>: Nothing.
  358. //!
  359. //! <b>Complexity</b>: Constant.
  360. void swap(map& x)
  361. { m_tree.swap(x.m_tree); }
  362. //! <b>Effects</b>: Inserts x if and only if there is no element in the container
  363. //! with key equivalent to the key of x.
  364. //!
  365. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  366. //! if the insertion takes place, and the iterator component of the pair
  367. //! points to the element with key equivalent to the key of x.
  368. //!
  369. //! <b>Complexity</b>: Logarithmic.
  370. std::pair<iterator,bool> insert(const value_type& x)
  371. { return m_tree.insert_unique(x); }
  372. //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if
  373. //! there is no element in the container with key equivalent to the key of x.
  374. //!
  375. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  376. //! if the insertion takes place, and the iterator component of the pair
  377. //! points to the element with key equivalent to the key of x.
  378. //!
  379. //! <b>Complexity</b>: Logarithmic.
  380. std::pair<iterator,bool> insert(const nonconst_value_type& x)
  381. { return m_tree.insert_unique(x); }
  382. //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
  383. //! only if there is no element in the container with key equivalent to the key of x.
  384. //!
  385. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  386. //! if the insertion takes place, and the iterator component of the pair
  387. //! points to the element with key equivalent to the key of x.
  388. //!
  389. //! <b>Complexity</b>: Logarithmic.
  390. std::pair<iterator,bool> insert(BOOST_MOVE_MACRO_RV_REF(nonconst_value_type) x)
  391. { return m_tree.insert_unique(BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  392. //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
  393. //! only if there is no element in the container with key equivalent to the key of x.
  394. //!
  395. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  396. //! if the insertion takes place, and the iterator component of the pair
  397. //! points to the element with key equivalent to the key of x.
  398. //!
  399. //! <b>Complexity</b>: Logarithmic.
  400. std::pair<iterator,bool> insert(BOOST_MOVE_MACRO_RV_REF(nonconst_impl_value_type) x)
  401. { return m_tree.insert_unique(BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  402. //! <b>Effects</b>: Move constructs a new value from x if and only if there is
  403. //! no element in the container with key equivalent to the key of x.
  404. //!
  405. //! <b>Returns</b>: The bool component of the returned pair is true if and only
  406. //! if the insertion takes place, and the iterator component of the pair
  407. //! points to the element with key equivalent to the key of x.
  408. //!
  409. //! <b>Complexity</b>: Logarithmic.
  410. std::pair<iterator,bool> insert(BOOST_MOVE_MACRO_RV_REF(value_type) x)
  411. { return m_tree.insert_unique(BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  412. //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
  413. //! no element in the container with key equivalent to the key of x.
  414. //! p is a hint pointing to where the insert should start to search.
  415. //!
  416. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  417. //! to the key of x.
  418. //!
  419. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  420. //! is inserted right before p.
  421. iterator insert(iterator position, const value_type& x)
  422. { return m_tree.insert_unique(position, x); }
  423. //! <b>Effects</b>: Move constructs a new value from x if and only if there is
  424. //! no element in the container with key equivalent to the key of x.
  425. //! p is a hint pointing to where the insert should start to search.
  426. //!
  427. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  428. //! to the key of x.
  429. //!
  430. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  431. //! is inserted right before p.
  432. iterator insert(iterator position, BOOST_MOVE_MACRO_RV_REF(nonconst_value_type) x)
  433. { return m_tree.insert_unique(position, BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  434. //! <b>Effects</b>: Move constructs a new value from x 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 in general, but amortized constant if t
  442. //! is inserted right before p.
  443. iterator insert(iterator position, BOOST_MOVE_MACRO_RV_REF(nonconst_impl_value_type) x)
  444. { return m_tree.insert_unique(position, BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  445. //! <b>Effects</b>: Inserts a copy of x in the container.
  446. //! p is a hint pointing to where the insert should start to search.
  447. //!
  448. //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
  449. //!
  450. //! <b>Complexity</b>: Logarithmic.
  451. iterator insert(iterator position, const nonconst_value_type& x)
  452. { return m_tree.insert_unique(position, x); }
  453. //! <b>Effects</b>: Inserts an element move constructed from x in the container.
  454. //! p is a hint pointing to where the insert should start to search.
  455. //!
  456. //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
  457. //!
  458. //! <b>Complexity</b>: Logarithmic.
  459. iterator insert(iterator position, BOOST_MOVE_MACRO_RV_REF(value_type) x)
  460. { return m_tree.insert_unique(position, BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  461. //! <b>Requires</b>: i, j are not iterators into *this.
  462. //!
  463. //! <b>Effects</b>: inserts each element from the range [i,j) if and only
  464. //! if there is no element with key equivalent to the key of that element.
  465. //!
  466. //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
  467. template <class InputIterator>
  468. void insert(InputIterator first, InputIterator last)
  469. { m_tree.insert_unique(first, last); }
  470. #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  471. //! <b>Effects</b>: Inserts an object of type T constructed with
  472. //! std::forward<Args>(args)... in the container if and only if there is
  473. //! no element in the container with an equivalent key.
  474. //! p is a hint pointing to where the insert should start to search.
  475. //!
  476. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  477. //! to the key of x.
  478. //!
  479. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  480. //! is inserted right before p.
  481. template <class... Args>
  482. iterator emplace(Args&&... args)
  483. { return m_tree.emplace_unique(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...); }
  484. //! <b>Effects</b>: Inserts an object of type T constructed with
  485. //! std::forward<Args>(args)... in the container if and only if there is
  486. //! no element in the container with an equivalent key.
  487. //! p is a hint pointing to where the insert should start to search.
  488. //!
  489. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  490. //! to the key of x.
  491. //!
  492. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  493. //! is inserted right before p.
  494. template <class... Args>
  495. iterator emplace_hint(const_iterator hint, Args&&... args)
  496. { return m_tree.emplace_hint_unique(hint, BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...); }
  497. #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
  498. iterator emplace()
  499. { return m_tree.emplace_unique(); }
  500. iterator emplace_hint(const_iterator hint)
  501. { return m_tree.emplace_hint_unique(hint); }
  502. #define BOOST_PP_LOCAL_MACRO(n) \
  503. template<BOOST_PP_ENUM_PARAMS(n, class P)> \
  504. iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
  505. { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
  506. \
  507. template<BOOST_PP_ENUM_PARAMS(n, class P)> \
  508. iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
  509. { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
  510. //!
  511. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
  512. #include BOOST_PP_LOCAL_ITERATE()
  513. #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
  514. //! <b>Effects</b>: Erases the element pointed to by position.
  515. //!
  516. //! <b>Returns</b>: Returns an iterator pointing to the element immediately
  517. //! following q prior to the element being erased. If no such element exists,
  518. //! returns end().
  519. //!
  520. //! <b>Complexity</b>: Amortized constant time
  521. iterator erase(const_iterator position)
  522. { return m_tree.erase(position); }
  523. //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
  524. //!
  525. //! <b>Returns</b>: Returns the number of erased elements.
  526. //!
  527. //! <b>Complexity</b>: log(size()) + count(k)
  528. size_type erase(const key_type& x)
  529. { return m_tree.erase(x); }
  530. //! <b>Effects</b>: Erases all the elements in the range [first, last).
  531. //!
  532. //! <b>Returns</b>: Returns last.
  533. //!
  534. //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
  535. iterator erase(const_iterator first, const_iterator last)
  536. { return m_tree.erase(first, last); }
  537. //! <b>Effects</b>: erase(a.begin(),a.end()).
  538. //!
  539. //! <b>Postcondition</b>: size() == 0.
  540. //!
  541. //! <b>Complexity</b>: linear in size().
  542. void clear()
  543. { m_tree.clear(); }
  544. //! <b>Returns</b>: An iterator pointing to an element with the key
  545. //! equivalent to x, or end() if such an element is not found.
  546. //!
  547. //! <b>Complexity</b>: Logarithmic.
  548. iterator find(const key_type& x)
  549. { return m_tree.find(x); }
  550. //! <b>Returns</b>: A const_iterator pointing to an element with the key
  551. //! equivalent to x, or end() if such an element is not found.
  552. //!
  553. //! <b>Complexity</b>: Logarithmic.
  554. const_iterator find(const key_type& x) const
  555. { return m_tree.find(x); }
  556. //! <b>Returns</b>: The number of elements with key equivalent to x.
  557. //!
  558. //! <b>Complexity</b>: log(size())+count(k)
  559. size_type count(const key_type& x) const
  560. { return m_tree.find(x) == m_tree.end() ? 0 : 1; }
  561. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  562. //! than k, or a.end() if such an element is not found.
  563. //!
  564. //! <b>Complexity</b>: Logarithmic
  565. iterator lower_bound(const key_type& x)
  566. { return m_tree.lower_bound(x); }
  567. //! <b>Returns</b>: A const iterator pointing to the first element with key not
  568. //! less than k, or a.end() if such an element is not found.
  569. //!
  570. //! <b>Complexity</b>: Logarithmic
  571. const_iterator lower_bound(const key_type& x) const
  572. { return m_tree.lower_bound(x); }
  573. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  574. //! than x, or end() if such an element is not found.
  575. //!
  576. //! <b>Complexity</b>: Logarithmic
  577. iterator upper_bound(const key_type& x)
  578. { return m_tree.upper_bound(x); }
  579. //! <b>Returns</b>: A const iterator pointing to the first element with key not
  580. //! less than x, or end() if such an element is not found.
  581. //!
  582. //! <b>Complexity</b>: Logarithmic
  583. const_iterator upper_bound(const key_type& x) const
  584. { return m_tree.upper_bound(x); }
  585. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  586. //!
  587. //! <b>Complexity</b>: Logarithmic
  588. std::pair<iterator,iterator> equal_range(const key_type& x)
  589. { return m_tree.equal_range(x); }
  590. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  591. //!
  592. //! <b>Complexity</b>: Logarithmic
  593. std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
  594. { return m_tree.equal_range(x); }
  595. /// @cond
  596. template <class K1, class T1, class C1, class A1>
  597. friend bool operator== (const map<K1, T1, C1, A1>&,
  598. const map<K1, T1, C1, A1>&);
  599. template <class K1, class T1, class C1, class A1>
  600. friend bool operator< (const map<K1, T1, C1, A1>&,
  601. const map<K1, T1, C1, A1>&);
  602. /// @endcond
  603. };
  604. template <class Key, class T, class Pred, class Alloc>
  605. inline bool operator==(const map<Key,T,Pred,Alloc>& x,
  606. const map<Key,T,Pred,Alloc>& y)
  607. { return x.m_tree == y.m_tree; }
  608. template <class Key, class T, class Pred, class Alloc>
  609. inline bool operator<(const map<Key,T,Pred,Alloc>& x,
  610. const map<Key,T,Pred,Alloc>& y)
  611. { return x.m_tree < y.m_tree; }
  612. template <class Key, class T, class Pred, class Alloc>
  613. inline bool operator!=(const map<Key,T,Pred,Alloc>& x,
  614. const map<Key,T,Pred,Alloc>& y)
  615. { return !(x == y); }
  616. template <class Key, class T, class Pred, class Alloc>
  617. inline bool operator>(const map<Key,T,Pred,Alloc>& x,
  618. const map<Key,T,Pred,Alloc>& y)
  619. { return y < x; }
  620. template <class Key, class T, class Pred, class Alloc>
  621. inline bool operator<=(const map<Key,T,Pred,Alloc>& x,
  622. const map<Key,T,Pred,Alloc>& y)
  623. { return !(y < x); }
  624. template <class Key, class T, class Pred, class Alloc>
  625. inline bool operator>=(const map<Key,T,Pred,Alloc>& x,
  626. const map<Key,T,Pred,Alloc>& y)
  627. { return !(x < y); }
  628. template <class Key, class T, class Pred, class Alloc>
  629. inline void swap(map<Key,T,Pred,Alloc>& x, map<Key,T,Pred,Alloc>& y)
  630. { x.swap(y); }
  631. /// @cond
  632. // Forward declaration of operators < and ==, needed for friend declaration.
  633. template <class Key, class T, class Pred, class Alloc>
  634. inline bool operator==(const multimap<Key,T,Pred,Alloc>& x,
  635. const multimap<Key,T,Pred,Alloc>& y);
  636. template <class Key, class T, class Pred, class Alloc>
  637. inline bool operator<(const multimap<Key,T,Pred,Alloc>& x,
  638. const multimap<Key,T,Pred,Alloc>& y);
  639. } //namespace container {
  640. /*
  641. //!has_trivial_destructor_after_move<> == true_type
  642. //!specialization for optimizations
  643. template <class K, class T, class C, class A>
  644. struct has_trivial_destructor_after_move<boost::container::map<K, T, C, A> >
  645. {
  646. static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
  647. };
  648. */
  649. namespace container {
  650. /// @endcond
  651. //! A multimap is a kind of associative container that supports equivalent keys
  652. //! (possibly containing multiple copies of the same key value) and provides for
  653. //! fast retrieval of values of another type T based on the keys. The multimap class
  654. //! supports bidirectional iterators.
  655. //!
  656. //! A multimap satisfies all of the requirements of a container and of a reversible
  657. //! container and of an associative container. For a
  658. //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
  659. //!
  660. //! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
  661. //!
  662. //! Alloc is the allocator to allocate the value_types
  663. //!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>).
  664. template <class Key, class T, class Pred, class Alloc>
  665. class multimap
  666. {
  667. /// @cond
  668. private:
  669. BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(multimap)
  670. typedef containers_detail::rbtree<Key,
  671. std::pair<const Key, T>,
  672. containers_detail::select1st< std::pair<const Key, T> >,
  673. Pred,
  674. Alloc> tree_t;
  675. tree_t m_tree; // red-black tree representing map
  676. /// @endcond
  677. public:
  678. // typedefs:
  679. typedef typename tree_t::key_type key_type;
  680. typedef typename tree_t::value_type value_type;
  681. typedef typename tree_t::pointer pointer;
  682. typedef typename tree_t::const_pointer const_pointer;
  683. typedef typename tree_t::reference reference;
  684. typedef typename tree_t::const_reference const_reference;
  685. typedef T mapped_type;
  686. typedef Pred key_compare;
  687. typedef typename tree_t::iterator iterator;
  688. typedef typename tree_t::const_iterator const_iterator;
  689. typedef typename tree_t::reverse_iterator reverse_iterator;
  690. typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
  691. typedef typename tree_t::size_type size_type;
  692. typedef typename tree_t::difference_type difference_type;
  693. typedef typename tree_t::allocator_type allocator_type;
  694. typedef typename tree_t::stored_allocator_type stored_allocator_type;
  695. typedef std::pair<key_type, mapped_type> nonconst_value_type;
  696. typedef containers_detail::pair
  697. <key_type, mapped_type> nonconst_impl_value_type;
  698. /// @cond
  699. class value_compare_impl
  700. : public Pred,
  701. public std::binary_function<value_type, value_type, bool>
  702. {
  703. friend class multimap<Key,T,Pred,Alloc>;
  704. protected :
  705. value_compare_impl(const Pred &c) : Pred(c) {}
  706. public:
  707. bool operator()(const value_type& x, const value_type& y) const {
  708. return Pred::operator()(x.first, y.first);
  709. }
  710. };
  711. /// @endcond
  712. typedef value_compare_impl value_compare;
  713. //! <b>Effects</b>: Constructs an empty multimap using the specified comparison
  714. //! object and allocator.
  715. //!
  716. //! <b>Complexity</b>: Constant.
  717. explicit multimap(const Pred& comp = Pred(),
  718. const allocator_type& a = allocator_type())
  719. : m_tree(comp, a)
  720. {}
  721. //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
  722. //! and allocator, and inserts elements from the range [first ,last ).
  723. //!
  724. //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
  725. //! comp and otherwise N logN, where N is last - first.
  726. template <class InputIterator>
  727. multimap(InputIterator first, InputIterator last,
  728. const Pred& comp = Pred(),
  729. const allocator_type& a = allocator_type())
  730. : m_tree(first, last, comp, a, false)
  731. {}
  732. //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
  733. //! allocator, and inserts elements from the ordered range [first ,last). This function
  734. //! is more efficient than the normal range creation for ordered ranges.
  735. //!
  736. //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
  737. //!
  738. //! <b>Complexity</b>: Linear in N.
  739. template <class InputIterator>
  740. multimap(ordered_range_t ordered_range, InputIterator first, InputIterator last, const Pred& comp = Pred(),
  741. const allocator_type& a = allocator_type())
  742. : m_tree(ordered_range, first, last, comp, a)
  743. {}
  744. //! <b>Effects</b>: Copy constructs a multimap.
  745. //!
  746. //! <b>Complexity</b>: Linear in x.size().
  747. multimap(const multimap<Key,T,Pred,Alloc>& x)
  748. : m_tree(x.m_tree)
  749. {}
  750. //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
  751. //!
  752. //! <b>Complexity</b>: Construct.
  753. //!
  754. //! <b>Postcondition</b>: x is emptied.
  755. multimap(BOOST_MOVE_MACRO_RV_REF(multimap) x)
  756. : m_tree(BOOST_CONTAINER_MOVE_NAMESPACE::move(x.m_tree))
  757. {}
  758. //! <b>Effects</b>: Makes *this a copy of x.
  759. //!
  760. //! <b>Complexity</b>: Linear in x.size().
  761. multimap& operator=(BOOST_MOVE_MACRO_COPY_ASSIGN_REF(multimap) x)
  762. { m_tree = x.m_tree; return *this; }
  763. //! <b>Effects</b>: this->swap(x.get()).
  764. //!
  765. //! <b>Complexity</b>: Constant.
  766. multimap& operator=(BOOST_MOVE_MACRO_RV_REF(multimap) x)
  767. { m_tree = BOOST_CONTAINER_MOVE_NAMESPACE::move(x.m_tree); return *this; }
  768. //! <b>Effects</b>: Returns the comparison object out
  769. //! of which a was constructed.
  770. //!
  771. //! <b>Complexity</b>: Constant.
  772. key_compare key_comp() const
  773. { return m_tree.key_comp(); }
  774. //! <b>Effects</b>: Returns an object of value_compare constructed out
  775. //! of the comparison object.
  776. //!
  777. //! <b>Complexity</b>: Constant.
  778. value_compare value_comp() const
  779. { return value_compare(m_tree.key_comp()); }
  780. //! <b>Effects</b>: Returns a copy of the Allocator that
  781. //! was passed to the object's constructor.
  782. //!
  783. //! <b>Complexity</b>: Constant.
  784. allocator_type get_allocator() const
  785. { return m_tree.get_allocator(); }
  786. const stored_allocator_type &get_stored_allocator() const
  787. { return m_tree.get_stored_allocator(); }
  788. stored_allocator_type &get_stored_allocator()
  789. { return m_tree.get_stored_allocator(); }
  790. //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
  791. //!
  792. //! <b>Throws</b>: Nothing.
  793. //!
  794. //! <b>Complexity</b>: Constant.
  795. iterator begin()
  796. { return m_tree.begin(); }
  797. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
  798. //!
  799. //! <b>Throws</b>: Nothing.
  800. //!
  801. //! <b>Complexity</b>: Constant.
  802. const_iterator begin() const
  803. { return m_tree.begin(); }
  804. //! <b>Effects</b>: Returns an iterator to the end of the container.
  805. //!
  806. //! <b>Throws</b>: Nothing.
  807. //!
  808. //! <b>Complexity</b>: Constant.
  809. iterator end()
  810. { return m_tree.end(); }
  811. //! <b>Effects</b>: Returns a const_iterator to the end of the container.
  812. //!
  813. //! <b>Throws</b>: Nothing.
  814. //!
  815. //! <b>Complexity</b>: Constant.
  816. const_iterator end() const
  817. { return m_tree.end(); }
  818. //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
  819. //! of the reversed container.
  820. //!
  821. //! <b>Throws</b>: Nothing.
  822. //!
  823. //! <b>Complexity</b>: Constant.
  824. reverse_iterator rbegin()
  825. { return m_tree.rbegin(); }
  826. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
  827. //! of the reversed container.
  828. //!
  829. //! <b>Throws</b>: Nothing.
  830. //!
  831. //! <b>Complexity</b>: Constant.
  832. const_reverse_iterator rbegin() const
  833. { return m_tree.rbegin(); }
  834. //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
  835. //! of the reversed container.
  836. //!
  837. //! <b>Throws</b>: Nothing.
  838. //!
  839. //! <b>Complexity</b>: Constant.
  840. reverse_iterator rend()
  841. { return m_tree.rend(); }
  842. //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
  843. //! of the reversed container.
  844. //!
  845. //! <b>Throws</b>: Nothing.
  846. //!
  847. //! <b>Complexity</b>: Constant.
  848. const_reverse_iterator rend() const
  849. { return m_tree.rend(); }
  850. //! <b>Effects</b>: Returns true if the container contains no elements.
  851. //!
  852. //! <b>Throws</b>: Nothing.
  853. //!
  854. //! <b>Complexity</b>: Constant.
  855. bool empty() const
  856. { return m_tree.empty(); }
  857. //! <b>Effects</b>: Returns the number of the elements contained in the container.
  858. //!
  859. //! <b>Throws</b>: Nothing.
  860. //!
  861. //! <b>Complexity</b>: Constant.
  862. size_type size() const
  863. { return m_tree.size(); }
  864. //! <b>Effects</b>: Returns the largest possible size of the container.
  865. //!
  866. //! <b>Throws</b>: Nothing.
  867. //!
  868. //! <b>Complexity</b>: Constant.
  869. size_type max_size() const
  870. { return m_tree.max_size(); }
  871. //! <b>Effects</b>: Swaps the contents of *this and x.
  872. //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
  873. //!
  874. //! <b>Throws</b>: Nothing.
  875. //!
  876. //! <b>Complexity</b>: Constant.
  877. void swap(multimap& x)
  878. { m_tree.swap(x.m_tree); }
  879. //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
  880. //! newly inserted element.
  881. //!
  882. //! <b>Complexity</b>: Logarithmic.
  883. iterator insert(const value_type& x)
  884. { return m_tree.insert_equal(x); }
  885. //! <b>Effects</b>: Inserts a new value constructed from x and returns
  886. //! the iterator pointing to the newly inserted element.
  887. //!
  888. //! <b>Complexity</b>: Logarithmic.
  889. iterator insert(const nonconst_value_type& x)
  890. { return m_tree.insert_equal(x); }
  891. //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
  892. //! the iterator pointing to the newly inserted element.
  893. //!
  894. //! <b>Complexity</b>: Logarithmic.
  895. iterator insert(BOOST_MOVE_MACRO_RV_REF(nonconst_value_type) x)
  896. { return m_tree.insert_equal(BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  897. //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
  898. //! the iterator pointing to the newly inserted element.
  899. //!
  900. //! <b>Complexity</b>: Logarithmic.
  901. iterator insert(BOOST_MOVE_MACRO_RV_REF(nonconst_impl_value_type) x)
  902. { return m_tree.insert_equal(BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  903. //! <b>Effects</b>: Inserts a copy of x in the container.
  904. //! p is a hint pointing to where the insert should start to search.
  905. //!
  906. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  907. //! to the key of x.
  908. //!
  909. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  910. //! is inserted right before p.
  911. iterator insert(iterator position, const value_type& x)
  912. { return m_tree.insert_equal(position, x); }
  913. //! <b>Effects</b>: Inserts a new value constructed from x in the container.
  914. //! p is a hint pointing to where the insert should start to search.
  915. //!
  916. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  917. //! to the key of x.
  918. //!
  919. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  920. //! is inserted right before p.
  921. iterator insert(iterator position, const nonconst_value_type& x)
  922. { return m_tree.insert_equal(position, x); }
  923. //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
  924. //! p is a hint pointing to where the insert should start to search.
  925. //!
  926. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  927. //! to the key of x.
  928. //!
  929. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  930. //! is inserted right before p.
  931. iterator insert(iterator position, BOOST_MOVE_MACRO_RV_REF(nonconst_value_type) x)
  932. { return m_tree.insert_equal(position, BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  933. //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
  934. //! p is a hint pointing to where the insert should start to search.
  935. //!
  936. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  937. //! to the key of x.
  938. //!
  939. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  940. //! is inserted right before p.
  941. iterator insert(iterator position, BOOST_MOVE_MACRO_RV_REF(nonconst_impl_value_type) x)
  942. { return m_tree.insert_equal(position, BOOST_CONTAINER_MOVE_NAMESPACE::move(x)); }
  943. //! <b>Requires</b>: i, j are not iterators into *this.
  944. //!
  945. //! <b>Effects</b>: inserts each element from the range [i,j) .
  946. //!
  947. //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
  948. template <class InputIterator>
  949. void insert(InputIterator first, InputIterator last)
  950. { m_tree.insert_equal(first, last); }
  951. #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  952. //! <b>Effects</b>: Inserts an object of type T constructed with
  953. //! std::forward<Args>(args)... in the container.
  954. //! p is a hint pointing to where the insert should start to search.
  955. //!
  956. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  957. //! to the key of x.
  958. //!
  959. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  960. //! is inserted right before p.
  961. template <class... Args>
  962. iterator emplace(Args&&... args)
  963. { return m_tree.emplace_equal(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...); }
  964. //! <b>Effects</b>: Inserts an object of type T constructed with
  965. //! std::forward<Args>(args)... in the container.
  966. //! p is a hint pointing to where the insert should start to search.
  967. //!
  968. //! <b>Returns</b>: An iterator pointing to the element with key equivalent
  969. //! to the key of x.
  970. //!
  971. //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
  972. //! is inserted right before p.
  973. template <class... Args>
  974. iterator emplace_hint(const_iterator hint, Args&&... args)
  975. { return m_tree.emplace_hint_equal(hint, BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...); }
  976. #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
  977. iterator emplace()
  978. { return m_tree.emplace_equal(); }
  979. iterator emplace_hint(const_iterator hint)
  980. { return m_tree.emplace_hint_equal(hint); }
  981. #define BOOST_PP_LOCAL_MACRO(n) \
  982. template<BOOST_PP_ENUM_PARAMS(n, class P)> \
  983. iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
  984. { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
  985. \
  986. template<BOOST_PP_ENUM_PARAMS(n, class P)> \
  987. iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
  988. { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
  989. //!
  990. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
  991. #include BOOST_PP_LOCAL_ITERATE()
  992. #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
  993. //! <b>Effects</b>: Erases the element pointed to by position.
  994. //!
  995. //! <b>Returns</b>: Returns an iterator pointing to the element immediately
  996. //! following q prior to the element being erased. If no such element exists,
  997. //! returns end().
  998. //!
  999. //! <b>Complexity</b>: Amortized constant time
  1000. iterator erase(const_iterator position)
  1001. { return m_tree.erase(position); }
  1002. //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
  1003. //!
  1004. //! <b>Returns</b>: Returns the number of erased elements.
  1005. //!
  1006. //! <b>Complexity</b>: log(size()) + count(k)
  1007. size_type erase(const key_type& x)
  1008. { return m_tree.erase(x); }
  1009. //! <b>Effects</b>: Erases all the elements in the range [first, last).
  1010. //!
  1011. //! <b>Returns</b>: Returns last.
  1012. //!
  1013. //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
  1014. iterator erase(const_iterator first, const_iterator last)
  1015. { return m_tree.erase(first, last); }
  1016. //! <b>Effects</b>: erase(a.begin(),a.end()).
  1017. //!
  1018. //! <b>Postcondition</b>: size() == 0.
  1019. //!
  1020. //! <b>Complexity</b>: linear in size().
  1021. void clear()
  1022. { m_tree.clear(); }
  1023. //! <b>Returns</b>: An iterator pointing to an element with the key
  1024. //! equivalent to x, or end() if such an element is not found.
  1025. //!
  1026. //! <b>Complexity</b>: Logarithmic.
  1027. iterator find(const key_type& x)
  1028. { return m_tree.find(x); }
  1029. //! <b>Returns</b>: A const iterator pointing to an element with the key
  1030. //! equivalent to x, or end() if such an element is not found.
  1031. //!
  1032. //! <b>Complexity</b>: Logarithmic.
  1033. const_iterator find(const key_type& x) const
  1034. { return m_tree.find(x); }
  1035. //! <b>Returns</b>: The number of elements with key equivalent to x.
  1036. //!
  1037. //! <b>Complexity</b>: log(size())+count(k)
  1038. size_type count(const key_type& x) const
  1039. { return m_tree.count(x); }
  1040. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  1041. //! than k, or a.end() if such an element is not found.
  1042. //!
  1043. //! <b>Complexity</b>: Logarithmic
  1044. iterator lower_bound(const key_type& x)
  1045. {return m_tree.lower_bound(x); }
  1046. //! <b>Returns</b>: A const iterator pointing to the first element with key not
  1047. //! less than k, or a.end() if such an element is not found.
  1048. //!
  1049. //! <b>Complexity</b>: Logarithmic
  1050. const_iterator lower_bound(const key_type& x) const
  1051. { return m_tree.lower_bound(x); }
  1052. //! <b>Returns</b>: An iterator pointing to the first element with key not less
  1053. //! than x, or end() if such an element is not found.
  1054. //!
  1055. //! <b>Complexity</b>: Logarithmic
  1056. iterator upper_bound(const key_type& x)
  1057. { return m_tree.upper_bound(x); }
  1058. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  1059. //!
  1060. //! <b>Complexity</b>: Logarithmic
  1061. std::pair<iterator,iterator> equal_range(const key_type& x)
  1062. { return m_tree.equal_range(x); }
  1063. //! <b>Returns</b>: A const iterator pointing to the first element with key not
  1064. //! less than x, or end() if such an element is not found.
  1065. //!
  1066. //! <b>Complexity</b>: Logarithmic
  1067. const_iterator upper_bound(const key_type& x) const
  1068. { return m_tree.upper_bound(x); }
  1069. //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
  1070. //!
  1071. //! <b>Complexity</b>: Logarithmic
  1072. std::pair<const_iterator,const_iterator>
  1073. equal_range(const key_type& x) const
  1074. { return m_tree.equal_range(x); }
  1075. /// @cond
  1076. template <class K1, class T1, class C1, class A1>
  1077. friend bool operator== (const multimap<K1, T1, C1, A1>& x,
  1078. const multimap<K1, T1, C1, A1>& y);
  1079. template <class K1, class T1, class C1, class A1>
  1080. friend bool operator< (const multimap<K1, T1, C1, A1>& x,
  1081. const multimap<K1, T1, C1, A1>& y);
  1082. /// @endcond
  1083. };
  1084. template <class Key, class T, class Pred, class Alloc>
  1085. inline bool operator==(const multimap<Key,T,Pred,Alloc>& x,
  1086. const multimap<Key,T,Pred,Alloc>& y)
  1087. { return x.m_tree == y.m_tree; }
  1088. template <class Key, class T, class Pred, class Alloc>
  1089. inline bool operator<(const multimap<Key,T,Pred,Alloc>& x,
  1090. const multimap<Key,T,Pred,Alloc>& y)
  1091. { return x.m_tree < y.m_tree; }
  1092. template <class Key, class T, class Pred, class Alloc>
  1093. inline bool operator!=(const multimap<Key,T,Pred,Alloc>& x,
  1094. const multimap<Key,T,Pred,Alloc>& y)
  1095. { return !(x == y); }
  1096. template <class Key, class T, class Pred, class Alloc>
  1097. inline bool operator>(const multimap<Key,T,Pred,Alloc>& x,
  1098. const multimap<Key,T,Pred,Alloc>& y)
  1099. { return y < x; }
  1100. template <class Key, class T, class Pred, class Alloc>
  1101. inline bool operator<=(const multimap<Key,T,Pred,Alloc>& x,
  1102. const multimap<Key,T,Pred,Alloc>& y)
  1103. { return !(y < x); }
  1104. template <class Key, class T, class Pred, class Alloc>
  1105. inline bool operator>=(const multimap<Key,T,Pred,Alloc>& x,
  1106. const multimap<Key,T,Pred,Alloc>& y)
  1107. { return !(x < y); }
  1108. template <class Key, class T, class Pred, class Alloc>
  1109. inline void swap(multimap<Key,T,Pred,Alloc>& x, multimap<Key,T,Pred,Alloc>& y)
  1110. { x.swap(y); }
  1111. /// @cond
  1112. } //namespace container {
  1113. /*
  1114. //!has_trivial_destructor_after_move<> == true_type
  1115. //!specialization for optimizations
  1116. template <class K, class T, class C, class A>
  1117. struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, A> >
  1118. {
  1119. static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
  1120. };
  1121. */
  1122. namespace container {
  1123. /// @endcond
  1124. }}
  1125. #include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
  1126. #endif /* BOOST_CONTAINERS_MAP_HPP */