Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:47:08

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga  2013-2014
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_BSTREE_HPP
0013 #define BOOST_INTRUSIVE_BSTREE_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/intrusive_fwd.hpp>
0020 #include <boost/intrusive/bs_set_hook.hpp>
0021 #include <boost/intrusive/detail/tree_node.hpp>
0022 #include <boost/intrusive/detail/tree_iterator.hpp>
0023 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
0024 #include <boost/intrusive/detail/mpl.hpp>
0025 #include <boost/intrusive/pointer_traits.hpp>
0026 #include <boost/intrusive/detail/is_stateful_value_traits.hpp>
0027 #include <boost/intrusive/detail/empty_node_checker.hpp>
0028 #include <boost/intrusive/detail/default_header_holder.hpp>
0029 #include <boost/intrusive/detail/reverse_iterator.hpp>
0030 #include <boost/intrusive/detail/exception_disposer.hpp>
0031 #include <boost/intrusive/detail/node_cloner_disposer.hpp>
0032 #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
0033 #include <boost/intrusive/detail/simple_disposers.hpp>
0034 #include <boost/intrusive/detail/size_holder.hpp>
0035 #include <boost/intrusive/detail/algo_type.hpp>
0036 #include <boost/intrusive/detail/algorithm.hpp>
0037 #include <boost/intrusive/detail/tree_value_compare.hpp>
0038 
0039 #include <boost/intrusive/detail/get_value_traits.hpp>
0040 #include <boost/intrusive/bstree_algorithms.hpp>
0041 #include <boost/intrusive/link_mode.hpp>
0042 #include <boost/intrusive/parent_from_member.hpp>
0043 #include <boost/move/utility_core.hpp>
0044 #include <boost/move/adl_move_swap.hpp>
0045 
0046 #include <boost/intrusive/detail/minimal_pair_header.hpp>
0047 #include <cstddef>   //size_t...
0048 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal_to
0049 
0050 #if defined(BOOST_HAS_PRAGMA_ONCE)
0051 #  pragma once
0052 #endif
0053 
0054 namespace boost {
0055 namespace intrusive {
0056 
0057 /// @cond
0058 
0059 struct default_bstree_hook_applier
0060 {  template <class T> struct apply{ typedef typename T::default_bstree_hook type;  };  };
0061 
0062 template<>
0063 struct is_default_hook_tag<default_bstree_hook_applier>
0064 {  static const bool value = true;  };
0065 
0066 struct bstree_defaults
0067 {
0068    typedef default_bstree_hook_applier proto_value_traits;
0069    static const bool constant_time_size = true;
0070    typedef std::size_t size_type;
0071    typedef void compare;
0072    typedef void key_of_value;
0073    static const bool floating_point = true;  //For sgtree
0074    typedef void priority;  //For treap
0075    typedef void header_holder_type;
0076 };
0077 
0078 template<class ValueTraits, algo_types AlgoType, typename HeaderHolder>
0079 struct bstbase3
0080 {
0081    typedef ValueTraits                                               value_traits;
0082    typedef typename value_traits::node_traits                        node_traits;
0083    typedef typename node_traits::node                                node_type;
0084    typedef typename get_algo<AlgoType, node_traits>::type            node_algorithms;
0085    typedef typename node_traits::node_ptr                            node_ptr;
0086    typedef typename node_traits::const_node_ptr                      const_node_ptr;
0087    typedef tree_iterator<value_traits, false>                                                   iterator;
0088    typedef tree_iterator<value_traits, true>                                                    const_iterator;
0089    typedef boost::intrusive::reverse_iterator<iterator>                                         reverse_iterator;
0090    typedef boost::intrusive::reverse_iterator<const_iterator>                                   const_reverse_iterator;
0091    typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer)                               pointer;
0092    typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer)                         const_pointer;
0093    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type)               value_type;
0094    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference)                  reference;
0095    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference)            const_reference;
0096    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type)      difference_type;
0097    typedef typename detail::get_header_holder_type
0098       < value_traits,HeaderHolder >::type                                                       header_holder_type;
0099 
0100    static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
0101    static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
0102    static const bool has_container_from_iterator =
0103         detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value;
0104 
0105    struct holder_t : public ValueTraits
0106    {
0107       inline explicit holder_t(const ValueTraits &vtraits)
0108          : ValueTraits(vtraits)
0109       {}
0110       header_holder_type root;
0111    } holder;
0112 
0113    static bstbase3 &get_tree_base_from_end_iterator(const const_iterator &end_iterator)
0114    {
0115       BOOST_INTRUSIVE_STATIC_ASSERT(has_container_from_iterator);
0116       node_ptr p = end_iterator.pointed_node();
0117       header_holder_type* h = header_holder_type::get_holder(p);
0118       holder_t *holder = get_parent_from_member<holder_t, header_holder_type>(h, &holder_t::root);
0119       bstbase3 *base   = get_parent_from_member<bstbase3, holder_t> (holder, &bstbase3::holder);
0120       return *base;
0121    }
0122 
0123    inline bstbase3(const ValueTraits &vtraits)
0124       : holder(vtraits)
0125    {
0126       node_algorithms::init_header(this->header_ptr());
0127    }
0128 
0129    inline node_ptr header_ptr()
0130    { return holder.root.get_node(); }
0131 
0132    inline const_node_ptr header_ptr() const
0133    { return holder.root.get_node(); }
0134 
0135    inline const value_traits &get_value_traits() const
0136    {  return this->holder;  }
0137 
0138    inline value_traits &get_value_traits()
0139    {  return this->holder;  }
0140 
0141    typedef typename boost::intrusive::value_traits_pointers
0142       <ValueTraits>::const_value_traits_ptr const_value_traits_ptr;
0143 
0144    inline const_value_traits_ptr priv_value_traits_ptr() const
0145    {  return pointer_traits<const_value_traits_ptr>::pointer_to(this->get_value_traits());  }
0146 
0147    inline iterator begin() BOOST_NOEXCEPT
0148    {  return iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr());   }
0149 
0150    inline const_iterator begin() const BOOST_NOEXCEPT
0151    {  return cbegin();   }
0152 
0153    inline const_iterator cbegin() const BOOST_NOEXCEPT
0154    {  return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr());   }
0155 
0156    inline iterator end() BOOST_NOEXCEPT
0157    {  return iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr());   }
0158 
0159    inline const_iterator end() const BOOST_NOEXCEPT
0160    {  return cend();  }
0161 
0162    inline const_iterator cend() const BOOST_NOEXCEPT
0163    {  return const_iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr());   }
0164 
0165    inline iterator root()
0166    {  return iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr());   }
0167 
0168    inline const_iterator root() const
0169    {  return croot();   }
0170 
0171    inline const_iterator croot() const
0172    {  return const_iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr());   }
0173 
0174    inline reverse_iterator rbegin()
0175    {  return reverse_iterator(end());  }
0176 
0177    inline const_reverse_iterator rbegin() const
0178    {  return const_reverse_iterator(end());  }
0179 
0180    inline const_reverse_iterator crbegin() const
0181    {  return const_reverse_iterator(end());  }
0182 
0183    inline reverse_iterator rend()
0184    {  return reverse_iterator(begin());   }
0185 
0186    inline const_reverse_iterator rend() const
0187    {  return const_reverse_iterator(begin());   }
0188 
0189    inline const_reverse_iterator crend() const
0190    {  return const_reverse_iterator(begin());   }
0191 
0192    void replace_node(iterator replace_this, reference with_this)
0193    {
0194       node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this)
0195                                    , this->header_ptr()
0196                                    , get_value_traits().to_node_ptr(with_this));
0197       BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0198          node_algorithms::init(replace_this.pointed_node());
0199    }
0200 
0201    inline void rebalance() BOOST_NOEXCEPT
0202    {  node_algorithms::rebalance(this->header_ptr()); }
0203 
0204    iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT
0205    {  return iterator(node_algorithms::rebalance_subtree(r.pointed_node()), this->priv_value_traits_ptr()); }
0206 
0207    static iterator s_iterator_to(reference value) BOOST_NOEXCEPT
0208    {
0209       BOOST_INTRUSIVE_STATIC_ASSERT((!stateful_value_traits));
0210       return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr());
0211    }
0212 
0213    static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT
0214    {
0215       BOOST_INTRUSIVE_STATIC_ASSERT((!stateful_value_traits));
0216       return const_iterator (value_traits::to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), const_value_traits_ptr());
0217    }
0218 
0219    iterator iterator_to(reference value) BOOST_NOEXCEPT
0220    {  return iterator (this->get_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); }
0221 
0222    const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT
0223    {  return const_iterator (this->get_value_traits().to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), this->priv_value_traits_ptr()); }
0224 
0225    inline static void init_node(reference value)
0226    { node_algorithms::init(value_traits::to_node_ptr(value)); }
0227 
0228 };
0229 
0230 template<class Less, class T>
0231 struct get_compare
0232 {
0233    typedef Less type;
0234 };
0235 
0236 template<class T>
0237 struct get_compare<void, T>
0238 {
0239    typedef ::std::less<T> type;
0240 };
0241 
0242 template<class KeyOfValue, class T>
0243 struct get_key_of_value
0244 {
0245    typedef KeyOfValue type;
0246 };
0247 
0248 template<class T>
0249 struct get_key_of_value<void, T>
0250 {
0251    typedef ::boost::intrusive::detail::identity<T> type;
0252 };
0253 
0254 template<class ValuePtr, class VoidOrKeyOfValue, class VoidOrKeyComp>
0255 struct bst_key_types
0256 {
0257    typedef typename
0258       boost::movelib::pointer_element<ValuePtr>::type value_type;
0259    typedef typename get_key_of_value
0260       < VoidOrKeyOfValue, value_type>::type           key_of_value;
0261    typedef typename key_of_value::type                key_type;
0262    typedef typename get_compare< VoidOrKeyComp
0263                       , key_type
0264                       >::type                         key_compare;
0265    typedef tree_value_compare
0266       <ValuePtr, key_compare, key_of_value>           value_compare;
0267 };
0268 
0269 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, algo_types AlgoType, typename HeaderHolder>
0270 struct bstbase2
0271    //Put the (possibly empty) functor in the first position to get EBO in MSVC
0272    //Use public inheritance to avoid MSVC bugs with closures
0273    : public detail::ebo_functor_holder
0274             < typename bst_key_types
0275                < typename ValueTraits::pointer
0276                , VoidOrKeyOfValue
0277                , VoidOrKeyComp
0278                
0279                >::value_compare
0280             >
0281    , public bstbase3<ValueTraits, AlgoType, HeaderHolder>
0282 {
0283    typedef bstbase3<ValueTraits, AlgoType, HeaderHolder>             treeheader_t;
0284    typedef bst_key_types< typename ValueTraits::pointer
0285                         , VoidOrKeyOfValue
0286                         , VoidOrKeyComp>                             key_types;
0287    typedef typename treeheader_t::value_traits                       value_traits;
0288    typedef typename treeheader_t::node_algorithms                    node_algorithms;
0289    typedef typename ValueTraits::value_type                          value_type;
0290    typedef typename key_types::key_type                              key_type;
0291    typedef typename key_types::key_of_value                          key_of_value;
0292    typedef typename key_types::key_compare                           key_compare;
0293    typedef typename key_types::value_compare                         value_compare;
0294    typedef typename treeheader_t::iterator                           iterator;
0295    typedef typename treeheader_t::const_iterator                     const_iterator;
0296    typedef typename treeheader_t::node_ptr                           node_ptr;
0297    typedef typename treeheader_t::const_node_ptr                     const_node_ptr;
0298 
0299    bstbase2(const key_compare &comp, const ValueTraits &vtraits)
0300       : detail::ebo_functor_holder<value_compare>(value_compare(comp)), treeheader_t(vtraits)
0301    {}
0302 
0303    const value_compare &get_comp() const
0304    {  return this->get();  }
0305 
0306    value_compare &get_comp()
0307    {  return this->get();  }
0308 
0309    typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer)                               pointer;
0310    typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer)                         const_pointer;
0311    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference)                  reference;
0312    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference)            const_reference;
0313    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type)      difference_type;
0314    typedef typename node_algorithms::insert_commit_data insert_commit_data;
0315 
0316    inline value_compare value_comp() const
0317    {  return this->get_comp();   }
0318 
0319    inline key_compare key_comp() const
0320    {  return this->get_comp().key_comp();   }
0321 
0322    //lower_bound
0323    inline iterator lower_bound(const key_type &key)
0324    {  return this->lower_bound(key, this->key_comp());   }
0325 
0326    inline const_iterator lower_bound(const key_type &key) const
0327    {  return this->lower_bound(key, this->key_comp());   }
0328 
0329    template<class KeyType, class KeyTypeKeyCompare>
0330    iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp)
0331    {
0332       return iterator(node_algorithms::lower_bound
0333          (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0334    }
0335 
0336    template<class KeyType, class KeyTypeKeyCompare>
0337    const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const
0338    {
0339       return const_iterator(node_algorithms::lower_bound
0340          (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0341    }
0342 
0343    //upper_bound
0344    inline iterator upper_bound(const key_type &key)
0345    {  return this->upper_bound(key, this->key_comp());   }
0346 
0347    template<class KeyType, class KeyTypeKeyCompare>
0348    iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp)
0349    {
0350       return iterator(node_algorithms::upper_bound
0351          (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0352    }
0353 
0354    inline const_iterator upper_bound(const key_type &key) const
0355    {  return this->upper_bound(key, this->key_comp());   }
0356 
0357    template<class KeyType, class KeyTypeKeyCompare>
0358    const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const
0359    {
0360       return const_iterator(node_algorithms::upper_bound
0361          (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0362    }
0363 
0364    template<class KeyTypeKeyCompare>
0365    struct key_node_comp_ret
0366    {  typedef detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value> type;  };
0367 
0368    template<class KeyTypeKeyCompare>
0369    inline typename key_node_comp_ret<KeyTypeKeyCompare>::type key_node_comp(KeyTypeKeyCompare comp) const
0370    {
0371       return detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value>(comp, &this->get_value_traits());
0372    }
0373 
0374    //find
0375    inline iterator find(const key_type &key)
0376    {  return this->find(key, this->key_comp()); }
0377 
0378    template<class KeyType, class KeyTypeKeyCompare>
0379    iterator find(const KeyType &key, KeyTypeKeyCompare comp)
0380    {
0381       return iterator
0382          (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0383    }
0384 
0385    inline const_iterator find(const key_type &key) const
0386    {  return this->find(key, this->key_comp()); }
0387 
0388    template<class KeyType, class KeyTypeKeyCompare>
0389    const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const
0390    {
0391       return const_iterator
0392          (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0393    }
0394 
0395    //equal_range
0396    inline std::pair<iterator,iterator> equal_range(const key_type &key)
0397    {  return this->equal_range(key, this->key_comp());   }
0398 
0399    template<class KeyType, class KeyTypeKeyCompare>
0400    std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp)
0401    {
0402       std::pair<node_ptr, node_ptr> ret = 
0403          node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp));
0404       return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
0405                                           , iterator(ret.second, this->priv_value_traits_ptr()));
0406    }
0407 
0408    inline std::pair<const_iterator, const_iterator>
0409       equal_range(const key_type &key) const
0410    {  return this->equal_range(key, this->key_comp());   }
0411 
0412    template<class KeyType, class KeyTypeKeyCompare>
0413    std::pair<const_iterator, const_iterator>
0414       equal_range(const KeyType &key, KeyTypeKeyCompare comp) const
0415    {
0416       std::pair<node_ptr, node_ptr> ret =
0417          node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp));
0418       return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
0419                                                       , const_iterator(ret.second, this->priv_value_traits_ptr()));
0420    }
0421 
0422    //lower_bound_range
0423    inline std::pair<iterator,iterator> lower_bound_range(const key_type &key)
0424    {  return this->lower_bound_range(key, this->key_comp());   }
0425 
0426    template<class KeyType, class KeyTypeKeyCompare>
0427    std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp)
0428    {
0429       std::pair<node_ptr, node_ptr> ret =
0430          node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp));
0431       return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
0432                                           , iterator(ret.second, this->priv_value_traits_ptr()));
0433    }
0434 
0435    inline std::pair<const_iterator, const_iterator>
0436       lower_bound_range(const key_type &key) const
0437    {  return this->lower_bound_range(key, this->key_comp());   }
0438 
0439    template<class KeyType, class KeyTypeKeyCompare>
0440    std::pair<const_iterator, const_iterator>
0441       lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) const
0442    {
0443       std::pair<node_ptr, node_ptr> ret =
0444          node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp));
0445       return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
0446                                                       , const_iterator(ret.second, this->priv_value_traits_ptr()));
0447    }
0448 
0449    //bounded_range
0450    inline std::pair<iterator,iterator> bounded_range
0451       (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed)
0452    {  return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed);   }
0453 
0454    template<class KeyType, class KeyTypeKeyCompare>
0455    std::pair<iterator,iterator> bounded_range
0456       (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed)
0457    {
0458       std::pair<node_ptr, node_ptr> ret =
0459          node_algorithms::bounded_range
0460             (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed);
0461       return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
0462                                           , iterator(ret.second, this->priv_value_traits_ptr()));
0463    }
0464 
0465    inline std::pair<const_iterator,const_iterator> bounded_range
0466       (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const
0467    {  return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed);   }
0468 
0469    template<class KeyType, class KeyTypeKeyCompare>
0470    std::pair<const_iterator,const_iterator> bounded_range
0471       (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const
0472    {
0473       std::pair<node_ptr, node_ptr> ret =
0474          node_algorithms::bounded_range
0475             (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed);
0476       return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
0477                                                       , const_iterator(ret.second, this->priv_value_traits_ptr()));
0478    }
0479 
0480    //insert_unique_check
0481    inline std::pair<iterator, bool> insert_unique_check
0482       (const key_type &key, insert_commit_data &commit_data)
0483    {  return this->insert_unique_check(key, this->key_comp(), commit_data);   }
0484 
0485    inline std::pair<iterator, bool> insert_unique_check
0486       (const_iterator hint, const key_type &key, insert_commit_data &commit_data)
0487    {  return this->insert_unique_check(hint, key, this->key_comp(), commit_data);   }
0488 
0489    template<class KeyType, class KeyTypeKeyCompare>
0490    BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
0491       , typename detail::disable_if_convertible
0492          <KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I 
0493          std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
0494       insert_unique_check
0495       (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
0496    {
0497       std::pair<node_ptr, bool> ret =
0498          (node_algorithms::insert_unique_check
0499             (this->header_ptr(), key, this->key_node_comp(comp), commit_data));
0500       return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0501    }
0502 
0503    template<class KeyType, class KeyTypeKeyCompare>
0504    std::pair<iterator, bool> insert_unique_check
0505       (const_iterator hint, const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
0506    {
0507       std::pair<node_ptr, bool> ret =
0508          (node_algorithms::insert_unique_check
0509             (this->header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data));
0510       return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0511    }
0512 };
0513 
0514 //Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member
0515 //in the first position, but if size is not going to be stored then we'll use an specialization
0516 //that doesn't inherit from size_holder
0517 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
0518 struct bstbase_hack
0519    : public detail::size_holder<ConstantTimeSize, SizeType>
0520    , public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
0521 {
0522    typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
0523    typedef typename base_type::key_compare         key_compare;
0524    typedef typename base_type::value_compare       value_compare;
0525    typedef SizeType                                size_type;
0526    typedef typename base_type::node_traits         node_traits;
0527    typedef typename get_algo
0528       <AlgoType, node_traits>::type                algo_type;
0529 
0530    inline bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
0531       : base_type(comp, vtraits)
0532    {
0533       this->sz_traits().set_size(size_type(0));
0534    }
0535 
0536    typedef detail::size_holder<ConstantTimeSize, SizeType>     size_traits;
0537 
0538    inline size_traits &sz_traits()
0539    {  return static_cast<size_traits &>(*this);  }
0540 
0541    inline const size_traits &sz_traits() const
0542    {  return static_cast<const size_traits &>(*this);  }
0543 };
0544 
0545 //Specialization for ConstantTimeSize == false
0546 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
0547 struct bstbase_hack<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>
0548    : public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
0549 {
0550    typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
0551    typedef typename base_type::value_compare       value_compare;
0552    typedef typename base_type::key_compare         key_compare;
0553    inline bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
0554       : base_type(comp, vtraits)
0555    {}
0556 
0557    typedef detail::size_holder<false, SizeType>     size_traits;
0558 
0559    inline size_traits sz_traits() const
0560    {  return size_traits();  }
0561 };
0562 
0563 //This class will
0564 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
0565 struct bstbase
0566    : public bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
0567 {
0568    typedef bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type;
0569    typedef ValueTraits                             value_traits;
0570    typedef typename base_type::value_compare       value_compare;
0571    typedef typename base_type::key_compare         key_compare;
0572    typedef typename base_type::const_reference     const_reference;
0573    typedef typename base_type::reference           reference;
0574    typedef typename base_type::iterator            iterator;
0575    typedef typename base_type::const_iterator      const_iterator;
0576    typedef typename base_type::node_traits         node_traits;
0577    typedef typename get_algo
0578       <AlgoType, node_traits>::type                node_algorithms;
0579    typedef SizeType                                size_type;
0580 
0581    inline bstbase(const key_compare & comp, const ValueTraits &vtraits)
0582       : base_type(comp, vtraits)
0583    {}
0584 
0585    //Detach all inserted nodes. This will add exception safety to bstree_impl
0586    //constructors inserting elements.
0587    ~bstbase()
0588    {
0589       if(is_safe_autounlink<value_traits::link_mode>::value){
0590          node_algorithms::clear_and_dispose
0591             ( this->header_ptr()
0592             , detail::node_disposer<detail::null_disposer, value_traits, AlgoType>
0593                (detail::null_disposer(), &this->get_value_traits()));
0594          node_algorithms::init(this->header_ptr());
0595       }
0596    }
0597 };
0598 
0599 
0600 /// @endcond
0601 
0602 //! The class template bstree is an unbalanced intrusive binary search tree
0603 //! container. The no-throw guarantee holds only, if the key_compare object
0604 //! doesn't throw.
0605 //!
0606 //! The complexity guarantees only hold if the tree is balanced, logarithmic
0607 //! complexity would increase to linear if the tree is totally unbalanced.
0608 //!
0609 //! The template parameter \c T is the type to be managed by the container.
0610 //! The user can specify additional options and if no options are provided
0611 //! default options are used.
0612 //!
0613 //! The container supports the following options:
0614 //! \c base_hook<>/member_hook<>/value_traits<>,
0615 //! \c constant_time_size<>, \c size_type<> and
0616 //! \c compare<>.
0617 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0618 template<class T, class ...Options>
0619 #else
0620 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
0621 #endif
0622 class bstree_impl
0623    :  public bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
0624 {
0625    public:
0626    /// @cond
0627    typedef bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> data_type;
0628    typedef tree_iterator<ValueTraits, false> iterator_type;
0629    typedef tree_iterator<ValueTraits, true>  const_iterator_type;
0630    /// @endcond
0631 
0632    typedef BOOST_INTRUSIVE_IMPDEF(ValueTraits)                                                  value_traits;
0633    typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer)                               pointer;
0634    typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer)                         const_pointer;
0635    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type)               value_type;
0636    typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_type)                                 key_type;
0637    typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_of_value)                             key_of_value;
0638    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference)                  reference;
0639    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference)            const_reference;
0640    typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type)      difference_type;
0641    typedef BOOST_INTRUSIVE_IMPDEF(SizeType)                                                     size_type;
0642    typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::value_compare)                            value_compare;
0643    typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_compare)                              key_compare;
0644    typedef BOOST_INTRUSIVE_IMPDEF(iterator_type)                                                iterator;
0645    typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type)                                          const_iterator;
0646    typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<iterator>)                 reverse_iterator;
0647    typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<const_iterator>)           const_reverse_iterator;
0648    typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::node_traits)                           node_traits;
0649    typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node)                                   node;
0650    typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node_ptr)                               node_ptr;
0651    typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::const_node_ptr)                         const_node_ptr;
0652    /// @cond
0653    typedef typename get_algo<AlgoType, node_traits>::type                                       algo_type;
0654    /// @endcond
0655    typedef BOOST_INTRUSIVE_IMPDEF(algo_type)                                                    node_algorithms;
0656 
0657    static const bool constant_time_size = ConstantTimeSize;
0658    static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
0659    /// @cond
0660    private:
0661 
0662    //noncopyable
0663    BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree_impl)
0664 
0665    static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
0666 
0667    //Constant-time size is incompatible with auto-unlink hooks!
0668    BOOST_INTRUSIVE_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
0669 
0670 
0671    protected:
0672 
0673 
0674    /// @endcond
0675 
0676    public:
0677 
0678    typedef typename node_algorithms::insert_commit_data insert_commit_data;
0679 
0680    //! <b>Effects</b>: Constructs an empty container.
0681    //!
0682    //! <b>Complexity</b>: Constant.
0683    //!
0684    //! <b>Throws</b>: If value_traits::node_traits::node
0685    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0686    //!   or the copy constructor of the key_compare object throws. Basic guarantee.
0687    bstree_impl()
0688       :  data_type(key_compare(), value_traits())
0689    {}
0690 
0691    //! <b>Effects</b>: Constructs an empty container with given comparison and traits.
0692    //!
0693    //! <b>Complexity</b>: Constant.
0694    //!
0695    //! <b>Throws</b>: If value_traits::node_traits::node
0696    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0697    //!   or the copy constructor of the key_compare object throws. Basic guarantee.
0698    explicit bstree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits())
0699       :  data_type(cmp, v_traits)
0700    {}
0701 
0702    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
0703    //!   cmp must be a comparison function that induces a strict weak ordering.
0704    //!
0705    //! <b>Effects</b>: Constructs an empty container and inserts elements from
0706    //!   [b, e).
0707    //!
0708    //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
0709    //!   comp and otherwise N * log N, where N is the distance between first and last.
0710    //!
0711    //! <b>Throws</b>: If value_traits::node_traits::node
0712    //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0713    //!   or the copy constructor/operator() of the key_compare object throws. Basic guarantee.
0714    template<class Iterator>
0715    bstree_impl( bool unique, Iterator b, Iterator e
0716               , const key_compare &cmp     = key_compare()
0717               , const value_traits &v_traits = value_traits())
0718       : data_type(cmp, v_traits)
0719    {
0720       //bstbase releases elements in case of exceptions
0721       if(unique)
0722          this->insert_unique(b, e);
0723       else
0724          this->insert_equal(b, e);
0725    }
0726 
0727    //! <b>Effects</b>: Constructs a container moving resources from another container.
0728    //!   Internal comparison object and value traits are move constructed and
0729    //!   nodes belonging to x (except the node representing the "end") are linked to *this.
0730    //!
0731    //! <b>Complexity</b>: Constant.
0732    //!
0733    //! <b>Throws</b>: If value_traits::node_traits::node's
0734    //!   move constructor throws (this does not happen with predefined Boost.Intrusive hooks)
0735    //!   or the move constructor of the comparison objet throws.
0736    bstree_impl(BOOST_RV_REF(bstree_impl) x)
0737       : data_type(::boost::move(x.get_comp()), ::boost::move(x.get_value_traits()))
0738    {
0739       this->swap(x);
0740    }
0741 
0742    //! <b>Effects</b>: Equivalent to swap
0743    //!
0744    inline bstree_impl& operator=(BOOST_RV_REF(bstree_impl) x)
0745    {  this->swap(x); return *this;  }
0746 
0747    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0748    //! <b>Effects</b>: Detaches all elements from this. The objects in the set
0749    //!   are not deleted (i.e. no destructors are called), but the nodes according to
0750    //!   the value_traits template parameter are reinitialized and thus can be reused.
0751    //!
0752    //! <b>Complexity</b>: Linear to elements contained in *this.
0753    //!
0754    //! <b>Throws</b>: Nothing.
0755    ~bstree_impl()
0756    {}
0757 
0758    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the container.
0759    //!
0760    //! <b>Complexity</b>: Constant.
0761    //!
0762    //! <b>Throws</b>: Nothing.
0763    iterator begin() BOOST_NOEXCEPT;
0764 
0765    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the container.
0766    //!
0767    //! <b>Complexity</b>: Constant.
0768    //!
0769    //! <b>Throws</b>: Nothing.
0770    const_iterator begin() const BOOST_NOEXCEPT;
0771 
0772    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the container.
0773    //!
0774    //! <b>Complexity</b>: Constant.
0775    //!
0776    //! <b>Throws</b>: Nothing.
0777    const_iterator cbegin() const BOOST_NOEXCEPT;
0778 
0779    //! <b>Effects</b>: Returns an iterator pointing to the end of the container.
0780    //!
0781    //! <b>Complexity</b>: Constant.
0782    //!
0783    //! <b>Throws</b>: Nothing.
0784    iterator end() BOOST_NOEXCEPT;
0785 
0786    //! <b>Effects</b>: Returns a const_iterator pointing to the end of the container.
0787    //!
0788    //! <b>Complexity</b>: Constant.
0789    //!
0790    //! <b>Throws</b>: Nothing.
0791    const_iterator end() const BOOST_NOEXCEPT;
0792 
0793    //! <b>Effects</b>: Returns a const_iterator pointing to the end of the container.
0794    //!
0795    //! <b>Complexity</b>: Constant.
0796    //!
0797    //! <b>Throws</b>: Nothing.
0798    const_iterator cend() const BOOST_NOEXCEPT;
0799 
0800    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
0801    //!    reversed container.
0802    //!
0803    //! <b>Complexity</b>: Constant.
0804    //!
0805    //! <b>Throws</b>: Nothing.
0806    reverse_iterator rbegin() BOOST_NOEXCEPT;
0807 
0808    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0809    //!    of the reversed container.
0810    //!
0811    //! <b>Complexity</b>: Constant.
0812    //!
0813    //! <b>Throws</b>: Nothing.
0814    const_reverse_iterator rbegin() const BOOST_NOEXCEPT;
0815 
0816    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
0817    //!    of the reversed container.
0818    //!
0819    //! <b>Complexity</b>: Constant.
0820    //!
0821    //! <b>Throws</b>: Nothing.
0822    const_reverse_iterator crbegin() const BOOST_NOEXCEPT;
0823 
0824    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
0825    //!    of the reversed container.
0826    //!
0827    //! <b>Complexity</b>: Constant.
0828    //!
0829    //! <b>Throws</b>: Nothing.
0830    reverse_iterator rend() BOOST_NOEXCEPT;
0831 
0832    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0833    //!    of the reversed container.
0834    //!
0835    //! <b>Complexity</b>: Constant.
0836    //!
0837    //! <b>Throws</b>: Nothing.
0838    const_reverse_iterator rend() const BOOST_NOEXCEPT;
0839 
0840    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
0841    //!    of the reversed container.
0842    //!
0843    //! <b>Complexity</b>: Constant.
0844    //!
0845    //! <b>Throws</b>: Nothing.
0846    const_reverse_iterator crend() const BOOST_NOEXCEPT;
0847 
0848    //! <b>Effects</b>: Returns a iterator pointing to the root node of the container or end() if not present.
0849    //!
0850    //! <b>Complexity</b>: Constant.
0851    //!
0852    //! <b>Throws</b>: Nothing.
0853    iterator root() BOOST_NOEXCEPT;
0854 
0855    //! <b>Effects</b>: Returns a const_iterator pointing to the root node of the container or cend() if not present.
0856    //!
0857    //! <b>Complexity</b>: Constant.
0858    //!
0859    //! <b>Throws</b>: Nothing.
0860    const_iterator root() const BOOST_NOEXCEPT;
0861 
0862    //! <b>Effects</b>: Returns a const_iterator pointing to the root node of the container or cend() if not present.
0863    //!
0864    //! <b>Complexity</b>: Constant.
0865    //!
0866    //! <b>Throws</b>: Nothing.
0867    const_iterator croot() const BOOST_NOEXCEPT;
0868 
0869    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0870 
0871    //! <b>Precondition</b>: end_iterator must be a valid end iterator
0872    //!   of the container.
0873    //!
0874    //! <b>Effects</b>: Returns a const reference to the container associated to the end iterator
0875    //!
0876    //! <b>Throws</b>: Nothing.
0877    //!
0878    //! <b>Complexity</b>: Constant.
0879    BOOST_INTRUSIVE_NO_DANGLING
0880    static bstree_impl& container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
0881    {
0882       return static_cast<bstree_impl&>
0883                (data_type::get_tree_base_from_end_iterator(end_iterator));
0884    }
0885 
0886    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
0887    //!   of the container.
0888    //!
0889    //! <b>Effects</b>: Returns a const reference to the container associated to the iterator
0890    //!
0891    //! <b>Throws</b>: Nothing.
0892    //!
0893    //! <b>Complexity</b>: Constant.
0894    BOOST_INTRUSIVE_NO_DANGLING
0895    static const bstree_impl & container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
0896    {
0897       return static_cast<bstree_impl&>
0898                (data_type::get_tree_base_from_end_iterator(end_iterator));
0899    }
0900 
0901    //! <b>Precondition</b>: it must be a valid iterator
0902    //!   of the container.
0903    //!
0904    //! <b>Effects</b>: Returns a const reference to the container associated to the iterator
0905    //!
0906    //! <b>Throws</b>: Nothing.
0907    //!
0908    //! <b>Complexity</b>: Logarithmic.
0909    BOOST_INTRUSIVE_NO_DANGLING
0910    static bstree_impl & container_from_iterator(iterator it) BOOST_NOEXCEPT
0911    {  return container_from_end_iterator(it.end_iterator_from_it());   }
0912 
0913    //! <b>Precondition</b>: it must be a valid end const_iterator
0914    //!   of container.
0915    //!
0916    //! <b>Effects</b>: Returns a const reference to the container associated to the end iterator
0917    //!
0918    //! <b>Throws</b>: Nothing.
0919    //!
0920    //! <b>Complexity</b>: Logarithmic.
0921    BOOST_INTRUSIVE_NO_DANGLING
0922    static const bstree_impl & container_from_iterator(const_iterator it) BOOST_NOEXCEPT
0923    {  return container_from_end_iterator(it.end_iterator_from_it());   }
0924 
0925    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0926 
0927    //! <b>Effects</b>: Returns the key_compare object used by the container.
0928    //!
0929    //! <b>Complexity</b>: Constant.
0930    //!
0931    //! <b>Throws</b>: If key_compare copy-constructor throws.
0932    key_compare key_comp() const;
0933 
0934    //! <b>Effects</b>: Returns the value_compare object used by the container.
0935    //!
0936    //! <b>Complexity</b>: Constant.
0937    //!
0938    //! <b>Throws</b>: If value_compare copy-constructor throws.
0939    value_compare value_comp() const;
0940 
0941    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0942 
0943    //! <b>Effects</b>: Returns true if the container is empty.
0944    //!
0945    //! <b>Complexity</b>: Constant.
0946    //!
0947    //! <b>Throws</b>: Nothing.
0948    bool empty() const BOOST_NOEXCEPT
0949    {
0950       if(ConstantTimeSize){
0951          return !this->data_type::sz_traits().get_size();
0952       }
0953       else{
0954          return algo_type::unique(this->header_ptr());
0955       }
0956    }
0957 
0958    //! <b>Effects</b>: Returns the number of elements stored in the container.
0959    //!
0960    //! <b>Complexity</b>: Linear to elements contained in *this
0961    //!   if constant-time size option is disabled. Constant time otherwise.
0962    //!
0963    //! <b>Throws</b>: Nothing.
0964    size_type size() const BOOST_NOEXCEPT
0965    {
0966       BOOST_IF_CONSTEXPR(constant_time_size)
0967          return this->sz_traits().get_size();
0968       else{
0969          return (size_type)node_algorithms::size(this->header_ptr());
0970       }
0971    }
0972 
0973    //! <b>Effects</b>: Swaps the contents of two containers.
0974    //!
0975    //! <b>Complexity</b>: Constant.
0976    //!
0977    //! <b>Throws</b>: If the comparison functor's swap call throws.
0978    void swap(bstree_impl& other)
0979    {
0980       //This can throw
0981       ::boost::adl_move_swap(this->get_comp(), other.get_comp());
0982       //These can't throw
0983       node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr()));
0984       this->sz_traits().swap(other.sz_traits());
0985    }
0986 
0987    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
0988    //!   Cloner should yield to nodes equivalent to the original nodes.
0989    //!
0990    //! <b>Effects</b>: Erases all the elements from *this
0991    //!   calling Disposer::operator()(pointer), clones all the
0992    //!   elements from src calling Cloner::operator()(const_reference )
0993    //!   and inserts them on *this. Copies the predicate from the source container.
0994    //!
0995    //!   If cloner throws, all cloned elements are unlinked and disposed
0996    //!   calling Disposer::operator()(pointer).
0997    //!
0998    //! <b>Complexity</b>: Linear to erased plus inserted elements.
0999    //!
1000    //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
1001    template <class Cloner, class Disposer>
1002    void clone_from(const bstree_impl &src, Cloner cloner, Disposer disposer)
1003    {
1004       this->clear_and_dispose(disposer);
1005       if(!src.empty()){
1006          detail::exception_disposer<bstree_impl, Disposer>
1007             rollback(*this, disposer);
1008          node_algorithms::clone
1009             (src.header_ptr()
1010             ,this->header_ptr()
1011             ,detail::node_cloner <Cloner,    value_traits, AlgoType>(cloner,   &this->get_value_traits())
1012             ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1013          this->sz_traits().set_size(src.sz_traits().get_size());
1014          this->get_comp() = src.get_comp();
1015          rollback.release();
1016       }
1017    }
1018 
1019    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1020    //!   Cloner should yield to nodes equivalent to the original nodes.
1021    //!
1022    //! <b>Effects</b>: Erases all the elements from *this
1023    //!   calling Disposer::operator()(pointer), clones all the
1024    //!   elements from src calling Cloner::operator()(reference)
1025    //!   and inserts them on *this. Copies the predicate from the source container.
1026    //!
1027    //!   If cloner throws, all cloned elements are unlinked and disposed
1028    //!   calling Disposer::operator()(pointer).
1029    //!
1030    //! <b>Complexity</b>: Linear to erased plus inserted elements.
1031    //!
1032    //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
1033    //!
1034    //! <b>Note</b>: This version can modify the source container, useful to implement
1035    //!    move semantics.
1036    template <class Cloner, class Disposer>
1037    void clone_from(BOOST_RV_REF(bstree_impl) src, Cloner cloner, Disposer disposer)
1038    {
1039       this->clear_and_dispose(disposer);
1040       if(!src.empty()){
1041          detail::exception_disposer<bstree_impl, Disposer>
1042             rollback(*this, disposer);
1043          node_algorithms::clone
1044             (src.header_ptr()
1045             ,this->header_ptr()
1046             ,detail::node_cloner <Cloner,    value_traits, AlgoType, false>(cloner,   &this->get_value_traits())
1047             ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1048          this->sz_traits().set_size(src.sz_traits().get_size());
1049          this->get_comp() = src.get_comp();
1050          rollback.release();
1051       }
1052    }
1053 
1054    //! <b>Requires</b>: value must be an lvalue
1055    //!
1056    //! <b>Effects</b>: Inserts value into the container before the upper bound.
1057    //!
1058    //! <b>Complexity</b>: Average complexity for insert element is at
1059    //!   most logarithmic.
1060    //!
1061    //! <b>Throws</b>: If the internal key_compare ordering function throws. Strong guarantee.
1062    //!
1063    //! <b>Note</b>: Does not affect the validity of iterators and references.
1064    //!   No copy-constructors are called.
1065    iterator insert_equal(reference value)
1066    {
1067       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1068       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1069       iterator ret(node_algorithms::insert_equal_upper_bound
1070          (this->header_ptr(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
1071       this->sz_traits().increment();
1072       return ret;
1073    }
1074 
1075    //! <b>Requires</b>: value must be an lvalue, and "hint" must be
1076    //!   a valid iterator.
1077    //!
1078    //! <b>Effects</b>: Inserts x into the container, using "hint" as a hint to
1079    //!   where it will be inserted. If "hint" is the upper_bound
1080    //!   the insertion takes constant time (two comparisons in the worst case)
1081    //!
1082    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
1083    //!   constant time if t is inserted immediately before hint.
1084    //!
1085    //! <b>Throws</b>: If the internal key_compare ordering function throws. Strong guarantee.
1086    //!
1087    //! <b>Note</b>: Does not affect the validity of iterators and references.
1088    //!   No copy-constructors are called.
1089    iterator insert_equal(const_iterator hint, reference value)
1090    {
1091       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1092       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1093       iterator ret(node_algorithms::insert_equal
1094          (this->header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
1095       this->sz_traits().increment();
1096       return ret;
1097    }
1098 
1099    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
1100    //!   of type value_type.
1101    //!
1102    //! <b>Effects</b>: Inserts a each element of a range into the container
1103    //!   before the upper bound of the key of each element.
1104    //!
1105    //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
1106    //!   size of the range. However, it is linear in N if the range is already sorted
1107    //!   by value_comp().
1108    //!
1109    //! <b>Throws</b>: If the comparison functor call throws.
1110    //!
1111    //! <b>Note</b>: Does not affect the validity of iterators and references.
1112    //!   No copy-constructors are called.
1113    template<class Iterator>
1114    void insert_equal(Iterator b, Iterator e)
1115    {
1116       iterator iend(this->end());
1117       for (; b != e; ++b)
1118          this->insert_equal(iend, *b);
1119    }
1120 
1121    //! <b>Requires</b>: value must be an lvalue
1122    //!
1123    //! <b>Effects</b>: Inserts value into the container if the value
1124    //!   is not already present.
1125    //!
1126    //! <b>Complexity</b>: Average complexity for insert element is at
1127    //!   most logarithmic.
1128    //!
1129    //! <b>Throws</b>: If the comparison functor call throws.
1130    //!
1131    //! <b>Note</b>: Does not affect the validity of iterators and references.
1132    //!   No copy-constructors are called.
1133    std::pair<iterator, bool> insert_unique(reference value)
1134    {
1135       insert_commit_data commit_data;
1136       std::pair<node_ptr, bool> ret =
1137          (node_algorithms::insert_unique_check
1138             (this->header_ptr(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
1139       return std::pair<iterator, bool>
1140          ( ret.second ? this->insert_unique_commit(value, commit_data)
1141                       : iterator(ret.first, this->priv_value_traits_ptr())
1142          , ret.second);
1143    }
1144 
1145    //! <b>Requires</b>: value must be an lvalue, and "hint" must be
1146    //!   a valid iterator
1147    //!
1148    //! <b>Effects</b>: Tries to insert x into the container, using "hint" as a hint
1149    //!   to where it will be inserted.
1150    //!
1151    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
1152    //!   constant time (two comparisons in the worst case)
1153    //!   if t is inserted immediately before hint.
1154    //!
1155    //! <b>Throws</b>: If the comparison functor call throws.
1156    //!
1157    //! <b>Note</b>: Does not affect the validity of iterators and references.
1158    //!   No copy-constructors are called.
1159    iterator insert_unique(const_iterator hint, reference value)
1160    {
1161       insert_commit_data commit_data;
1162       std::pair<node_ptr, bool> ret =
1163          (node_algorithms::insert_unique_check
1164             (this->header_ptr(), hint.pointed_node(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
1165       return ret.second ? this->insert_unique_commit(value, commit_data)
1166                         : iterator(ret.first, this->priv_value_traits_ptr());
1167    }
1168 
1169    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
1170    //!   of type value_type.
1171    //!
1172    //! <b>Effects</b>: Tries to insert each element of a range into the container.
1173    //!
1174    //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
1175    //!   size of the range. However, it is linear in N if the range is already sorted
1176    //!   by value_comp().
1177    //!
1178    //! <b>Throws</b>: If the comparison functor call throws.
1179    //!
1180    //! <b>Note</b>: Does not affect the validity of iterators and references.
1181    //!   No copy-constructors are called.
1182    template<class Iterator>
1183    void insert_unique(Iterator b, Iterator e)
1184    {
1185       if(this->empty()){
1186          iterator iend(this->end());
1187          for (; b != e; ++b)
1188             this->insert_unique(iend, *b);
1189       }
1190       else{
1191          for (; b != e; ++b)
1192             this->insert_unique(*b);
1193       }
1194    }
1195 
1196    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1197 
1198    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
1199    //!   a user provided key instead of the value itself.
1200    //!
1201    //! <b>Returns</b>: If there is an equivalent value
1202    //!   returns a pair containing an iterator to the already present value
1203    //!   and false. If the value can be inserted returns true in the returned
1204    //!   pair boolean and fills "commit_data" that is meant to be used with
1205    //!   the "insert_commit" function.
1206    //!
1207    //! <b>Complexity</b>: Average complexity is at most logarithmic.
1208    //!
1209    //! <b>Throws</b>: If the comp ordering function throws. Strong guarantee.
1210    std::pair<iterator, bool> insert_unique_check(const key_type &key, insert_commit_data &commit_data);
1211 
1212    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
1213    //!   a user provided key instead of the value itself, using "hint"
1214    //!   as a hint to where it will be inserted.
1215    //!
1216    //! <b>Returns</b>: If there is an equivalent value
1217    //!   returns a pair containing an iterator to the already present value
1218    //!   and false. If the value can be inserted returns true in the returned
1219    //!   pair boolean and fills "commit_data" that is meant to be used with
1220    //!   the "insert_commit" function.
1221    //!
1222    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
1223    //!   constant time if t is inserted immediately before hint.
1224    //!
1225    //! <b>Throws</b>: If the comp ordering function throws. Strong guarantee.
1226    std::pair<iterator, bool> insert_unique_check(const_iterator hint, const key_type &key, insert_commit_data &commit_data);
1227 
1228    //! <b>Requires</b>: comp must be a comparison function that induces
1229    //!   the same strict weak ordering as key_compare. The difference is that
1230    //!   comp compares an arbitrary key with the contained values.
1231    //!
1232    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
1233    //!   a user provided key instead of the value itself.
1234    //!
1235    //! <b>Returns</b>: If there is an equivalent value
1236    //!   returns a pair containing an iterator to the already present value
1237    //!   and false. If the value can be inserted returns true in the returned
1238    //!   pair boolean and fills "commit_data" that is meant to be used with
1239    //!   the "insert_commit" function.
1240    //!
1241    //! <b>Complexity</b>: Average complexity is at most logarithmic.
1242    //!
1243    //! <b>Throws</b>: If the comp ordering function throws. Strong guarantee.
1244    //!
1245    //! <b>Notes</b>: This function is used to improve performance when constructing
1246    //!   a value_type is expensive: if there is an equivalent value
1247    //!   the constructed object must be discarded. Many times, the part of the
1248    //!   node that is used to impose the order is much cheaper to construct
1249    //!   than the value_type and this function offers the possibility to use that
1250    //!   part to check if the insertion will be successful.
1251    //!
1252    //!   If the check is successful, the user can construct the value_type and use
1253    //!   "insert_commit" to insert the object in constant-time. This gives a total
1254    //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
1255    //!
1256    //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
1257    //!   objects are inserted or erased from the container.
1258    template<class KeyType, class KeyTypeKeyCompare>
1259    std::pair<iterator, bool> insert_unique_check
1260       (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
1261 
1262    //! <b>Requires</b>: comp must be a comparison function that induces
1263    //!   the same strict weak ordering as key_compare. The difference is that
1264    //!   comp compares an arbitrary key with the contained values.
1265    //!
1266    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
1267    //!   a user provided key instead of the value itself, using "hint"
1268    //!   as a hint to where it will be inserted.
1269    //!
1270    //! <b>Returns</b>: If there is an equivalent value
1271    //!   returns a pair containing an iterator to the already present value
1272    //!   and false. If the value can be inserted returns true in the returned
1273    //!   pair boolean and fills "commit_data" that is meant to be used with
1274    //!   the "insert_commit" function.
1275    //!
1276    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
1277    //!   constant time if t is inserted immediately before hint.
1278    //!
1279    //! <b>Throws</b>: If the comp ordering function throws. Strong guarantee.
1280    //!
1281    //! <b>Notes</b>: This function is used to improve performance when constructing
1282    //!   a value_type is expensive: if there is an equivalent value
1283    //!   the constructed object must be discarded. Many times, the part of the
1284    //!   constructing that is used to impose the order is much cheaper to construct
1285    //!   than the value_type and this function offers the possibility to use that key
1286    //!   to check if the insertion will be successful.
1287    //!
1288    //!   If the check is successful, the user can construct the value_type and use
1289    //!   "insert_commit" to insert the object in constant-time. This can give a total
1290    //!   constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
1291    //!
1292    //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
1293    //!   objects are inserted or erased from the container.
1294    template<class KeyType, class KeyTypeKeyCompare>
1295    std::pair<iterator, bool> insert_unique_check
1296       (const_iterator hint, const KeyType &key
1297       ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
1298 
1299    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1300 
1301    //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
1302    //!   must have been obtained from a previous call to "insert_check".
1303    //!   No objects should have been inserted or erased from the container between
1304    //!   the "insert_check" that filled "commit_data" and the call to "insert_commit".
1305    //!
1306    //! <b>Effects</b>: Inserts the value in the container using the information obtained
1307    //!   from the "commit_data" that a previous "insert_check" filled.
1308    //!
1309    //! <b>Returns</b>: An iterator to the newly inserted object.
1310    //!
1311    //! <b>Complexity</b>: Constant time.
1312    //!
1313    //! <b>Throws</b>: Nothing.
1314    //!
1315    //! <b>Notes</b>: This function has only sense if a "insert_check" has been
1316    //!   previously executed to fill "commit_data". No value should be inserted or
1317    //!   erased between the "insert_check" and "insert_commit" calls.
1318    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
1319    {
1320       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1321       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1322 
1323       #if !(defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ))
1324       //Test insertion position is correct
1325       iterator p(commit_data.node, this->priv_value_traits_ptr());
1326       if(!commit_data.link_left){
1327          ++p;
1328       }
1329       //Check if the insertion point is correct to detect wrong
1330       //uses insert_unique_check
1331       BOOST_ASSERT(( p == this->end()   || !this->get_comp()(*p, value)   ));
1332       BOOST_ASSERT(( p == this->begin() || !this->get_comp()(value, *--p) ));
1333       #endif
1334 
1335       node_algorithms::insert_unique_commit
1336                (this->header_ptr(), to_insert, commit_data);
1337       this->sz_traits().increment();
1338       return iterator(to_insert, this->priv_value_traits_ptr());
1339    }
1340 
1341    //! <b>Requires</b>: value must be an lvalue, "pos" must be
1342    //!   a valid iterator (or end) and must be the succesor of value
1343    //!   once inserted according to the predicate
1344    //!
1345    //! <b>Effects</b>: Inserts x into the container before "pos".
1346    //!
1347    //! <b>Complexity</b>: Constant time.
1348    //!
1349    //! <b>Throws</b>: Nothing.
1350    //!
1351    //! <b>Note</b>: This function does not check preconditions so if "pos" is not
1352    //! the successor of "value" container ordering invariant will be broken.
1353    //! This is a low-level function to be used only for performance reasons
1354    //! by advanced users.
1355    iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT
1356    {
1357       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1358       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1359       this->sz_traits().increment();
1360       return iterator(node_algorithms::insert_before
1361          (this->header_ptr(), pos.pointed_node(), to_insert), this->priv_value_traits_ptr());
1362    }
1363 
1364    //! <b>Requires</b>: value must be an lvalue, and it must be no less
1365    //!   than the greatest inserted key
1366    //!
1367    //! <b>Effects</b>: Inserts x into the container in the last position.
1368    //!
1369    //! <b>Complexity</b>: Constant time.
1370    //!
1371    //! <b>Throws</b>: Nothing.
1372    //!
1373    //! <b>Note</b>: This function does not check preconditions so if value is
1374    //!   less than the greatest inserted key container ordering invariant will be broken.
1375    //!   This function is slightly more efficient than using "insert_before".
1376    //!   This is a low-level function to be used only for performance reasons
1377    //!   by advanced users.
1378    void push_back(reference value) BOOST_NOEXCEPT
1379    {
1380       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1381       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1382       this->sz_traits().increment();
1383       node_algorithms::push_back(this->header_ptr(), to_insert);
1384    }
1385 
1386    //! <b>Requires</b>: value must be an lvalue, and it must be no greater
1387    //!   than the minimum inserted key
1388    //!
1389    //! <b>Effects</b>: Inserts x into the container in the first position.
1390    //!
1391    //! <b>Complexity</b>: Constant time.
1392    //!
1393    //! <b>Throws</b>: Nothing.
1394    //!
1395    //! <b>Note</b>: This function does not check preconditions so if value is
1396    //!   greater than the minimum inserted key container ordering invariant will be broken.
1397    //!   This function is slightly more efficient than using "insert_before".
1398    //!   This is a low-level function to be used only for performance reasons
1399    //!   by advanced users.
1400    void push_front(reference value) BOOST_NOEXCEPT
1401    {
1402       node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1403       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1404       this->sz_traits().increment();
1405       node_algorithms::push_front(this->header_ptr(), to_insert);
1406    }
1407 
1408    //! <b>Effects</b>: Erases the element pointed to by i.
1409    //!
1410    //! <b>Complexity</b>: Average complexity for erase element is constant time.
1411    //!
1412    //! <b>Throws</b>: Nothing.
1413    //!
1414    //! <b>Note</b>: Invalidates the iterators (but not the references)
1415    //!    to the erased elements. No destructors are called.
1416    iterator erase(const_iterator i) BOOST_NOEXCEPT
1417    {
1418       const_iterator ret(i);
1419       ++ret;
1420       node_ptr to_erase(i.pointed_node());
1421       BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
1422       node_algorithms::erase(this->header_ptr(), to_erase);
1423       this->sz_traits().decrement();
1424       BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1425          node_algorithms::init(to_erase);
1426       return ret.unconst();
1427    }
1428 
1429    //! <b>Effects</b>: Erases the range pointed to by b end e.
1430    //!
1431    //! <b>Complexity</b>: Average complexity for erase range is at most
1432    //!   O(log(size() + N)), where N is the number of elements in the range.
1433    //!
1434    //! <b>Throws</b>: Nothing.
1435    //!
1436    //! <b>Note</b>: Invalidates the iterators (but not the references)
1437    //!    to the erased elements. No destructors are called.
1438    iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT
1439    {  size_type n;   return this->private_erase(b, e, n);   }
1440 
1441    //! <b>Effects</b>: Erases all the elements with the given value.
1442    //!
1443    //! <b>Returns</b>: The number of erased elements.
1444    //!
1445    //! <b>Complexity</b>: O(log(size() + N).
1446    //!
1447    //! <b>Throws</b>: Nothing.
1448    //!
1449    //! <b>Note</b>: Invalidates the iterators (but not the references)
1450    //!    to the erased elements. No destructors are called.
1451    size_type erase(const key_type &key) BOOST_NOEXCEPT
1452    {  return this->erase(key, this->key_comp());   }
1453 
1454    //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to
1455    //!   comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk),
1456    //!   with nk the key_type of a value_type inserted into `*this`.
1457    //!
1458    //! <b>Effects</b>: Erases all the elements with the given key.
1459    //!   according to the comparison functor "comp".
1460    //!
1461    //! <b>Returns</b>: The number of erased elements.
1462    //!
1463    //! <b>Complexity</b>: O(log(size() + N).
1464    //!
1465    //! <b>Throws</b>: Nothing.
1466    //!
1467    //! <b>Note</b>: Invalidates the iterators (but not the references)
1468    //!    to the erased elements. No destructors are called.
1469    template<class KeyType, class KeyTypeKeyCompare>
1470    BOOST_INTRUSIVE_DOC1ST(size_type
1471       , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
1472       erase(const KeyType& key, KeyTypeKeyCompare comp)
1473    {
1474       std::pair<iterator,iterator> p = this->equal_range(key, comp);
1475       size_type n;
1476       this->private_erase(p.first, p.second, n);
1477       return n;
1478    }
1479 
1480    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1481    //!
1482    //! <b>Effects</b>: Erases the element pointed to by i.
1483    //!   Disposer::operator()(pointer) is called for the removed element.
1484    //!
1485    //! <b>Complexity</b>: Average complexity for erase element is constant time.
1486    //!
1487    //! <b>Throws</b>: Nothing.
1488    //!
1489    //! <b>Note</b>: Invalidates the iterators
1490    //!    to the erased elements.
1491    template<class Disposer>
1492    iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT
1493    {
1494       node_ptr to_erase(i.pointed_node());
1495       iterator ret(this->erase(i));
1496       disposer(this->get_value_traits().to_value_ptr(to_erase));
1497       return ret;
1498    }
1499 
1500    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1501    //!
1502    //! <b>Effects</b>: Erases all the elements with the given value.
1503    //!   Disposer::operator()(pointer) is called for the removed elements.
1504    //!
1505    //! <b>Returns</b>: The number of erased elements.
1506    //!
1507    //! <b>Complexity</b>: O(log(size() + N).
1508    //!
1509    //! <b>Throws</b>: Nothing.
1510    //!
1511    //! <b>Note</b>: Invalidates the iterators (but not the references)
1512    //!    to the erased elements. No destructors are called.
1513    template<class Disposer>
1514    size_type erase_and_dispose(const key_type &key, Disposer disposer)
1515    {
1516       std::pair<iterator,iterator> p = this->equal_range(key);
1517       size_type n;
1518       this->private_erase(p.first, p.second, n, disposer);
1519       return n;
1520    }
1521 
1522    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1523    //!
1524    //! <b>Effects</b>: Erases the range pointed to by b end e.
1525    //!   Disposer::operator()(pointer) is called for the removed elements.
1526    //!
1527    //! <b>Complexity</b>: Average complexity for erase range is at most
1528    //!   O(log(size() + N)), where N is the number of elements in the range.
1529    //!
1530    //! <b>Throws</b>: Nothing.
1531    //!
1532    //! <b>Note</b>: Invalidates the iterators
1533    //!    to the erased elements.
1534    template<class Disposer>
1535    iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT
1536    {  size_type n;   return this->private_erase(b, e, n, disposer);   }
1537 
1538    //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to
1539    //!   comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk)
1540    //!   and nk the key_type of a value_type inserted into `*this`.
1541    //!
1542    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
1543    //!
1544    //! <b>Effects</b>: Erases all the elements with the given key.
1545    //!   according to the comparison functor "comp".
1546    //!   Disposer::operator()(pointer) is called for the removed elements.
1547    //!
1548    //! <b>Returns</b>: The number of erased elements.
1549    //!
1550    //! <b>Complexity</b>: O(log(size() + N).
1551    //!
1552    //! <b>Throws</b>: Nothing.
1553    //!
1554    //! <b>Note</b>: Invalidates the iterators
1555    //!    to the erased elements.
1556    template<class KeyType, class KeyTypeKeyCompare, class Disposer>
1557    BOOST_INTRUSIVE_DOC1ST(size_type
1558       , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
1559       erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
1560    {
1561       std::pair<iterator,iterator> p = this->equal_range(key, comp);
1562       size_type n;
1563       this->private_erase(p.first, p.second, n, disposer);
1564       return n;
1565    }
1566 
1567    //! <b>Effects</b>: Erases all of the elements.
1568    //!
1569    //! <b>Complexity</b>: Linear to the number of elements on the container.
1570    //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
1571    //!
1572    //! <b>Throws</b>: Nothing.
1573    //!
1574    //! <b>Note</b>: Invalidates the iterators (but not the references)
1575    //!    to the erased elements. No destructors are called.
1576    void clear() BOOST_NOEXCEPT
1577    {
1578       BOOST_IF_CONSTEXPR(safemode_or_autounlink){
1579          this->clear_and_dispose(detail::null_disposer());
1580       }
1581       else{
1582          node_algorithms::init_header(this->header_ptr());
1583          this->sz_traits().set_size(0);
1584       }
1585    }
1586 
1587    //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
1588    //!   each node to be erased.
1589    //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
1590    //!   where N is the number of elements in the container.
1591    //!
1592    //! <b>Throws</b>: Nothing.
1593    //!
1594    //! <b>Note</b>: Invalidates the iterators (but not the references)
1595    //!    to the erased elements. Calls N times to disposer functor.
1596    template<class Disposer>
1597    void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT
1598    {
1599       node_algorithms::clear_and_dispose(this->header_ptr()
1600          , detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1601       node_algorithms::init_header(this->header_ptr());
1602       this->sz_traits().set_size(0);
1603    }
1604 
1605    //! <b>Effects</b>: Returns the number of contained elements with the given value
1606    //!
1607    //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
1608    //!   to number of objects with the given value.
1609    //!
1610    //! <b>Throws</b>: If `key_compare` throws.
1611    size_type count(const key_type &key) const
1612    {  return size_type(this->count(key, this->key_comp()));   }
1613 
1614    //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to
1615    //!   comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk),
1616    //!   and nk the key_type of a value_type inserted into `*this`.
1617    //!
1618    //! <b>Effects</b>: Returns the number of contained elements with the given key
1619    //!
1620    //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
1621    //!   to number of objects with the given key.
1622    //!
1623    //! <b>Throws</b>: If `comp` throws.
1624    template<class KeyType, class KeyTypeKeyCompare>
1625    size_type count(const KeyType &key, KeyTypeKeyCompare comp) const
1626    {
1627       std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
1628       size_type n = 0;
1629       for(; ret.first != ret.second; ++ret.first){ ++n; }
1630       return n;
1631    }
1632 
1633    #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1634 
1635    //Add non-const overloads to theoretically const members
1636    //as some algorithms have different behavior when non-const versions are used (like splay trees).
1637    size_type count(const key_type &key)
1638    {  return size_type(this->count(key, this->key_comp()));   }
1639 
1640    template<class KeyType, class KeyTypeKeyCompare>
1641    size_type count(const KeyType &key, KeyTypeKeyCompare comp)
1642    {
1643       std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
1644       size_type n = 0;
1645       for(; ret.first != ret.second; ++ret.first){ ++n; }
1646       return n;
1647    }
1648 
1649    #else //defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1650 
1651    //! <b>Effects</b>: Returns an iterator to the first element whose
1652    //!   key is not less than k or end() if that element does not exist.
1653    //!
1654    //! <b>Complexity</b>: Logarithmic.
1655    //!
1656    //! <b>Throws</b>: If `key_compare` throws.
1657    iterator lower_bound(const key_type &key);
1658 
1659    //! <b>Effects</b>: Returns an iterator to the first element whose
1660    //!   key is not less than k or end() if that element does not exist.
1661    //!
1662    //! <b>Complexity</b>: Logarithmic.
1663    //!
1664    //! <b>Throws</b>: If `key_compare` throws.
1665    const_iterator lower_bound(const key_type &key) const;
1666 
1667    //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
1668    template<class KeyType, class KeyTypeKeyCompare>
1669    iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
1670 
1671    //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
1672    template<class KeyType, class KeyTypeKeyCompare>
1673    const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
1674 
1675    //! <b>Effects</b>: Returns an iterator to the first element whose
1676    //!   key is greater than k or end() if that element does not exist.
1677    //!
1678    //! <b>Complexity</b>: Logarithmic.
1679    //!
1680    //! <b>Throws</b>: If `key_compare` throws.
1681    iterator upper_bound(const key_type &key);
1682 
1683    //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to
1684    //!   !comp(key, nk), with nk the key_type of a value_type inserted into `*this`.
1685    //!
1686    //! <b>Effects</b>: Returns an iterator to the first element whose
1687    //!   key is greater than k according to comp or end() if that element
1688    //!   does not exist.
1689    //!
1690    //! <b>Complexity</b>: Logarithmic.
1691    //!
1692    //! <b>Throws</b>: If `comp` throws.
1693    template<class KeyType, class KeyTypeKeyCompare>
1694    iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
1695 
1696    //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
1697    const_iterator upper_bound(const key_type &key) const;
1698 
1699    //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
1700    template<class KeyType, class KeyTypeKeyCompare>
1701    const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
1702 
1703    //! <b>Effects</b>: Finds an iterator to the first element whose key is
1704    //!   k or end() if that element does not exist.
1705    //!
1706    //! <b>Complexity</b>: Logarithmic.
1707    //!
1708    //! <b>Throws</b>: If `key_compare` throws.
1709    iterator find(const key_type &key);
1710 
1711    //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to
1712    //!   comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk),
1713    //!   and nk the key_type of a value_type inserted into `*this`.
1714    //!
1715    //! <b>Effects</b>: Finds an iterator to the first element whose key is
1716    //!   k or end() if that element does not exist.
1717    //!
1718    //! <b>Complexity</b>: Logarithmic.
1719    //!
1720    //! <b>Throws</b>: If `comp` throws.
1721    template<class KeyType, class KeyTypeKeyCompare>
1722    iterator find(const KeyType &key, KeyTypeKeyCompare comp);
1723 
1724    //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
1725    const_iterator find(const key_type &key) const;
1726 
1727    //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
1728    template<class KeyType, class KeyTypeKeyCompare>
1729    const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
1730 
1731    //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1732    //!   an empty range that indicates the position where those elements would be
1733    //!   if they there is no elements with key k.
1734    //!
1735    //! <b>Complexity</b>: Logarithmic.
1736    //!
1737    //! <b>Throws</b>: If `key_compare` throws.
1738    std::pair<iterator,iterator> equal_range(const key_type &key);
1739 
1740    //! <b>Requires</b>: key is a value such that `*this` is partitioned with respect to
1741    //!   comp(nk, key) and !comp(key, nk), with comp(nk, key) implying !comp(key, nk),
1742    //!   with nk the key_type of a value_type inserted into `*this`.
1743    //!
1744    //! <b>Effects</b>: Finds a range containing all elements whose key is k or
1745    //!   an empty range that indicates the position where those elements would be
1746    //!   if they there is no elements with key k.
1747    //!
1748    //! <b>Complexity</b>: Logarithmic.
1749    //!
1750    //! <b>Throws</b>: If `comp` throws.
1751    template<class KeyType, class KeyTypeKeyCompare>
1752    std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
1753 
1754    //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
1755    std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const;
1756 
1757    //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
1758    template<class KeyType, class KeyTypeKeyCompare>
1759    std::pair<const_iterator, const_iterator>
1760       equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
1761 
1762    //! <b>Requires</b>:
1763    //!   `upper_key` shall not precede `lower_key` according to key_compare.
1764    //!   [key_comp()(upper_key, lower_key) shall be false]
1765    //!
1766    //!   If `lower_key` is equivalent to `upper_key`
1767    //!   [!key_comp()(upper_key, lower_key) && !key_comp()(lower_key, upper_key)] then
1768    //!   ('left_closed' || 'right_closed') must be false.
1769    //!
1770    //! <b>Effects</b>: Returns an a pair with the following criteria:
1771    //!
1772    //!   first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise
1773    //!
1774    //!   second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise
1775    //!
1776    //! <b>Complexity</b>: Logarithmic.
1777    //!
1778    //! <b>Throws</b>: If `key_compare` throws.
1779    //!
1780    //! <b>Note</b>: This function can be more efficient than calling upper_bound
1781    //!   and lower_bound for lower_value and upper_value.
1782    //!
1783    //! <b>Note</b>: Experimental function, the interface might change in future releases.
1784    std::pair<iterator,iterator> bounded_range
1785       (const key_type &lower_key, const key_type &upper_value, bool left_closed, bool right_closed);
1786 
1787    //! <b>Requires</b>:
1788    //!   `lower_key` is a value such that `*this` is partitioned with respect to
1789    //!   comp(nk, lower_key) if left_closed is true, with respect to !comp(lower_key, nk) otherwise.
1790    //!
1791    //! `upper_key` is a value such that `*this` is partitioned with respect to
1792    //!   !comp(upper_key, nk) if right_closed is true, with respect to comp(nk, upper_key) otherwise.
1793    //!
1794    //!   `upper_key` shall not precede `lower_key` according to comp
1795    //!   [comp(upper_key, lower_key) shall be false]
1796    //!
1797    //!   If `lower_key` is equivalent to `upper_key`
1798    //!   [!comp(upper_key, lower_key) && !comp(lower_key, upper_key)] then
1799    //!   ('left_closed' || 'right_closed') must be false.
1800    //!
1801    //! <b>Effects</b>: Returns an a pair with the following criteria:
1802    //!
1803    //!   first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise
1804    //!
1805    //!   second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise
1806    //!
1807    //! <b>Complexity</b>: Logarithmic.
1808    //!
1809    //! <b>Throws</b>: If `comp` throws.
1810    //!
1811    //! <b>Note</b>: This function can be more efficient than calling upper_bound
1812    //!   and lower_bound for lower_key and upper_key.
1813    //!
1814    //! <b>Note</b>: Experimental function, the interface might change in future releases.
1815    template<class KeyType, class KeyTypeKeyCompare>
1816    std::pair<iterator,iterator> bounded_range
1817       (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
1818    
1819    //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
1820    std::pair<const_iterator,const_iterator> bounded_range
1821       (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
1822 
1823    //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
1824    template<class KeyType, class KeyTypeKeyCompare>
1825    std::pair<const_iterator,const_iterator> bounded_range
1826       (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
1827 
1828    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1829    //!   appropriate type. Otherwise the behavior is undefined.
1830    //!
1831    //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1832    //!   that points to the value
1833    //!
1834    //! <b>Complexity</b>: Constant.
1835    //!
1836    //! <b>Throws</b>: Nothing.
1837    //!
1838    //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1839    //!   is stateless.
1840    static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
1841 
1842    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1843    //!   appropriate type. Otherwise the behavior is undefined.
1844    //!
1845    //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1846    //!   set that points to the value
1847    //!
1848    //! <b>Complexity</b>: Constant.
1849    //!
1850    //! <b>Throws</b>: Nothing.
1851    //!
1852    //! <b>Note</b>: This static function is available only if the <i>value traits</i>
1853    //!   is stateless.
1854    static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
1855 
1856    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1857    //!   appropriate type. Otherwise the behavior is undefined.
1858    //!
1859    //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
1860    //!   that points to the value
1861    //!
1862    //! <b>Complexity</b>: Constant.
1863    //!
1864    //! <b>Throws</b>: Nothing.
1865    iterator iterator_to(reference value) BOOST_NOEXCEPT;
1866 
1867    //! <b>Requires</b>: value must be an lvalue and shall be in a set of
1868    //!   appropriate type. Otherwise the behavior is undefined.
1869    //!
1870    //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
1871    //!   set that points to the value
1872    //!
1873    //! <b>Complexity</b>: Constant.
1874    //!
1875    //! <b>Throws</b>: Nothing.
1876    const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
1877 
1878    //! <b>Requires</b>: value shall not be in a container.
1879    //!
1880    //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
1881    //!   state.
1882    //!
1883    //! <b>Throws</b>: Nothing.
1884    //!
1885    //! <b>Complexity</b>: Constant time.
1886    //!
1887    //! <b>Note</b>: This function puts the hook in the well-known default state
1888    //!   used by auto_unlink and safe hooks.
1889    static void init_node(reference value) BOOST_NOEXCEPT;
1890 
1891    #endif   //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1892 
1893    //! <b>Effects</b>: Unlinks the leftmost node from the container.
1894    //!
1895    //! <b>Complexity</b>: Average complexity is constant time.
1896    //!
1897    //! <b>Throws</b>: Nothing.
1898    //!
1899    //! <b>Notes</b>: This function breaks the container and the container can
1900    //!   only be used for more unlink_leftmost_without_rebalance calls.
1901    //!   This function is normally used to achieve a step by step
1902    //!   controlled destruction of the container.
1903    pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT
1904    {
1905       node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
1906                            (this->header_ptr()));
1907       if(!to_be_disposed)
1908          return 0;
1909       this->sz_traits().decrement();
1910       BOOST_IF_CONSTEXPR(safemode_or_autounlink)//If this is commented does not work with normal_link
1911          node_algorithms::init(to_be_disposed);
1912       return this->get_value_traits().to_value_ptr(to_be_disposed);
1913    }
1914 
1915    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1916 
1917    //! <b>Requires</b>: replace_this must be a valid iterator of *this
1918    //!   and with_this must not be inserted in any container.
1919    //!
1920    //! <b>Effects</b>: Replaces replace_this in its position in the
1921    //!   container with with_this. The container does not need to be rebalanced.
1922    //!
1923    //! <b>Complexity</b>: Constant.
1924    //!
1925    //! <b>Throws</b>: Nothing.
1926    //!
1927    //! <b>Note</b>: This function will break container ordering invariants if
1928    //!   with_this is not equivalent to *replace_this according to the
1929    //!   ordering rules. This function is faster than erasing and inserting
1930    //!   the node, since no rebalancing or comparison is needed.
1931    void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
1932 
1933    //! <b>Effects</b>: Rebalances the tree.
1934    //!
1935    //! <b>Throws</b>: Nothing.
1936    //!
1937    //! <b>Complexity</b>: Linear.
1938    void rebalance() BOOST_NOEXCEPT;
1939 
1940    //! <b>Requires</b>: old_root is a node of a tree.
1941    //!
1942    //! <b>Effects</b>: Rebalances the subtree rooted at old_root.
1943    //!
1944    //! <b>Returns</b>: The new root of the subtree.
1945    //!
1946    //! <b>Throws</b>: Nothing.
1947    //!
1948    //! <b>Complexity</b>: Linear to the elements in the subtree.
1949    iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT;
1950 
1951    #endif   //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1952 
1953    //! <b>Effects</b>: removes "value" from the container.
1954    //!
1955    //! <b>Throws</b>: Nothing.
1956    //!
1957    //! <b>Complexity</b>: Logarithmic time.
1958    //!
1959    //! <b>Note</b>: This static function is only usable with non-constant
1960    //! time size containers that have stateless comparison functors.
1961    //!
1962    //! If the user calls
1963    //! this function with a constant time size container or stateful comparison
1964    //! functor a compilation error will be issued.
1965    static void remove_node(reference value) BOOST_NOEXCEPT
1966    {
1967       BOOST_INTRUSIVE_STATIC_ASSERT((!constant_time_size));
1968       node_ptr to_remove(value_traits::to_node_ptr(value));
1969       node_algorithms::unlink(to_remove);
1970       BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1971          node_algorithms::init(to_remove);
1972    }
1973 
1974    //! <b>Requires</b>: "source" container's Options can only can differ in the comparison
1975    //!   function from *this.
1976    //! 
1977    //! <b>Effects</b>: Attempts to extract each element in source and insert it into a using
1978    //!   the comparison object of *this. If there is an element in a with key equivalent to the
1979    //!   key of an element from source, then that element is not extracted from source.
1980    //! 
1981    //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
1982    //!   to those same elements but as members of *this. Iterators referring to the transferred
1983    //!   elements will continue to refer to their elements, but they now behave as iterators into *this,
1984    //!   not into source.
1985    //!
1986    //! <b>Throws</b>: Nothing unless the comparison object throws.
1987    //!
1988    //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
1989    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1990    template<class T, class ...Options2> void merge_unique(bstree<T, Options2...> &);
1991    #else
1992    template<class Compare2>
1993    void merge_unique(bstree_impl
1994       <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &source)
1995    #endif
1996    {
1997       node_ptr it   (node_algorithms::begin_node(source.header_ptr()))
1998              , itend(node_algorithms::end_node  (source.header_ptr()));
1999 
2000       while(it != itend){
2001          node_ptr const p(it);
2002          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
2003          it = node_algorithms::next_node(it);
2004          if( node_algorithms::transfer_unique(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p) ){
2005             source.sz_traits().decrement();
2006             this->sz_traits().increment();
2007          }
2008       }
2009    }
2010 
2011    //! <b>Requires</b>: "source" container's Options can only can differ in the comparison
2012    //!   function from *this.
2013    //! 
2014    //! <b>Effects</b>: Extracts each element in source and insert it into a using
2015    //!   the comparison object of *this.
2016    //! 
2017    //! <b>Postcondition</b>: Pointers and references to the transferred elements of source refer
2018    //!   to those same elements but as members of *this. Iterators referring to the transferred
2019    //!   elements will continue to refer to their elements, but they now behave as iterators into *this,
2020    //!   not into source.
2021    //!
2022    //! <b>Throws</b>: Nothing unless the comparison object throws.
2023    //!
2024    //! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
2025    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2026    template<class T, class ...Options2> void merge_equal(bstree<T, Options2...> &);
2027    #else
2028    template<class Compare2>
2029    void merge_equal(bstree_impl
2030       <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &source)
2031    #endif
2032    {
2033       node_ptr it   (node_algorithms::begin_node(source.header_ptr()))
2034              , itend(node_algorithms::end_node  (source.header_ptr()));
2035 
2036       while(it != itend){
2037          node_ptr const p(it);
2038          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
2039          it = node_algorithms::next_node(it);
2040          node_algorithms::transfer_equal(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p);
2041          source.sz_traits().decrement();
2042          this->sz_traits().increment();
2043       }
2044    }
2045 
2046    //! <b>Effects</b>: Asserts the integrity of the container with additional checks provided by the user.
2047    //!
2048    //! <b>Complexity</b>: Linear time.
2049    //!
2050    //! <b>Note</b>: The method might not have effect when asserts are turned off (e.g., with NDEBUG).
2051    //!   Experimental function, interface might change in future versions.
2052    template <class ExtraChecker>
2053    void check(ExtraChecker extra_checker) const
2054    {
2055       typedef detail::key_nodeptr_comp<key_compare, value_traits, key_of_value> nodeptr_comp_t;
2056       nodeptr_comp_t nodeptr_comp(this->key_comp(), &this->get_value_traits());
2057       typedef typename get_node_checker<AlgoType, ValueTraits, nodeptr_comp_t, ExtraChecker>::type node_checker_t;
2058       typename node_checker_t::return_type checker_return;
2059       node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return);
2060       BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->sz_traits().get_size() == checker_return.node_count);
2061    }
2062 
2063    //! <b>Effects</b>: Asserts the integrity of the container.
2064    //!
2065    //! <b>Complexity</b>: Linear time.
2066    //!
2067    //! <b>Note</b>: The method has no effect when asserts are turned off (e.g., with NDEBUG).
2068    //!   Experimental function, interface might change in future versions.
2069    void check() const
2070    {
2071       check(detail::empty_node_checker<ValueTraits>());
2072    }
2073 
2074    friend bool operator==(const bstree_impl &x, const bstree_impl &y)
2075    {
2076       if(constant_time_size && x.size() != y.size()){
2077          return false;
2078       }
2079       return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
2080    }
2081 
2082    friend bool operator!=(const bstree_impl &x, const bstree_impl &y)
2083    {  return !(x == y); }
2084 
2085    friend bool operator<(const bstree_impl &x, const bstree_impl &y)
2086    {  return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
2087 
2088    friend bool operator>(const bstree_impl &x, const bstree_impl &y)
2089    {  return y < x;  }
2090 
2091    friend bool operator<=(const bstree_impl &x, const bstree_impl &y)
2092    {  return !(x > y);  }
2093 
2094    friend bool operator>=(const bstree_impl &x, const bstree_impl &y)
2095    {  return !(x < y);  }
2096 
2097    friend void swap(bstree_impl &x, bstree_impl &y)
2098    {  x.swap(y);  }
2099 
2100    /// @cond
2101    private:
2102    template<class Disposer>
2103    iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
2104    {
2105       for(n = 0; b != e; ++n)
2106         this->erase_and_dispose(b++, disposer);
2107       return b.unconst();
2108    }
2109 
2110    iterator private_erase(const_iterator b, const_iterator e, size_type &n)
2111    {
2112       for(n = 0; b != e; ++n)
2113         this->erase(b++);
2114       return b.unconst();
2115    }
2116    /// @endcond
2117 };
2118 
2119 //! Helper metafunction to define a \c bstree that yields to the same type when the
2120 //! same options (either explicitly or implicitly) are used.
2121 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2122 template<class T, class ...Options>
2123 #else
2124 template<class T, class O1 = void, class O2 = void
2125                 , class O3 = void, class O4 = void
2126                 , class O5 = void, class O6 = void>
2127 #endif
2128 struct make_bstree
2129 {
2130    /// @cond
2131    typedef typename pack_options
2132       < bstree_defaults,
2133       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2134       O1, O2, O3, O4, O5, O6
2135       #else
2136       Options...
2137       #endif
2138       >::type packed_options;
2139 
2140    typedef typename detail::get_value_traits
2141       <T, typename packed_options::proto_value_traits>::type value_traits;
2142 
2143    typedef bstree_impl
2144          < value_traits
2145          , typename packed_options::key_of_value
2146          , typename packed_options::compare
2147          , typename packed_options::size_type
2148          , packed_options::constant_time_size
2149          , BsTreeAlgorithms
2150          , typename packed_options::header_holder_type
2151          > implementation_defined;
2152    /// @endcond
2153    typedef implementation_defined type;
2154 };
2155 
2156 
2157 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
2158 
2159 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2160 template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
2161 #else
2162 template<class T, class ...Options>
2163 #endif
2164 class bstree
2165    :  public make_bstree<T,
2166       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2167       O1, O2, O3, O4, O5, O6
2168       #else
2169       Options...
2170       #endif
2171       >::type
2172 {
2173    typedef typename make_bstree
2174       <T,
2175       #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2176       O1, O2, O3, O4, O5, O6
2177       #else
2178       Options...
2179       #endif
2180       >::type   Base;
2181    BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree)
2182 
2183    public:
2184    typedef typename Base::key_compare        key_compare;
2185    typedef typename Base::value_traits       value_traits;
2186    typedef typename Base::iterator           iterator;
2187    typedef typename Base::const_iterator     const_iterator;
2188 
2189    //Assert if passed value traits are compatible with the type
2190    BOOST_INTRUSIVE_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
2191 
2192    inline bstree()
2193       :  Base()
2194    {}
2195 
2196    inline explicit bstree( const key_compare &cmp, const value_traits &v_traits = value_traits())
2197       :  Base(cmp, v_traits)
2198    {}
2199 
2200    template<class Iterator>
2201    inline bstree( bool unique, Iterator b, Iterator e
2202          , const key_compare &cmp = key_compare()
2203          , const value_traits &v_traits = value_traits())
2204       :  Base(unique, b, e, cmp, v_traits)
2205    {}
2206 
2207    inline bstree(BOOST_RV_REF(bstree) x)
2208       :  Base(BOOST_MOVE_BASE(Base, x))
2209    {}
2210 
2211    inline bstree& operator=(BOOST_RV_REF(bstree) x)
2212    {  return static_cast<bstree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x)));  }
2213 
2214    template <class Cloner, class Disposer>
2215    inline void clone_from(const bstree &src, Cloner cloner, Disposer disposer)
2216    {  Base::clone_from(src, cloner, disposer);  }
2217 
2218    template <class Cloner, class Disposer>
2219    inline void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer)
2220    {  Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer);  }
2221 
2222    BOOST_INTRUSIVE_NO_DANGLING
2223    inline static bstree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
2224    {  return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator));   }
2225 
2226    BOOST_INTRUSIVE_NO_DANGLING
2227    inline static const bstree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
2228    {  return static_cast<const bstree &>(Base::container_from_end_iterator(end_iterator));   }
2229 
2230    BOOST_INTRUSIVE_NO_DANGLING
2231    inline static bstree &container_from_iterator(iterator it) BOOST_NOEXCEPT
2232    {  return static_cast<bstree &>(Base::container_from_iterator(it));   }
2233 
2234    BOOST_INTRUSIVE_NO_DANGLING
2235    inline static const bstree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
2236    {  return static_cast<const bstree &>(Base::container_from_iterator(it));   }
2237 };
2238 
2239 #endif
2240 } //namespace intrusive
2241 } //namespace boost
2242 
2243 #include <boost/intrusive/detail/config_end.hpp>
2244 
2245 #endif //BOOST_INTRUSIVE_BSTREE_HPP