unordered_map.hpp 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355
  1. // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
  2. // Copyright (C) 2005-2011 Daniel James.
  3. // Copyright (C) 2022-2023 Christian Mazakas
  4. // Copyright (C) 2024 Joaquin M Lopez Munoz.
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org/libs/unordered for documentation
  8. #ifndef BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
  9. #define BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
  10. #include <boost/config.hpp>
  11. #if defined(BOOST_HAS_PRAGMA_ONCE)
  12. #pragma once
  13. #endif
  14. #include <boost/unordered/detail/map.hpp>
  15. #include <boost/unordered/detail/serialize_fca_container.hpp>
  16. #include <boost/unordered/detail/throw_exception.hpp>
  17. #include <boost/unordered/detail/type_traits.hpp>
  18. #include <boost/container_hash/hash.hpp>
  19. #include <initializer_list>
  20. #if defined(BOOST_MSVC)
  21. #pragma warning(push)
  22. // conditional expression is constant
  23. #pragma warning(disable : 4127)
  24. #if BOOST_MSVC >= 1400
  25. // the inline specifier cannot be used when a friend declaration refers to a
  26. // specialization of a function template
  27. #pragma warning(disable : 4396)
  28. #endif
  29. #endif
  30. namespace boost {
  31. namespace unordered {
  32. template <class K, class T, class H, class P, class A> class unordered_map
  33. {
  34. template <typename, typename, typename, typename, typename>
  35. friend class unordered_multimap;
  36. public:
  37. typedef K key_type;
  38. typedef T mapped_type;
  39. typedef std::pair<const K, T> value_type;
  40. typedef typename boost::unordered::detail::type_identity<H>::type hasher;
  41. typedef
  42. typename boost::unordered::detail::type_identity<P>::type key_equal;
  43. typedef typename boost::unordered::detail::type_identity<A>::type
  44. allocator_type;
  45. private:
  46. typedef boost::unordered::detail::map<A, K, T, H, P> types;
  47. typedef typename types::value_allocator_traits value_allocator_traits;
  48. typedef typename types::table table;
  49. public:
  50. typedef typename value_allocator_traits::pointer pointer;
  51. typedef typename value_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::iterator iterator;
  57. typedef typename table::c_iterator const_iterator;
  58. typedef typename table::l_iterator local_iterator;
  59. typedef typename table::cl_iterator const_local_iterator;
  60. typedef typename types::node_type node_type;
  61. typedef typename types::insert_return_type insert_return_type;
  62. private:
  63. table table_;
  64. public:
  65. // constructors
  66. unordered_map();
  67. explicit unordered_map(size_type, const hasher& = hasher(),
  68. const key_equal& = key_equal(),
  69. const allocator_type& = allocator_type());
  70. template <class InputIt>
  71. unordered_map(InputIt, InputIt,
  72. size_type = boost::unordered::detail::default_bucket_count,
  73. const hasher& = hasher(), const key_equal& = key_equal(),
  74. const allocator_type& = allocator_type());
  75. unordered_map(unordered_map const&);
  76. unordered_map(unordered_map&& other)
  77. noexcept(table::nothrow_move_constructible)
  78. : table_(other.table_, boost::unordered::detail::move_tag())
  79. {
  80. // The move is done in table_
  81. }
  82. explicit unordered_map(allocator_type const&);
  83. unordered_map(unordered_map const&, allocator_type const&);
  84. unordered_map(unordered_map&&, allocator_type const&);
  85. unordered_map(std::initializer_list<value_type>,
  86. size_type = boost::unordered::detail::default_bucket_count,
  87. const hasher& = hasher(), const key_equal& l = key_equal(),
  88. const allocator_type& = allocator_type());
  89. explicit unordered_map(size_type, const allocator_type&);
  90. explicit unordered_map(size_type, const hasher&, const allocator_type&);
  91. template <class InputIterator>
  92. unordered_map(InputIterator, InputIterator, const allocator_type&);
  93. template <class InputIt>
  94. unordered_map(InputIt, InputIt, size_type, const allocator_type&);
  95. template <class InputIt>
  96. unordered_map(
  97. InputIt, InputIt, size_type, const hasher&, const allocator_type&);
  98. unordered_map(std::initializer_list<value_type>, const allocator_type&);
  99. unordered_map(
  100. std::initializer_list<value_type>, size_type, const allocator_type&);
  101. unordered_map(std::initializer_list<value_type>, size_type, const hasher&,
  102. const allocator_type&);
  103. // Destructor
  104. ~unordered_map() noexcept;
  105. // Assign
  106. unordered_map& operator=(unordered_map const& x)
  107. {
  108. table_.assign(x.table_, std::true_type());
  109. return *this;
  110. }
  111. unordered_map& operator=(unordered_map&& x)
  112. noexcept(value_allocator_traits::is_always_equal::value&&
  113. std::is_nothrow_move_assignable<H>::value&&
  114. std::is_nothrow_move_assignable<P>::value)
  115. {
  116. table_.move_assign(x.table_, std::true_type());
  117. return *this;
  118. }
  119. unordered_map& operator=(std::initializer_list<value_type>);
  120. allocator_type get_allocator() const noexcept
  121. {
  122. return allocator_type(table_.node_alloc());
  123. }
  124. // // iterators
  125. iterator begin() noexcept { return table_.begin(); }
  126. const_iterator begin() const noexcept
  127. {
  128. return const_iterator(table_.begin());
  129. }
  130. iterator end() noexcept { return iterator(); }
  131. const_iterator end() const noexcept { return const_iterator(); }
  132. const_iterator cbegin() const noexcept
  133. {
  134. return const_iterator(table_.begin());
  135. }
  136. const_iterator cend() const noexcept { return const_iterator(); }
  137. // size and capacity
  138. BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
  139. {
  140. return table_.size_ == 0;
  141. }
  142. size_type size() const noexcept { return table_.size_; }
  143. size_type max_size() const noexcept;
  144. // emplace
  145. template <class... Args> std::pair<iterator, bool> emplace(Args&&... args)
  146. {
  147. return table_.emplace_unique(
  148. table::extractor::extract(std::forward<Args>(args)...),
  149. std::forward<Args>(args)...);
  150. }
  151. template <class... Args>
  152. iterator emplace_hint(const_iterator hint, Args&&... args)
  153. {
  154. return table_.emplace_hint_unique(hint,
  155. table::extractor::extract(std::forward<Args>(args)...),
  156. std::forward<Args>(args)...);
  157. }
  158. std::pair<iterator, bool> insert(value_type const& x)
  159. {
  160. return this->emplace(x);
  161. }
  162. std::pair<iterator, bool> insert(value_type&& x)
  163. {
  164. return this->emplace(std::move(x));
  165. }
  166. template <class P2>
  167. typename boost::enable_if<std::is_constructible<value_type, P2&&>,
  168. std::pair<iterator, bool> >::type
  169. insert(P2&& obj)
  170. {
  171. return this->emplace(std::forward<P2>(obj));
  172. }
  173. iterator insert(const_iterator hint, value_type const& x)
  174. {
  175. return this->emplace_hint(hint, x);
  176. }
  177. iterator insert(const_iterator hint, value_type&& x)
  178. {
  179. return this->emplace_hint(hint, std::move(x));
  180. }
  181. template <class P2>
  182. typename boost::enable_if<std::is_constructible<value_type, P2&&>,
  183. iterator>::type
  184. insert(const_iterator hint, P2&& obj)
  185. {
  186. return this->emplace_hint(hint, std::forward<P2>(obj));
  187. }
  188. template <class InputIt> void insert(InputIt, InputIt);
  189. void insert(std::initializer_list<value_type>);
  190. // extract
  191. node_type extract(const_iterator position)
  192. {
  193. return node_type(
  194. table_.extract_by_iterator_unique(position),
  195. allocator_type(table_.node_alloc()));
  196. }
  197. node_type extract(const key_type& k)
  198. {
  199. return node_type(
  200. table_.extract_by_key_impl(k),
  201. allocator_type(table_.node_alloc()));
  202. }
  203. template <class Key>
  204. typename boost::enable_if_c<
  205. detail::transparent_non_iterable<Key, unordered_map>::value,
  206. node_type>::type
  207. extract(Key&& k)
  208. {
  209. return node_type(
  210. table_.extract_by_key_impl(std::forward<Key>(k)),
  211. allocator_type(table_.node_alloc()));
  212. }
  213. insert_return_type insert(node_type&& np)
  214. {
  215. insert_return_type result;
  216. table_.move_insert_node_type_unique((node_type&)np, result);
  217. return result;
  218. }
  219. iterator insert(const_iterator hint, node_type&& np)
  220. {
  221. return table_.move_insert_node_type_with_hint_unique(hint, np);
  222. }
  223. template <class... Args>
  224. std::pair<iterator, bool> try_emplace(key_type const& k, Args&&... args)
  225. {
  226. return table_.try_emplace_unique(k, std::forward<Args>(args)...);
  227. }
  228. template <class... Args>
  229. std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args)
  230. {
  231. return table_.try_emplace_unique(
  232. std::move(k), std::forward<Args>(args)...);
  233. }
  234. template <class Key, class... Args>
  235. typename boost::enable_if_c<
  236. detail::transparent_non_iterable<Key, unordered_map>::value,
  237. std::pair<iterator, bool> >::type
  238. try_emplace(Key&& k, Args&&... args)
  239. {
  240. return table_.try_emplace_unique(
  241. std::forward<Key>(k), std::forward<Args>(args)...);
  242. }
  243. template <class... Args>
  244. iterator try_emplace(
  245. const_iterator hint, key_type const& k, Args&&... args)
  246. {
  247. return table_.try_emplace_hint_unique(
  248. hint, k, std::forward<Args>(args)...);
  249. }
  250. template <class... Args>
  251. iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args)
  252. {
  253. return table_.try_emplace_hint_unique(
  254. hint, std::move(k), std::forward<Args>(args)...);
  255. }
  256. template <class Key, class... Args>
  257. typename boost::enable_if_c<
  258. detail::transparent_non_iterable<Key, unordered_map>::value,
  259. iterator>::type
  260. try_emplace(const_iterator hint, Key&& k, Args&&... args)
  261. {
  262. return table_.try_emplace_hint_unique(
  263. hint, std::forward<Key>(k), std::forward<Args>(args)...);
  264. }
  265. template <class M>
  266. std::pair<iterator, bool> insert_or_assign(key_type const& k, M&& obj)
  267. {
  268. return table_.insert_or_assign_unique(k, std::forward<M>(obj));
  269. }
  270. template <class M>
  271. std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj)
  272. {
  273. return table_.insert_or_assign_unique(
  274. std::move(k), std::forward<M>(obj));
  275. }
  276. template <class Key, class M>
  277. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  278. std::pair<iterator, bool> >::type
  279. insert_or_assign(Key&& k, M&& obj)
  280. {
  281. return table_.insert_or_assign_unique(
  282. std::forward<Key>(k), std::forward<M>(obj));
  283. }
  284. template <class M>
  285. iterator insert_or_assign(const_iterator, key_type const& k, M&& obj)
  286. {
  287. return table_.insert_or_assign_unique(k, std::forward<M>(obj)).first;
  288. }
  289. template <class M>
  290. iterator insert_or_assign(const_iterator, key_type&& k, M&& obj)
  291. {
  292. return table_
  293. .insert_or_assign_unique(std::move(k), std::forward<M>(obj))
  294. .first;
  295. }
  296. template <class Key, class M>
  297. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  298. iterator>::type
  299. insert_or_assign(const_iterator, Key&& k, M&& obj)
  300. {
  301. return table_
  302. .insert_or_assign_unique(std::forward<Key>(k), std::forward<M>(obj))
  303. .first;
  304. }
  305. iterator erase(iterator);
  306. iterator erase(const_iterator);
  307. size_type erase(const key_type&);
  308. iterator erase(const_iterator, const_iterator);
  309. template <class Key>
  310. typename boost::enable_if_c<
  311. detail::transparent_non_iterable<Key, unordered_map>::value,
  312. size_type>::type
  313. erase(Key&& k)
  314. {
  315. return table_.erase_key_unique_impl(std::forward<Key>(k));
  316. }
  317. BOOST_UNORDERED_DEPRECATED("Use erase instead")
  318. void quick_erase(const_iterator it) { erase(it); }
  319. BOOST_UNORDERED_DEPRECATED("Use erase instead")
  320. void erase_return_void(const_iterator it) { erase(it); }
  321. void swap(unordered_map&)
  322. noexcept(value_allocator_traits::is_always_equal::value&&
  323. boost::unordered::detail::is_nothrow_swappable<H>::value&&
  324. boost::unordered::detail::is_nothrow_swappable<P>::value);
  325. void clear() noexcept { table_.clear_impl(); }
  326. template <typename H2, typename P2>
  327. void merge(boost::unordered_map<K, T, H2, P2, A>& source);
  328. template <typename H2, typename P2>
  329. void merge(boost::unordered_map<K, T, H2, P2, A>&& source);
  330. template <typename H2, typename P2>
  331. void merge(boost::unordered_multimap<K, T, H2, P2, A>& source);
  332. template <typename H2, typename P2>
  333. void merge(boost::unordered_multimap<K, T, H2, P2, A>&& source);
  334. // observers
  335. hasher hash_function() const;
  336. key_equal key_eq() const;
  337. // lookup
  338. iterator find(const key_type&);
  339. const_iterator find(const key_type&) const;
  340. template <class Key>
  341. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  342. iterator>::type
  343. find(const Key& key)
  344. {
  345. return table_.find(key);
  346. }
  347. template <class Key>
  348. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  349. const_iterator>::type
  350. find(const Key& key) const
  351. {
  352. return const_iterator(table_.find(key));
  353. }
  354. template <class CompatibleKey, class CompatibleHash,
  355. class CompatiblePredicate>
  356. iterator find(CompatibleKey const&, CompatibleHash const&,
  357. CompatiblePredicate const&);
  358. template <class CompatibleKey, class CompatibleHash,
  359. class CompatiblePredicate>
  360. const_iterator find(CompatibleKey const&, CompatibleHash const&,
  361. CompatiblePredicate const&) const;
  362. bool contains(const key_type& k) const
  363. {
  364. return table_.find(k) != this->end();
  365. }
  366. template <class Key>
  367. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  368. bool>::type
  369. contains(const Key& k) const
  370. {
  371. return table_.find(k) != this->end();
  372. }
  373. size_type count(const key_type&) const;
  374. template <class Key>
  375. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  376. size_type>::type
  377. count(const Key& k) const
  378. {
  379. return (table_.find(k) != this->end() ? 1 : 0);
  380. }
  381. std::pair<iterator, iterator> equal_range(const key_type&);
  382. std::pair<const_iterator, const_iterator> equal_range(
  383. const key_type&) const;
  384. template <class Key>
  385. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  386. std::pair<iterator, iterator> >::type
  387. equal_range(const Key& key)
  388. {
  389. iterator first = table_.find(key);
  390. iterator last = first;
  391. if (last != this->end()) {
  392. ++last;
  393. }
  394. return std::make_pair(first, last);
  395. }
  396. template <class Key>
  397. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  398. std::pair<const_iterator, const_iterator> >::type
  399. equal_range(const Key& key) const
  400. {
  401. iterator first = table_.find(key);
  402. iterator last = first;
  403. if (last != this->end()) {
  404. ++last;
  405. }
  406. return std::make_pair(first, last);
  407. }
  408. mapped_type& operator[](const key_type&);
  409. mapped_type& operator[](key_type&&);
  410. template <class Key>
  411. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  412. mapped_type&>::type
  413. operator[](Key&& k);
  414. mapped_type& at(const key_type&);
  415. mapped_type const& at(const key_type&) const;
  416. template <class Key>
  417. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  418. mapped_type&>::type
  419. at(Key&& k);
  420. template <class Key>
  421. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  422. mapped_type const&>::type
  423. at(Key&& k) const;
  424. // bucket interface
  425. size_type bucket_count() const noexcept { return table_.bucket_count(); }
  426. size_type max_bucket_count() const noexcept
  427. {
  428. return table_.max_bucket_count();
  429. }
  430. size_type bucket_size(size_type) const;
  431. size_type bucket(const key_type& k) const
  432. {
  433. return table_.hash_to_bucket(table_.hash(k));
  434. }
  435. template <class Key>
  436. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  437. size_type>::type
  438. bucket(Key&& k) const
  439. {
  440. return table_.hash_to_bucket(table_.hash(std::forward<Key>(k)));
  441. }
  442. local_iterator begin(size_type n) { return table_.begin(n); }
  443. const_local_iterator begin(size_type n) const
  444. {
  445. return const_local_iterator(table_.begin(n));
  446. }
  447. local_iterator end(size_type) { return local_iterator(); }
  448. const_local_iterator end(size_type) const
  449. {
  450. return const_local_iterator();
  451. }
  452. const_local_iterator cbegin(size_type n) const
  453. {
  454. return const_local_iterator(table_.begin(n));
  455. }
  456. const_local_iterator cend(size_type) const
  457. {
  458. return const_local_iterator();
  459. }
  460. // hash policy
  461. float load_factor() const noexcept;
  462. float max_load_factor() const noexcept { return table_.mlf_; }
  463. void max_load_factor(float) noexcept;
  464. void rehash(size_type);
  465. void reserve(size_type);
  466. #if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x0582)
  467. friend bool operator==
  468. <K, T, H, P, A>(unordered_map const&, unordered_map const&);
  469. friend bool operator!=
  470. <K, T, H, P, A>(unordered_map const&, unordered_map const&);
  471. #endif
  472. }; // class template unordered_map
  473. template <class Archive, class K, class T, class H, class P, class A>
  474. void serialize(
  475. Archive& ar, unordered_map<K, T, H, P, A>& m, unsigned int version)
  476. {
  477. detail::serialize_fca_container(ar, m, version);
  478. }
  479. #if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
  480. template <class InputIterator,
  481. class Hash =
  482. boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
  483. class Pred =
  484. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  485. class Allocator = std::allocator<
  486. boost::unordered::detail::iter_to_alloc_t<InputIterator> >,
  487. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  488. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  489. class = std::enable_if_t<detail::is_pred_v<Pred> >,
  490. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  491. unordered_map(InputIterator, InputIterator,
  492. std::size_t = boost::unordered::detail::default_bucket_count,
  493. Hash = Hash(), Pred = Pred(), Allocator = Allocator())
  494. -> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
  495. boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
  496. Allocator>;
  497. template <class Key, class T,
  498. class Hash = boost::hash<std::remove_const_t<Key> >,
  499. class Pred = std::equal_to<std::remove_const_t<Key> >,
  500. class Allocator = std::allocator<std::pair<const Key, T> >,
  501. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  502. class = std::enable_if_t<detail::is_pred_v<Pred> >,
  503. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  504. unordered_map(std::initializer_list<std::pair<Key, T> >,
  505. std::size_t = boost::unordered::detail::default_bucket_count,
  506. Hash = Hash(), Pred = Pred(), Allocator = Allocator())
  507. -> unordered_map<std::remove_const_t<Key>, T, Hash, Pred, Allocator>;
  508. template <class InputIterator, class Allocator,
  509. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  510. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  511. unordered_map(InputIterator, InputIterator, std::size_t, Allocator)
  512. -> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
  513. boost::unordered::detail::iter_val_t<InputIterator>,
  514. boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
  515. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  516. Allocator>;
  517. template <class InputIterator, class Allocator,
  518. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  519. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  520. unordered_map(InputIterator, InputIterator, Allocator)
  521. -> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
  522. boost::unordered::detail::iter_val_t<InputIterator>,
  523. boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
  524. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  525. Allocator>;
  526. template <class InputIterator, class Hash, class Allocator,
  527. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  528. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  529. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  530. unordered_map(InputIterator, InputIterator, std::size_t, Hash, Allocator)
  531. -> unordered_map<boost::unordered::detail::iter_key_t<InputIterator>,
  532. boost::unordered::detail::iter_val_t<InputIterator>, Hash,
  533. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  534. Allocator>;
  535. template <class Key, class T, class Allocator,
  536. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  537. unordered_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
  538. Allocator) -> unordered_map<std::remove_const_t<Key>, T,
  539. boost::hash<std::remove_const_t<Key> >,
  540. std::equal_to<std::remove_const_t<Key> >, Allocator>;
  541. template <class Key, class T, class Allocator,
  542. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  543. unordered_map(std::initializer_list<std::pair<Key, T> >, Allocator)
  544. -> unordered_map<std::remove_const_t<Key>, T,
  545. boost::hash<std::remove_const_t<Key> >,
  546. std::equal_to<std::remove_const_t<Key> >, Allocator>;
  547. template <class Key, class T, class Hash, class Allocator,
  548. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  549. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  550. unordered_map(std::initializer_list<std::pair<Key, T> >, std::size_t, Hash,
  551. Allocator) -> unordered_map<std::remove_const_t<Key>, T, Hash,
  552. std::equal_to<std::remove_const_t<Key> >, Allocator>;
  553. #endif
  554. template <class K, class T, class H, class P, class A>
  555. class unordered_multimap
  556. {
  557. template <typename, typename, typename, typename, typename>
  558. friend class unordered_map;
  559. public:
  560. typedef K key_type;
  561. typedef T mapped_type;
  562. typedef std::pair<const K, T> value_type;
  563. typedef typename boost::unordered::detail::type_identity<H>::type hasher;
  564. typedef
  565. typename boost::unordered::detail::type_identity<P>::type key_equal;
  566. typedef typename boost::unordered::detail::type_identity<A>::type
  567. allocator_type;
  568. private:
  569. typedef boost::unordered::detail::map<A, K, T, H, P> types;
  570. typedef typename types::value_allocator_traits value_allocator_traits;
  571. typedef typename types::table table;
  572. public:
  573. typedef typename value_allocator_traits::pointer pointer;
  574. typedef typename value_allocator_traits::const_pointer const_pointer;
  575. typedef value_type& reference;
  576. typedef value_type const& const_reference;
  577. typedef std::size_t size_type;
  578. typedef std::ptrdiff_t difference_type;
  579. typedef typename table::iterator iterator;
  580. typedef typename table::c_iterator const_iterator;
  581. typedef typename table::l_iterator local_iterator;
  582. typedef typename table::cl_iterator const_local_iterator;
  583. typedef typename types::node_type node_type;
  584. private:
  585. table table_;
  586. public:
  587. // constructors
  588. unordered_multimap();
  589. explicit unordered_multimap(size_type, const hasher& = hasher(),
  590. const key_equal& = key_equal(),
  591. const allocator_type& = allocator_type());
  592. template <class InputIt>
  593. unordered_multimap(InputIt, InputIt,
  594. size_type = boost::unordered::detail::default_bucket_count,
  595. const hasher& = hasher(), const key_equal& = key_equal(),
  596. const allocator_type& = allocator_type());
  597. unordered_multimap(unordered_multimap const&);
  598. unordered_multimap(unordered_multimap&& other)
  599. noexcept(table::nothrow_move_constructible)
  600. : table_(other.table_, boost::unordered::detail::move_tag())
  601. {
  602. // The move is done in table_
  603. }
  604. explicit unordered_multimap(allocator_type const&);
  605. unordered_multimap(unordered_multimap const&, allocator_type const&);
  606. unordered_multimap(unordered_multimap&&, allocator_type const&);
  607. unordered_multimap(std::initializer_list<value_type>,
  608. size_type = boost::unordered::detail::default_bucket_count,
  609. const hasher& = hasher(), const key_equal& l = key_equal(),
  610. const allocator_type& = allocator_type());
  611. explicit unordered_multimap(size_type, const allocator_type&);
  612. explicit unordered_multimap(
  613. size_type, const hasher&, const allocator_type&);
  614. template <class InputIterator>
  615. unordered_multimap(InputIterator, InputIterator, const allocator_type&);
  616. template <class InputIt>
  617. unordered_multimap(InputIt, InputIt, size_type, const allocator_type&);
  618. template <class InputIt>
  619. unordered_multimap(
  620. InputIt, InputIt, size_type, const hasher&, const allocator_type&);
  621. unordered_multimap(
  622. std::initializer_list<value_type>, const allocator_type&);
  623. unordered_multimap(
  624. std::initializer_list<value_type>, size_type, const allocator_type&);
  625. unordered_multimap(std::initializer_list<value_type>, size_type,
  626. const hasher&, const allocator_type&);
  627. // Destructor
  628. ~unordered_multimap() noexcept;
  629. // Assign
  630. unordered_multimap& operator=(unordered_multimap const& x)
  631. {
  632. table_.assign(x.table_, std::false_type());
  633. return *this;
  634. }
  635. unordered_multimap& operator=(unordered_multimap&& x)
  636. noexcept(value_allocator_traits::is_always_equal::value&&
  637. std::is_nothrow_move_assignable<H>::value&&
  638. std::is_nothrow_move_assignable<P>::value)
  639. {
  640. table_.move_assign(x.table_, std::false_type());
  641. return *this;
  642. }
  643. unordered_multimap& operator=(std::initializer_list<value_type>);
  644. allocator_type get_allocator() const noexcept
  645. {
  646. return allocator_type(table_.node_alloc());
  647. }
  648. // iterators
  649. iterator begin() noexcept { return iterator(table_.begin()); }
  650. const_iterator begin() const noexcept
  651. {
  652. return const_iterator(table_.begin());
  653. }
  654. iterator end() noexcept { return iterator(); }
  655. const_iterator end() const noexcept { return const_iterator(); }
  656. const_iterator cbegin() const noexcept
  657. {
  658. return const_iterator(table_.begin());
  659. }
  660. const_iterator cend() const noexcept { return const_iterator(); }
  661. // size and capacity
  662. BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
  663. {
  664. return table_.size_ == 0;
  665. }
  666. size_type size() const noexcept { return table_.size_; }
  667. size_type max_size() const noexcept;
  668. // emplace
  669. template <class... Args> iterator emplace(Args&&... args)
  670. {
  671. return iterator(table_.emplace_equiv(
  672. boost::unordered::detail::func::construct_node_from_args(
  673. table_.node_alloc(), std::forward<Args>(args)...)));
  674. }
  675. template <class... Args>
  676. iterator emplace_hint(const_iterator hint, Args&&... args)
  677. {
  678. return iterator(table_.emplace_hint_equiv(
  679. hint, boost::unordered::detail::func::construct_node_from_args(
  680. table_.node_alloc(), std::forward<Args>(args)...)));
  681. }
  682. iterator insert(value_type const& x) { return this->emplace(x); }
  683. iterator insert(value_type&& x) { return this->emplace(std::move(x)); }
  684. template <class P2>
  685. typename boost::enable_if<std::is_constructible<value_type, P2&&>,
  686. iterator>::type
  687. insert(P2&& obj)
  688. {
  689. return this->emplace(std::forward<P2>(obj));
  690. }
  691. iterator insert(const_iterator hint, value_type const& x)
  692. {
  693. return this->emplace_hint(hint, x);
  694. }
  695. iterator insert(const_iterator hint, value_type&& x)
  696. {
  697. return this->emplace_hint(hint, std::move(x));
  698. }
  699. template <class P2>
  700. typename boost::enable_if<std::is_constructible<value_type, P2&&>,
  701. iterator>::type
  702. insert(const_iterator hint, P2&& obj)
  703. {
  704. return this->emplace_hint(hint, std::forward<P2>(obj));
  705. }
  706. template <class InputIt> void insert(InputIt, InputIt);
  707. void insert(std::initializer_list<value_type>);
  708. // extract
  709. node_type extract(const_iterator position)
  710. {
  711. return node_type(
  712. table_.extract_by_iterator_equiv(position), table_.node_alloc());
  713. }
  714. node_type extract(const key_type& k)
  715. {
  716. return node_type(table_.extract_by_key_impl(k), table_.node_alloc());
  717. }
  718. template <class Key>
  719. typename boost::enable_if_c<
  720. detail::transparent_non_iterable<Key, unordered_multimap>::value,
  721. node_type>::type
  722. extract(const Key& k)
  723. {
  724. return node_type(table_.extract_by_key_impl(k), table_.node_alloc());
  725. }
  726. iterator insert(node_type&& np)
  727. {
  728. return table_.move_insert_node_type_equiv(np);
  729. }
  730. iterator insert(const_iterator hint, node_type&& np)
  731. {
  732. return table_.move_insert_node_type_with_hint_equiv(hint, np);
  733. }
  734. iterator erase(iterator);
  735. iterator erase(const_iterator);
  736. size_type erase(const key_type&);
  737. iterator erase(const_iterator, const_iterator);
  738. template <class Key>
  739. typename boost::enable_if_c<
  740. detail::transparent_non_iterable<Key, unordered_multimap>::value,
  741. size_type>::type
  742. erase(Key&& k)
  743. {
  744. return table_.erase_key_equiv_impl(std::forward<Key>(k));
  745. }
  746. BOOST_UNORDERED_DEPRECATED("Use erase instead")
  747. void quick_erase(const_iterator it) { erase(it); }
  748. BOOST_UNORDERED_DEPRECATED("Use erase instead")
  749. void erase_return_void(const_iterator it) { erase(it); }
  750. void swap(unordered_multimap&)
  751. noexcept(value_allocator_traits::is_always_equal::value&&
  752. boost::unordered::detail::is_nothrow_swappable<H>::value&&
  753. boost::unordered::detail::is_nothrow_swappable<P>::value);
  754. void clear() noexcept { table_.clear_impl(); }
  755. template <typename H2, typename P2>
  756. void merge(boost::unordered_multimap<K, T, H2, P2, A>& source);
  757. template <typename H2, typename P2>
  758. void merge(boost::unordered_multimap<K, T, H2, P2, A>&& source);
  759. template <typename H2, typename P2>
  760. void merge(boost::unordered_map<K, T, H2, P2, A>& source);
  761. template <typename H2, typename P2>
  762. void merge(boost::unordered_map<K, T, H2, P2, A>&& source);
  763. // observers
  764. hasher hash_function() const;
  765. key_equal key_eq() const;
  766. // lookup
  767. iterator find(const key_type&);
  768. const_iterator find(const key_type&) const;
  769. template <class Key>
  770. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  771. iterator>::type
  772. find(const Key& key)
  773. {
  774. return table_.find(key);
  775. }
  776. template <class Key>
  777. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  778. const_iterator>::type
  779. find(const Key& key) const
  780. {
  781. return const_iterator(table_.find(key));
  782. }
  783. template <class CompatibleKey, class CompatibleHash,
  784. class CompatiblePredicate>
  785. iterator find(CompatibleKey const&, CompatibleHash const&,
  786. CompatiblePredicate const&);
  787. template <class CompatibleKey, class CompatibleHash,
  788. class CompatiblePredicate>
  789. const_iterator find(CompatibleKey const&, CompatibleHash const&,
  790. CompatiblePredicate const&) const;
  791. bool contains(key_type const& k) const
  792. {
  793. return table_.find(k) != this->end();
  794. }
  795. template <class Key>
  796. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  797. bool>::type
  798. contains(const Key& k) const
  799. {
  800. return table_.find(k) != this->end();
  801. }
  802. size_type count(const key_type&) const;
  803. template <class Key>
  804. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  805. size_type>::type
  806. count(const Key& k) const
  807. {
  808. return table_.group_count(k);
  809. }
  810. std::pair<iterator, iterator> equal_range(const key_type&);
  811. std::pair<const_iterator, const_iterator> equal_range(
  812. const key_type&) const;
  813. template <class Key>
  814. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  815. std::pair<iterator, iterator> >::type
  816. equal_range(const Key& key)
  817. {
  818. iterator p = table_.find(key);
  819. return std::make_pair(p, table_.next_group(key, p));
  820. }
  821. template <class Key>
  822. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  823. std::pair<const_iterator, const_iterator> >::type
  824. equal_range(const Key& key) const
  825. {
  826. iterator p = table_.find(key);
  827. return std::make_pair(
  828. const_iterator(p), const_iterator(table_.next_group(key, p)));
  829. }
  830. // bucket interface
  831. size_type bucket_count() const noexcept { return table_.bucket_count(); }
  832. size_type max_bucket_count() const noexcept
  833. {
  834. return table_.max_bucket_count();
  835. }
  836. size_type bucket_size(size_type) const;
  837. size_type bucket(const key_type& k) const
  838. {
  839. return table_.hash_to_bucket(table_.hash(k));
  840. }
  841. template <class Key>
  842. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  843. size_type>::type
  844. bucket(Key&& k) const
  845. {
  846. return table_.hash_to_bucket(table_.hash(std::forward<Key>(k)));
  847. }
  848. local_iterator begin(size_type n)
  849. {
  850. return local_iterator(table_.begin(n));
  851. }
  852. const_local_iterator begin(size_type n) const
  853. {
  854. return const_local_iterator(table_.begin(n));
  855. }
  856. local_iterator end(size_type) { return local_iterator(); }
  857. const_local_iterator end(size_type) const
  858. {
  859. return const_local_iterator();
  860. }
  861. const_local_iterator cbegin(size_type n) const
  862. {
  863. return const_local_iterator(table_.begin(n));
  864. }
  865. const_local_iterator cend(size_type) const
  866. {
  867. return const_local_iterator();
  868. }
  869. // hash policy
  870. float load_factor() const noexcept;
  871. float max_load_factor() const noexcept { return table_.mlf_; }
  872. void max_load_factor(float) noexcept;
  873. void rehash(size_type);
  874. void reserve(size_type);
  875. #if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x0582)
  876. friend bool operator==
  877. <K, T, H, P, A>(unordered_multimap const&, unordered_multimap const&);
  878. friend bool operator!=
  879. <K, T, H, P, A>(unordered_multimap const&, unordered_multimap const&);
  880. #endif
  881. }; // class template unordered_multimap
  882. template <class Archive, class K, class T, class H, class P, class A>
  883. void serialize(
  884. Archive& ar, unordered_multimap<K, T, H, P, A>& m, unsigned int version)
  885. {
  886. detail::serialize_fca_container(ar, m, version);
  887. }
  888. #if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
  889. template <class InputIterator,
  890. class Hash =
  891. boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
  892. class Pred =
  893. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  894. class Allocator = std::allocator<
  895. boost::unordered::detail::iter_to_alloc_t<InputIterator> >,
  896. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  897. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  898. class = std::enable_if_t<detail::is_pred_v<Pred> >,
  899. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  900. unordered_multimap(InputIterator, InputIterator,
  901. std::size_t = boost::unordered::detail::default_bucket_count,
  902. Hash = Hash(), Pred = Pred(), Allocator = Allocator())
  903. -> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
  904. boost::unordered::detail::iter_val_t<InputIterator>, Hash, Pred,
  905. Allocator>;
  906. template <class Key, class T,
  907. class Hash = boost::hash<std::remove_const_t<Key> >,
  908. class Pred = std::equal_to<std::remove_const_t<Key> >,
  909. class Allocator = std::allocator<std::pair<const Key, T> >,
  910. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  911. class = std::enable_if_t<detail::is_pred_v<Pred> >,
  912. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  913. unordered_multimap(std::initializer_list<std::pair<Key, T> >,
  914. std::size_t = boost::unordered::detail::default_bucket_count,
  915. Hash = Hash(), Pred = Pred(), Allocator = Allocator())
  916. -> unordered_multimap<std::remove_const_t<Key>, T, Hash, Pred, Allocator>;
  917. template <class InputIterator, class Allocator,
  918. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  919. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  920. unordered_multimap(InputIterator, InputIterator, std::size_t, Allocator)
  921. -> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
  922. boost::unordered::detail::iter_val_t<InputIterator>,
  923. boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
  924. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  925. Allocator>;
  926. template <class InputIterator, class Allocator,
  927. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  928. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  929. unordered_multimap(InputIterator, InputIterator, Allocator)
  930. -> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
  931. boost::unordered::detail::iter_val_t<InputIterator>,
  932. boost::hash<boost::unordered::detail::iter_key_t<InputIterator> >,
  933. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  934. Allocator>;
  935. template <class InputIterator, class Hash, class Allocator,
  936. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  937. class = std::enable_if_t<detail::is_input_iterator_v<InputIterator> >,
  938. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  939. unordered_multimap(
  940. InputIterator, InputIterator, std::size_t, Hash, Allocator)
  941. -> unordered_multimap<boost::unordered::detail::iter_key_t<InputIterator>,
  942. boost::unordered::detail::iter_val_t<InputIterator>, Hash,
  943. std::equal_to<boost::unordered::detail::iter_key_t<InputIterator> >,
  944. Allocator>;
  945. template <class Key, class T, class Allocator,
  946. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  947. unordered_multimap(std::initializer_list<std::pair<Key, T> >, std::size_t,
  948. Allocator) -> unordered_multimap<std::remove_const_t<Key>, T,
  949. boost::hash<std::remove_const_t<Key> >,
  950. std::equal_to<std::remove_const_t<Key> >, Allocator>;
  951. template <class Key, class T, class Allocator,
  952. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  953. unordered_multimap(std::initializer_list<std::pair<Key, T> >, Allocator)
  954. -> unordered_multimap<std::remove_const_t<Key>, T,
  955. boost::hash<std::remove_const_t<Key> >,
  956. std::equal_to<std::remove_const_t<Key> >, Allocator>;
  957. template <class Key, class T, class Hash, class Allocator,
  958. class = std::enable_if_t<detail::is_hash_v<Hash> >,
  959. class = std::enable_if_t<detail::is_allocator_v<Allocator> > >
  960. unordered_multimap(std::initializer_list<std::pair<Key, T> >, std::size_t,
  961. Hash, Allocator) -> unordered_multimap<std::remove_const_t<Key>, T, Hash,
  962. std::equal_to<std::remove_const_t<Key> >, Allocator>;
  963. #endif
  964. ////////////////////////////////////////////////////////////////////////////
  965. template <class K, class T, class H, class P, class A>
  966. unordered_map<K, T, H, P, A>::unordered_map()
  967. {
  968. }
  969. template <class K, class T, class H, class P, class A>
  970. unordered_map<K, T, H, P, A>::unordered_map(size_type n, const hasher& hf,
  971. const key_equal& eql, const allocator_type& a)
  972. : table_(n, hf, eql, a)
  973. {
  974. }
  975. template <class K, class T, class H, class P, class A>
  976. template <class InputIt>
  977. unordered_map<K, T, H, P, A>::unordered_map(InputIt f, InputIt l,
  978. size_type n, const hasher& hf, const key_equal& eql,
  979. const allocator_type& a)
  980. : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
  981. {
  982. this->insert(f, l);
  983. }
  984. template <class K, class T, class H, class P, class A>
  985. unordered_map<K, T, H, P, A>::unordered_map(unordered_map const& other)
  986. : table_(other.table_,
  987. unordered_map::value_allocator_traits::
  988. select_on_container_copy_construction(other.get_allocator()))
  989. {
  990. if (other.size()) {
  991. table_.copy_buckets(other.table_, std::true_type());
  992. }
  993. }
  994. template <class K, class T, class H, class P, class A>
  995. unordered_map<K, T, H, P, A>::unordered_map(allocator_type const& a)
  996. : table_(boost::unordered::detail::default_bucket_count, hasher(),
  997. key_equal(), a)
  998. {
  999. }
  1000. template <class K, class T, class H, class P, class A>
  1001. unordered_map<K, T, H, P, A>::unordered_map(
  1002. unordered_map const& other, allocator_type const& a)
  1003. : table_(other.table_, a)
  1004. {
  1005. if (other.table_.size_) {
  1006. table_.copy_buckets(other.table_, std::true_type());
  1007. }
  1008. }
  1009. template <class K, class T, class H, class P, class A>
  1010. unordered_map<K, T, H, P, A>::unordered_map(
  1011. unordered_map&& other, allocator_type const& a)
  1012. : table_(other.table_, a, boost::unordered::detail::move_tag())
  1013. {
  1014. table_.move_construct_buckets(other.table_);
  1015. }
  1016. template <class K, class T, class H, class P, class A>
  1017. unordered_map<K, T, H, P, A>::unordered_map(
  1018. std::initializer_list<value_type> list, size_type n, const hasher& hf,
  1019. const key_equal& eql, const allocator_type& a)
  1020. : table_(
  1021. boost::unordered::detail::initial_size(list.begin(), list.end(), n),
  1022. hf, eql, a)
  1023. {
  1024. this->insert(list.begin(), list.end());
  1025. }
  1026. template <class K, class T, class H, class P, class A>
  1027. unordered_map<K, T, H, P, A>::unordered_map(
  1028. size_type n, const allocator_type& a)
  1029. : table_(n, hasher(), key_equal(), a)
  1030. {
  1031. }
  1032. template <class K, class T, class H, class P, class A>
  1033. unordered_map<K, T, H, P, A>::unordered_map(
  1034. size_type n, const hasher& hf, const allocator_type& a)
  1035. : table_(n, hf, key_equal(), a)
  1036. {
  1037. }
  1038. template <class K, class T, class H, class P, class A>
  1039. template <class InputIterator>
  1040. unordered_map<K, T, H, P, A>::unordered_map(
  1041. InputIterator f, InputIterator l, const allocator_type& a)
  1042. : table_(boost::unordered::detail::initial_size(
  1043. f, l, detail::default_bucket_count),
  1044. hasher(), key_equal(), a)
  1045. {
  1046. this->insert(f, l);
  1047. }
  1048. template <class K, class T, class H, class P, class A>
  1049. template <class InputIt>
  1050. unordered_map<K, T, H, P, A>::unordered_map(
  1051. InputIt f, InputIt l, size_type n, const allocator_type& a)
  1052. : table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
  1053. key_equal(), a)
  1054. {
  1055. this->insert(f, l);
  1056. }
  1057. template <class K, class T, class H, class P, class A>
  1058. template <class InputIt>
  1059. unordered_map<K, T, H, P, A>::unordered_map(InputIt f, InputIt l,
  1060. size_type n, const hasher& hf, const allocator_type& a)
  1061. : table_(
  1062. boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
  1063. {
  1064. this->insert(f, l);
  1065. }
  1066. template <class K, class T, class H, class P, class A>
  1067. unordered_map<K, T, H, P, A>::unordered_map(
  1068. std::initializer_list<value_type> list, const allocator_type& a)
  1069. : table_(boost::unordered::detail::initial_size(
  1070. list.begin(), list.end(), detail::default_bucket_count),
  1071. hasher(), key_equal(), a)
  1072. {
  1073. this->insert(list.begin(), list.end());
  1074. }
  1075. template <class K, class T, class H, class P, class A>
  1076. unordered_map<K, T, H, P, A>::unordered_map(
  1077. std::initializer_list<value_type> list, size_type n,
  1078. const allocator_type& a)
  1079. : table_(
  1080. boost::unordered::detail::initial_size(list.begin(), list.end(), n),
  1081. hasher(), key_equal(), a)
  1082. {
  1083. this->insert(list.begin(), list.end());
  1084. }
  1085. template <class K, class T, class H, class P, class A>
  1086. unordered_map<K, T, H, P, A>::unordered_map(
  1087. std::initializer_list<value_type> list, size_type n, const hasher& hf,
  1088. const allocator_type& a)
  1089. : table_(
  1090. boost::unordered::detail::initial_size(list.begin(), list.end(), n),
  1091. hf, key_equal(), a)
  1092. {
  1093. this->insert(list.begin(), list.end());
  1094. }
  1095. template <class K, class T, class H, class P, class A>
  1096. unordered_map<K, T, H, P, A>::~unordered_map() noexcept
  1097. {
  1098. }
  1099. template <class K, class T, class H, class P, class A>
  1100. unordered_map<K, T, H, P, A>& unordered_map<K, T, H, P, A>::operator=(
  1101. std::initializer_list<value_type> list)
  1102. {
  1103. this->clear();
  1104. this->insert(list.begin(), list.end());
  1105. return *this;
  1106. }
  1107. // size and capacity
  1108. template <class K, class T, class H, class P, class A>
  1109. std::size_t unordered_map<K, T, H, P, A>::max_size() const noexcept
  1110. {
  1111. using namespace std;
  1112. // size <= mlf_ * count
  1113. return boost::unordered::detail::double_to_size(
  1114. ceil(static_cast<double>(table_.mlf_) *
  1115. static_cast<double>(table_.max_bucket_count()))) -
  1116. 1;
  1117. }
  1118. // modifiers
  1119. template <class K, class T, class H, class P, class A>
  1120. template <class InputIt>
  1121. void unordered_map<K, T, H, P, A>::insert(InputIt first, InputIt last)
  1122. {
  1123. if (first != last) {
  1124. table_.insert_range_unique(
  1125. table::extractor::extract(*first), first, last);
  1126. }
  1127. }
  1128. template <class K, class T, class H, class P, class A>
  1129. void unordered_map<K, T, H, P, A>::insert(
  1130. std::initializer_list<value_type> list)
  1131. {
  1132. this->insert(list.begin(), list.end());
  1133. }
  1134. template <class K, class T, class H, class P, class A>
  1135. typename unordered_map<K, T, H, P, A>::iterator
  1136. unordered_map<K, T, H, P, A>::erase(iterator position)
  1137. {
  1138. return table_.erase_node(position);
  1139. }
  1140. template <class K, class T, class H, class P, class A>
  1141. typename unordered_map<K, T, H, P, A>::iterator
  1142. unordered_map<K, T, H, P, A>::erase(const_iterator position)
  1143. {
  1144. return table_.erase_node(position);
  1145. }
  1146. template <class K, class T, class H, class P, class A>
  1147. typename unordered_map<K, T, H, P, A>::size_type
  1148. unordered_map<K, T, H, P, A>::erase(const key_type& k)
  1149. {
  1150. return table_.erase_key_unique_impl(k);
  1151. }
  1152. template <class K, class T, class H, class P, class A>
  1153. typename unordered_map<K, T, H, P, A>::iterator
  1154. unordered_map<K, T, H, P, A>::erase(
  1155. const_iterator first, const_iterator last)
  1156. {
  1157. return table_.erase_nodes_range(first, last);
  1158. }
  1159. template <class K, class T, class H, class P, class A>
  1160. void unordered_map<K, T, H, P, A>::swap(unordered_map& other)
  1161. noexcept(value_allocator_traits::is_always_equal::value&&
  1162. boost::unordered::detail::is_nothrow_swappable<H>::value&&
  1163. boost::unordered::detail::is_nothrow_swappable<P>::value)
  1164. {
  1165. table_.swap(other.table_);
  1166. }
  1167. template <class K, class T, class H, class P, class A>
  1168. template <typename H2, typename P2>
  1169. void unordered_map<K, T, H, P, A>::merge(
  1170. boost::unordered_map<K, T, H2, P2, A>& source)
  1171. {
  1172. table_.merge_unique(source.table_);
  1173. }
  1174. template <class K, class T, class H, class P, class A>
  1175. template <typename H2, typename P2>
  1176. void unordered_map<K, T, H, P, A>::merge(
  1177. boost::unordered_map<K, T, H2, P2, A>&& source)
  1178. {
  1179. table_.merge_unique(source.table_);
  1180. }
  1181. template <class K, class T, class H, class P, class A>
  1182. template <typename H2, typename P2>
  1183. void unordered_map<K, T, H, P, A>::merge(
  1184. boost::unordered_multimap<K, T, H2, P2, A>& source)
  1185. {
  1186. table_.merge_unique(source.table_);
  1187. }
  1188. template <class K, class T, class H, class P, class A>
  1189. template <typename H2, typename P2>
  1190. void unordered_map<K, T, H, P, A>::merge(
  1191. boost::unordered_multimap<K, T, H2, P2, A>&& source)
  1192. {
  1193. table_.merge_unique(source.table_);
  1194. }
  1195. // observers
  1196. template <class K, class T, class H, class P, class A>
  1197. typename unordered_map<K, T, H, P, A>::hasher
  1198. unordered_map<K, T, H, P, A>::hash_function() const
  1199. {
  1200. return table_.hash_function();
  1201. }
  1202. template <class K, class T, class H, class P, class A>
  1203. typename unordered_map<K, T, H, P, A>::key_equal
  1204. unordered_map<K, T, H, P, A>::key_eq() const
  1205. {
  1206. return table_.key_eq();
  1207. }
  1208. // lookup
  1209. template <class K, class T, class H, class P, class A>
  1210. typename unordered_map<K, T, H, P, A>::iterator
  1211. unordered_map<K, T, H, P, A>::find(const key_type& k)
  1212. {
  1213. return iterator(table_.find(k));
  1214. }
  1215. template <class K, class T, class H, class P, class A>
  1216. typename unordered_map<K, T, H, P, A>::const_iterator
  1217. unordered_map<K, T, H, P, A>::find(const key_type& k) const
  1218. {
  1219. return const_iterator(table_.find(k));
  1220. }
  1221. template <class K, class T, class H, class P, class A>
  1222. template <class CompatibleKey, class CompatibleHash,
  1223. class CompatiblePredicate>
  1224. typename unordered_map<K, T, H, P, A>::iterator
  1225. unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
  1226. CompatibleHash const& hash, CompatiblePredicate const& eq)
  1227. {
  1228. return table_.transparent_find(k, hash, eq);
  1229. }
  1230. template <class K, class T, class H, class P, class A>
  1231. template <class CompatibleKey, class CompatibleHash,
  1232. class CompatiblePredicate>
  1233. typename unordered_map<K, T, H, P, A>::const_iterator
  1234. unordered_map<K, T, H, P, A>::find(CompatibleKey const& k,
  1235. CompatibleHash const& hash, CompatiblePredicate const& eq) const
  1236. {
  1237. return table_.transparent_find(k, hash, eq);
  1238. }
  1239. template <class K, class T, class H, class P, class A>
  1240. typename unordered_map<K, T, H, P, A>::size_type
  1241. unordered_map<K, T, H, P, A>::count(const key_type& k) const
  1242. {
  1243. return table_.find_node(k) ? 1 : 0;
  1244. }
  1245. template <class K, class T, class H, class P, class A>
  1246. std::pair<typename unordered_map<K, T, H, P, A>::iterator,
  1247. typename unordered_map<K, T, H, P, A>::iterator>
  1248. unordered_map<K, T, H, P, A>::equal_range(const key_type& k)
  1249. {
  1250. iterator first = table_.find(k);
  1251. iterator second = first;
  1252. if (second != this->end()) {
  1253. ++second;
  1254. }
  1255. return std::make_pair(first, second);
  1256. }
  1257. template <class K, class T, class H, class P, class A>
  1258. std::pair<typename unordered_map<K, T, H, P, A>::const_iterator,
  1259. typename unordered_map<K, T, H, P, A>::const_iterator>
  1260. unordered_map<K, T, H, P, A>::equal_range(const key_type& k) const
  1261. {
  1262. iterator first = table_.find(k);
  1263. iterator second = first;
  1264. if (second != this->end()) {
  1265. ++second;
  1266. }
  1267. return std::make_pair(const_iterator(first), const_iterator(second));
  1268. }
  1269. template <class K, class T, class H, class P, class A>
  1270. typename unordered_map<K, T, H, P, A>::mapped_type&
  1271. unordered_map<K, T, H, P, A>::operator[](const key_type& k)
  1272. {
  1273. return table_.try_emplace_unique(k).first->second;
  1274. }
  1275. template <class K, class T, class H, class P, class A>
  1276. typename unordered_map<K, T, H, P, A>::mapped_type&
  1277. unordered_map<K, T, H, P, A>::operator[](key_type&& k)
  1278. {
  1279. return table_.try_emplace_unique(std::move(k)).first->second;
  1280. }
  1281. template <class K, class T, class H, class P, class A>
  1282. template <class Key>
  1283. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  1284. typename unordered_map<K, T, H, P, A>::mapped_type&>::type
  1285. unordered_map<K, T, H, P, A>::operator[](Key&& k)
  1286. {
  1287. return table_.try_emplace_unique(std::forward<Key>(k)).first->second;
  1288. }
  1289. template <class K, class T, class H, class P, class A>
  1290. typename unordered_map<K, T, H, P, A>::mapped_type&
  1291. unordered_map<K, T, H, P, A>::at(const key_type& k)
  1292. {
  1293. typedef typename table::node_pointer node_pointer;
  1294. if (table_.size_) {
  1295. node_pointer p = table_.find_node(k);
  1296. if (p)
  1297. return p->value().second;
  1298. }
  1299. boost::unordered::detail::throw_out_of_range(
  1300. "Unable to find key in unordered_map.");
  1301. }
  1302. template <class K, class T, class H, class P, class A>
  1303. typename unordered_map<K, T, H, P, A>::mapped_type const&
  1304. unordered_map<K, T, H, P, A>::at(const key_type& k) const
  1305. {
  1306. typedef typename table::node_pointer node_pointer;
  1307. if (table_.size_) {
  1308. node_pointer p = table_.find_node(k);
  1309. if (p)
  1310. return p->value().second;
  1311. }
  1312. boost::unordered::detail::throw_out_of_range(
  1313. "Unable to find key in unordered_map.");
  1314. }
  1315. template <class K, class T, class H, class P, class A>
  1316. template <class Key>
  1317. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  1318. typename unordered_map<K, T, H, P, A>::mapped_type&>::type
  1319. unordered_map<K, T, H, P, A>::at(Key&& k)
  1320. {
  1321. typedef typename table::node_pointer node_pointer;
  1322. if (table_.size_) {
  1323. node_pointer p = table_.find_node(std::forward<Key>(k));
  1324. if (p)
  1325. return p->value().second;
  1326. }
  1327. boost::unordered::detail::throw_out_of_range(
  1328. "Unable to find key in unordered_map.");
  1329. }
  1330. template <class K, class T, class H, class P, class A>
  1331. template <class Key>
  1332. typename boost::enable_if_c<detail::are_transparent<Key, H, P>::value,
  1333. typename unordered_map<K, T, H, P, A>::mapped_type const&>::type
  1334. unordered_map<K, T, H, P, A>::at(Key&& k) const
  1335. {
  1336. typedef typename table::node_pointer node_pointer;
  1337. if (table_.size_) {
  1338. node_pointer p = table_.find_node(std::forward<Key>(k));
  1339. if (p)
  1340. return p->value().second;
  1341. }
  1342. boost::unordered::detail::throw_out_of_range(
  1343. "Unable to find key in unordered_map.");
  1344. }
  1345. template <class K, class T, class H, class P, class A>
  1346. typename unordered_map<K, T, H, P, A>::size_type
  1347. unordered_map<K, T, H, P, A>::bucket_size(size_type n) const
  1348. {
  1349. return table_.bucket_size(n);
  1350. }
  1351. // hash policy
  1352. template <class K, class T, class H, class P, class A>
  1353. float unordered_map<K, T, H, P, A>::load_factor() const noexcept
  1354. {
  1355. if (table_.size_ == 0) {
  1356. return 0.0f;
  1357. }
  1358. BOOST_ASSERT(table_.bucket_count() != 0);
  1359. return static_cast<float>(table_.size_) /
  1360. static_cast<float>(table_.bucket_count());
  1361. }
  1362. template <class K, class T, class H, class P, class A>
  1363. void unordered_map<K, T, H, P, A>::max_load_factor(float m) noexcept
  1364. {
  1365. table_.max_load_factor(m);
  1366. }
  1367. template <class K, class T, class H, class P, class A>
  1368. void unordered_map<K, T, H, P, A>::rehash(size_type n)
  1369. {
  1370. table_.rehash(n);
  1371. }
  1372. template <class K, class T, class H, class P, class A>
  1373. void unordered_map<K, T, H, P, A>::reserve(size_type n)
  1374. {
  1375. table_.reserve(n);
  1376. }
  1377. template <class K, class T, class H, class P, class A>
  1378. inline bool operator==(unordered_map<K, T, H, P, A> const& m1,
  1379. unordered_map<K, T, H, P, A> const& m2)
  1380. {
  1381. #if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
  1382. struct dummy
  1383. {
  1384. unordered_map<K, T, H, P, A> x;
  1385. };
  1386. #endif
  1387. return m1.table_.equals_unique(m2.table_);
  1388. }
  1389. template <class K, class T, class H, class P, class A>
  1390. inline bool operator!=(unordered_map<K, T, H, P, A> const& m1,
  1391. unordered_map<K, T, H, P, A> const& m2)
  1392. {
  1393. #if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
  1394. struct dummy
  1395. {
  1396. unordered_map<K, T, H, P, A> x;
  1397. };
  1398. #endif
  1399. return !m1.table_.equals_unique(m2.table_);
  1400. }
  1401. template <class K, class T, class H, class P, class A>
  1402. inline void swap(unordered_map<K, T, H, P, A>& m1,
  1403. unordered_map<K, T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)))
  1404. {
  1405. #if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
  1406. struct dummy
  1407. {
  1408. unordered_map<K, T, H, P, A> x;
  1409. };
  1410. #endif
  1411. m1.swap(m2);
  1412. }
  1413. template <class K, class T, class H, class P, class A, class Predicate>
  1414. typename unordered_map<K, T, H, P, A>::size_type erase_if(
  1415. unordered_map<K, T, H, P, A>& c, Predicate pred)
  1416. {
  1417. return detail::erase_if(c, pred);
  1418. }
  1419. ////////////////////////////////////////////////////////////////////////////
  1420. template <class K, class T, class H, class P, class A>
  1421. unordered_multimap<K, T, H, P, A>::unordered_multimap()
  1422. {
  1423. }
  1424. template <class K, class T, class H, class P, class A>
  1425. unordered_multimap<K, T, H, P, A>::unordered_multimap(size_type n,
  1426. const hasher& hf, const key_equal& eql, const allocator_type& a)
  1427. : table_(n, hf, eql, a)
  1428. {
  1429. }
  1430. template <class K, class T, class H, class P, class A>
  1431. template <class InputIt>
  1432. unordered_multimap<K, T, H, P, A>::unordered_multimap(InputIt f, InputIt l,
  1433. size_type n, const hasher& hf, const key_equal& eql,
  1434. const allocator_type& a)
  1435. : table_(boost::unordered::detail::initial_size(f, l, n), hf, eql, a)
  1436. {
  1437. this->insert(f, l);
  1438. }
  1439. template <class K, class T, class H, class P, class A>
  1440. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1441. unordered_multimap const& other)
  1442. : table_(other.table_,
  1443. unordered_multimap::value_allocator_traits::
  1444. select_on_container_copy_construction(other.get_allocator()))
  1445. {
  1446. if (other.table_.size_) {
  1447. table_.copy_buckets(other.table_, std::false_type());
  1448. }
  1449. }
  1450. template <class K, class T, class H, class P, class A>
  1451. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1452. allocator_type const& a)
  1453. : table_(boost::unordered::detail::default_bucket_count, hasher(),
  1454. key_equal(), a)
  1455. {
  1456. }
  1457. template <class K, class T, class H, class P, class A>
  1458. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1459. unordered_multimap const& other, allocator_type const& a)
  1460. : table_(other.table_, a)
  1461. {
  1462. if (other.table_.size_) {
  1463. table_.copy_buckets(other.table_, std::false_type());
  1464. }
  1465. }
  1466. template <class K, class T, class H, class P, class A>
  1467. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1468. unordered_multimap&& other, allocator_type const& a)
  1469. : table_(other.table_, a, boost::unordered::detail::move_tag())
  1470. {
  1471. table_.move_construct_buckets(other.table_);
  1472. }
  1473. template <class K, class T, class H, class P, class A>
  1474. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1475. std::initializer_list<value_type> list, size_type n, const hasher& hf,
  1476. const key_equal& eql, const allocator_type& a)
  1477. : table_(
  1478. boost::unordered::detail::initial_size(list.begin(), list.end(), n),
  1479. hf, eql, a)
  1480. {
  1481. this->insert(list.begin(), list.end());
  1482. }
  1483. template <class K, class T, class H, class P, class A>
  1484. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1485. size_type n, const allocator_type& a)
  1486. : table_(n, hasher(), key_equal(), a)
  1487. {
  1488. }
  1489. template <class K, class T, class H, class P, class A>
  1490. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1491. size_type n, const hasher& hf, const allocator_type& a)
  1492. : table_(n, hf, key_equal(), a)
  1493. {
  1494. }
  1495. template <class K, class T, class H, class P, class A>
  1496. template <class InputIterator>
  1497. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1498. InputIterator f, InputIterator l, const allocator_type& a)
  1499. : table_(boost::unordered::detail::initial_size(
  1500. f, l, detail::default_bucket_count),
  1501. hasher(), key_equal(), a)
  1502. {
  1503. this->insert(f, l);
  1504. }
  1505. template <class K, class T, class H, class P, class A>
  1506. template <class InputIt>
  1507. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1508. InputIt f, InputIt l, size_type n, const allocator_type& a)
  1509. : table_(boost::unordered::detail::initial_size(f, l, n), hasher(),
  1510. key_equal(), a)
  1511. {
  1512. this->insert(f, l);
  1513. }
  1514. template <class K, class T, class H, class P, class A>
  1515. template <class InputIt>
  1516. unordered_multimap<K, T, H, P, A>::unordered_multimap(InputIt f, InputIt l,
  1517. size_type n, const hasher& hf, const allocator_type& a)
  1518. : table_(
  1519. boost::unordered::detail::initial_size(f, l, n), hf, key_equal(), a)
  1520. {
  1521. this->insert(f, l);
  1522. }
  1523. template <class K, class T, class H, class P, class A>
  1524. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1525. std::initializer_list<value_type> list, const allocator_type& a)
  1526. : table_(boost::unordered::detail::initial_size(
  1527. list.begin(), list.end(), detail::default_bucket_count),
  1528. hasher(), key_equal(), a)
  1529. {
  1530. this->insert(list.begin(), list.end());
  1531. }
  1532. template <class K, class T, class H, class P, class A>
  1533. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1534. std::initializer_list<value_type> list, size_type n,
  1535. const allocator_type& a)
  1536. : table_(
  1537. boost::unordered::detail::initial_size(list.begin(), list.end(), n),
  1538. hasher(), key_equal(), a)
  1539. {
  1540. this->insert(list.begin(), list.end());
  1541. }
  1542. template <class K, class T, class H, class P, class A>
  1543. unordered_multimap<K, T, H, P, A>::unordered_multimap(
  1544. std::initializer_list<value_type> list, size_type n, const hasher& hf,
  1545. const allocator_type& a)
  1546. : table_(
  1547. boost::unordered::detail::initial_size(list.begin(), list.end(), n),
  1548. hf, key_equal(), a)
  1549. {
  1550. this->insert(list.begin(), list.end());
  1551. }
  1552. template <class K, class T, class H, class P, class A>
  1553. unordered_multimap<K, T, H, P, A>::~unordered_multimap() noexcept
  1554. {
  1555. }
  1556. template <class K, class T, class H, class P, class A>
  1557. unordered_multimap<K, T, H, P, A>&
  1558. unordered_multimap<K, T, H, P, A>::operator=(
  1559. std::initializer_list<value_type> list)
  1560. {
  1561. this->clear();
  1562. this->insert(list.begin(), list.end());
  1563. return *this;
  1564. }
  1565. // size and capacity
  1566. template <class K, class T, class H, class P, class A>
  1567. std::size_t unordered_multimap<K, T, H, P, A>::max_size() const noexcept
  1568. {
  1569. using namespace std;
  1570. // size <= mlf_ * count
  1571. return boost::unordered::detail::double_to_size(
  1572. ceil(static_cast<double>(table_.mlf_) *
  1573. static_cast<double>(table_.max_bucket_count()))) -
  1574. 1;
  1575. }
  1576. // modifiers
  1577. template <class K, class T, class H, class P, class A>
  1578. template <class InputIt>
  1579. void unordered_multimap<K, T, H, P, A>::insert(InputIt first, InputIt last)
  1580. {
  1581. table_.insert_range_equiv(first, last);
  1582. }
  1583. template <class K, class T, class H, class P, class A>
  1584. void unordered_multimap<K, T, H, P, A>::insert(
  1585. std::initializer_list<value_type> list)
  1586. {
  1587. this->insert(list.begin(), list.end());
  1588. }
  1589. template <class K, class T, class H, class P, class A>
  1590. typename unordered_multimap<K, T, H, P, A>::iterator
  1591. unordered_multimap<K, T, H, P, A>::erase(iterator position)
  1592. {
  1593. BOOST_ASSERT(position != this->end());
  1594. return table_.erase_node(position);
  1595. }
  1596. template <class K, class T, class H, class P, class A>
  1597. typename unordered_multimap<K, T, H, P, A>::iterator
  1598. unordered_multimap<K, T, H, P, A>::erase(const_iterator position)
  1599. {
  1600. BOOST_ASSERT(position != this->end());
  1601. return table_.erase_node(position);
  1602. }
  1603. template <class K, class T, class H, class P, class A>
  1604. typename unordered_multimap<K, T, H, P, A>::size_type
  1605. unordered_multimap<K, T, H, P, A>::erase(const key_type& k)
  1606. {
  1607. return table_.erase_key_equiv(k);
  1608. }
  1609. template <class K, class T, class H, class P, class A>
  1610. typename unordered_multimap<K, T, H, P, A>::iterator
  1611. unordered_multimap<K, T, H, P, A>::erase(
  1612. const_iterator first, const_iterator last)
  1613. {
  1614. return table_.erase_nodes_range(first, last);
  1615. }
  1616. template <class K, class T, class H, class P, class A>
  1617. void unordered_multimap<K, T, H, P, A>::swap(unordered_multimap& other)
  1618. noexcept(value_allocator_traits::is_always_equal::value&&
  1619. boost::unordered::detail::is_nothrow_swappable<H>::value&&
  1620. boost::unordered::detail::is_nothrow_swappable<P>::value)
  1621. {
  1622. table_.swap(other.table_);
  1623. }
  1624. // observers
  1625. template <class K, class T, class H, class P, class A>
  1626. typename unordered_multimap<K, T, H, P, A>::hasher
  1627. unordered_multimap<K, T, H, P, A>::hash_function() const
  1628. {
  1629. return table_.hash_function();
  1630. }
  1631. template <class K, class T, class H, class P, class A>
  1632. typename unordered_multimap<K, T, H, P, A>::key_equal
  1633. unordered_multimap<K, T, H, P, A>::key_eq() const
  1634. {
  1635. return table_.key_eq();
  1636. }
  1637. template <class K, class T, class H, class P, class A>
  1638. template <typename H2, typename P2>
  1639. void unordered_multimap<K, T, H, P, A>::merge(
  1640. boost::unordered_multimap<K, T, H2, P2, A>& source)
  1641. {
  1642. while (!source.empty()) {
  1643. insert(source.extract(source.begin()));
  1644. }
  1645. }
  1646. template <class K, class T, class H, class P, class A>
  1647. template <typename H2, typename P2>
  1648. void unordered_multimap<K, T, H, P, A>::merge(
  1649. boost::unordered_multimap<K, T, H2, P2, A>&& source)
  1650. {
  1651. while (!source.empty()) {
  1652. insert(source.extract(source.begin()));
  1653. }
  1654. }
  1655. template <class K, class T, class H, class P, class A>
  1656. template <typename H2, typename P2>
  1657. void unordered_multimap<K, T, H, P, A>::merge(
  1658. boost::unordered_map<K, T, H2, P2, A>& source)
  1659. {
  1660. while (!source.empty()) {
  1661. insert(source.extract(source.begin()));
  1662. }
  1663. }
  1664. template <class K, class T, class H, class P, class A>
  1665. template <typename H2, typename P2>
  1666. void unordered_multimap<K, T, H, P, A>::merge(
  1667. boost::unordered_map<K, T, H2, P2, A>&& source)
  1668. {
  1669. while (!source.empty()) {
  1670. insert(source.extract(source.begin()));
  1671. }
  1672. }
  1673. // lookup
  1674. template <class K, class T, class H, class P, class A>
  1675. typename unordered_multimap<K, T, H, P, A>::iterator
  1676. unordered_multimap<K, T, H, P, A>::find(const key_type& k)
  1677. {
  1678. return iterator(table_.find(k));
  1679. }
  1680. template <class K, class T, class H, class P, class A>
  1681. typename unordered_multimap<K, T, H, P, A>::const_iterator
  1682. unordered_multimap<K, T, H, P, A>::find(const key_type& k) const
  1683. {
  1684. return const_iterator(table_.find(k));
  1685. }
  1686. template <class K, class T, class H, class P, class A>
  1687. template <class CompatibleKey, class CompatibleHash,
  1688. class CompatiblePredicate>
  1689. typename unordered_multimap<K, T, H, P, A>::iterator
  1690. unordered_multimap<K, T, H, P, A>::find(CompatibleKey const& k,
  1691. CompatibleHash const& hash, CompatiblePredicate const& eq)
  1692. {
  1693. return table_.transparent_find(k, hash, eq);
  1694. }
  1695. template <class K, class T, class H, class P, class A>
  1696. template <class CompatibleKey, class CompatibleHash,
  1697. class CompatiblePredicate>
  1698. typename unordered_multimap<K, T, H, P, A>::const_iterator
  1699. unordered_multimap<K, T, H, P, A>::find(CompatibleKey const& k,
  1700. CompatibleHash const& hash, CompatiblePredicate const& eq) const
  1701. {
  1702. return table_.transparent_find(k, hash, eq);
  1703. }
  1704. template <class K, class T, class H, class P, class A>
  1705. typename unordered_multimap<K, T, H, P, A>::size_type
  1706. unordered_multimap<K, T, H, P, A>::count(const key_type& k) const
  1707. {
  1708. return table_.group_count(k);
  1709. }
  1710. template <class K, class T, class H, class P, class A>
  1711. std::pair<typename unordered_multimap<K, T, H, P, A>::iterator,
  1712. typename unordered_multimap<K, T, H, P, A>::iterator>
  1713. unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k)
  1714. {
  1715. iterator n = table_.find(k);
  1716. return std::make_pair(n, (n == end() ? n : table_.next_group(k, n)));
  1717. }
  1718. template <class K, class T, class H, class P, class A>
  1719. std::pair<typename unordered_multimap<K, T, H, P, A>::const_iterator,
  1720. typename unordered_multimap<K, T, H, P, A>::const_iterator>
  1721. unordered_multimap<K, T, H, P, A>::equal_range(const key_type& k) const
  1722. {
  1723. iterator n = table_.find(k);
  1724. return std::make_pair(const_iterator(n),
  1725. const_iterator(n == end() ? n : table_.next_group(k, n)));
  1726. }
  1727. template <class K, class T, class H, class P, class A>
  1728. typename unordered_multimap<K, T, H, P, A>::size_type
  1729. unordered_multimap<K, T, H, P, A>::bucket_size(size_type n) const
  1730. {
  1731. return table_.bucket_size(n);
  1732. }
  1733. // hash policy
  1734. template <class K, class T, class H, class P, class A>
  1735. float unordered_multimap<K, T, H, P, A>::load_factor() const noexcept
  1736. {
  1737. if (table_.size_ == 0) {
  1738. return 0.0f;
  1739. }
  1740. BOOST_ASSERT(table_.bucket_count() != 0);
  1741. return static_cast<float>(table_.size_) /
  1742. static_cast<float>(table_.bucket_count());
  1743. }
  1744. template <class K, class T, class H, class P, class A>
  1745. void unordered_multimap<K, T, H, P, A>::max_load_factor(float m) noexcept
  1746. {
  1747. table_.max_load_factor(m);
  1748. }
  1749. template <class K, class T, class H, class P, class A>
  1750. void unordered_multimap<K, T, H, P, A>::rehash(size_type n)
  1751. {
  1752. table_.rehash(n);
  1753. }
  1754. template <class K, class T, class H, class P, class A>
  1755. void unordered_multimap<K, T, H, P, A>::reserve(size_type n)
  1756. {
  1757. table_.reserve(n);
  1758. }
  1759. template <class K, class T, class H, class P, class A>
  1760. inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1,
  1761. unordered_multimap<K, T, H, P, A> const& m2)
  1762. {
  1763. #if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
  1764. struct dummy
  1765. {
  1766. unordered_multimap<K, T, H, P, A> x;
  1767. };
  1768. #endif
  1769. return m1.table_.equals_equiv(m2.table_);
  1770. }
  1771. template <class K, class T, class H, class P, class A>
  1772. inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1,
  1773. unordered_multimap<K, T, H, P, A> const& m2)
  1774. {
  1775. #if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
  1776. struct dummy
  1777. {
  1778. unordered_multimap<K, T, H, P, A> x;
  1779. };
  1780. #endif
  1781. return !m1.table_.equals_equiv(m2.table_);
  1782. }
  1783. template <class K, class T, class H, class P, class A>
  1784. inline void swap(unordered_multimap<K, T, H, P, A>& m1,
  1785. unordered_multimap<K, T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)))
  1786. {
  1787. #if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
  1788. struct dummy
  1789. {
  1790. unordered_multimap<K, T, H, P, A> x;
  1791. };
  1792. #endif
  1793. m1.swap(m2);
  1794. }
  1795. template <class K, class T, class H, class P, class A, class Predicate>
  1796. typename unordered_multimap<K, T, H, P, A>::size_type erase_if(
  1797. unordered_multimap<K, T, H, P, A>& c, Predicate pred)
  1798. {
  1799. return detail::erase_if(c, pred);
  1800. }
  1801. template <typename N, class K, class T, class A> class node_handle_map
  1802. {
  1803. template <typename Types> friend struct ::boost::unordered::detail::table;
  1804. template <class K2, class T2, class H2, class P2, class A2>
  1805. friend class boost::unordered::unordered_map;
  1806. template <class K2, class T2, class H2, class P2, class A2>
  1807. friend class boost::unordered::unordered_multimap;
  1808. typedef typename boost::allocator_rebind<A, std::pair<K const, T> >::type
  1809. value_allocator;
  1810. typedef N node;
  1811. typedef typename boost::allocator_rebind<A, node>::type node_allocator;
  1812. typedef
  1813. typename boost::allocator_pointer<node_allocator>::type node_pointer;
  1814. public:
  1815. typedef K key_type;
  1816. typedef T mapped_type;
  1817. typedef A allocator_type;
  1818. private:
  1819. node_pointer ptr_;
  1820. boost::unordered::detail::optional<value_allocator> alloc_;
  1821. node_handle_map(node_pointer ptr, allocator_type const& a)
  1822. : ptr_(ptr), alloc_(a)
  1823. {
  1824. }
  1825. public:
  1826. constexpr node_handle_map() noexcept : ptr_(), alloc_() {}
  1827. node_handle_map(node_handle_map const&) = delete;
  1828. node_handle_map& operator=(node_handle_map const&) = delete;
  1829. ~node_handle_map()
  1830. {
  1831. if (ptr_) {
  1832. node_allocator node_alloc(*alloc_);
  1833. boost::unordered::detail::node_tmp<node_allocator> tmp(
  1834. ptr_, node_alloc);
  1835. }
  1836. }
  1837. node_handle_map(node_handle_map&& n) noexcept
  1838. : ptr_(n.ptr_),
  1839. alloc_(std::move(n.alloc_))
  1840. {
  1841. n.ptr_ = node_pointer();
  1842. }
  1843. node_handle_map& operator=(node_handle_map&& n)
  1844. {
  1845. BOOST_ASSERT(!alloc_.has_value() ||
  1846. boost::allocator_propagate_on_container_move_assignment<
  1847. value_allocator>::type::value ||
  1848. (n.alloc_.has_value() && alloc_ == n.alloc_));
  1849. if (ptr_) {
  1850. node_allocator node_alloc(*alloc_);
  1851. boost::unordered::detail::node_tmp<node_allocator> tmp(
  1852. ptr_, node_alloc);
  1853. ptr_ = node_pointer();
  1854. }
  1855. if (!alloc_.has_value() ||
  1856. boost::allocator_propagate_on_container_move_assignment<
  1857. value_allocator>::type::value) {
  1858. alloc_ = std::move(n.alloc_);
  1859. }
  1860. ptr_ = n.ptr_;
  1861. n.ptr_ = node_pointer();
  1862. return *this;
  1863. }
  1864. key_type& key() const
  1865. {
  1866. return const_cast<key_type&>(ptr_->value().first);
  1867. }
  1868. mapped_type& mapped() const { return ptr_->value().second; }
  1869. allocator_type get_allocator() const { return *alloc_; }
  1870. explicit operator bool() const noexcept
  1871. {
  1872. return !this->operator!();
  1873. }
  1874. bool operator!() const noexcept { return ptr_ ? 0 : 1; }
  1875. BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
  1876. {
  1877. return ptr_ ? 0 : 1;
  1878. }
  1879. void swap(node_handle_map& n)
  1880. noexcept(boost::allocator_propagate_on_container_swap<
  1881. value_allocator>::type::value ||
  1882. boost::allocator_is_always_equal<value_allocator>::type::value)
  1883. {
  1884. BOOST_ASSERT(!alloc_.has_value() || !n.alloc_.has_value() ||
  1885. boost::allocator_propagate_on_container_swap<
  1886. value_allocator>::type::value ||
  1887. alloc_ == n.alloc_);
  1888. if (boost::allocator_propagate_on_container_swap<
  1889. value_allocator>::type::value ||
  1890. !alloc_.has_value() || !n.alloc_.has_value()) {
  1891. boost::core::invoke_swap(alloc_, n.alloc_);
  1892. }
  1893. boost::core::invoke_swap(ptr_, n.ptr_);
  1894. }
  1895. };
  1896. template <class N, class K, class T, class A>
  1897. void swap(node_handle_map<N, K, T, A>& x, node_handle_map<N, K, T, A>& y)
  1898. noexcept(noexcept(x.swap(y)))
  1899. {
  1900. x.swap(y);
  1901. }
  1902. template <class Iter, class NodeType> struct insert_return_type_map
  1903. {
  1904. public:
  1905. Iter position;
  1906. bool inserted;
  1907. NodeType node;
  1908. insert_return_type_map() : position(), inserted(false), node() {}
  1909. insert_return_type_map(insert_return_type_map const&) = delete;
  1910. insert_return_type_map& operator=(insert_return_type_map const&) = delete;
  1911. insert_return_type_map(insert_return_type_map&& x) noexcept
  1912. : position(x.position),
  1913. inserted(x.inserted),
  1914. node(std::move(x.node))
  1915. {
  1916. }
  1917. insert_return_type_map& operator=(insert_return_type_map&& x)
  1918. {
  1919. inserted = x.inserted;
  1920. position = x.position;
  1921. node = std::move(x.node);
  1922. return *this;
  1923. }
  1924. };
  1925. template <class Iter, class NodeType>
  1926. void swap(insert_return_type_map<Iter, NodeType>& x,
  1927. insert_return_type_map<Iter, NodeType>& y)
  1928. {
  1929. boost::core::invoke_swap(x.node, y.node);
  1930. boost::core::invoke_swap(x.inserted, y.inserted);
  1931. boost::core::invoke_swap(x.position, y.position);
  1932. }
  1933. } // namespace unordered
  1934. namespace serialization {
  1935. template <class K, class T, class H, class P, class A>
  1936. struct version<boost::unordered_map<K, T, H, P, A> >
  1937. {
  1938. BOOST_STATIC_CONSTANT(int, value = 1);
  1939. };
  1940. template <class K, class T, class H, class P, class A>
  1941. struct version<boost::unordered_multimap<K, T, H, P, A> >
  1942. {
  1943. BOOST_STATIC_CONSTANT(int, value = 1);
  1944. };
  1945. } // namespace serialization
  1946. } // namespace boost
  1947. #if defined(BOOST_MSVC)
  1948. #pragma warning(pop)
  1949. #endif
  1950. #endif // BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED