1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga  2006-2014
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 //    (See accompanying file LICENSE_1_0.txt or copy at
8 //          http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // See http://www.boost.org/libs/intrusive for documentation.
11 //
12 /////////////////////////////////////////////////////////////////////////////
13 #ifndef BOOST_INTRUSIVE_SET_HPP
14 #define BOOST_INTRUSIVE_SET_HPP
15 
16 #include <boost/intrusive/detail/config_begin.hpp>
17 #include <boost/intrusive/intrusive_fwd.hpp>
18 
19 #include <boost/intrusive/detail/mpl.hpp>
20 #include <boost/intrusive/rbtree.hpp>
21 #include <boost/move/utility_core.hpp>
22 #include <boost/static_assert.hpp>
23 
24 #if defined(BOOST_HAS_PRAGMA_ONCE)
25 #  pragma once
26 #endif
27 
28 namespace boost {
29 namespace intrusive {
30 
31 //! The class template set is an intrusive container, that mimics most of
32 //! the interface of std::set as described in the C++ standard.
33 //!
34 //! The template parameter \c T is the type to be managed by the container.
35 //! The user can specify additional options and if no options are provided
36 //! default options are used.
37 //!
38 //! The container supports the following options:
39 //! \c base_hook<>/member_hook<>/value_traits<>,
40 //! \c constant_time_size<>, \c size_type<> and
41 //! \c compare<>.
42 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
43 template<class T, class ...Options>
44 #else
45 template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
46 #endif
47 class set_impl
48 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
49    : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
50 #endif
51 {
52    /// @cond
53    typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
54    BOOST_MOVABLE_BUT_NOT_COPYABLE(set_impl)
55 
56    typedef tree_type implementation_defined;
57    /// @endcond
58 
59    public:
60    typedef typename implementation_defined::value_type               value_type;
61    typedef typename implementation_defined::key_type                 key_type;
62    typedef typename implementation_defined::key_of_value             key_of_value;
63    typedef typename implementation_defined::value_traits             value_traits;
64    typedef typename implementation_defined::pointer                  pointer;
65    typedef typename implementation_defined::const_pointer            const_pointer;
66    typedef typename implementation_defined::reference                reference;
67    typedef typename implementation_defined::const_reference          const_reference;
68    typedef typename implementation_defined::difference_type          difference_type;
69    typedef typename implementation_defined::size_type                size_type;
70    typedef typename implementation_defined::value_compare            value_compare;
71    typedef typename implementation_defined::key_compare              key_compare;
72    typedef typename implementation_defined::iterator                 iterator;
73    typedef typename implementation_defined::const_iterator           const_iterator;
74    typedef typename implementation_defined::reverse_iterator         reverse_iterator;
75    typedef typename implementation_defined::const_reverse_iterator   const_reverse_iterator;
76    typedef typename implementation_defined::insert_commit_data       insert_commit_data;
77    typedef typename implementation_defined::node_traits              node_traits;
78    typedef typename implementation_defined::node                     node;
79    typedef typename implementation_defined::node_ptr                 node_ptr;
80    typedef typename implementation_defined::const_node_ptr           const_node_ptr;
81    typedef typename implementation_defined::node_algorithms          node_algorithms;
82 
83    static const bool constant_time_size = tree_type::constant_time_size;
84 
85    public:
86    //! @copydoc ::boost::intrusive::rbtree::rbtree(const key_compare &,const value_traits &)
set_impl(const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())87    explicit set_impl( const key_compare &cmp = key_compare()
88                     , const value_traits &v_traits = value_traits())
89       :  tree_type(cmp, v_traits)
90    {}
91 
92    //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
93    template<class Iterator>
set_impl(Iterator b,Iterator e,const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())94    set_impl( Iterator b, Iterator e
95            , const key_compare &cmp = key_compare()
96            , const value_traits &v_traits = value_traits())
97       : tree_type(true, b, e, cmp, v_traits)
98    {}
99 
100    //! @copydoc ::boost::intrusive::rbtree::rbtree(rbtree &&)
set_impl(BOOST_RV_REF (set_impl)x)101    set_impl(BOOST_RV_REF(set_impl) x)
102       :  tree_type(BOOST_MOVE_BASE(tree_type, x))
103    {}
104 
105    //! @copydoc ::boost::intrusive::rbtree::operator=(rbtree &&)
operator =(BOOST_RV_REF (set_impl)x)106    set_impl& operator=(BOOST_RV_REF(set_impl) x)
107    {  return static_cast<set_impl&>(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); }
108 
109    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
110    //! @copydoc ::boost::intrusive::rbtree::~rbtree()
111    ~set_impl();
112 
113    //! @copydoc ::boost::intrusive::rbtree::begin()
114    iterator begin();
115 
116    //! @copydoc ::boost::intrusive::rbtree::begin()const
117    const_iterator begin() const;
118 
119    //! @copydoc ::boost::intrusive::rbtree::cbegin()const
120    const_iterator cbegin() const;
121 
122    //! @copydoc ::boost::intrusive::rbtree::end()
123    iterator end();
124 
125    //! @copydoc ::boost::intrusive::rbtree::end()const
126    const_iterator end() const;
127 
128    //! @copydoc ::boost::intrusive::rbtree::cend()const
129    const_iterator cend() const;
130 
131    //! @copydoc ::boost::intrusive::rbtree::rbegin()
132    reverse_iterator rbegin();
133 
134    //! @copydoc ::boost::intrusive::rbtree::rbegin()const
135    const_reverse_iterator rbegin() const;
136 
137    //! @copydoc ::boost::intrusive::rbtree::crbegin()const
138    const_reverse_iterator crbegin() const;
139 
140    //! @copydoc ::boost::intrusive::rbtree::rend()
141    reverse_iterator rend();
142 
143    //! @copydoc ::boost::intrusive::rbtree::rend()const
144    const_reverse_iterator rend() const;
145 
146    //! @copydoc ::boost::intrusive::rbtree::crend()const
147    const_reverse_iterator crend() const;
148 
149    //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator)
150    static set_impl &container_from_end_iterator(iterator end_iterator);
151 
152    //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator)
153    static const set_impl &container_from_end_iterator(const_iterator end_iterator);
154 
155    //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator)
156    static set_impl &container_from_iterator(iterator it);
157 
158    //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator)
159    static const set_impl &container_from_iterator(const_iterator it);
160 
161    //! @copydoc ::boost::intrusive::rbtree::key_comp()const
162    key_compare key_comp() const;
163 
164    //! @copydoc ::boost::intrusive::rbtree::value_comp()const
165    value_compare value_comp() const;
166 
167    //! @copydoc ::boost::intrusive::rbtree::empty()const
168    bool empty() const;
169 
170    //! @copydoc ::boost::intrusive::rbtree::size()const
171    size_type size() const;
172 
173    //! @copydoc ::boost::intrusive::rbtree::swap
174    void swap(set_impl& other);
175 
176    //! @copydoc ::boost::intrusive::rbtree::clone_from(const rbtree&,Cloner,Disposer)
177    template <class Cloner, class Disposer>
178    void clone_from(const set_impl &src, Cloner cloner, Disposer disposer);
179 
180    #else
181 
182    using tree_type::clone_from;
183 
184    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
185 
186    //! @copydoc ::boost::intrusive::rbtree::clone_from(rbtree&&,Cloner,Disposer)
187    template <class Cloner, class Disposer>
clone_from(BOOST_RV_REF (set_impl)src,Cloner cloner,Disposer disposer)188    void clone_from(BOOST_RV_REF(set_impl) src, Cloner cloner, Disposer disposer)
189    {  tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);  }
190 
191    //! @copydoc ::boost::intrusive::rbtree::insert_unique(reference)
insert(reference value)192    std::pair<iterator, bool> insert(reference value)
193    {  return tree_type::insert_unique(value);  }
194 
195    //! @copydoc ::boost::intrusive::rbtree::insert_unique(const_iterator,reference)
insert(const_iterator hint,reference value)196    iterator insert(const_iterator hint, reference value)
197    {  return tree_type::insert_unique(hint, value);  }
198 
199    //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
200    template<class KeyType, class KeyTypeKeyCompare>
insert_check(const KeyType & key,KeyTypeKeyCompare comp,insert_commit_data & commit_data)201    std::pair<iterator, bool> insert_check
202       (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
203    {  return tree_type::insert_unique_check(key, comp, commit_data); }
204 
205    //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
206    template<class KeyType, class KeyTypeKeyCompare>
insert_check(const_iterator hint,const KeyType & key,KeyTypeKeyCompare comp,insert_commit_data & commit_data)207    std::pair<iterator, bool> insert_check
208       (const_iterator hint, const KeyType &key
209       ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
210    {  return tree_type::insert_unique_check(hint, key, comp, commit_data); }
211 
212    //! @copydoc ::boost::intrusive::rbtree::insert_unique(Iterator,Iterator)
213    template<class Iterator>
insert(Iterator b,Iterator e)214    void insert(Iterator b, Iterator e)
215    {  tree_type::insert_unique(b, e);  }
216 
217    //! @copydoc ::boost::intrusive::rbtree::insert_unique_commit
insert_commit(reference value,const insert_commit_data & commit_data)218    iterator insert_commit(reference value, const insert_commit_data &commit_data)
219    {  return tree_type::insert_unique_commit(value, commit_data);  }
220 
221    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
222    //! @copydoc ::boost::intrusive::rbtree::insert_before
223    iterator insert_before(const_iterator pos, reference value);
224 
225    //! @copydoc ::boost::intrusive::rbtree::push_back
226    void push_back(reference value);
227 
228    //! @copydoc ::boost::intrusive::rbtree::push_front
229    void push_front(reference value);
230 
231    //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator)
232    iterator erase(const_iterator i);
233 
234    //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator)
235    iterator erase(const_iterator b, const_iterator e);
236 
237    //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &)
238    size_type erase(const key_type &key);
239 
240    //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyTypeKeyCompare)
241    template<class KeyType, class KeyTypeKeyCompare>
242    size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
243 
244    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer)
245    template<class Disposer>
246    iterator erase_and_dispose(const_iterator i, Disposer disposer);
247 
248    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer)
249    template<class Disposer>
250    iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
251 
252    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer)
253    template<class Disposer>
254    size_type erase_and_dispose(const key_type &key, Disposer disposer);
255 
256    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
257    template<class KeyType, class KeyTypeKeyCompare, class Disposer>
258    size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
259 
260    //! @copydoc ::boost::intrusive::rbtree::clear
261    void clear();
262 
263    //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose
264    template<class Disposer>
265    void clear_and_dispose(Disposer disposer);
266 
267    #endif   //   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
268 
269    //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const
count(const key_type & key) const270    size_type count(const key_type &key) const
271    {  return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
272 
273    //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyTypeKeyCompare)const
274    template<class KeyType, class KeyTypeKeyCompare>
count(const KeyType & key,KeyTypeKeyCompare comp) const275    size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
276    {  return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
277 
278    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
279 
280    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)
281    iterator lower_bound(const key_type &key);
282 
283    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
284    template<class KeyType, class KeyTypeKeyCompare>
285    iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
286 
287    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)const
288    const_iterator lower_bound(const key_type &key) const;
289 
290    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
291    template<class KeyType, class KeyTypeKeyCompare>
292    const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
293 
294    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)
295    iterator upper_bound(const key_type &key);
296 
297    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
298    template<class KeyType, class KeyTypeKeyCompare>
299    iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
300 
301    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)const
302    const_iterator upper_bound(const key_type &key) const;
303 
304    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
305    template<class KeyType, class KeyTypeKeyCompare>
306    const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
307 
308    //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)
309    iterator find(const key_type &key);
310 
311    //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)
312    template<class KeyType, class KeyTypeKeyCompare>
313    iterator find(const KeyType& key, KeyTypeKeyCompare comp);
314 
315    //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)const
316    const_iterator find(const key_type &key) const;
317 
318    //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)const
319    template<class KeyType, class KeyTypeKeyCompare>
320    const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
321 
322    #endif   //   #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
323 
324    //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
equal_range(const key_type & key)325    std::pair<iterator,iterator> equal_range(const key_type &key)
326    {  return this->tree_type::lower_bound_range(key); }
327 
328    //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
329    template<class KeyType, class KeyTypeKeyCompare>
equal_range(const KeyType & key,KeyTypeKeyCompare comp)330    std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp)
331    {  return this->tree_type::lower_bound_range(key, comp); }
332 
333    //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
334    std::pair<const_iterator, const_iterator>
equal_range(const key_type & key) const335       equal_range(const key_type &key) const
336    {  return this->tree_type::lower_bound_range(key); }
337 
338    //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
339    template<class KeyType, class KeyTypeKeyCompare>
340    std::pair<const_iterator, const_iterator>
equal_range(const KeyType & key,KeyTypeKeyCompare comp) const341       equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
342    {  return this->tree_type::lower_bound_range(key, comp); }
343 
344    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
345 
346    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)
347    std::pair<iterator,iterator> bounded_range
348       (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
349 
350    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
351    template<class KeyType, class KeyTypeKeyCompare>
352    std::pair<iterator,iterator> bounded_range
353       (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
354 
355    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)const
356    std::pair<const_iterator, const_iterator>
357       bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
358 
359    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
360    template<class KeyType, class KeyTypeKeyCompare>
361    std::pair<const_iterator, const_iterator> bounded_range
362          (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
363 
364    //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference)
365    static iterator s_iterator_to(reference value);
366 
367    //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference)
368    static const_iterator s_iterator_to(const_reference value);
369 
370    //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference)
371    iterator iterator_to(reference value);
372 
373    //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const
374    const_iterator iterator_to(const_reference value) const;
375 
376    //! @copydoc ::boost::intrusive::rbtree::init_node(reference)
377    static void init_node(reference value);
378 
379    //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance
380    pointer unlink_leftmost_without_rebalance();
381 
382    //! @copydoc ::boost::intrusive::rbtree::replace_node
383    void replace_node(iterator replace_this, reference with_this);
384 
385    //! @copydoc ::boost::intrusive::rbtree::remove_node
386    void remove_node(reference value);
387    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
388 };
389 
390 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
391 
392 template<class T, class ...Options>
393 bool operator!= (const set_impl<T, Options...> &x, const set_impl<T, Options...> &y);
394 
395 template<class T, class ...Options>
396 bool operator>(const set_impl<T, Options...> &x, const set_impl<T, Options...> &y);
397 
398 template<class T, class ...Options>
399 bool operator<=(const set_impl<T, Options...> &x, const set_impl<T, Options...> &y);
400 
401 template<class T, class ...Options>
402 bool operator>=(const set_impl<T, Options...> &x, const set_impl<T, Options...> &y);
403 
404 template<class T, class ...Options>
405 void swap(set_impl<T, Options...> &x, set_impl<T, Options...> &y);
406 
407 #endif   //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
408 
409 //! Helper metafunction to define a \c set that yields to the same type when the
410 //! same options (either explicitly or implicitly) are used.
411 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
412 template<class T, class ...Options>
413 #else
414 template<class T, class O1 = void, class O2 = void
415                 , class O3 = void, class O4 = void
416                 , class O5 = void, class O6 = void>
417 #endif
418 struct make_set
419 {
420    /// @cond
421    typedef typename pack_options
422       < rbtree_defaults,
423       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
424       O1, O2, O3, O4, O5, O6
425       #else
426       Options...
427       #endif
428       >::type packed_options;
429 
430    typedef typename detail::get_value_traits
431       <T, typename packed_options::proto_value_traits>::type value_traits;
432 
433    typedef set_impl
434          < value_traits
435          , typename packed_options::key_of_value
436          , typename packed_options::compare
437          , typename packed_options::size_type
438          , packed_options::constant_time_size
439          , typename packed_options::header_holder_type
440          > implementation_defined;
441    /// @endcond
442    typedef implementation_defined type;
443 };
444 
445 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
446 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
447 template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
448 #else
449 template<class T, class ...Options>
450 #endif
451 class set
452    :  public make_set<T,
453    #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
454    O1, O2, O3, O4, O5, O6
455    #else
456    Options...
457    #endif
458    >::type
459 {
460    typedef typename make_set
461       <T,
462       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
463       O1, O2, O3, O4, O5, O6
464       #else
465       Options...
466       #endif
467       >::type   Base;
468 
469    BOOST_MOVABLE_BUT_NOT_COPYABLE(set)
470    public:
471    typedef typename Base::key_compare        key_compare;
472    typedef typename Base::value_traits       value_traits;
473    typedef typename Base::iterator           iterator;
474    typedef typename Base::const_iterator     const_iterator;
475 
476    //Assert if passed value traits are compatible with the type
477    BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
478 
set(const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())479    explicit set( const key_compare &cmp = key_compare()
480                , const value_traits &v_traits = value_traits())
481       :  Base(cmp, v_traits)
482    {}
483 
484    template<class Iterator>
set(Iterator b,Iterator e,const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())485    set( Iterator b, Iterator e
486       , const key_compare &cmp = key_compare()
487       , const value_traits &v_traits = value_traits())
488       :  Base(b, e, cmp, v_traits)
489    {}
490 
set(BOOST_RV_REF (set)x)491    set(BOOST_RV_REF(set) x)
492       :  Base(BOOST_MOVE_BASE(Base, x))
493    {}
494 
operator =(BOOST_RV_REF (set)x)495    set& operator=(BOOST_RV_REF(set) x)
496    {  return static_cast<set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
497 
498    template <class Cloner, class Disposer>
clone_from(const set & src,Cloner cloner,Disposer disposer)499    void clone_from(const set &src, Cloner cloner, Disposer disposer)
500    {  Base::clone_from(src, cloner, disposer);  }
501 
502    template <class Cloner, class Disposer>
clone_from(BOOST_RV_REF (set)src,Cloner cloner,Disposer disposer)503    void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer)
504    {  Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer);  }
505 
container_from_end_iterator(iterator end_iterator)506    static set &container_from_end_iterator(iterator end_iterator)
507    {  return static_cast<set &>(Base::container_from_end_iterator(end_iterator));   }
508 
container_from_end_iterator(const_iterator end_iterator)509    static const set &container_from_end_iterator(const_iterator end_iterator)
510    {  return static_cast<const set &>(Base::container_from_end_iterator(end_iterator));   }
511 
container_from_iterator(iterator it)512    static set &container_from_iterator(iterator it)
513    {  return static_cast<set &>(Base::container_from_iterator(it));   }
514 
container_from_iterator(const_iterator it)515    static const set &container_from_iterator(const_iterator it)
516    {  return static_cast<const set &>(Base::container_from_iterator(it));   }
517 };
518 
519 #endif
520 
521 //! The class template multiset is an intrusive container, that mimics most of
522 //! the interface of std::multiset as described in the C++ standard.
523 //!
524 //! The template parameter \c T is the type to be managed by the container.
525 //! The user can specify additional options and if no options are provided
526 //! default options are used.
527 //!
528 //! The container supports the following options:
529 //! \c base_hook<>/member_hook<>/value_traits<>,
530 //! \c constant_time_size<>, \c size_type<> and
531 //! \c compare<>.
532 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
533 template<class T, class ...Options>
534 #else
535 template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
536 #endif
537 class multiset_impl
538 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
539    : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
540 #endif
541 {
542    /// @cond
543    typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
544 
545    BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset_impl)
546    typedef tree_type implementation_defined;
547    /// @endcond
548 
549    public:
550    typedef typename implementation_defined::value_type               value_type;
551    typedef typename implementation_defined::key_type                 key_type;
552    typedef typename implementation_defined::key_of_value             key_of_value;
553    typedef typename implementation_defined::value_traits             value_traits;
554    typedef typename implementation_defined::pointer                  pointer;
555    typedef typename implementation_defined::const_pointer            const_pointer;
556    typedef typename implementation_defined::reference                reference;
557    typedef typename implementation_defined::const_reference          const_reference;
558    typedef typename implementation_defined::difference_type          difference_type;
559    typedef typename implementation_defined::size_type                size_type;
560    typedef typename implementation_defined::value_compare            value_compare;
561    typedef typename implementation_defined::key_compare              key_compare;
562    typedef typename implementation_defined::iterator                 iterator;
563    typedef typename implementation_defined::const_iterator           const_iterator;
564    typedef typename implementation_defined::reverse_iterator         reverse_iterator;
565    typedef typename implementation_defined::const_reverse_iterator   const_reverse_iterator;
566    typedef typename implementation_defined::insert_commit_data       insert_commit_data;
567    typedef typename implementation_defined::node_traits              node_traits;
568    typedef typename implementation_defined::node                     node;
569    typedef typename implementation_defined::node_ptr                 node_ptr;
570    typedef typename implementation_defined::const_node_ptr           const_node_ptr;
571    typedef typename implementation_defined::node_algorithms          node_algorithms;
572 
573    static const bool constant_time_size = tree_type::constant_time_size;
574 
575    public:
576    //! @copydoc ::boost::intrusive::rbtree::rbtree(const key_compare &,const value_traits &)
multiset_impl(const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())577    explicit multiset_impl( const key_compare &cmp = key_compare()
578                          , const value_traits &v_traits = value_traits())
579       :  tree_type(cmp, v_traits)
580    {}
581 
582    //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
583    template<class Iterator>
multiset_impl(Iterator b,Iterator e,const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())584    multiset_impl( Iterator b, Iterator e
585                 , const key_compare &cmp = key_compare()
586                 , const value_traits &v_traits = value_traits())
587       : tree_type(false, b, e, cmp, v_traits)
588    {}
589 
590    //! @copydoc ::boost::intrusive::rbtree::rbtree(rbtree &&)
multiset_impl(BOOST_RV_REF (multiset_impl)x)591    multiset_impl(BOOST_RV_REF(multiset_impl) x)
592       :  tree_type(BOOST_MOVE_BASE(tree_type, x))
593    {}
594 
595    //! @copydoc ::boost::intrusive::rbtree::operator=(rbtree &&)
operator =(BOOST_RV_REF (multiset_impl)x)596    multiset_impl& operator=(BOOST_RV_REF(multiset_impl) x)
597    {  return static_cast<multiset_impl&>(tree_type::operator=(BOOST_MOVE_BASE(tree_type, x))); }
598 
599    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
600    //! @copydoc ::boost::intrusive::rbtree::~rbtree()
601    ~multiset_impl();
602 
603    //! @copydoc ::boost::intrusive::rbtree::begin()
604    iterator begin();
605 
606    //! @copydoc ::boost::intrusive::rbtree::begin()const
607    const_iterator begin() const;
608 
609    //! @copydoc ::boost::intrusive::rbtree::cbegin()const
610    const_iterator cbegin() const;
611 
612    //! @copydoc ::boost::intrusive::rbtree::end()
613    iterator end();
614 
615    //! @copydoc ::boost::intrusive::rbtree::end()const
616    const_iterator end() const;
617 
618    //! @copydoc ::boost::intrusive::rbtree::cend()const
619    const_iterator cend() const;
620 
621    //! @copydoc ::boost::intrusive::rbtree::rbegin()
622    reverse_iterator rbegin();
623 
624    //! @copydoc ::boost::intrusive::rbtree::rbegin()const
625    const_reverse_iterator rbegin() const;
626 
627    //! @copydoc ::boost::intrusive::rbtree::crbegin()const
628    const_reverse_iterator crbegin() const;
629 
630    //! @copydoc ::boost::intrusive::rbtree::rend()
631    reverse_iterator rend();
632 
633    //! @copydoc ::boost::intrusive::rbtree::rend()const
634    const_reverse_iterator rend() const;
635 
636    //! @copydoc ::boost::intrusive::rbtree::crend()const
637    const_reverse_iterator crend() const;
638 
639    //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(iterator)
640    static multiset_impl &container_from_end_iterator(iterator end_iterator);
641 
642    //! @copydoc ::boost::intrusive::rbtree::container_from_end_iterator(const_iterator)
643    static const multiset_impl &container_from_end_iterator(const_iterator end_iterator);
644 
645    //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(iterator)
646    static multiset_impl &container_from_iterator(iterator it);
647 
648    //! @copydoc ::boost::intrusive::rbtree::container_from_iterator(const_iterator)
649    static const multiset_impl &container_from_iterator(const_iterator it);
650 
651    //! @copydoc ::boost::intrusive::rbtree::key_comp()const
652    key_compare key_comp() const;
653 
654    //! @copydoc ::boost::intrusive::rbtree::value_comp()const
655    value_compare value_comp() const;
656 
657    //! @copydoc ::boost::intrusive::rbtree::empty()const
658    bool empty() const;
659 
660    //! @copydoc ::boost::intrusive::rbtree::size()const
661    size_type size() const;
662 
663    //! @copydoc ::boost::intrusive::rbtree::swap
664    void swap(multiset_impl& other);
665 
666    //! @copydoc ::boost::intrusive::rbtree::clone_from(const rbtree&,Cloner,Disposer)
667    template <class Cloner, class Disposer>
668    void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer);
669 
670    #else
671 
672    using tree_type::clone_from;
673 
674    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
675 
676    //! @copydoc ::boost::intrusive::rbtree::clone_from(rbtree&&,Cloner,Disposer)
677    template <class Cloner, class Disposer>
clone_from(BOOST_RV_REF (multiset_impl)src,Cloner cloner,Disposer disposer)678    void clone_from(BOOST_RV_REF(multiset_impl) src, Cloner cloner, Disposer disposer)
679    {  tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);  }
680 
681    //! @copydoc ::boost::intrusive::rbtree::insert_equal(reference)
insert(reference value)682    iterator insert(reference value)
683    {  return tree_type::insert_equal(value);  }
684 
685    //! @copydoc ::boost::intrusive::rbtree::insert_equal(const_iterator,reference)
insert(const_iterator hint,reference value)686    iterator insert(const_iterator hint, reference value)
687    {  return tree_type::insert_equal(hint, value);  }
688 
689    //! @copydoc ::boost::intrusive::rbtree::insert_equal(Iterator,Iterator)
690    template<class Iterator>
insert(Iterator b,Iterator e)691    void insert(Iterator b, Iterator e)
692    {  tree_type::insert_equal(b, e);  }
693 
694    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
695    //! @copydoc ::boost::intrusive::rbtree::insert_before
696    iterator insert_before(const_iterator pos, reference value);
697 
698    //! @copydoc ::boost::intrusive::rbtree::push_back
699    void push_back(reference value);
700 
701    //! @copydoc ::boost::intrusive::rbtree::push_front
702    void push_front(reference value);
703 
704    //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator)
705    iterator erase(const_iterator i);
706 
707    //! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator)
708    iterator erase(const_iterator b, const_iterator e);
709 
710    //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &)
711    size_type erase(const key_type &key);
712 
713    //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyTypeKeyCompare)
714    template<class KeyType, class KeyTypeKeyCompare>
715    size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
716 
717    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer)
718    template<class Disposer>
719    iterator erase_and_dispose(const_iterator i, Disposer disposer);
720 
721    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,const_iterator,Disposer)
722    template<class Disposer>
723    iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
724 
725    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer)
726    template<class Disposer>
727    size_type erase_and_dispose(const key_type &key, Disposer disposer);
728 
729    //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
730    template<class KeyType, class KeyTypeKeyCompare, class Disposer>
731    size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
732 
733    //! @copydoc ::boost::intrusive::rbtree::clear
734    void clear();
735 
736    //! @copydoc ::boost::intrusive::rbtree::clear_and_dispose
737    template<class Disposer>
738    void clear_and_dispose(Disposer disposer);
739 
740    //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const
741    size_type count(const key_type &key) const;
742 
743    //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyTypeKeyCompare)const
744    template<class KeyType, class KeyTypeKeyCompare>
745    size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
746 
747    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)
748    iterator lower_bound(const key_type &key);
749 
750    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
751    template<class KeyType, class KeyTypeKeyCompare>
752    iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
753 
754    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)const
755    const_iterator lower_bound(const key_type &key) const;
756 
757    //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
758    template<class KeyType, class KeyTypeKeyCompare>
759    const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
760 
761    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)
762    iterator upper_bound(const key_type &key);
763 
764    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
765    template<class KeyType, class KeyTypeKeyCompare>
766    iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
767 
768    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)const
769    const_iterator upper_bound(const key_type &key) const;
770 
771    //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
772    template<class KeyType, class KeyTypeKeyCompare>
773    const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
774 
775    //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)
776    iterator find(const key_type &key);
777 
778    //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)
779    template<class KeyType, class KeyTypeKeyCompare>
780    iterator find(const KeyType& key, KeyTypeKeyCompare comp);
781 
782    //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)const
783    const_iterator find(const key_type &key) const;
784 
785    //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)const
786    template<class KeyType, class KeyTypeKeyCompare>
787    const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
788 
789    //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
790    std::pair<iterator,iterator> equal_range(const key_type &key);
791 
792    //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
793    template<class KeyType, class KeyTypeKeyCompare>
794    std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
795 
796    //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
797    std::pair<const_iterator, const_iterator>
798       equal_range(const key_type &key) const;
799 
800    //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
801    template<class KeyType, class KeyTypeKeyCompare>
802    std::pair<const_iterator, const_iterator>
803       equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
804 
805    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)
806    std::pair<iterator,iterator> bounded_range
807       (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
808 
809    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
810    template<class KeyType, class KeyTypeKeyCompare>
811    std::pair<iterator,iterator> bounded_range
812       (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
813 
814    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)const
815    std::pair<const_iterator, const_iterator>
816       bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
817 
818    //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
819    template<class KeyType, class KeyTypeKeyCompare>
820    std::pair<const_iterator, const_iterator> bounded_range
821          (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
822 
823    //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference)
824    static iterator s_iterator_to(reference value);
825 
826    //! @copydoc ::boost::intrusive::rbtree::s_iterator_to(const_reference)
827    static const_iterator s_iterator_to(const_reference value);
828 
829    //! @copydoc ::boost::intrusive::rbtree::iterator_to(reference)
830    iterator iterator_to(reference value);
831 
832    //! @copydoc ::boost::intrusive::rbtree::iterator_to(const_reference)const
833    const_iterator iterator_to(const_reference value) const;
834 
835    //! @copydoc ::boost::intrusive::rbtree::init_node(reference)
836    static void init_node(reference value);
837 
838    //! @copydoc ::boost::intrusive::rbtree::unlink_leftmost_without_rebalance
839    pointer unlink_leftmost_without_rebalance();
840 
841    //! @copydoc ::boost::intrusive::rbtree::replace_node
842    void replace_node(iterator replace_this, reference with_this);
843 
844    //! @copydoc ::boost::intrusive::rbtree::remove_node
845    void remove_node(reference value);
846    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
847 };
848 
849 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
850 
851 template<class T, class ...Options>
852 bool operator!= (const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y);
853 
854 template<class T, class ...Options>
855 bool operator>(const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y);
856 
857 template<class T, class ...Options>
858 bool operator<=(const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y);
859 
860 template<class T, class ...Options>
861 bool operator>=(const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y);
862 
863 template<class T, class ...Options>
864 void swap(multiset_impl<T, Options...> &x, multiset_impl<T, Options...> &y);
865 
866 #endif   //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
867 
868 //! Helper metafunction to define a \c multiset that yields to the same type when the
869 //! same options (either explicitly or implicitly) are used.
870 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
871 template<class T, class ...Options>
872 #else
873 template<class T, class O1 = void, class O2 = void
874                 , class O3 = void, class O4 = void
875                 , class O5 = void, class O6 = void>
876 #endif
877 struct make_multiset
878 {
879    /// @cond
880    typedef typename pack_options
881       < rbtree_defaults,
882       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
883       O1, O2, O3, O4, O5, O6
884       #else
885       Options...
886       #endif
887       >::type packed_options;
888 
889    typedef typename detail::get_value_traits
890       <T, typename packed_options::proto_value_traits>::type value_traits;
891 
892    typedef multiset_impl
893          < value_traits
894          , typename packed_options::key_of_value
895          , typename packed_options::compare
896          , typename packed_options::size_type
897          , packed_options::constant_time_size
898          , typename packed_options::header_holder_type
899          > implementation_defined;
900    /// @endcond
901    typedef implementation_defined type;
902 };
903 
904 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
905 
906 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
907 template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
908 #else
909 template<class T, class ...Options>
910 #endif
911 class multiset
912    :  public make_multiset<T,
913       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
914       O1, O2, O3, O4, O5, O6
915       #else
916       Options...
917       #endif
918       >::type
919 {
920    typedef typename make_multiset<T,
921       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
922       O1, O2, O3, O4, O5, O6
923       #else
924       Options...
925       #endif
926       >::type   Base;
927 
928    BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset)
929 
930    public:
931    typedef typename Base::key_compare        key_compare;
932    typedef typename Base::value_traits       value_traits;
933    typedef typename Base::iterator           iterator;
934    typedef typename Base::const_iterator     const_iterator;
935 
936    //Assert if passed value traits are compatible with the type
937    BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
938 
multiset(const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())939    multiset( const key_compare &cmp = key_compare()
940            , const value_traits &v_traits = value_traits())
941       :  Base(cmp, v_traits)
942    {}
943 
944    template<class Iterator>
multiset(Iterator b,Iterator e,const key_compare & cmp=key_compare (),const value_traits & v_traits=value_traits ())945    multiset( Iterator b, Iterator e
946            , const key_compare &cmp = key_compare()
947            , const value_traits &v_traits = value_traits())
948       :  Base(b, e, cmp, v_traits)
949    {}
950 
multiset(BOOST_RV_REF (multiset)x)951    multiset(BOOST_RV_REF(multiset) x)
952       :  Base(BOOST_MOVE_BASE(Base, x))
953    {}
954 
operator =(BOOST_RV_REF (multiset)x)955    multiset& operator=(BOOST_RV_REF(multiset) x)
956    {  return static_cast<multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
957 
958    template <class Cloner, class Disposer>
clone_from(const multiset & src,Cloner cloner,Disposer disposer)959    void clone_from(const multiset &src, Cloner cloner, Disposer disposer)
960    {  Base::clone_from(src, cloner, disposer);  }
961 
962    template <class Cloner, class Disposer>
clone_from(BOOST_RV_REF (multiset)src,Cloner cloner,Disposer disposer)963    void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer)
964    {  Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer);  }
965 
container_from_end_iterator(iterator end_iterator)966    static multiset &container_from_end_iterator(iterator end_iterator)
967    {  return static_cast<multiset &>(Base::container_from_end_iterator(end_iterator));   }
968 
container_from_end_iterator(const_iterator end_iterator)969    static const multiset &container_from_end_iterator(const_iterator end_iterator)
970    {  return static_cast<const multiset &>(Base::container_from_end_iterator(end_iterator));   }
971 
container_from_iterator(iterator it)972    static multiset &container_from_iterator(iterator it)
973    {  return static_cast<multiset &>(Base::container_from_iterator(it));   }
974 
container_from_iterator(const_iterator it)975    static const multiset &container_from_iterator(const_iterator it)
976    {  return static_cast<const multiset &>(Base::container_from_iterator(it));   }
977 };
978 
979 #endif
980 
981 } //namespace intrusive
982 } //namespace boost
983 
984 #include <boost/intrusive/detail/config_end.hpp>
985 
986 #endif //BOOST_INTRUSIVE_SET_HPP
987