unordered_map.hpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656
  1. // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
  2. // Copyright (C) 2005-2011 Daniel James.
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/unordered for documentation
  6. #ifndef BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
  7. #define BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
  8. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  9. # pragma once
  10. #endif
  11. #include <boost/unordered/unordered_map_fwd.hpp>
  12. #include <boost/unordered/detail/equivalent.hpp>
  13. #include <boost/unordered/detail/unique.hpp>
  14. #include <boost/unordered/detail/util.hpp>
  15. #include <boost/functional/hash.hpp>
  16. #include <boost/move/move.hpp>
  17. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  18. #include <initializer_list>
  19. #endif
  20. #if defined(BOOST_MSVC)
  21. #pragma warning(push)
  22. #if BOOST_MSVC >= 1400
  23. #pragma warning(disable:4396) //the inline specifier cannot be used when a
  24. // friend declaration refers to a specialization
  25. // of a function template
  26. #endif
  27. #endif
  28. namespace boost
  29. {
  30. namespace unordered
  31. {
  32. template <class K, class T, class H, class P, class A>
  33. class unordered_map
  34. {
  35. #if defined(BOOST_UNORDERED_USE_MOVE)
  36. BOOST_COPYABLE_AND_MOVABLE(unordered_map)
  37. #endif
  38. public:
  39. typedef K key_type;
  40. typedef std::pair<const K, T> value_type;
  41. typedef T mapped_type;
  42. typedef H hasher;
  43. typedef P key_equal;
  44. typedef A allocator_type;
  45. private:
  46. typedef boost::unordered::detail::map<A, K, T, H, P> types;
  47. typedef typename types::traits allocator_traits;
  48. typedef typename types::table table;
  49. public:
  50. typedef typename allocator_traits::pointer pointer;
  51. typedef typename allocator_traits::const_pointer const_pointer;
  52. typedef value_type& reference;
  53. typedef value_type const& const_reference;
  54. typedef std::size_t size_type;
  55. typedef std::ptrdiff_t difference_type;
  56. typedef typename table::cl_iterator const_local_iterator;
  57. typedef typename table::l_iterator local_iterator;
  58. typedef typename table::c_iterator const_iterator;
  59. typedef typename table::iterator iterator;
  60. private:
  61. table table_;
  62. public:
  63. // constructors
  64. explicit unordered_map(
  65. size_type = boost::unordered::detail::default_bucket_count,
  66. const hasher& = hasher(),
  67. const key_equal& = key_equal(),
  68. const allocator_type& = allocator_type());
  69. explicit unordered_map(allocator_type const&);
  70. template <class InputIt>
  71. unordered_map(InputIt, InputIt);
  72. template <class InputIt>
  73. unordered_map(
  74. InputIt, InputIt,
  75. size_type,
  76. const hasher& = hasher(),
  77. const key_equal& = key_equal());
  78. template <class InputIt>
  79. unordered_map(
  80. InputIt, InputIt,
  81. size_type,
  82. const hasher&,
  83. const key_equal&,
  84. const allocator_type&);
  85. // copy/move constructors
  86. unordered_map(unordered_map const&);
  87. unordered_map(unordered_map const&, allocator_type const&);
  88. #if defined(BOOST_UNORDERED_USE_MOVE)
  89. unordered_map(BOOST_RV_REF(unordered_map) other)
  90. BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
  91. : table_(other.table_, boost::unordered::detail::move_tag())
  92. {
  93. }
  94. #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  95. unordered_map(unordered_map&& other)
  96. BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
  97. : table_(other.table_, boost::unordered::detail::move_tag())
  98. {
  99. }
  100. #endif
  101. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  102. unordered_map(unordered_map&&, allocator_type const&);
  103. #endif
  104. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  105. unordered_map(
  106. std::initializer_list<value_type>,
  107. size_type = boost::unordered::detail::default_bucket_count,
  108. const hasher& = hasher(),
  109. const key_equal&l = key_equal(),
  110. const allocator_type& = allocator_type());
  111. #endif
  112. // Destructor
  113. ~unordered_map() BOOST_NOEXCEPT;
  114. // Assign
  115. #if defined(BOOST_UNORDERED_USE_MOVE)
  116. unordered_map& operator=(BOOST_COPY_ASSIGN_REF(unordered_map) x)
  117. {
  118. table_.assign(x.table_);
  119. return *this;
  120. }
  121. unordered_map& operator=(BOOST_RV_REF(unordered_map) x)
  122. {
  123. table_.move_assign(x.table_);
  124. return *this;
  125. }
  126. #else
  127. unordered_map& operator=(unordered_map const& x)
  128. {
  129. table_.assign(x.table_);
  130. return *this;
  131. }
  132. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  133. unordered_map& operator=(unordered_map&& x)
  134. {
  135. table_.move_assign(x.table_);
  136. return *this;
  137. }
  138. #endif
  139. #endif
  140. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  141. unordered_map& operator=(std::initializer_list<value_type>);
  142. #endif
  143. allocator_type get_allocator() const BOOST_NOEXCEPT
  144. {
  145. return table_.node_alloc();
  146. }
  147. // size and capacity
  148. bool empty() const BOOST_NOEXCEPT
  149. {
  150. return table_.size_ == 0;
  151. }
  152. size_type size() const BOOST_NOEXCEPT
  153. {
  154. return table_.size_;
  155. }
  156. size_type max_size() const BOOST_NOEXCEPT;
  157. // iterators
  158. iterator begin() BOOST_NOEXCEPT
  159. {
  160. return table_.begin();
  161. }
  162. const_iterator begin() const BOOST_NOEXCEPT
  163. {
  164. return table_.begin();
  165. }
  166. iterator end() BOOST_NOEXCEPT
  167. {
  168. return iterator();
  169. }
  170. const_iterator end() const BOOST_NOEXCEPT
  171. {
  172. return const_iterator();
  173. }
  174. const_iterator cbegin() const BOOST_NOEXCEPT
  175. {
  176. return table_.begin();
  177. }
  178. const_iterator cend() const BOOST_NOEXCEPT
  179. {
  180. return const_iterator();
  181. }
  182. // emplace
  183. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  184. template <class... Args>
  185. std::pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args)
  186. {
  187. return table_.emplace(boost::forward<Args>(args)...);
  188. }
  189. template <class... Args>
  190. iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
  191. {
  192. return table_.emplace(boost::forward<Args>(args)...).first;
  193. }
  194. #else
  195. #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
  196. // 0 argument emplace requires special treatment in case
  197. // the container is instantiated with a value type that
  198. // doesn't have a default constructor.
  199. std::pair<iterator, bool> emplace(
  200. boost::unordered::detail::empty_emplace
  201. = boost::unordered::detail::empty_emplace(),
  202. value_type v = value_type())
  203. {
  204. return this->emplace(boost::move(v));
  205. }
  206. iterator emplace_hint(const_iterator hint,
  207. boost::unordered::detail::empty_emplace
  208. = boost::unordered::detail::empty_emplace(),
  209. value_type v = value_type()
  210. )
  211. {
  212. return this->emplace_hint(hint, boost::move(v));
  213. }
  214. #endif
  215. template <typename A0>
  216. std::pair<iterator, bool> emplace(BOOST_FWD_REF(A0) a0)
  217. {
  218. return table_.emplace(
  219. boost::unordered::detail::create_emplace_args(
  220. boost::forward<A0>(a0))
  221. );
  222. }
  223. template <typename A0>
  224. iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
  225. {
  226. return table_.emplace(
  227. boost::unordered::detail::create_emplace_args(
  228. boost::forward<A0>(a0))
  229. ).first;
  230. }
  231. template <typename A0, typename A1>
  232. std::pair<iterator, bool> emplace(
  233. BOOST_FWD_REF(A0) a0,
  234. BOOST_FWD_REF(A1) a1)
  235. {
  236. return table_.emplace(
  237. boost::unordered::detail::create_emplace_args(
  238. boost::forward<A0>(a0),
  239. boost::forward<A1>(a1))
  240. );
  241. }
  242. template <typename A0, typename A1>
  243. iterator emplace_hint(const_iterator,
  244. BOOST_FWD_REF(A0) a0,
  245. BOOST_FWD_REF(A1) a1)
  246. {
  247. return table_.emplace(
  248. boost::unordered::detail::create_emplace_args(
  249. boost::forward<A0>(a0),
  250. boost::forward<A1>(a1))
  251. ).first;
  252. }
  253. template <typename A0, typename A1, typename A2>
  254. std::pair<iterator, bool> emplace(
  255. BOOST_FWD_REF(A0) a0,
  256. BOOST_FWD_REF(A1) a1,
  257. BOOST_FWD_REF(A2) a2)
  258. {
  259. return table_.emplace(
  260. boost::unordered::detail::create_emplace_args(
  261. boost::forward<A0>(a0),
  262. boost::forward<A1>(a1),
  263. boost::forward<A2>(a2))
  264. );
  265. }
  266. template <typename A0, typename A1, typename A2>
  267. iterator emplace_hint(const_iterator,
  268. BOOST_FWD_REF(A0) a0,
  269. BOOST_FWD_REF(A1) a1,
  270. BOOST_FWD_REF(A2) a2)
  271. {
  272. return table_.emplace(
  273. boost::unordered::detail::create_emplace_args(
  274. boost::forward<A0>(a0),
  275. boost::forward<A1>(a1),
  276. boost::forward<A2>(a2))
  277. ).first;
  278. }
  279. #define BOOST_UNORDERED_EMPLACE(z, n, _) \
  280. template < \
  281. BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
  282. > \
  283. std::pair<iterator, bool> emplace( \
  284. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
  285. ) \
  286. { \
  287. return table_.emplace( \
  288. boost::unordered::detail::create_emplace_args( \
  289. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
  290. a) \
  291. )); \
  292. } \
  293. \
  294. template < \
  295. BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
  296. > \
  297. iterator emplace_hint( \
  298. const_iterator, \
  299. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
  300. ) \
  301. { \
  302. return table_.emplace( \
  303. boost::unordered::detail::create_emplace_args( \
  304. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
  305. a) \
  306. )).first; \
  307. }
  308. BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
  309. BOOST_UNORDERED_EMPLACE, _)
  310. #undef BOOST_UNORDERED_EMPLACE
  311. #endif
  312. std::pair<iterator, bool> insert(value_type const& x)
  313. {
  314. return this->emplace(x);
  315. }
  316. std::pair<iterator, bool> insert(BOOST_RV_REF(value_type) x)
  317. {
  318. return this->emplace(boost::move(x));
  319. }
  320. iterator insert(const_iterator hint, value_type const& x)
  321. {
  322. return this->emplace_hint(hint, x);
  323. }
  324. iterator insert(const_iterator hint, BOOST_RV_REF(value_type) x)
  325. {
  326. return this->emplace_hint(hint, boost::move(x));
  327. }
  328. template <class InputIt> void insert(InputIt, InputIt);
  329. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  330. void insert(std::initializer_list<value_type>);
  331. #endif
  332. iterator erase(const_iterator);
  333. size_type erase(const key_type&);
  334. iterator erase(const_iterator, const_iterator);
  335. void quick_erase(const_iterator it) { erase(it); }
  336. void erase_return_void(const_iterator it) { erase(it); }
  337. void clear();
  338. void swap(unordered_map&);
  339. // observers
  340. hasher hash_function() const;
  341. key_equal key_eq() const;
  342. mapped_type& operator[](const key_type&);
  343. mapped_type& at(const key_type&);
  344. mapped_type const& at(const key_type&) const;
  345. // lookup
  346. iterator find(const key_type&);
  347. const_iterator find(const key_type&) const;
  348. template <class CompatibleKey, class CompatibleHash,
  349. class CompatiblePredicate>
  350. iterator find(
  351. CompatibleKey const&,
  352. CompatibleHash const&,
  353. CompatiblePredicate const&);
  354. template <class CompatibleKey, class CompatibleHash,
  355. class CompatiblePredicate>
  356. const_iterator find(
  357. CompatibleKey const&,
  358. CompatibleHash const&,
  359. CompatiblePredicate const&) const;
  360. size_type count(const key_type&) const;
  361. std::pair<iterator, iterator>
  362. equal_range(const key_type&);
  363. std::pair<const_iterator, const_iterator>
  364. equal_range(const key_type&) const;
  365. // bucket interface
  366. size_type bucket_count() const BOOST_NOEXCEPT
  367. {
  368. return table_.bucket_count_;
  369. }
  370. size_type max_bucket_count() const BOOST_NOEXCEPT
  371. {
  372. return table_.max_bucket_count();
  373. }
  374. size_type bucket_size(size_type) const;
  375. size_type bucket(const key_type& k) const
  376. {
  377. return table_.hash_to_bucket(table_.hash(k));
  378. }
  379. local_iterator begin(size_type n)
  380. {
  381. return local_iterator(
  382. table_.begin(n), n, table_.bucket_count_);
  383. }
  384. const_local_iterator begin(size_type n) const
  385. {
  386. return const_local_iterator(
  387. table_.begin(n), n, table_.bucket_count_);
  388. }
  389. local_iterator end(size_type)
  390. {
  391. return local_iterator();
  392. }
  393. const_local_iterator end(size_type) const
  394. {
  395. return const_local_iterator();
  396. }
  397. const_local_iterator cbegin(size_type n) const
  398. {
  399. return const_local_iterator(
  400. table_.begin(n), n, table_.bucket_count_);
  401. }
  402. const_local_iterator cend(size_type) const
  403. {
  404. return const_local_iterator();
  405. }
  406. // hash policy
  407. float max_load_factor() const BOOST_NOEXCEPT
  408. {
  409. return table_.mlf_;
  410. }
  411. float load_factor() const BOOST_NOEXCEPT;
  412. void max_load_factor(float) BOOST_NOEXCEPT;
  413. void rehash(size_type);
  414. void reserve(size_type);
  415. #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
  416. friend bool operator==<K,T,H,P,A>(
  417. unordered_map const&, unordered_map const&);
  418. friend bool operator!=<K,T,H,P,A>(
  419. unordered_map const&, unordered_map const&);
  420. #endif
  421. }; // class template unordered_map
  422. template <class K, class T, class H, class P, class A>
  423. class unordered_multimap
  424. {
  425. #if defined(BOOST_UNORDERED_USE_MOVE)
  426. BOOST_COPYABLE_AND_MOVABLE(unordered_multimap)
  427. #endif
  428. public:
  429. typedef K key_type;
  430. typedef std::pair<const K, T> value_type;
  431. typedef T mapped_type;
  432. typedef H hasher;
  433. typedef P key_equal;
  434. typedef A allocator_type;
  435. private:
  436. typedef boost::unordered::detail::multimap<A, K, T, H, P> types;
  437. typedef typename types::traits allocator_traits;
  438. typedef typename types::table table;
  439. public:
  440. typedef typename allocator_traits::pointer pointer;
  441. typedef typename allocator_traits::const_pointer const_pointer;
  442. typedef value_type& reference;
  443. typedef value_type const& const_reference;
  444. typedef std::size_t size_type;
  445. typedef std::ptrdiff_t difference_type;
  446. typedef typename table::cl_iterator const_local_iterator;
  447. typedef typename table::l_iterator local_iterator;
  448. typedef typename table::c_iterator const_iterator;
  449. typedef typename table::iterator iterator;
  450. private:
  451. table table_;
  452. public:
  453. // constructors
  454. explicit unordered_multimap(
  455. size_type = boost::unordered::detail::default_bucket_count,
  456. const hasher& = hasher(),
  457. const key_equal& = key_equal(),
  458. const allocator_type& = allocator_type());
  459. explicit unordered_multimap(allocator_type const&);
  460. template <class InputIt>
  461. unordered_multimap(InputIt, InputIt);
  462. template <class InputIt>
  463. unordered_multimap(
  464. InputIt, InputIt,
  465. size_type,
  466. const hasher& = hasher(),
  467. const key_equal& = key_equal());
  468. template <class InputIt>
  469. unordered_multimap(
  470. InputIt, InputIt,
  471. size_type,
  472. const hasher&,
  473. const key_equal&,
  474. const allocator_type&);
  475. // copy/move constructors
  476. unordered_multimap(unordered_multimap const&);
  477. unordered_multimap(unordered_multimap const&, allocator_type const&);
  478. #if defined(BOOST_UNORDERED_USE_MOVE)
  479. unordered_multimap(BOOST_RV_REF(unordered_multimap) other)
  480. BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
  481. : table_(other.table_, boost::unordered::detail::move_tag())
  482. {
  483. }
  484. #elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  485. unordered_multimap(unordered_multimap&& other)
  486. BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
  487. : table_(other.table_, boost::unordered::detail::move_tag())
  488. {
  489. }
  490. #endif
  491. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  492. unordered_multimap(unordered_multimap&&, allocator_type const&);
  493. #endif
  494. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  495. unordered_multimap(
  496. std::initializer_list<value_type>,
  497. size_type = boost::unordered::detail::default_bucket_count,
  498. const hasher& = hasher(),
  499. const key_equal&l = key_equal(),
  500. const allocator_type& = allocator_type());
  501. #endif
  502. // Destructor
  503. ~unordered_multimap() BOOST_NOEXCEPT;
  504. // Assign
  505. #if defined(BOOST_UNORDERED_USE_MOVE)
  506. unordered_multimap& operator=(
  507. BOOST_COPY_ASSIGN_REF(unordered_multimap) x)
  508. {
  509. table_.assign(x.table_);
  510. return *this;
  511. }
  512. unordered_multimap& operator=(BOOST_RV_REF(unordered_multimap) x)
  513. {
  514. table_.move_assign(x.table_);
  515. return *this;
  516. }
  517. #else
  518. unordered_multimap& operator=(unordered_multimap const& x)
  519. {
  520. table_.assign(x.table_);
  521. return *this;
  522. }
  523. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  524. unordered_multimap& operator=(unordered_multimap&& x)
  525. {
  526. table_.move_assign(x.table_);
  527. return *this;
  528. }
  529. #endif
  530. #endif
  531. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  532. unordered_multimap& operator=(std::initializer_list<value_type>);
  533. #endif
  534. allocator_type get_allocator() const BOOST_NOEXCEPT
  535. {
  536. return table_.node_alloc();
  537. }
  538. // size and capacity
  539. bool empty() const BOOST_NOEXCEPT
  540. {
  541. return table_.size_ == 0;
  542. }
  543. size_type size() const BOOST_NOEXCEPT
  544. {
  545. return table_.size_;
  546. }
  547. size_type max_size() const BOOST_NOEXCEPT;
  548. // iterators
  549. iterator begin() BOOST_NOEXCEPT
  550. {
  551. return table_.begin();
  552. }
  553. const_iterator begin() const BOOST_NOEXCEPT
  554. {
  555. return table_.begin();
  556. }
  557. iterator end() BOOST_NOEXCEPT
  558. {
  559. return iterator();
  560. }
  561. const_iterator end() const BOOST_NOEXCEPT
  562. {
  563. return const_iterator();
  564. }
  565. const_iterator cbegin() const BOOST_NOEXCEPT
  566. {
  567. return table_.begin();
  568. }
  569. const_iterator cend() const BOOST_NOEXCEPT
  570. {
  571. return const_iterator();
  572. }
  573. // emplace
  574. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  575. template <class... Args>
  576. iterator emplace(BOOST_FWD_REF(Args)... args)
  577. {
  578. return table_.emplace(boost::forward<Args>(args)...);
  579. }
  580. template <class... Args>
  581. iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
  582. {
  583. return table_.emplace(boost::forward<Args>(args)...);
  584. }
  585. #else
  586. #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
  587. // 0 argument emplace requires special treatment in case
  588. // the container is instantiated with a value type that
  589. // doesn't have a default constructor.
  590. iterator emplace(
  591. boost::unordered::detail::empty_emplace
  592. = boost::unordered::detail::empty_emplace(),
  593. value_type v = value_type())
  594. {
  595. return this->emplace(boost::move(v));
  596. }
  597. iterator emplace_hint(const_iterator hint,
  598. boost::unordered::detail::empty_emplace
  599. = boost::unordered::detail::empty_emplace(),
  600. value_type v = value_type()
  601. )
  602. {
  603. return this->emplace_hint(hint, boost::move(v));
  604. }
  605. #endif
  606. template <typename A0>
  607. iterator emplace(BOOST_FWD_REF(A0) a0)
  608. {
  609. return table_.emplace(
  610. boost::unordered::detail::create_emplace_args(
  611. boost::forward<A0>(a0))
  612. );
  613. }
  614. template <typename A0>
  615. iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
  616. {
  617. return table_.emplace(
  618. boost::unordered::detail::create_emplace_args(
  619. boost::forward<A0>(a0))
  620. );
  621. }
  622. template <typename A0, typename A1>
  623. iterator emplace(
  624. BOOST_FWD_REF(A0) a0,
  625. BOOST_FWD_REF(A1) a1)
  626. {
  627. return table_.emplace(
  628. boost::unordered::detail::create_emplace_args(
  629. boost::forward<A0>(a0),
  630. boost::forward<A1>(a1))
  631. );
  632. }
  633. template <typename A0, typename A1>
  634. iterator emplace_hint(const_iterator,
  635. BOOST_FWD_REF(A0) a0,
  636. BOOST_FWD_REF(A1) a1)
  637. {
  638. return table_.emplace(
  639. boost::unordered::detail::create_emplace_args(
  640. boost::forward<A0>(a0),
  641. boost::forward<A1>(a1))
  642. );
  643. }
  644. template <typename A0, typename A1, typename A2>
  645. iterator emplace(
  646. BOOST_FWD_REF(A0) a0,
  647. BOOST_FWD_REF(A1) a1,
  648. BOOST_FWD_REF(A2) a2)
  649. {
  650. return table_.emplace(
  651. boost::unordered::detail::create_emplace_args(
  652. boost::forward<A0>(a0),
  653. boost::forward<A1>(a1),
  654. boost::forward<A2>(a2))
  655. );
  656. }
  657. template <typename A0, typename A1, typename A2>
  658. iterator emplace_hint(const_iterator,
  659. BOOST_FWD_REF(A0) a0,
  660. BOOST_FWD_REF(A1) a1,
  661. BOOST_FWD_REF(A2) a2)
  662. {
  663. return table_.emplace(
  664. boost::unordered::detail::create_emplace_args(
  665. boost::forward<A0>(a0),
  666. boost::forward<A1>(a1),
  667. boost::forward<A2>(a2))
  668. );
  669. }
  670. #define BOOST_UNORDERED_EMPLACE(z, n, _) \
  671. template < \
  672. BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
  673. > \
  674. iterator emplace( \
  675. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
  676. ) \
  677. { \
  678. return table_.emplace( \
  679. boost::unordered::detail::create_emplace_args( \
  680. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
  681. a) \
  682. )); \
  683. } \
  684. \
  685. template < \
  686. BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
  687. > \
  688. iterator emplace_hint( \
  689. const_iterator, \
  690. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
  691. ) \
  692. { \
  693. return table_.emplace( \
  694. boost::unordered::detail::create_emplace_args( \
  695. BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
  696. a) \
  697. )); \
  698. }
  699. BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
  700. BOOST_UNORDERED_EMPLACE, _)
  701. #undef BOOST_UNORDERED_EMPLACE
  702. #endif
  703. iterator insert(value_type const& x)
  704. {
  705. return this->emplace(x);
  706. }
  707. iterator insert(BOOST_RV_REF(value_type) x)
  708. {
  709. return this->emplace(boost::move(x));
  710. }
  711. iterator insert(const_iterator hint, value_type const& x)
  712. {
  713. return this->emplace_hint(hint, x);
  714. }
  715. iterator insert(const_iterator hint, BOOST_RV_REF(value_type) x)
  716. {
  717. return this->emplace_hint(hint, boost::move(x));
  718. }
  719. template <class InputIt> void insert(InputIt, InputIt);
  720. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  721. void insert(std::initializer_list<value_type>);
  722. #endif
  723. iterator erase(const_iterator);
  724. size_type erase(const key_type&);
  725. iterator erase(const_iterator, const_iterator);
  726. void quick_erase(const_iterator it) { erase(it); }
  727. void erase_return_void(const_iterator it) { erase(it); }
  728. void clear();
  729. void swap(unordered_multimap&);
  730. // observers
  731. hasher hash_function() const;
  732. key_equal key_eq() const;
  733. // lookup
  734. iterator find(const key_type&);
  735. const_iterator find(const key_type&) const;
  736. template <class CompatibleKey, class CompatibleHash,
  737. class CompatiblePredicate>
  738. iterator find(
  739. CompatibleKey const&,
  740. CompatibleHash const&,
  741. CompatiblePredicate const&);
  742. template <class CompatibleKey, class CompatibleHash,
  743. class CompatiblePredicate>
  744. const_iterator find(
  745. CompatibleKey const&,
  746. CompatibleHash const&,
  747. CompatiblePredicate const&) const;
  748. size_type count(const key_type&) const;
  749. std::pair<iterator, iterator>
  750. equal_range(const key_type&);
  751. std::pair<const_iterator, const_iterator>
  752. equal_range(const key_type&) const;
  753. // bucket interface
  754. size_type bucket_count() const BOOST_NOEXCEPT
  755. {
  756. return table_.bucket_count_;
  757. }
  758. size_type max_bucket_count() const BOOST_NOEXCEPT
  759. {
  760. return table_.max_bucket_count();
  761. }
  762. size_type bucket_size(size_type) const;
  763. size_type bucket(const key_type& k) const
  764. {
  765. return table_.hash_to_bucket(table_.hash(k));
  766. }
  767. local_iterator begin(size_type n)
  768. {
  769. return local_iterator(
  770. table_.begin(n), n, table_.bucket_count_);
  771. }
  772. const_local_iterator begin(size_type n) const
  773. {
  774. return const_local_iterator(
  775. table_.begin(n), n, table_.bucket_count_);
  776. }
  777. local_iterator end(size_type)
  778. {
  779. return local_iterator();
  780. }
  781. const_local_iterator end(size_type) const
  782. {
  783. return const_local_iterator();
  784. }
  785. const_local_iterator cbegin(size_type n) const
  786. {
  787. return const_local_iterator(
  788. table_.begin(n), n, table_.bucket_count_);
  789. }
  790. const_local_iterator cend(size_type) const
  791. {
  792. return const_local_iterator();
  793. }
  794. // hash policy
  795. float max_load_factor() const BOOST_NOEXCEPT
  796. {
  797. return table_.mlf_;
  798. }
  799. float load_factor() const BOOST_NOEXCEPT;
  800. void max_load_factor(float) BOOST_NOEXCEPT;
  801. void rehash(size_type);
  802. void reserve(size_type);
  803. #if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
  804. friend bool operator==<K,T,H,P,A>(
  805. unordered_multimap const&, unordered_multimap const&);
  806. friend bool operator!=<K,T,H,P,A>(
  807. unordered_multimap const&, unordered_multimap const&);
  808. #endif
  809. }; // class template unordered_multimap
  810. ////////////////////////////////////////////////////////////////////////////////
  811. template <class K, class T, class H, class P, class A>
  812. unordered_map<K,T,H,P,A>::unordered_map(
  813. size_type n, const hasher &hf, const key_equal &eql,
  814. const allocator_type &a)
  815. : table_(n, hf, eql, a)
  816. {
  817. }
  818. template <class K, class T, class H, class P, class A>
  819. unordered_map<K,T,H,P,A>::unordered_map(allocator_type const& a)
  820. : table_(boost::unordered::detail::default_bucket_count,
  821. hasher(), key_equal(), a)
  822. {
  823. }
  824. template <class K, class T, class H, class P, class A>
  825. unordered_map<K,T,H,P,A>::unordered_map(
  826. unordered_map const& other, allocator_type const& a)
  827. : table_(other.table_, a)
  828. {
  829. }
  830. template <class K, class T, class H, class P, class A>
  831. template <class InputIt>
  832. unordered_map<K,T,H,P,A>::unordered_map(InputIt f, InputIt l)
  833. : table_(boost::unordered::detail::initial_size(f, l),
  834. hasher(), key_equal(), allocator_type())
  835. {
  836. table_.insert_range(f, l);
  837. }
  838. template <class K, class T, class H, class P, class A>
  839. template <class InputIt>
  840. unordered_map<K,T,H,P,A>::unordered_map(
  841. InputIt f, InputIt l,
  842. size_type n,
  843. const hasher &hf,
  844. const key_equal &eql)
  845. : table_(boost::unordered::detail::initial_size(f, l, n),
  846. hf, eql, allocator_type())
  847. {
  848. table_.insert_range(f, l);
  849. }
  850. template <class K, class T, class H, class P, class A>
  851. template <class InputIt>
  852. unordered_map<K,T,H,P,A>::unordered_map(
  853. InputIt f, InputIt l,
  854. size_type n,
  855. const hasher &hf,
  856. const key_equal &eql,
  857. const allocator_type &a)
  858. : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
  859. {
  860. table_.insert_range(f, l);
  861. }
  862. template <class K, class T, class H, class P, class A>
  863. unordered_map<K,T,H,P,A>::~unordered_map() BOOST_NOEXCEPT {}
  864. template <class K, class T, class H, class P, class A>
  865. unordered_map<K,T,H,P,A>::unordered_map(
  866. unordered_map const& other)
  867. : table_(other.table_)
  868. {
  869. }
  870. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  871. template <class K, class T, class H, class P, class A>
  872. unordered_map<K,T,H,P,A>::unordered_map(
  873. unordered_map&& other, allocator_type const& a)
  874. : table_(other.table_, a, boost::unordered::detail::move_tag())
  875. {
  876. }
  877. #endif
  878. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  879. template <class K, class T, class H, class P, class A>
  880. unordered_map<K,T,H,P,A>::unordered_map(
  881. std::initializer_list<value_type> list, size_type n,
  882. const hasher &hf, const key_equal &eql, const allocator_type &a)
  883. : table_(
  884. boost::unordered::detail::initial_size(
  885. list.begin(), list.end(), n),
  886. hf, eql, a)
  887. {
  888. table_.insert_range(list.begin(), list.end());
  889. }
  890. template <class K, class T, class H, class P, class A>
  891. unordered_map<K,T,H,P,A>& unordered_map<K,T,H,P,A>::operator=(
  892. std::initializer_list<value_type> list)
  893. {
  894. table_.clear();
  895. table_.insert_range(list.begin(), list.end());
  896. return *this;
  897. }
  898. #endif
  899. // size and capacity
  900. template <class K, class T, class H, class P, class A>
  901. std::size_t unordered_map<K,T,H,P,A>::max_size() const BOOST_NOEXCEPT
  902. {
  903. return table_.max_size();
  904. }
  905. // modifiers
  906. template <class K, class T, class H, class P, class A>
  907. template <class InputIt>
  908. void unordered_map<K,T,H,P,A>::insert(InputIt first, InputIt last)
  909. {
  910. table_.insert_range(first, last);
  911. }
  912. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  913. template <class K, class T, class H, class P, class A>
  914. void unordered_map<K,T,H,P,A>::insert(
  915. std::initializer_list<value_type> list)
  916. {
  917. table_.insert_range(list.begin(), list.end());
  918. }
  919. #endif
  920. template <class K, class T, class H, class P, class A>
  921. typename unordered_map<K,T,H,P,A>::iterator
  922. unordered_map<K,T,H,P,A>::erase(const_iterator position)
  923. {
  924. return table_.erase(position);
  925. }
  926. template <class K, class T, class H, class P, class A>
  927. typename unordered_map<K,T,H,P,A>::size_type
  928. unordered_map<K,T,H,P,A>::erase(const key_type& k)
  929. {
  930. return table_.erase_key(k);
  931. }
  932. template <class K, class T, class H, class P, class A>
  933. typename unordered_map<K,T,H,P,A>::iterator
  934. unordered_map<K,T,H,P,A>::erase(
  935. const_iterator first, const_iterator last)
  936. {
  937. return table_.erase_range(first, last);
  938. }
  939. template <class K, class T, class H, class P, class A>
  940. void unordered_map<K,T,H,P,A>::clear()
  941. {
  942. table_.clear();
  943. }
  944. template <class K, class T, class H, class P, class A>
  945. void unordered_map<K,T,H,P,A>::swap(unordered_map& other)
  946. {
  947. table_.swap(other.table_);
  948. }
  949. // observers
  950. template <class K, class T, class H, class P, class A>
  951. typename unordered_map<K,T,H,P,A>::hasher
  952. unordered_map<K,T,H,P,A>::hash_function() const
  953. {
  954. return table_.hash_function();
  955. }
  956. template <class K, class T, class H, class P, class A>
  957. typename unordered_map<K,T,H,P,A>::key_equal
  958. unordered_map<K,T,H,P,A>::key_eq() const
  959. {
  960. return table_.key_eq();
  961. }
  962. template <class K, class T, class H, class P, class A>
  963. typename unordered_map<K,T,H,P,A>::mapped_type&
  964. unordered_map<K,T,H,P,A>::operator[](const key_type &k)
  965. {
  966. return table_[k].second;
  967. }
  968. template <class K, class T, class H, class P, class A>
  969. typename unordered_map<K,T,H,P,A>::mapped_type&
  970. unordered_map<K,T,H,P,A>::at(const key_type& k)
  971. {
  972. return table_.at(k).second;
  973. }
  974. template <class K, class T, class H, class P, class A>
  975. typename unordered_map<K,T,H,P,A>::mapped_type const&
  976. unordered_map<K,T,H,P,A>::at(const key_type& k) const
  977. {
  978. return table_.at(k).second;
  979. }
  980. // lookup
  981. template <class K, class T, class H, class P, class A>
  982. typename unordered_map<K,T,H,P,A>::iterator
  983. unordered_map<K,T,H,P,A>::find(const key_type& k)
  984. {
  985. return table_.find_node(k);
  986. }
  987. template <class K, class T, class H, class P, class A>
  988. typename unordered_map<K,T,H,P,A>::const_iterator
  989. unordered_map<K,T,H,P,A>::find(const key_type& k) const
  990. {
  991. return table_.find_node(k);
  992. }
  993. template <class K, class T, class H, class P, class A>
  994. template <class CompatibleKey, class CompatibleHash,
  995. class CompatiblePredicate>
  996. typename unordered_map<K,T,H,P,A>::iterator
  997. unordered_map<K,T,H,P,A>::find(
  998. CompatibleKey const& k,
  999. CompatibleHash const& hash,
  1000. CompatiblePredicate const& eq)
  1001. {
  1002. return table_.generic_find_node(k, hash, eq);
  1003. }
  1004. template <class K, class T, class H, class P, class A>
  1005. template <class CompatibleKey, class CompatibleHash,
  1006. class CompatiblePredicate>
  1007. typename unordered_map<K,T,H,P,A>::const_iterator
  1008. unordered_map<K,T,H,P,A>::find(
  1009. CompatibleKey const& k,
  1010. CompatibleHash const& hash,
  1011. CompatiblePredicate const& eq) const
  1012. {
  1013. return table_.generic_find_node(k, hash, eq);
  1014. }
  1015. template <class K, class T, class H, class P, class A>
  1016. typename unordered_map<K,T,H,P,A>::size_type
  1017. unordered_map<K,T,H,P,A>::count(const key_type& k) const
  1018. {
  1019. return table_.count(k);
  1020. }
  1021. template <class K, class T, class H, class P, class A>
  1022. std::pair<
  1023. typename unordered_map<K,T,H,P,A>::iterator,
  1024. typename unordered_map<K,T,H,P,A>::iterator>
  1025. unordered_map<K,T,H,P,A>::equal_range(const key_type& k)
  1026. {
  1027. return table_.equal_range(k);
  1028. }
  1029. template <class K, class T, class H, class P, class A>
  1030. std::pair<
  1031. typename unordered_map<K,T,H,P,A>::const_iterator,
  1032. typename unordered_map<K,T,H,P,A>::const_iterator>
  1033. unordered_map<K,T,H,P,A>::equal_range(const key_type& k) const
  1034. {
  1035. return table_.equal_range(k);
  1036. }
  1037. template <class K, class T, class H, class P, class A>
  1038. typename unordered_map<K,T,H,P,A>::size_type
  1039. unordered_map<K,T,H,P,A>::bucket_size(size_type n) const
  1040. {
  1041. return table_.bucket_size(n);
  1042. }
  1043. // hash policy
  1044. template <class K, class T, class H, class P, class A>
  1045. float unordered_map<K,T,H,P,A>::load_factor() const BOOST_NOEXCEPT
  1046. {
  1047. return table_.load_factor();
  1048. }
  1049. template <class K, class T, class H, class P, class A>
  1050. void unordered_map<K,T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
  1051. {
  1052. table_.max_load_factor(m);
  1053. }
  1054. template <class K, class T, class H, class P, class A>
  1055. void unordered_map<K,T,H,P,A>::rehash(size_type n)
  1056. {
  1057. table_.rehash(n);
  1058. }
  1059. template <class K, class T, class H, class P, class A>
  1060. void unordered_map<K,T,H,P,A>::reserve(size_type n)
  1061. {
  1062. table_.reserve(n);
  1063. }
  1064. template <class K, class T, class H, class P, class A>
  1065. inline bool operator==(
  1066. unordered_map<K,T,H,P,A> const& m1,
  1067. unordered_map<K,T,H,P,A> const& m2)
  1068. {
  1069. #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
  1070. struct dummy { unordered_map<K,T,H,P,A> x; };
  1071. #endif
  1072. return m1.table_.equals(m2.table_);
  1073. }
  1074. template <class K, class T, class H, class P, class A>
  1075. inline bool operator!=(
  1076. unordered_map<K,T,H,P,A> const& m1,
  1077. unordered_map<K,T,H,P,A> const& m2)
  1078. {
  1079. #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
  1080. struct dummy { unordered_map<K,T,H,P,A> x; };
  1081. #endif
  1082. return !m1.table_.equals(m2.table_);
  1083. }
  1084. template <class K, class T, class H, class P, class A>
  1085. inline void swap(
  1086. unordered_map<K,T,H,P,A> &m1,
  1087. unordered_map<K,T,H,P,A> &m2)
  1088. {
  1089. #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
  1090. struct dummy { unordered_map<K,T,H,P,A> x; };
  1091. #endif
  1092. m1.swap(m2);
  1093. }
  1094. ////////////////////////////////////////////////////////////////////////////////
  1095. template <class K, class T, class H, class P, class A>
  1096. unordered_multimap<K,T,H,P,A>::unordered_multimap(
  1097. size_type n, const hasher &hf, const key_equal &eql,
  1098. const allocator_type &a)
  1099. : table_(n, hf, eql, a)
  1100. {
  1101. }
  1102. template <class K, class T, class H, class P, class A>
  1103. unordered_multimap<K,T,H,P,A>::unordered_multimap(allocator_type const& a)
  1104. : table_(boost::unordered::detail::default_bucket_count,
  1105. hasher(), key_equal(), a)
  1106. {
  1107. }
  1108. template <class K, class T, class H, class P, class A>
  1109. unordered_multimap<K,T,H,P,A>::unordered_multimap(
  1110. unordered_multimap const& other, allocator_type const& a)
  1111. : table_(other.table_, a)
  1112. {
  1113. }
  1114. template <class K, class T, class H, class P, class A>
  1115. template <class InputIt>
  1116. unordered_multimap<K,T,H,P,A>::unordered_multimap(InputIt f, InputIt l)
  1117. : table_(boost::unordered::detail::initial_size(f, l),
  1118. hasher(), key_equal(), allocator_type())
  1119. {
  1120. table_.insert_range(f, l);
  1121. }
  1122. template <class K, class T, class H, class P, class A>
  1123. template <class InputIt>
  1124. unordered_multimap<K,T,H,P,A>::unordered_multimap(
  1125. InputIt f, InputIt l,
  1126. size_type n,
  1127. const hasher &hf,
  1128. const key_equal &eql)
  1129. : table_(boost::unordered::detail::initial_size(f, l, n),
  1130. hf, eql, allocator_type())
  1131. {
  1132. table_.insert_range(f, l);
  1133. }
  1134. template <class K, class T, class H, class P, class A>
  1135. template <class InputIt>
  1136. unordered_multimap<K,T,H,P,A>::unordered_multimap(
  1137. InputIt f, InputIt l,
  1138. size_type n,
  1139. const hasher &hf,
  1140. const key_equal &eql,
  1141. const allocator_type &a)
  1142. : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
  1143. {
  1144. table_.insert_range(f, l);
  1145. }
  1146. template <class K, class T, class H, class P, class A>
  1147. unordered_multimap<K,T,H,P,A>::~unordered_multimap() BOOST_NOEXCEPT {}
  1148. template <class K, class T, class H, class P, class A>
  1149. unordered_multimap<K,T,H,P,A>::unordered_multimap(
  1150. unordered_multimap const& other)
  1151. : table_(other.table_)
  1152. {
  1153. }
  1154. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  1155. template <class K, class T, class H, class P, class A>
  1156. unordered_multimap<K,T,H,P,A>::unordered_multimap(
  1157. unordered_multimap&& other, allocator_type const& a)
  1158. : table_(other.table_, a, boost::unordered::detail::move_tag())
  1159. {
  1160. }
  1161. #endif
  1162. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1163. template <class K, class T, class H, class P, class A>
  1164. unordered_multimap<K,T,H,P,A>::unordered_multimap(
  1165. std::initializer_list<value_type> list, size_type n,
  1166. const hasher &hf, const key_equal &eql, const allocator_type &a)
  1167. : table_(
  1168. boost::unordered::detail::initial_size(
  1169. list.begin(), list.end(), n),
  1170. hf, eql, a)
  1171. {
  1172. table_.insert_range(list.begin(), list.end());
  1173. }
  1174. template <class K, class T, class H, class P, class A>
  1175. unordered_multimap<K,T,H,P,A>& unordered_multimap<K,T,H,P,A>::operator=(
  1176. std::initializer_list<value_type> list)
  1177. {
  1178. table_.clear();
  1179. table_.insert_range(list.begin(), list.end());
  1180. return *this;
  1181. }
  1182. #endif
  1183. // size and capacity
  1184. template <class K, class T, class H, class P, class A>
  1185. std::size_t unordered_multimap<K,T,H,P,A>::max_size() const BOOST_NOEXCEPT
  1186. {
  1187. return table_.max_size();
  1188. }
  1189. // modifiers
  1190. template <class K, class T, class H, class P, class A>
  1191. template <class InputIt>
  1192. void unordered_multimap<K,T,H,P,A>::insert(InputIt first, InputIt last)
  1193. {
  1194. table_.insert_range(first, last);
  1195. }
  1196. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  1197. template <class K, class T, class H, class P, class A>
  1198. void unordered_multimap<K,T,H,P,A>::insert(
  1199. std::initializer_list<value_type> list)
  1200. {
  1201. table_.insert_range(list.begin(), list.end());
  1202. }
  1203. #endif
  1204. template <class K, class T, class H, class P, class A>
  1205. typename unordered_multimap<K,T,H,P,A>::iterator
  1206. unordered_multimap<K,T,H,P,A>::erase(const_iterator position)
  1207. {
  1208. return table_.erase(position);
  1209. }
  1210. template <class K, class T, class H, class P, class A>
  1211. typename unordered_multimap<K,T,H,P,A>::size_type
  1212. unordered_multimap<K,T,H,P,A>::erase(const key_type& k)
  1213. {
  1214. return table_.erase_key(k);
  1215. }
  1216. template <class K, class T, class H, class P, class A>
  1217. typename unordered_multimap<K,T,H,P,A>::iterator
  1218. unordered_multimap<K,T,H,P,A>::erase(
  1219. const_iterator first, const_iterator last)
  1220. {
  1221. return table_.erase_range(first, last);
  1222. }
  1223. template <class K, class T, class H, class P, class A>
  1224. void unordered_multimap<K,T,H,P,A>::clear()
  1225. {
  1226. table_.clear();
  1227. }
  1228. template <class K, class T, class H, class P, class A>
  1229. void unordered_multimap<K,T,H,P,A>::swap(unordered_multimap& other)
  1230. {
  1231. table_.swap(other.table_);
  1232. }
  1233. // observers
  1234. template <class K, class T, class H, class P, class A>
  1235. typename unordered_multimap<K,T,H,P,A>::hasher
  1236. unordered_multimap<K,T,H,P,A>::hash_function() const
  1237. {
  1238. return table_.hash_function();
  1239. }
  1240. template <class K, class T, class H, class P, class A>
  1241. typename unordered_multimap<K,T,H,P,A>::key_equal
  1242. unordered_multimap<K,T,H,P,A>::key_eq() const
  1243. {
  1244. return table_.key_eq();
  1245. }
  1246. // lookup
  1247. template <class K, class T, class H, class P, class A>
  1248. typename unordered_multimap<K,T,H,P,A>::iterator
  1249. unordered_multimap<K,T,H,P,A>::find(const key_type& k)
  1250. {
  1251. return table_.find_node(k);
  1252. }
  1253. template <class K, class T, class H, class P, class A>
  1254. typename unordered_multimap<K,T,H,P,A>::const_iterator
  1255. unordered_multimap<K,T,H,P,A>::find(const key_type& k) const
  1256. {
  1257. return table_.find_node(k);
  1258. }
  1259. template <class K, class T, class H, class P, class A>
  1260. template <class CompatibleKey, class CompatibleHash,
  1261. class CompatiblePredicate>
  1262. typename unordered_multimap<K,T,H,P,A>::iterator
  1263. unordered_multimap<K,T,H,P,A>::find(
  1264. CompatibleKey const& k,
  1265. CompatibleHash const& hash,
  1266. CompatiblePredicate const& eq)
  1267. {
  1268. return table_.generic_find_node(k, hash, eq);
  1269. }
  1270. template <class K, class T, class H, class P, class A>
  1271. template <class CompatibleKey, class CompatibleHash,
  1272. class CompatiblePredicate>
  1273. typename unordered_multimap<K,T,H,P,A>::const_iterator
  1274. unordered_multimap<K,T,H,P,A>::find(
  1275. CompatibleKey const& k,
  1276. CompatibleHash const& hash,
  1277. CompatiblePredicate const& eq) const
  1278. {
  1279. return table_.generic_find_node(k, hash, eq);
  1280. }
  1281. template <class K, class T, class H, class P, class A>
  1282. typename unordered_multimap<K,T,H,P,A>::size_type
  1283. unordered_multimap<K,T,H,P,A>::count(const key_type& k) const
  1284. {
  1285. return table_.count(k);
  1286. }
  1287. template <class K, class T, class H, class P, class A>
  1288. std::pair<
  1289. typename unordered_multimap<K,T,H,P,A>::iterator,
  1290. typename unordered_multimap<K,T,H,P,A>::iterator>
  1291. unordered_multimap<K,T,H,P,A>::equal_range(const key_type& k)
  1292. {
  1293. return table_.equal_range(k);
  1294. }
  1295. template <class K, class T, class H, class P, class A>
  1296. std::pair<
  1297. typename unordered_multimap<K,T,H,P,A>::const_iterator,
  1298. typename unordered_multimap<K,T,H,P,A>::const_iterator>
  1299. unordered_multimap<K,T,H,P,A>::equal_range(const key_type& k) const
  1300. {
  1301. return table_.equal_range(k);
  1302. }
  1303. template <class K, class T, class H, class P, class A>
  1304. typename unordered_multimap<K,T,H,P,A>::size_type
  1305. unordered_multimap<K,T,H,P,A>::bucket_size(size_type n) const
  1306. {
  1307. return table_.bucket_size(n);
  1308. }
  1309. // hash policy
  1310. template <class K, class T, class H, class P, class A>
  1311. float unordered_multimap<K,T,H,P,A>::load_factor() const BOOST_NOEXCEPT
  1312. {
  1313. return table_.load_factor();
  1314. }
  1315. template <class K, class T, class H, class P, class A>
  1316. void unordered_multimap<K,T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
  1317. {
  1318. table_.max_load_factor(m);
  1319. }
  1320. template <class K, class T, class H, class P, class A>
  1321. void unordered_multimap<K,T,H,P,A>::rehash(size_type n)
  1322. {
  1323. table_.rehash(n);
  1324. }
  1325. template <class K, class T, class H, class P, class A>
  1326. void unordered_multimap<K,T,H,P,A>::reserve(size_type n)
  1327. {
  1328. table_.reserve(n);
  1329. }
  1330. template <class K, class T, class H, class P, class A>
  1331. inline bool operator==(
  1332. unordered_multimap<K,T,H,P,A> const& m1,
  1333. unordered_multimap<K,T,H,P,A> const& m2)
  1334. {
  1335. #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
  1336. struct dummy { unordered_multimap<K,T,H,P,A> x; };
  1337. #endif
  1338. return m1.table_.equals(m2.table_);
  1339. }
  1340. template <class K, class T, class H, class P, class A>
  1341. inline bool operator!=(
  1342. unordered_multimap<K,T,H,P,A> const& m1,
  1343. unordered_multimap<K,T,H,P,A> const& m2)
  1344. {
  1345. #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
  1346. struct dummy { unordered_multimap<K,T,H,P,A> x; };
  1347. #endif
  1348. return !m1.table_.equals(m2.table_);
  1349. }
  1350. template <class K, class T, class H, class P, class A>
  1351. inline void swap(
  1352. unordered_multimap<K,T,H,P,A> &m1,
  1353. unordered_multimap<K,T,H,P,A> &m2)
  1354. {
  1355. #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
  1356. struct dummy { unordered_multimap<K,T,H,P,A> x; };
  1357. #endif
  1358. m1.swap(m2);
  1359. }
  1360. } // namespace unordered
  1361. } // namespace boost
  1362. #if defined(BOOST_MSVC)
  1363. #pragma warning(pop)
  1364. #endif
  1365. #endif // BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED