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