unordered_set.hpp 46 KB

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