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