Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:37:03

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2008-2013
0004 //
0005 // Distributed under the Boost Software License, Version 1.0.
0006 //    (See accompanying file LICENSE_1_0.txt or copy at
0007 //          http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // See http://www.boost.org/libs/intrusive for documentation.
0010 //
0011 /////////////////////////////////////////////////////////////////////////////
0012 #ifndef BOOST_INTRUSIVE_TREAP_HPP
0013 #define BOOST_INTRUSIVE_TREAP_HPP
0014 
0015 #include <boost/intrusive/detail/config_begin.hpp>
0016 #include <boost/intrusive/intrusive_fwd.hpp>
0017 
0018 #include <boost/intrusive/detail/assert.hpp>
0019 #include <boost/intrusive/bs_set_hook.hpp>
0020 #include <boost/intrusive/bstree.hpp>
0021 #include <boost/intrusive/detail/tree_node.hpp>
0022 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
0023 #include <boost/intrusive/pointer_traits.hpp>
0024 #include <boost/intrusive/detail/get_value_traits.hpp>
0025 #include <boost/intrusive/detail/mpl.hpp>
0026 #include <boost/intrusive/treap_algorithms.hpp>
0027 #include <boost/intrusive/link_mode.hpp>
0028 #include <boost/intrusive/priority_compare.hpp>
0029 #include <boost/intrusive/detail/node_cloner_disposer.hpp>
0030 #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
0031 
0032 #include <boost/move/utility_core.hpp>
0033 #include <boost/move/adl_move_swap.hpp>
0034 
0035 #include <cstddef>
0036 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>
0037 #include <boost/intrusive/detail/minimal_pair_header.hpp>   //std::pair
0038 
0039 #if defined(BOOST_HAS_PRAGMA_ONCE)
0040 #  pragma once
0041 #endif
0042 
0043 namespace boost {
0044 namespace intrusive {
0045 
0046 /// @cond
0047 
0048 struct treap_defaults
0049    : bstree_defaults
0050 {
0051    typedef void priority;
0052    typedef void priority_of_value;
0053 };
0054 
0055 template<class ValuePtr, class VoidOrPrioOfValue, class VoidOrPrioComp>
0056 struct treap_prio_types
0057 {
0058    typedef typename
0059       boost::movelib::pointer_element<ValuePtr>::type value_type;
0060    typedef typename get_key_of_value
0061       < VoidOrPrioOfValue, value_type>::type          priority_of_value;
0062    typedef typename priority_of_value::type           priority_type;
0063    typedef typename get_prio_comp< VoidOrPrioComp
0064                       , priority_type
0065                       >::type                         priority_compare;
0066 };
0067 
0068 struct treap_tag;
0069 
0070 /// @endcond
0071 
0072 //! The class template treap is an intrusive treap container that
0073 //! is used to construct intrusive set and multiset containers. The no-throw
0074 //! guarantee holds only, if the key_compare object and priority_compare object
0075 //! don't throw.
0076 //!
0077 //! The template parameter \c T is the type to be managed by the container.
0078 //! The user can specify additional options and if no options are provided
0079 //! default options are used.
0080 //!
0081 //! The container supports the following options:
0082 //! \c base_hook<>/member_hook<>/value_traits<>,
0083 //! \c constant_time_size<>, \c size_type<>,
0084 //! \c compare<>, \c priority<> and \c priority_of_value<>
0085 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0086 template<class T, class ...Options>
0087 #else
0088 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioOfValue, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
0089 #endif
0090 class treap_impl
0091    /// @cond
0092    : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
0093    //Use public inheritance to avoid MSVC bugs with closures
0094    , public detail::ebo_functor_holder
0095          < typename treap_prio_types<typename ValueTraits::pointer, VoidOrPrioOfValue, VoidOrPrioComp>::priority_compare
0096          , treap_tag>
0097    /// @endcond
0098 {
0099    public:
0100    typedef ValueTraits                                               value_traits;
0101    /// @cond
0102    typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
0103                       , ConstantTimeSize, BsTreeAlgorithms
0104                       , HeaderHolder>                                tree_type;
0105    typedef tree_type                                                 implementation_defined;
0106    typedef treap_prio_types
0107       < typename ValueTraits::pointer
0108       , VoidOrPrioOfValue, VoidOrPrioComp>                           treap_prio_types_t;
0109 
0110    typedef detail::ebo_functor_holder
0111       <typename treap_prio_types_t::priority_compare, treap_tag>     prio_base;
0112 
0113    /// @endcond
0114 
0115    typedef typename implementation_defined::pointer                  pointer;
0116    typedef typename implementation_defined::const_pointer            const_pointer;
0117    typedef typename implementation_defined::value_type               value_type;
0118    typedef typename implementation_defined::key_type                 key_type;
0119    typedef typename implementation_defined::key_of_value             key_of_value;
0120    typedef typename implementation_defined::reference                reference;
0121    typedef typename implementation_defined::const_reference          const_reference;
0122    typedef typename implementation_defined::difference_type          difference_type;
0123    typedef typename implementation_defined::size_type                size_type;
0124    typedef typename implementation_defined::value_compare            value_compare;
0125    typedef typename implementation_defined::key_compare              key_compare;
0126    typedef typename implementation_defined::iterator                 iterator;
0127    typedef typename implementation_defined::const_iterator           const_iterator;
0128    typedef typename implementation_defined::reverse_iterator         reverse_iterator;
0129    typedef typename implementation_defined::const_reverse_iterator   const_reverse_iterator;
0130    typedef typename implementation_defined::node_traits              node_traits;
0131    typedef typename implementation_defined::node                     node;
0132    typedef typename implementation_defined::node_ptr                 node_ptr;
0133    typedef typename implementation_defined::const_node_ptr           const_node_ptr;
0134    typedef BOOST_INTRUSIVE_IMPDEF(treap_algorithms<node_traits>)     node_algorithms;
0135    typedef BOOST_INTRUSIVE_IMPDEF
0136       (typename treap_prio_types_t::priority_type)                   priority_type;
0137    typedef BOOST_INTRUSIVE_IMPDEF
0138       (typename treap_prio_types_t::priority_of_value)               priority_of_value;
0139    typedef BOOST_INTRUSIVE_IMPDEF
0140       (typename treap_prio_types_t::priority_compare)                priority_compare;
0141 
0142    static const bool constant_time_size      = implementation_defined::constant_time_size;
0143    static const bool stateful_value_traits   = implementation_defined::stateful_value_traits;
0144    static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
0145 
0146    typedef detail::key_nodeptr_comp<priority_compare, value_traits, priority_of_value> prio_node_prio_comp_t;
0147 
0148    template<class PrioPrioComp>
0149    detail::key_nodeptr_comp<PrioPrioComp, value_traits, priority_of_value> prio_node_prio_comp(PrioPrioComp priopriocomp) const
0150    {  return detail::key_nodeptr_comp<PrioPrioComp, value_traits, priority_of_value>(priopriocomp, &this->get_value_traits());  }
0151 
0152    /// @cond
0153    private:
0154 
0155    //noncopyable
0156    BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_impl)
0157 
0158    const priority_compare &priv_pcomp() const
0159    {  return static_cast<const prio_base&>(*this).get();  }
0160 
0161    priority_compare &priv_pcomp()
0162    {  return static_cast<prio_base&>(*this).get();  }
0163 
0164    /// @endcond
0165 
0166    public:
0167    typedef typename node_algorithms::insert_commit_data insert_commit_data;
0168 
0169    //! <b>Effects</b>: Constructs an empty container.
0170    //!
0171    //! <b>Complexity</b>: Constant.
0172    //!
0173    //! <b>Throws</b>: If value_traits::node_traits::node
0174    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0175    //!   or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee.
0176    treap_impl()
0177       : tree_type(), prio_base()
0178    {}
0179 
0180    //! <b>Effects</b>: Constructs an empty container.
0181    //!
0182    //! <b>Complexity</b>: Constant.
0183    //!
0184    //! <b>Throws</b>: If value_traits::node_traits::node
0185    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0186    //!   or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee.
0187    explicit treap_impl( const key_compare &cmp
0188                       , const priority_compare &pcmp = priority_compare()
0189                       , const value_traits &v_traits = value_traits())
0190       : tree_type(cmp, v_traits), prio_base(pcmp)
0191    {}
0192 
0193    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
0194    //!   cmp must be a comparison function that induces a strict weak ordering.
0195    //!
0196    //! <b>Effects</b>: Constructs an empty container and inserts elements from
0197    //!   [b, e).
0198    //!
0199    //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
0200    //!   comp and otherwise N * log N, where N is the distance between first and last.
0201    //!
0202    //! <b>Throws</b>: If value_traits::node_traits::node
0203    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0204    //!   or the copy constructor/operator() of the key_compare/priority_compare objects
0205    //!   throw. Basic guarantee.
0206    template<class Iterator>
0207    treap_impl( bool unique, Iterator b, Iterator e
0208             , const key_compare &cmp     = key_compare()
0209             , const priority_compare &pcmp = priority_compare()
0210             , const value_traits &v_traits = value_traits())
0211       : tree_type(cmp, v_traits), prio_base(pcmp)
0212    {
0213       if(unique)
0214          this->insert_unique(b, e);
0215       else
0216          this->insert_equal(b, e);
0217    }
0218 
0219    //! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
0220    treap_impl(BOOST_RV_REF(treap_impl) x)
0221       : tree_type(BOOST_MOVE_BASE(tree_type, x))
0222       , prio_base(::boost::move(x.priv_pcomp()))
0223    {}
0224 
0225    //! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
0226    treap_impl& operator=(BOOST_RV_REF(treap_impl) x)
0227    {  this->swap(x); return *this;  }
0228 
0229    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0230    //! @copydoc ::boost::intrusive::bstree::~bstree()
0231    ~treap_impl();
0232 
0233    //! @copydoc ::boost::intrusive::bstree::begin()
0234    iterator begin() BOOST_NOEXCEPT;
0235 
0236    //! @copydoc ::boost::intrusive::bstree::begin()const
0237    const_iterator begin() const BOOST_NOEXCEPT;
0238 
0239    //! @copydoc ::boost::intrusive::bstree::cbegin()const
0240    const_iterator cbegin() const BOOST_NOEXCEPT;
0241 
0242    //! @copydoc ::boost::intrusive::bstree::end()
0243    iterator end() BOOST_NOEXCEPT;
0244 
0245    //! @copydoc ::boost::intrusive::bstree::end()const
0246    const_iterator end() const BOOST_NOEXCEPT;
0247 
0248    //! @copydoc ::boost::intrusive::bstree::cend()const
0249    const_iterator cend() const BOOST_NOEXCEPT;
0250    #endif
0251 
0252    //! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the treap.
0253    //!
0254    //! <b>Complexity</b>: Constant.
0255    //!
0256    //! <b>Throws</b>: Nothing.
0257    inline iterator top() BOOST_NOEXCEPT
0258    {  return this->tree_type::root();   }
0259 
0260    //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
0261    //!
0262    //! <b>Complexity</b>: Constant.
0263    //!
0264    //! <b>Throws</b>: Nothing.
0265    inline const_iterator top() const BOOST_NOEXCEPT
0266    {  return this->ctop();   }
0267 
0268    //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
0269    //!
0270    //! <b>Complexity</b>: Constant.
0271    //!
0272    //! <b>Throws</b>: Nothing.
0273    inline const_iterator ctop() const BOOST_NOEXCEPT
0274    {  return this->tree_type::root();   }
0275 
0276    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0277    //! @copydoc ::boost::intrusive::bstree::rbegin()
0278    reverse_iterator rbegin() BOOST_NOEXCEPT;
0279 
0280    //! @copydoc ::boost::intrusive::bstree::rbegin()const
0281    const_reverse_iterator rbegin() const BOOST_NOEXCEPT;
0282 
0283    //! @copydoc ::boost::intrusive::bstree::crbegin()const
0284    const_reverse_iterator crbegin() const BOOST_NOEXCEPT;
0285 
0286    //! @copydoc ::boost::intrusive::bstree::rend()
0287    reverse_iterator rend() BOOST_NOEXCEPT;
0288 
0289    //! @copydoc ::boost::intrusive::bstree::rend()const
0290    const_reverse_iterator rend() const BOOST_NOEXCEPT;
0291 
0292    //! @copydoc ::boost::intrusive::bstree::crend()const
0293    const_reverse_iterator crend() const BOOST_NOEXCEPT;
0294 
0295    //! @copydoc ::boost::intrusive::bstree::root()
0296    iterator root() BOOST_NOEXCEPT;
0297 
0298    //! @copydoc ::boost::intrusive::bstree::root()const
0299    const_iterator root() const BOOST_NOEXCEPT;
0300 
0301    //! @copydoc ::boost::intrusive::bstree::croot()const
0302    const_iterator croot() const BOOST_NOEXCEPT;
0303 
0304    #endif
0305 
0306    //! <b>Effects</b>: Returns a reverse_iterator pointing to the highest priority object of the
0307    //!    reversed treap.
0308    //!
0309    //! <b>Complexity</b>: Constant.
0310    //!
0311    //! <b>Throws</b>: Nothing.
0312    inline reverse_iterator rtop() BOOST_NOEXCEPT
0313    {  return reverse_iterator(this->top());  }
0314 
0315    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority objec
0316    //!    of the reversed treap.
0317    //!
0318    //! <b>Complexity</b>: Constant.
0319    //!
0320    //! <b>Throws</b>: Nothing.
0321    inline const_reverse_iterator rtop() const BOOST_NOEXCEPT
0322    {  return const_reverse_iterator(this->top());  }
0323 
0324    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority object
0325    //!    of the reversed treap.
0326    //!
0327    //! <b>Complexity</b>: Constant.
0328    //!
0329    //! <b>Throws</b>: Nothing.
0330    inline const_reverse_iterator crtop() const BOOST_NOEXCEPT
0331    {  return const_reverse_iterator(this->top());  }
0332 
0333    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0334    //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
0335    static treap_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT;
0336 
0337    //! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
0338    static const treap_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT;
0339 
0340    //! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
0341    static treap_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT;
0342 
0343    //! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
0344    static const treap_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT;
0345 
0346    //! @copydoc ::boost::intrusive::bstree::key_comp()const
0347    key_compare key_comp() const;
0348 
0349    //! @copydoc ::boost::intrusive::bstree::value_comp()const
0350    value_compare value_comp() const;
0351 
0352    //! @copydoc ::boost::intrusive::bstree::empty()const
0353    bool empty() const BOOST_NOEXCEPT;
0354 
0355    //! @copydoc ::boost::intrusive::bstree::size()const
0356    size_type size() const BOOST_NOEXCEPT;
0357    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0358 
0359    //! <b>Effects</b>: Returns the priority_compare object used by the container.
0360    //!
0361    //! <b>Complexity</b>: Constant.
0362    //!
0363    //! <b>Throws</b>: If priority_compare copy-constructor throws.
0364    priority_compare priority_comp() const
0365    {  return this->priv_pcomp();   }
0366 
0367    //! <b>Effects</b>: Swaps the contents of two treaps.
0368    //!
0369    //! <b>Complexity</b>: Constant.
0370    //!
0371    //! <b>Throws</b>: If the comparison functor's swap call throws.
0372    void swap(treap_impl& other)
0373    {
0374       //This can throw
0375       ::boost::adl_move_swap(this->priv_pcomp(), other.priv_pcomp());
0376       tree_type::swap(other);
0377    }
0378 
0379    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0380    //!   Cloner should yield to nodes equivalent to the original nodes.
0381    //!
0382    //! <b>Effects</b>: Erases all the elements from *this
0383    //!   calling Disposer::operator()(pointer), clones all the
0384    //!   elements from src calling Cloner::operator()(const_reference )
0385    //!   and inserts them on *this. Copies the predicate from the source container.
0386    //!
0387    //!   If cloner throws, all cloned elements are unlinked and disposed
0388    //!   calling Disposer::operator()(pointer).
0389    //!
0390    //! <b>Complexity</b>: Linear to erased plus inserted elements.
0391    //!
0392    //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
0393    template <class Cloner, class Disposer>
0394    void clone_from(const treap_impl &src, Cloner cloner, Disposer disposer)
0395    {
0396       tree_type::clone_from(src, cloner, disposer);
0397       this->priv_pcomp() = src.priv_pcomp();
0398    }
0399 
0400    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0401    //!   Cloner should yield to nodes equivalent to the original nodes.
0402    //!
0403    //! <b>Effects</b>: Erases all the elements from *this
0404    //!   calling Disposer::operator()(pointer), clones all the
0405    //!   elements from src calling Cloner::operator()(reference)
0406    //!   and inserts them on *this. Copies the predicate from the source container.
0407    //!
0408    //!   If cloner throws, all cloned elements are unlinked and disposed
0409    //!   calling Disposer::operator()(pointer).
0410    //!
0411    //! <b>Complexity</b>: Linear to erased plus inserted elements.
0412    //!
0413    //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
0414    template <class Cloner, class Disposer>
0415    void clone_from(BOOST_RV_REF(treap_impl) src, Cloner cloner, Disposer disposer)
0416    {
0417       tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
0418       this->priv_pcomp() = ::boost::move(src.priv_pcomp());
0419    }
0420 
0421    //! <b>Requires</b>: value must be an lvalue
0422    //!
0423    //! <b>Effects</b>: Inserts value into the container before the upper bound.
0424    //!
0425    //! <b>Complexity</b>: Average complexity for insert element is at
0426    //!   most logarithmic.
0427    //!
0428    //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
0429    //!
0430    //! <b>Note</b>: Does not affect the validity of iterators and references.
0431    //!   No copy-constructors are called.
0432    iterator insert_equal(reference value)
0433    {
0434       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0435       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0436       iterator ret
0437          ( node_algorithms::insert_equal_upper_bound
0438             ( this->tree_type::header_ptr()
0439             , to_insert
0440             , this->key_node_comp(this->key_comp())
0441             , this->prio_node_prio_comp(this->priv_pcomp()))
0442          , this->priv_value_traits_ptr());
0443       this->tree_type::sz_traits().increment();
0444       return ret;
0445    }
0446 
0447    //! <b>Requires</b>: value must be an lvalue, and "hint" must be
0448    //!   a valid iterator.
0449    //!
0450    //! <b>Effects</b>: Inserts x into the container, using "hint" as a hint to
0451    //!   where it will be inserted. If "hint" is the upper_bound
0452    //!   the insertion takes constant time (two comparisons in the worst case)
0453    //!
0454    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
0455    //!   constant time if t is inserted immediately before hint.
0456    //!
0457    //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
0458    //!
0459    //! <b>Note</b>: Does not affect the validity of iterators and references.
0460    //!   No copy-constructors are called.
0461    iterator insert_equal(const_iterator hint, reference value)
0462    {
0463       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0464       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0465       iterator ret
0466          (node_algorithms::insert_equal
0467             ( this->tree_type::header_ptr()
0468             , hint.pointed_node()
0469             , to_insert
0470             , this->key_node_comp(this->key_comp())
0471             , this->prio_node_prio_comp(this->priv_pcomp()))
0472          , this->priv_value_traits_ptr());
0473       this->tree_type::sz_traits().increment();
0474       return ret;
0475    }
0476 
0477    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
0478    //!   of type value_type.
0479    //!
0480    //! <b>Effects</b>: Inserts a each element of a range into the container
0481    //!   before the upper bound of the key of each element.
0482    //!
0483    //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
0484    //!   size of the range. However, it is linear in N if the range is already sorted
0485    //!   by key_comp().
0486    //!
0487    //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
0488    //!   Strong guarantee.
0489    //!
0490    //! <b>Note</b>: Does not affect the validity of iterators and references.
0491    //!   No copy-constructors are called.
0492    template<class Iterator>
0493    void insert_equal(Iterator b, Iterator e)
0494    {
0495       iterator iend(this->end());
0496       for (; b != e; ++b)
0497          this->insert_equal(iend, *b);
0498    }
0499 
0500    //! <b>Requires</b>: value must be an lvalue
0501    //!
0502    //! <b>Effects</b>: Inserts value into the container if the value
0503    //!   is not already present.
0504    //!
0505    //! <b>Complexity</b>: Average complexity for insert element is at
0506    //!   most logarithmic.
0507    //!
0508    //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
0509    //!   Strong guarantee.
0510    //!
0511    //! <b>Note</b>: Does not affect the validity of iterators and references.
0512    //!   No copy-constructors are called.
0513    std::pair<iterator, bool> insert_unique(reference value)
0514    {
0515       insert_commit_data commit_data;
0516       std::pair<iterator, bool> ret = this->insert_unique_check(key_of_value()(value), priority_of_value()(value), commit_data);
0517       if(!ret.second)
0518          return ret;
0519       return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
0520    }
0521 
0522    //! <b>Requires</b>: value must be an lvalue, and "hint" must be
0523    //!   a valid iterator
0524    //!
0525    //! <b>Effects</b>: Tries to insert x into the container, using "hint" as a hint
0526    //!   to where it will be inserted.
0527    //!
0528    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
0529    //!   constant time (two comparisons in the worst case)
0530    //!   if t is inserted immediately before hint.
0531    //!
0532    //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
0533    //!   Strong guarantee.
0534    //!
0535    //! <b>Note</b>: Does not affect the validity of iterators and references.
0536    //!   No copy-constructors are called.
0537    iterator insert_unique(const_iterator hint, reference value)
0538    {
0539       insert_commit_data commit_data;
0540       std::pair<iterator, bool> ret = this->insert_unique_check(hint, key_of_value()(value), priority_of_value()(value), commit_data);
0541       if(!ret.second)
0542          return ret.first;
0543       return this->insert_unique_commit(value, commit_data);
0544    }
0545 
0546    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
0547    //!   of type value_type.
0548    //!
0549    //! <b>Effects</b>: Tries to insert each element of a range into the container.
0550    //!
0551    //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
0552    //!   size of the range. However, it is linear in N if the range is already sorted
0553    //!   by key_comp().
0554    //!
0555    //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
0556    //!   Strong guarantee.
0557    //!
0558    //! <b>Note</b>: Does not affect the validity of iterators and references.
0559    //!   No copy-constructors are called.
0560    template<class Iterator>
0561    void insert_unique(Iterator b, Iterator e)
0562    {
0563       if(this->empty()){
0564          iterator iend(this->end());
0565          for (; b != e; ++b)
0566             this->insert_unique(iend, *b);
0567       }
0568       else{
0569          for (; b != e; ++b)
0570             this->insert_unique(*b);
0571       }
0572    }
0573 
0574    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
0575    //!   a user provided key instead of the value itself.
0576    //!
0577    //! <b>Returns</b>: If there is an equivalent value
0578    //!   returns a pair containing an iterator to the already present value
0579    //!   and false. If the value can be inserted returns true in the returned
0580    //!   pair boolean and fills "commit_data" that is meant to be used with
0581    //!   the "insert_commit" function.
0582    //!
0583    //! <b>Complexity</b>: Average complexity is at most logarithmic.
0584    //!
0585    //! <b>Throws</b>: If the comparison or predicate functions throw. Strong guarantee.
0586    //!
0587    //! <b>Notes</b>: This function is used to improve performance when constructing
0588    //!   a value_type is expensive: if there is an equivalent value
0589    //!   the constructed object must be discarded. Many times, the part of the
0590    //!   node that is used to impose the order is much cheaper to construct
0591    //!   than the value_type and this function offers the possibility to use that
0592    //!   part to check if the insertion will be successful.
0593    //!
0594    //!   If the check is successful, the user can construct the value_type and use
0595    //!   "insert_commit" to insert the object in constant-time. This gives a total
0596    //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
0597    //!
0598    //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
0599    //!   objects are inserted or erased from the container.
0600    std::pair<iterator, bool> insert_unique_check
0601       ( const key_type &key, const priority_type &prio, insert_commit_data &commit_data)
0602    {  return this->insert_unique_check(key, this->key_comp(), prio, this->priv_pcomp(), commit_data); }
0603 
0604    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
0605    //!   a user provided key instead of the value itself, using "hint"
0606    //!   as a hint to where it will be inserted.
0607    //!
0608    //! <b>Returns</b>: If there is an equivalent value
0609    //!   returns a pair containing an iterator to the already present value
0610    //!   and false. If the value can be inserted returns true in the returned
0611    //!   pair boolean and fills "commit_data" that is meant to be used with
0612    //!   the "insert_commit" function.
0613    //!
0614    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
0615    //!   constant time if t is inserted immediately before hint.
0616    //!
0617    //! <b>Throws</b>: If the comparison or predicate functions throw. Strong guarantee.
0618    //!
0619    //! <b>Notes</b>: This function is used to improve performance when constructing
0620    //!   a value_type is expensive: if there is an equivalent value
0621    //!   the constructed object must be discarded. Many times, the part of the
0622    //!   constructing that is used to impose the order is much cheaper to construct
0623    //!   than the value_type and this function offers the possibility to use that key
0624    //!   to check if the insertion will be successful.
0625    //!
0626    //!   If the check is successful, the user can construct the value_type and use
0627    //!   "insert_commit" to insert the object in constant-time. This can give a total
0628    //!   constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
0629    //!
0630    //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
0631    //!   objects are inserted or erased from the container.
0632    std::pair<iterator, bool> insert_unique_check
0633       ( const_iterator hint, const key_type &key, const priority_type &prio, insert_commit_data &commit_data)
0634    {  return this->insert_unique_check(hint, key, this->key_comp(), prio, this->priv_pcomp(), commit_data); }
0635 
0636    //! <b>Requires</b>: comp must be a comparison function that induces
0637    //!   the same strict weak ordering as key_compare.
0638    //!   prio_value_pcomp must be a comparison function that induces
0639    //!   the same strict weak ordering as priority_compare. The difference is that
0640    //!   prio_value_pcomp and comp compare an arbitrary key/priority with the contained values.
0641    //!
0642    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
0643    //!   a user provided key instead of the value itself.
0644    //!
0645    //! <b>Returns</b>: If there is an equivalent value
0646    //!   returns a pair containing an iterator to the already present value
0647    //!   and false. If the value can be inserted returns true in the returned
0648    //!   pair boolean and fills "commit_data" that is meant to be used with
0649    //!   the "insert_commit" function.
0650    //!
0651    //! <b>Complexity</b>: Average complexity is at most logarithmic.
0652    //!
0653    //! <b>Throws</b>: If the comp or prio_value_pcomp
0654    //!   ordering functions throw. Strong guarantee.
0655    //!
0656    //! <b>Notes</b>: This function is used to improve performance when constructing
0657    //!   a value_type is expensive: if there is an equivalent value
0658    //!   the constructed object must be discarded. Many times, the part of the
0659    //!   node that is used to impose the order is much cheaper to construct
0660    //!   than the value_type and this function offers the possibility to use that
0661    //!   part to check if the insertion will be successful.
0662    //!
0663    //!   If the check is successful, the user can construct the value_type and use
0664    //!   "insert_commit" to insert the object in constant-time. This gives a total
0665    //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
0666    //!
0667    //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
0668    //!   objects are inserted or erased from the container.
0669    template<class KeyType, class KeyTypeKeyCompare, class PrioType, class PrioValuePrioCompare>
0670    BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
0671       , typename detail::disable_if_convertible
0672          <KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I 
0673          std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
0674       insert_unique_check
0675       ( const KeyType &key, KeyTypeKeyCompare comp
0676       , const PrioType &prio, PrioValuePrioCompare prio_value_pcomp, insert_commit_data &commit_data)
0677    {
0678       std::pair<node_ptr, bool> const ret =
0679          (node_algorithms::insert_unique_check
0680             ( this->tree_type::header_ptr()
0681             , key, this->key_node_comp(comp)
0682             , prio, this->prio_node_prio_comp(prio_value_pcomp)
0683             , commit_data));
0684       return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0685    }
0686 
0687    //! <b>Requires</b>: comp must be a comparison function that induces
0688    //!   the same strict weak ordering as key_compare.
0689    //!   prio_value_pcomp must be a comparison function that induces
0690    //!   the same strict weak ordering as priority_compare. The difference is that
0691    //!   prio_value_pcomp and comp compare an arbitrary key/priority with the contained values.
0692    //!
0693    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
0694    //!   a user provided key instead of the value itself, using "hint"
0695    //!   as a hint to where it will be inserted.
0696    //!
0697    //! <b>Returns</b>: If there is an equivalent value
0698    //!   returns a pair containing an iterator to the already present value
0699    //!   and false. If the value can be inserted returns true in the returned
0700    //!   pair boolean and fills "commit_data" that is meant to be used with
0701    //!   the "insert_commit" function.
0702    //!
0703    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
0704    //!   constant time if t is inserted immediately before hint.
0705    //!
0706    //! <b>Throws</b>: If the comp or prio_value_pcomp
0707    //!   ordering functions throw. Strong guarantee.
0708    //!
0709    //! <b>Notes</b>: This function is used to improve performance when constructing
0710    //!   a value_type is expensive: if there is an equivalent value
0711    //!   the constructed object must be discarded. Many times, the part of the
0712    //!   constructing that is used to impose the order is much cheaper to construct
0713    //!   than the value_type and this function offers the possibility to use that key
0714    //!   to check if the insertion will be successful.
0715    //!
0716    //!   If the check is successful, the user can construct the value_type and use
0717    //!   "insert_commit" to insert the object in constant-time. This can give a total
0718    //!   constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
0719    //!
0720    //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
0721    //!   objects are inserted or erased from the container.
0722    template<class KeyType, class KeyTypeKeyCompare, class PrioType, class PrioValuePrioCompare>
0723    std::pair<iterator, bool> insert_unique_check
0724       ( const_iterator hint
0725       , const KeyType &key
0726       , KeyTypeKeyCompare comp
0727       , const PrioType &prio
0728       , PrioValuePrioCompare prio_value_pcomp
0729       , insert_commit_data &commit_data)
0730    {
0731       std::pair<node_ptr, bool> const ret =
0732          (node_algorithms::insert_unique_check
0733             ( this->tree_type::header_ptr(), hint.pointed_node()
0734             , key, this->key_node_comp(comp)
0735             , prio, this->prio_node_prio_comp(prio_value_pcomp)
0736             , commit_data));
0737       return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0738    }
0739 
0740    //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
0741    //!   must have been obtained from a previous call to "insert_check".
0742    //!   No objects should have been inserted or erased from the container between
0743    //!   the "insert_check" that filled "commit_data" and the call to "insert_commit".
0744    //!
0745    //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
0746    //!   from the "commit_data" that a previous "insert_check" filled.
0747    //!
0748    //! <b>Returns</b>: An iterator to the newly inserted object.
0749    //!
0750    //! <b>Complexity</b>: Constant time.
0751    //!
0752    //! <b>Throws</b>: Nothing
0753    //!
0754    //! <b>Notes</b>: This function has only sense if a "insert_check" has been
0755    //!   previously executed to fill "commit_data". No value should be inserted or
0756    //!   erased between the "insert_check" and "insert_commit" calls.
0757    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
0758    {
0759       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0760       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0761       node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
0762       this->tree_type::sz_traits().increment();
0763       return iterator(to_insert, this->priv_value_traits_ptr());
0764    }
0765 
0766    //! <b>Requires</b>: value must be an lvalue, "pos" must be
0767    //!   a valid iterator (or end) and must be the succesor of value
0768    //!   once inserted according to the predicate
0769    //!
0770    //! <b>Effects</b>: Inserts x into the container before "pos".
0771    //!
0772    //! <b>Complexity</b>: Constant time.
0773    //!
0774    //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
0775    //!
0776    //! <b>Note</b>: This function does not check preconditions so if "pos" is not
0777    //! the successor of "value" container ordering invariant will be broken.
0778    //! This is a low-level function to be used only for performance reasons
0779    //! by advanced users.
0780    iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT
0781    {
0782       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0783       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0784       iterator ret
0785          ( node_algorithms::insert_before
0786             ( this->tree_type::header_ptr()
0787             , pos.pointed_node()
0788             , to_insert
0789             , this->prio_node_prio_comp(this->priv_pcomp())
0790             )
0791          , this->priv_value_traits_ptr());
0792       this->tree_type::sz_traits().increment();
0793       return ret;
0794    }
0795 
0796    //! <b>Requires</b>: value must be an lvalue, and it must be no less
0797    //!   than the greatest inserted key
0798    //!
0799    //! <b>Effects</b>: Inserts x into the container in the last position.
0800    //!
0801    //! <b>Complexity</b>: Constant time.
0802    //!
0803    //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
0804    //!
0805    //! <b>Note</b>: This function does not check preconditions so if value is
0806    //!   less than the greatest inserted key container ordering invariant will be broken.
0807    //!   This function is slightly more efficient than using "insert_before".
0808    //!   This is a low-level function to be used only for performance reasons
0809    //!   by advanced users.
0810    void push_back(reference value) BOOST_NOEXCEPT
0811    {
0812       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0813       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0814       node_algorithms::push_back
0815          (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp()));
0816       this->tree_type::sz_traits().increment();
0817    }
0818 
0819    //! <b>Requires</b>: value must be an lvalue, and it must be no greater
0820    //!   than the minimum inserted key
0821    //!
0822    //! <b>Effects</b>: Inserts x into the container in the first position.
0823    //!
0824    //! <b>Complexity</b>: Constant time.
0825    //!
0826    //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
0827    //!
0828    //! <b>Note</b>: This function does not check preconditions so if value is
0829    //!   greater than the minimum inserted key container ordering invariant will be broken.
0830    //!   This function is slightly more efficient than using "insert_before".
0831    //!   This is a low-level function to be used only for performance reasons
0832    //!   by advanced users.
0833    void push_front(reference value) BOOST_NOEXCEPT
0834    {
0835       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
0836       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
0837       node_algorithms::push_front
0838          (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp()));
0839       this->tree_type::sz_traits().increment();
0840    }
0841 
0842    //! <b>Effects</b>: Erases the element pointed to by i.
0843    //!
0844    //! <b>Complexity</b>: Average complexity for erase element is constant time.
0845    //!
0846    //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
0847    //!
0848    //! <b>Note</b>: Invalidates the iterators (but not the references)
0849    //!    to the erased elements. No destructors are called.
0850    iterator erase(const_iterator i) BOOST_NOEXCEPT
0851    {
0852       const_iterator ret(i);
0853       ++ret;
0854       node_ptr to_erase(i.pointed_node());
0855       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
0856       node_algorithms::erase
0857          (this->tree_type::header_ptr(), to_erase, this->prio_node_prio_comp(this->priv_pcomp()));
0858       this->tree_type::sz_traits().decrement();
0859       BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0860          node_algorithms::init(to_erase);
0861       return ret.unconst();
0862    }
0863 
0864    //! <b>Effects</b>: Erases the range pointed to by b end e.
0865    //!
0866    //! <b>Complexity</b>: Average complexity for erase range is at most
0867    //!   O(log(size() + N)), where N is the number of elements in the range.
0868    //!
0869    //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
0870    //!
0871    //! <b>Note</b>: Invalidates the iterators (but not the references)
0872    //!    to the erased elements. No destructors are called.
0873    iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT
0874    {  size_type n;   return private_erase(b, e, n);   }
0875 
0876    //! <b>Effects</b>: Erases all the elements with the given value.
0877    //!
0878    //! <b>Returns</b>: The number of erased elements.
0879    //!
0880    //! <b>Complexity</b>: O(log(size() + N).
0881    //!
0882    //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
0883    //!
0884    //! <b>Note</b>: Invalidates the iterators (but not the references)
0885    //!    to the erased elements. No destructors are called.
0886    size_type erase(const key_type &key)
0887    {  return this->erase(key, this->key_comp());   }
0888 
0889    //! <b>Effects</b>: Erases all the elements with the given key.
0890    //!   according to the comparison functor "comp".
0891    //!
0892    //! <b>Returns</b>: The number of erased elements.
0893    //!
0894    //! <b>Complexity</b>: O(log(size() + N).
0895    //!
0896    //! <b>Throws</b>: if the internal priority_compare function throws.
0897    //!   Equivalent guarantee to <i>while(beg != end) erase(beg++);</i>
0898    //!
0899    //! <b>Note</b>: Invalidates the iterators (but not the references)
0900    //!    to the erased elements. No destructors are called.
0901    template<class KeyType, class KeyTypeKeyCompare>
0902    BOOST_INTRUSIVE_DOC1ST(size_type
0903       , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
0904       erase(const KeyType& key, KeyTypeKeyCompare comp)
0905    {
0906       std::pair<iterator,iterator> p = this->equal_range(key, comp);
0907       size_type n;
0908       private_erase(p.first, p.second, n);
0909       return n;
0910    }
0911 
0912    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0913    //!
0914    //! <b>Effects</b>: Erases the element pointed to by i.
0915    //!   Disposer::operator()(pointer) is called for the removed element.
0916    //!
0917    //! <b>Complexity</b>: Average complexity for erase element is constant time.
0918    //!
0919    //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
0920    //!
0921    //! <b>Note</b>: Invalidates the iterators
0922    //!    to the erased elements.
0923    template<class Disposer>
0924    iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT
0925    {
0926       node_ptr to_erase(i.pointed_node());
0927       iterator ret(this->erase(i));
0928       disposer(this->get_value_traits().to_value_ptr(to_erase));
0929       return ret;
0930    }
0931 
0932    #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0933    template<class Disposer>
0934    iterator erase_and_dispose(iterator i, Disposer disposer) BOOST_NOEXCEPT
0935    {  return this->erase_and_dispose(const_iterator(i), disposer);   }
0936    #endif
0937 
0938    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0939    //!
0940    //! <b>Effects</b>: Erases the range pointed to by b end e.
0941    //!   Disposer::operator()(pointer) is called for the removed elements.
0942    //!
0943    //! <b>Complexity</b>: Average complexity for erase range is at most
0944    //!   O(log(size() + N)), where N is the number of elements in the range.
0945    //!
0946    //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
0947    //!
0948    //! <b>Note</b>: Invalidates the iterators
0949    //!    to the erased elements.
0950    template<class Disposer>
0951    iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT
0952    {  size_type n;   return private_erase(b, e, n, disposer);   }
0953 
0954    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0955    //!
0956    //! <b>Effects</b>: Erases all the elements with the given value.
0957    //!   Disposer::operator()(pointer) is called for the removed elements.
0958    //!
0959    //! <b>Returns</b>: The number of erased elements.
0960    //!
0961    //! <b>Complexity</b>: O(log(size() + N).
0962    //!
0963    //! <b>Throws</b>: if the priority_compare function throws then weak guarantee and heap invariants are broken.
0964    //!   The safest thing would be to clear or destroy the container.
0965    //!
0966    //! <b>Note</b>: Invalidates the iterators (but not the references)
0967    //!    to the erased elements. No destructors are called.
0968    template<class Disposer>
0969    size_type erase_and_dispose(const key_type &key, Disposer disposer)
0970    {
0971       std::pair<iterator,iterator> p = this->equal_range(key);
0972       size_type n;
0973       private_erase(p.first, p.second, n, disposer);
0974       return n;
0975    }
0976 
0977    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0978    //!
0979    //! <b>Effects</b>: Erases all the elements with the given key.
0980    //!   according to the comparison functor "comp".
0981    //!   Disposer::operator()(pointer) is called for the removed elements.
0982    //!
0983    //! <b>Returns</b>: The number of erased elements.
0984    //!
0985    //! <b>Complexity</b>: O(log(size() + N).
0986    //!
0987    //! <b>Throws</b>: if the priority_compare function throws then weak guarantee and heap invariants are broken.
0988    //!   The safest thing would be to clear or destroy the container.
0989    //!
0990    //! <b>Note</b>: Invalidates the iterators
0991    //!    to the erased elements.
0992    template<class KeyType, class KeyTypeKeyCompare, class Disposer>
0993    BOOST_INTRUSIVE_DOC1ST(size_type
0994       , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
0995       erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
0996    {
0997       std::pair<iterator,iterator> p = this->equal_range(key, comp);
0998       size_type n;
0999       private_erase(p.first, p.second, n, disposer);
1000       return n;
1001    }
1002 
1003    //! <b>Effects</b>: Erases all of the elements.
1004    //!
1005    //! <b>Complexity</b>: Linear to the number of elements on the container.
1006    //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
1007    //!
1008    //! <b>Throws</b>: Nothing.
1009    //!
1010    //! <b>Note</b>: Invalidates the iterators (but not the references)
1011    //!    to the erased elements. No destructors are called.
1012    void clear() BOOST_NOEXCEPT
1013    {  tree_type::clear(); }
1014 
1015    //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
1016    //!   each node to be erased.
1017    //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
1018    //!   where N is the number of elements in the container.
1019    //!
1020    //! <b>Throws</b>: Nothing.
1021    //!
1022    //! <b>Note</b>: Invalidates the iterators (but not the references)
1023    //!    to the erased elements. Calls N times to disposer functor.
1024    template<class Disposer>
1025    void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT
1026    {
1027       node_algorithms::clear_and_dispose(this->tree_type::header_ptr()
1028          , detail::node_disposer<Disposer, value_traits, TreapAlgorithms>(disposer, &this->get_value_traits()));
1029       node_algorithms::init_header(this->tree_type::header_ptr());
1030       this->tree_type::sz_traits().set_size(0);
1031    }
1032 
1033    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1034    //! @copydoc ::boost::intrusive::bstree::merge_unique
1035    template<class T, class ...Options2> void merge_unique(sgtree<T, Options2...> &);
1036    #else
1037    template<class Compare2>
1038    void merge_unique(treap_impl
1039       <ValueTraits, VoidOrKeyOfValue, Compare2, VoidOrPrioOfValue, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> &source)
1040    #endif
1041    {
1042       node_ptr it   (node_algorithms::begin_node(source.header_ptr()))
1043              , itend(node_algorithms::end_node  (source.header_ptr()));
1044 
1045       while(it != itend){
1046          node_ptr const p(it);
1047          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
1048          it = node_algorithms::next_node(it);
1049 
1050          if( node_algorithms::transfer_unique
1051                ( this->header_ptr(), this->key_node_comp(this->key_comp())
1052                , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p) ){
1053             this->sz_traits().increment();
1054             source.sz_traits().decrement();
1055          }
1056       }
1057    }
1058 
1059    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1060    //! @copydoc ::boost::intrusive::bstree::merge_equal(bstree<T, Options2...>&)
1061    template<class T, class ...Options2> void merge_equal(sgtree<T, Options2...> &);
1062    #else
1063    template<class Compare2>
1064    void merge_equal(treap_impl
1065       <ValueTraits, VoidOrKeyOfValue, Compare2, VoidOrPrioOfValue, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> &source)
1066    #endif
1067    {
1068       node_ptr it   (node_algorithms::begin_node(source.header_ptr()))
1069              , itend(node_algorithms::end_node  (source.header_ptr()));
1070 
1071       while(it != itend){
1072          node_ptr const p(it);
1073          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
1074          it = node_algorithms::next_node(it);
1075          node_algorithms::transfer_equal
1076             ( this->header_ptr(), this->key_node_comp(this->key_comp())
1077             , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p);
1078          this->sz_traits().increment();
1079          source.sz_traits().decrement();
1080       }
1081    }
1082 
1083    //! @copydoc ::boost::intrusive::bstree::check(ExtraChecker)const
1084    template <class ExtraChecker>
1085    void check(ExtraChecker extra_checker) const
1086    {
1087       typedef detail::key_nodeptr_comp<priority_compare, value_traits, priority_of_value> nodeptr_prio_comp_t;
1088       tree_type::check(detail::treap_node_extra_checker
1089          <ValueTraits, nodeptr_prio_comp_t, ExtraChecker>
1090             (this->prio_node_prio_comp(this->priv_pcomp()), extra_checker));
1091    }
1092 
1093    //! @copydoc ::boost::intrusive::bstree::check()const
1094    void check() const
1095    {  check(detail::empty_node_checker<ValueTraits>());  }
1096 
1097    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1098    //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
1099    size_type count(const key_type &key) const;
1100 
1101    //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
1102    template<class KeyType, class KeyTypeKeyCompare>
1103    size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
1104 
1105    //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
1106    iterator lower_bound(const key_type &key);
1107 
1108    //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
1109    template<class KeyType, class KeyTypeKeyCompare>
1110    iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
1111 
1112    //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
1113    const_iterator lower_bound(const key_type &key) const;
1114 
1115    //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
1116    template<class KeyType, class KeyTypeKeyCompare>
1117    const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
1118 
1119    //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
1120    iterator upper_bound(const key_type &key);
1121 
1122    //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
1123    template<class KeyType, class KeyTypeKeyCompare>
1124    iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
1125 
1126    //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
1127    const_iterator upper_bound(const key_type &key) const;
1128 
1129    //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
1130    template<class KeyType, class KeyTypeKeyCompare>
1131    const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
1132 
1133    //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
1134    iterator find(const key_type &key);
1135 
1136    //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
1137    template<class KeyType, class KeyTypeKeyCompare>
1138    iterator find(const KeyType& key, KeyTypeKeyCompare comp);
1139 
1140    //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
1141    const_iterator find(const key_type &key) const;
1142 
1143    //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
1144    template<class KeyType, class KeyTypeKeyCompare>
1145    const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
1146 
1147    //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
1148    std::pair<iterator,iterator> equal_range(const key_type &key);
1149 
1150    //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
1151    template<class KeyType, class KeyTypeKeyCompare>
1152    std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
1153 
1154    //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
1155    std::pair<const_iterator, const_iterator>
1156       equal_range(const key_type &key) const;
1157 
1158    //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
1159    template<class KeyType, class KeyTypeKeyCompare>
1160    std::pair<const_iterator, const_iterator>
1161       equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
1162 
1163    //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
1164    std::pair<iterator,iterator> bounded_range
1165       (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
1166 
1167    //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
1168    template<class KeyType, class KeyTypeKeyCompare>
1169    std::pair<iterator,iterator> bounded_range
1170       (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
1171 
1172    //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
1173    std::pair<const_iterator, const_iterator>
1174       bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
1175 
1176    //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
1177    template<class KeyType, class KeyTypeKeyCompare>
1178    std::pair<const_iterator, const_iterator> bounded_range
1179          (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
1180 
1181    //! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
1182    static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
1183 
1184    //! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
1185    static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
1186 
1187    //! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
1188    iterator iterator_to(reference value) BOOST_NOEXCEPT;
1189 
1190    //! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
1191    const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
1192 
1193    //! @copydoc ::boost::intrusive::bstree::init_node(reference)
1194    static void init_node(reference value) BOOST_NOEXCEPT;
1195 
1196    //! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
1197    pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT;
1198 
1199    //! @copydoc ::boost::intrusive::bstree::replace_node
1200    void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
1201 
1202    //! @copydoc ::boost::intrusive::bstree::remove_node
1203    void remove_node(reference value) BOOST_NOEXCEPT;
1204 
1205    friend bool operator< (const treap_impl &x, const treap_impl &y);
1206 
1207    friend bool operator==(const treap_impl &x, const treap_impl &y);
1208 
1209    friend bool operator!= (const treap_impl &x, const treap_impl &y);
1210 
1211    friend bool operator>(const treap_impl &x, const treap_impl &y);
1212 
1213    friend bool operator<=(const treap_impl &x, const treap_impl &y);
1214 
1215    friend bool operator>=(const treap_impl &x, const treap_impl &y);
1216 
1217    friend void swap(treap_impl &x, treap_impl &y);
1218 
1219    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1220 
1221    /// @cond
1222    private:
1223    template<class Disposer>
1224    iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
1225    {
1226       for(n = 0; b != e; ++n)
1227         this->erase_and_dispose(b++, disposer);
1228       return b.unconst();
1229    }
1230 
1231    iterator private_erase(const_iterator b, const_iterator e, size_type &n)
1232    {
1233       for(n = 0; b != e; ++n)
1234         this->erase(b++);
1235       return b.unconst();
1236    }
1237    /// @endcond
1238 };
1239 
1240 
1241 //! Helper metafunction to define a \c treap that yields to the same type when the
1242 //! same options (either explicitly or implicitly) are used.
1243 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1244 template<class T, class ...Options>
1245 #else
1246 template<class T, class O1 = void, class O2 = void
1247                 , class O3 = void, class O4 = void
1248                 , class O5 = void, class O6 = void
1249                 , class O7 = void>
1250 #endif
1251 struct make_treap
1252 {
1253    typedef typename pack_options
1254       < treap_defaults,
1255       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1256       O1, O2, O3, O4, O5, O6, O7
1257       #else
1258       Options...
1259       #endif
1260       >::type packed_options;
1261 
1262    typedef typename detail::get_value_traits
1263       <T, typename packed_options::proto_value_traits>::type value_traits;
1264 
1265    typedef treap_impl
1266          < value_traits
1267          , typename packed_options::key_of_value
1268          , typename packed_options::compare
1269          , typename packed_options::priority_of_value
1270          , typename packed_options::priority
1271          , typename packed_options::size_type
1272          , packed_options::constant_time_size
1273          , typename packed_options::header_holder_type
1274          > implementation_defined;
1275    /// @endcond
1276    typedef implementation_defined type;
1277 };
1278 
1279 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1280 
1281 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1282 template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
1283 #else
1284 template<class T, class ...Options>
1285 #endif
1286 class treap
1287    :  public make_treap<T,
1288       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1289       O1, O2, O3, O4, O5, O6, O7
1290       #else
1291       Options...
1292       #endif
1293       >::type
1294 {
1295    typedef typename make_treap
1296       <T,
1297       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
1298       O1, O2, O3, O4, O5, O6, O7
1299       #else
1300       Options...
1301       #endif
1302       >::type   Base;
1303    BOOST_MOVABLE_BUT_NOT_COPYABLE(treap)
1304 
1305    public:
1306    typedef typename Base::key_compare        key_compare;
1307    typedef typename Base::priority_compare   priority_compare;
1308    typedef typename Base::value_traits       value_traits;
1309    typedef typename Base::iterator           iterator;
1310    typedef typename Base::const_iterator     const_iterator;
1311    typedef typename Base::reverse_iterator           reverse_iterator;
1312    typedef typename Base::const_reverse_iterator     const_reverse_iterator;
1313 
1314    //Assert if passed value traits are compatible with the type
1315    BOOST_INTRUSIVE_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
1316 
1317    inline treap()
1318       :  Base()
1319    {}
1320 
1321    inline explicit treap( const key_compare &cmp
1322                  , const priority_compare &pcmp = priority_compare()
1323                  , const value_traits &v_traits = value_traits())
1324       :  Base(cmp, pcmp, v_traits)
1325    {}
1326 
1327    template<class Iterator>
1328    inline treap( bool unique, Iterator b, Iterator e
1329        , const key_compare &cmp = key_compare()
1330        , const priority_compare &pcmp = priority_compare()
1331        , const value_traits &v_traits = value_traits())
1332       :  Base(unique, b, e, cmp, pcmp, v_traits)
1333    {}
1334 
1335    inline treap(BOOST_RV_REF(treap) x)
1336       :  Base(BOOST_MOVE_BASE(Base, x))
1337    {}
1338 
1339    inline treap& operator=(BOOST_RV_REF(treap) x)
1340    {  return static_cast<treap&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
1341 
1342    template <class Cloner, class Disposer>
1343    inline void clone_from(const treap &src, Cloner cloner, Disposer disposer)
1344    {  Base::clone_from(src, cloner, disposer);  }
1345 
1346    template <class Cloner, class Disposer>
1347    inline void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer)
1348    {  Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer);  }
1349 
1350    inline static treap &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
1351    {  return static_cast<treap &>(Base::container_from_end_iterator(end_iterator));   }
1352 
1353    inline static const treap &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
1354    {  return static_cast<const treap &>(Base::container_from_end_iterator(end_iterator));   }
1355 
1356    inline static treap &container_from_iterator(iterator it) BOOST_NOEXCEPT
1357    {  return static_cast<treap &>(Base::container_from_iterator(it));   }
1358 
1359    inline static const treap &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
1360    {  return static_cast<const treap &>(Base::container_from_iterator(it));   }
1361 };
1362 
1363 #endif
1364 
1365 } //namespace intrusive
1366 } //namespace boost
1367 
1368 #include <boost/intrusive/detail/config_end.hpp>
1369 
1370 #endif //BOOST_INTRUSIVE_TREAP_HPP