Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:46

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga  2006-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 
0013 #ifndef BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
0014 #define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
0015 
0016 #include <boost/intrusive/detail/config_begin.hpp>
0017 #include <boost/intrusive/intrusive_fwd.hpp>
0018 
0019 #include <cstddef>
0020 
0021 #include <boost/intrusive/detail/assert.hpp>
0022 #include <boost/intrusive/detail/algo_type.hpp>
0023 #include <boost/intrusive/bstree_algorithms.hpp>
0024 
0025 #if defined(BOOST_HAS_PRAGMA_ONCE)
0026 #  pragma once
0027 #endif
0028 
0029 namespace boost {
0030 namespace intrusive {
0031 
0032 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0033 
0034 namespace detail
0035 {
0036 
0037 template<class ValueTraits, class NodePtrPrioCompare, class ExtraChecker>
0038 struct treap_node_extra_checker
0039       : public ExtraChecker
0040 {
0041    typedef ExtraChecker                            base_checker_t;
0042    typedef ValueTraits                             value_traits;
0043    typedef typename value_traits::node_traits      node_traits;
0044    typedef typename node_traits::const_node_ptr const_node_ptr;
0045 
0046    typedef typename base_checker_t::return_type    return_type;
0047 
0048    treap_node_extra_checker(const NodePtrPrioCompare& prio_comp, ExtraChecker extra_checker)
0049       : base_checker_t(extra_checker), prio_comp_(prio_comp)
0050    {}
0051 
0052    void operator () (const_node_ptr p,
0053                      const return_type& check_return_left, const return_type& check_return_right,
0054                      return_type& check_return)
0055    {
0056       BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_traits::get_left(p) || !prio_comp_(node_traits::get_left(p), p));
0057       BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_traits::get_right(p) || !prio_comp_(node_traits::get_right(p), p));
0058       base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
0059    }
0060 
0061    const NodePtrPrioCompare prio_comp_;
0062 };
0063 
0064 } // namespace detail
0065 
0066 #endif   //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0067 
0068 //! treap_algorithms provides basic algorithms to manipulate
0069 //! nodes forming a treap.
0070 //!
0071 //! (1) the header node is maintained with links not only to the root
0072 //! but also to the leftmost node of the tree, to enable constant time
0073 //! begin(), and to the rightmost node of the tree, to enable linear time
0074 //! performance when used with the generic set algorithms (set_union,
0075 //! etc.);
0076 //!
0077 //! (2) when a node being deleted has two children its successor node is
0078 //! relinked into its place, rather than copied, so that the only
0079 //! pointers invalidated are those referring to the deleted node.
0080 //!
0081 //! treap_algorithms is configured with a NodeTraits class, which encapsulates the
0082 //! information about the node to be manipulated. NodeTraits must support the
0083 //! following interface:
0084 //!
0085 //! <b>Typedefs</b>:
0086 //!
0087 //! <tt>node</tt>: The type of the node that forms the treap
0088 //!
0089 //! <tt>node_ptr</tt>: A pointer to a node
0090 //!
0091 //! <tt>const_node_ptr</tt>: A pointer to a const node
0092 //!
0093 //! <b>Static functions</b>:
0094 //!
0095 //! <tt>static node_ptr get_parent(const_node_ptr n);</tt>
0096 //!
0097 //! <tt>static void set_parent(node_ptr n, node_ptr parent);</tt>
0098 //!
0099 //! <tt>static node_ptr get_left(const_node_ptr n);</tt>
0100 //!
0101 //! <tt>static void set_left(node_ptr n, node_ptr left);</tt>
0102 //!
0103 //! <tt>static node_ptr get_right(const_node_ptr n);</tt>
0104 //!
0105 //! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
0106 template<class NodeTraits>
0107 class treap_algorithms
0108    #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0109    : public bstree_algorithms<NodeTraits>
0110    #endif
0111 {
0112    public:
0113    typedef NodeTraits                           node_traits;
0114    typedef typename NodeTraits::node            node;
0115    typedef typename NodeTraits::node_ptr       node_ptr;
0116    typedef typename NodeTraits::const_node_ptr const_node_ptr;
0117 
0118    /// @cond
0119    private:
0120 
0121    typedef bstree_algorithms<NodeTraits>  bstree_algo;
0122 
0123    class rerotate_on_destroy
0124    {
0125       rerotate_on_destroy& operator=(const rerotate_on_destroy&);
0126 
0127       public:
0128       rerotate_on_destroy(node_ptr header, node_ptr p, std::size_t &n)
0129          :  header_(header), p_(p), n_(n), remove_it_(true)
0130       {}
0131 
0132       ~rerotate_on_destroy()
0133       {
0134          if(remove_it_){
0135             rotate_up_n(header_, p_, n_);
0136          }
0137       }
0138 
0139       void release()
0140       {  remove_it_ = false;  }
0141 
0142       const node_ptr header_;
0143       const node_ptr p_;
0144       std::size_t &n_;
0145       bool remove_it_;
0146    };
0147 
0148    static void rotate_up_n(const node_ptr header, const node_ptr p, std::size_t n)
0149    {
0150       node_ptr p_parent(NodeTraits::get_parent(p));
0151       node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
0152       while(n--){
0153          if(p == NodeTraits::get_left(p_parent)){  //p is left child
0154             bstree_algo::rotate_right(p_parent, p, p_grandparent, header);
0155          }
0156          else{ //p is right child
0157             bstree_algo::rotate_left(p_parent, p, p_grandparent, header);
0158          }
0159          p_parent      = p_grandparent;
0160          p_grandparent = NodeTraits::get_parent(p_parent);
0161       }
0162    }
0163 
0164    /// @endcond
0165 
0166    public:
0167    //! This type is the information that will be
0168    //! filled by insert_unique_check
0169    struct insert_commit_data
0170       /// @cond
0171       :  public bstree_algo::insert_commit_data
0172       /// @endcond
0173    {
0174       /// @cond
0175       std::size_t rotations;
0176       /// @endcond
0177    };
0178 
0179    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0180 
0181    //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr)
0182    static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
0183 
0184    //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
0185    static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
0186 
0187    //! @copydoc ::boost::intrusive::bstree_algorithms::end_node
0188    static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
0189 
0190    //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
0191    static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
0192 
0193    //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr)
0194    static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT;
0195 
0196    //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr)
0197    static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT;
0198 
0199    //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr)
0200    static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT;
0201 
0202    //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr)
0203    static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT;
0204    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0205 
0206    //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr)
0207    template<class NodePtrPriorityCompare>
0208    static void unlink(node_ptr n, NodePtrPriorityCompare pcomp)
0209    {
0210       node_ptr x = NodeTraits::get_parent(n);
0211       if(x){
0212          while(!bstree_algo::is_header(x))
0213             x = NodeTraits::get_parent(x);
0214          erase(x, n, pcomp);
0215       }
0216    }
0217 
0218    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0219    //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
0220    static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
0221 
0222    //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr)
0223    static bool unique(const_node_ptr n) BOOST_NOEXCEPT;
0224 
0225    //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr)
0226    static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
0227 
0228    //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr)
0229    static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT;
0230 
0231    //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr)
0232    static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT;
0233 
0234    //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr)
0235    static void init(node_ptr n) BOOST_NOEXCEPT;
0236 
0237    //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr)
0238    static void init_header(node_ptr header) BOOST_NOEXCEPT;
0239    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0240 
0241    //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr)
0242    template<class NodePtrPriorityCompare>
0243    static node_ptr erase(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
0244    {
0245       rebalance_for_erasure(header, z, pcomp);
0246       bstree_algo::erase(header, z);
0247       return z;
0248    }
0249 
0250    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0251    //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer)
0252    template <class Cloner, class Disposer>
0253    static void clone
0254       (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer);
0255 
0256    //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer)
0257    template<class Disposer>
0258    static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
0259 
0260    //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0261    template<class KeyType, class KeyNodePtrCompare>
0262    static node_ptr lower_bound
0263       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0264 
0265    //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0266    template<class KeyType, class KeyNodePtrCompare>
0267    static node_ptr upper_bound
0268       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0269 
0270    //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare)
0271    template<class KeyType, class KeyNodePtrCompare>
0272    static node_ptr find
0273       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0274 
0275    //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0276    template<class KeyType, class KeyNodePtrCompare>
0277    static std::pair<node_ptr, node_ptr> equal_range
0278       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0279 
0280    //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
0281    template<class KeyType, class KeyNodePtrCompare>
0282    static std::pair<node_ptr, node_ptr> bounded_range
0283       (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
0284       , bool left_closed, bool right_closed);
0285 
0286    //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0287    template<class KeyType, class KeyNodePtrCompare>
0288    static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0289 
0290    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0291 
0292    //! <b>Requires</b>: "h" must be the header node of a tree.
0293    //!   NodePtrCompare is a function object that induces a strict weak
0294    //!   ordering compatible with the strict weak ordering used to create the
0295    //!   the tree. NodePtrCompare compares two node_ptrs.
0296    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0297    //!   ordering compatible with the one used to create the
0298    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0299    //!
0300    //! <b>Effects</b>: Inserts new_node into the tree before the upper bound
0301    //!   according to "comp" and rotates the tree according to "pcomp".
0302    //!
0303    //! <b>Complexity</b>: Average complexity for insert element is at
0304    //!   most logarithmic.
0305    //!
0306    //! <b>Throws</b>: If "comp" throw or "pcomp" throw.
0307    template<class NodePtrCompare, class NodePtrPriorityCompare>
0308    static node_ptr insert_equal_upper_bound
0309       (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
0310    {
0311       insert_commit_data commit_data;
0312       bstree_algo::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
0313       rebalance_check_and_commit(h, new_node, pcomp, commit_data);
0314       return new_node;
0315    }
0316 
0317    //! <b>Requires</b>: "h" must be the header node of a tree.
0318    //!   NodePtrCompare is a function object that induces a strict weak
0319    //!   ordering compatible with the strict weak ordering used to create the
0320    //!   the tree. NodePtrCompare compares two node_ptrs.
0321    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0322    //!   ordering compatible with the one used to create the
0323    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0324    //!
0325    //! <b>Effects</b>: Inserts new_node into the tree before the upper bound
0326    //!   according to "comp" and rotates the tree according to "pcomp".
0327    //!
0328    //! <b>Complexity</b>: Average complexity for insert element is at
0329    //!   most logarithmic.
0330    //!
0331    //! <b>Throws</b>: If "comp" throws.
0332    template<class NodePtrCompare, class NodePtrPriorityCompare>
0333    static node_ptr insert_equal_lower_bound
0334       (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
0335    {
0336       insert_commit_data commit_data;
0337       bstree_algo::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
0338       rebalance_check_and_commit(h, new_node, pcomp, commit_data);
0339       return new_node;
0340    }
0341 
0342    //! <b>Requires</b>: "header" must be the header node of a tree.
0343    //!   NodePtrCompare is a function object that induces a strict weak
0344    //!   ordering compatible with the strict weak ordering used to create the
0345    //!   the tree. NodePtrCompare compares two node_ptrs. "hint" is node from
0346    //!   the "header"'s tree.
0347    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0348    //!   ordering compatible with the one used to create the
0349    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0350    //!
0351    //! <b>Effects</b>: Inserts new_node into the tree, using "hint" as a hint to
0352    //!   where it will be inserted. If "hint" is the upper_bound
0353    //!   the insertion takes constant time (two comparisons in the worst case).
0354    //!   Rotates the tree according to "pcomp".
0355    //!
0356    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
0357    //!   constant time if new_node is inserted immediately before "hint".
0358    //!
0359    //! <b>Throws</b>: If "comp" throw or "pcomp" throw.
0360    template<class NodePtrCompare, class NodePtrPriorityCompare>
0361    static node_ptr insert_equal
0362       (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
0363    {
0364       insert_commit_data commit_data;
0365       bstree_algo::insert_equal_check(h, hint, new_node, comp, commit_data);
0366       rebalance_check_and_commit(h, new_node, pcomp, commit_data);
0367       return new_node;
0368    }
0369 
0370    //! <b>Requires</b>: "header" must be the header node of a tree.
0371    //!   "pos" must be a valid node of the tree (including header end) node.
0372    //!   "pos" must be a node pointing to the successor to "new_node"
0373    //!   once inserted according to the order of already inserted nodes. This function does not
0374    //!   check "pos" and this precondition must be guaranteed by the caller.
0375    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0376    //!   ordering compatible with the one used to create the
0377    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0378    //!
0379    //! <b>Effects</b>: Inserts new_node into the tree before "pos"
0380    //!   and rotates the tree according to "pcomp".
0381    //!
0382    //! <b>Complexity</b>: Constant-time.
0383    //!
0384    //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
0385    //!
0386    //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
0387    //! tree invariants might be broken.
0388    template<class NodePtrPriorityCompare>
0389    static node_ptr insert_before
0390       (node_ptr header, node_ptr pos, node_ptr new_node, NodePtrPriorityCompare pcomp)
0391    {
0392       insert_commit_data commit_data;
0393       bstree_algo::insert_before_check(header, pos, commit_data);
0394       rebalance_check_and_commit(header, new_node, pcomp, commit_data);
0395       return new_node;
0396    }
0397 
0398    //! <b>Requires</b>: "header" must be the header node of a tree.
0399    //!   "new_node" must be, according to the used ordering no less than the
0400    //!   greatest inserted key.
0401    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0402    //!   ordering compatible with the one used to create the
0403    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0404    //!
0405    //! <b>Effects</b>: Inserts x into the tree in the last position
0406    //!   and rotates the tree according to "pcomp".
0407    //!
0408    //! <b>Complexity</b>: Constant-time.
0409    //!
0410    //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
0411    //!
0412    //! <b>Note</b>: If "new_node" is less than the greatest inserted key
0413    //! tree invariants are broken. This function is slightly faster than
0414    //! using "insert_before".
0415    template<class NodePtrPriorityCompare>
0416    static void push_back(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
0417    {
0418       insert_commit_data commit_data;
0419       bstree_algo::push_back_check(header, commit_data);
0420       rebalance_check_and_commit(header, new_node, pcomp, commit_data);
0421    }
0422 
0423    //! <b>Requires</b>: "header" must be the header node of a tree.
0424    //!   "new_node" must be, according to the used ordering, no greater than the
0425    //!   lowest inserted key.
0426    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0427    //!   ordering compatible with the one used to create the
0428    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0429    //!
0430    //! <b>Effects</b>: Inserts x into the tree in the first position
0431    //!   and rotates the tree according to "pcomp".
0432    //!
0433    //! <b>Complexity</b>: Constant-time.
0434    //!
0435    //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
0436    //!
0437    //! <b>Note</b>: If "new_node" is greater than the lowest inserted key
0438    //! tree invariants are broken. This function is slightly faster than
0439    //! using "insert_before".
0440    template<class NodePtrPriorityCompare>
0441    static void push_front(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
0442    {
0443       insert_commit_data commit_data;
0444       bstree_algo::push_front_check(header, commit_data);
0445       rebalance_check_and_commit(header, new_node, pcomp, commit_data);
0446    }
0447 
0448    //! <b>Requires</b>: "header" must be the header node of a tree.
0449    //!   KeyNodePtrCompare is a function object that induces a strict weak
0450    //!   ordering compatible with the strict weak ordering used to create the
0451    //!   the tree. NodePtrCompare compares KeyType with a node_ptr.
0452    //!
0453    //! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
0454    //!   tree according to "comp" and obtains the needed information to realize
0455    //!   a constant-time node insertion if there is no equivalent node.
0456    //!
0457    //! <b>Returns</b>: If there is an equivalent value
0458    //!   returns a pair containing a node_ptr to the already present node
0459    //!   and false. If there is not equivalent key can be inserted returns true
0460    //!   in the returned pair's boolean and fills "commit_data" that is meant to
0461    //!   be used with the "insert_commit" function to achieve a constant-time
0462    //!   insertion function.
0463    //!
0464    //! <b>Complexity</b>: Average complexity is at most logarithmic.
0465    //!
0466    //! <b>Throws</b>: If "comp" throws.
0467    //!
0468    //! <b>Notes</b>: This function is used to improve performance when constructing
0469    //!   a node is expensive and the user does not want to have two equivalent nodes
0470    //!   in the tree: if there is an equivalent value
0471    //!   the constructed object must be discarded. Many times, the part of the
0472    //!   node that is used to impose the order is much cheaper to construct
0473    //!   than the node and this function offers the possibility to use that part
0474    //!   to check if the insertion will be successful.
0475    //!
0476    //!   If the check is successful, the user can construct the node and use
0477    //!   "insert_commit" to insert the node in constant-time. This gives a total
0478    //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
0479    //!
0480    //!   "commit_data" remains valid for a subsequent "insert_unique_commit" only
0481    //!   if no more objects are inserted or erased from the set.
0482    template<class KeyType, class KeyNodePtrCompare, class PrioType, class PrioNodePtrPrioCompare>
0483    static std::pair<node_ptr, bool> insert_unique_check
0484       ( const_node_ptr header
0485       , const KeyType &key, KeyNodePtrCompare comp
0486       , const PrioType &prio, PrioNodePtrPrioCompare pcomp
0487       , insert_commit_data &commit_data)
0488    {
0489       std::pair<node_ptr, bool> ret =
0490          bstree_algo::insert_unique_check(header, key, comp, commit_data);
0491       if(ret.second)
0492          rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations);
0493       return ret;
0494    }
0495 
0496    //! <b>Requires</b>: "header" must be the header node of a tree.
0497    //!   KeyNodePtrCompare is a function object that induces a strict weak
0498    //!   ordering compatible with the strict weak ordering used to create the
0499    //!   the tree. NodePtrCompare compares KeyType with a node_ptr.
0500    //!   "hint" is node from the "header"'s tree.
0501    //!
0502    //! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
0503    //!   tree according to "comp" using "hint" as a hint to where it should be
0504    //!   inserted and obtains the needed information to realize
0505    //!   a constant-time node insertion if there is no equivalent node.
0506    //!   If "hint" is the upper_bound the function has constant time
0507    //!   complexity (two comparisons in the worst case).
0508    //!
0509    //! <b>Returns</b>: If there is an equivalent value
0510    //!   returns a pair containing a node_ptr to the already present node
0511    //!   and false. If there is not equivalent key can be inserted returns true
0512    //!   in the returned pair's boolean and fills "commit_data" that is meant to
0513    //!   be used with the "insert_commit" function to achieve a constant-time
0514    //!   insertion function.
0515    //!
0516    //! <b>Complexity</b>: Average complexity is at most logarithmic, but it is
0517    //!   amortized constant time if new_node should be inserted immediately before "hint".
0518    //!
0519    //! <b>Throws</b>: If "comp" throws.
0520    //!
0521    //! <b>Notes</b>: This function is used to improve performance when constructing
0522    //!   a node is expensive and the user does not want to have two equivalent nodes
0523    //!   in the tree: if there is an equivalent value
0524    //!   the constructed object must be discarded. Many times, the part of the
0525    //!   node that is used to impose the order is much cheaper to construct
0526    //!   than the node and this function offers the possibility to use that part
0527    //!   to check if the insertion will be successful.
0528    //!
0529    //!   If the check is successful, the user can construct the node and use
0530    //!   "insert_commit" to insert the node in constant-time. This gives a total
0531    //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
0532    //!
0533    //!   "commit_data" remains valid for a subsequent "insert_unique_commit" only
0534    //!   if no more objects are inserted or erased from the set.
0535    template<class KeyType, class KeyNodePtrCompare, class PrioType, class PrioNodePtrPrioCompare>
0536    static std::pair<node_ptr, bool> insert_unique_check
0537       ( const_node_ptr header, node_ptr hint
0538       , const KeyType &key, KeyNodePtrCompare comp
0539       , const PrioType &prio, PrioNodePtrPrioCompare pcomp
0540       , insert_commit_data &commit_data)
0541    {
0542       std::pair<node_ptr, bool> ret =
0543          bstree_algo::insert_unique_check(header, hint, key, comp, commit_data);
0544       if(ret.second)
0545          rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations);
0546       return ret;
0547    }
0548 
0549    //! <b>Requires</b>: "header" must be the header node of a tree.
0550    //!   "commit_data" must have been obtained from a previous call to
0551    //!   "insert_unique_check". No objects should have been inserted or erased
0552    //!   from the set between the "insert_unique_check" that filled "commit_data"
0553    //!   and the call to "insert_commit".
0554    //!
0555    //!
0556    //! <b>Effects</b>: Inserts new_node in the set using the information obtained
0557    //!   from the "commit_data" that a previous "insert_check" filled.
0558    //!
0559    //! <b>Complexity</b>: Constant time.
0560    //!
0561    //! <b>Throws</b>: Nothing.
0562    //!
0563    //! <b>Notes</b>: This function has only sense if a "insert_unique_check" has been
0564    //!   previously executed to fill "commit_data". No value should be inserted or
0565    //!   erased between the "insert_check" and "insert_commit" calls.
0566    static void insert_unique_commit
0567       (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) BOOST_NOEXCEPT
0568    {
0569       bstree_algo::insert_unique_commit(header, new_node, commit_data);
0570       rotate_up_n(header, new_node, commit_data.rotations);
0571    }
0572 
0573    //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique
0574    template<class NodePtrCompare, class PrioNodePtrPrioCompare>
0575    static bool transfer_unique
0576       (node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z)
0577    {
0578       insert_commit_data commit_data;
0579       bool const transferable = insert_unique_check(header1, z, comp, z, pcomp, commit_data).second;
0580       if(transferable){
0581          erase(header2, z, pcomp);
0582          insert_unique_commit(header1, z, commit_data);         
0583       }
0584       return transferable;
0585    }
0586 
0587    //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal
0588    template<class NodePtrCompare, class PrioNodePtrPrioCompare>
0589    static void transfer_equal
0590       (node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z)
0591    {
0592       insert_commit_data commit_data;
0593       bstree_algo::insert_equal_upper_bound_check(header1, z, comp, commit_data);
0594       rebalance_after_insertion_check(header1, commit_data.node, z, pcomp, commit_data.rotations);
0595       rebalance_for_erasure(header2, z, pcomp);
0596       bstree_algo::erase(header2, z);
0597       bstree_algo::insert_unique_commit(header1, z, commit_data);
0598       rotate_up_n(header1, z, commit_data.rotations);
0599    }
0600 
0601    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0602 
0603    //! @copydoc ::boost::intrusive::bstree_algorithms::is_header
0604    static bool is_header(const_node_ptr p) BOOST_NOEXCEPT;
0605    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0606 
0607    /// @cond
0608    private:
0609 
0610    template<class NodePtrPriorityCompare>
0611    static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
0612    {
0613       std::size_t n = 0;
0614       rerotate_on_destroy rb(header, z, n);
0615 
0616       node_ptr z_left  = NodeTraits::get_left(z);
0617       node_ptr z_right = NodeTraits::get_right(z);
0618       while(z_left || z_right){
0619          const node_ptr z_parent(NodeTraits::get_parent(z));
0620          if(!z_right || (z_left && pcomp(z_left, z_right))){
0621             bstree_algo::rotate_right(z, z_left, z_parent, header);
0622          }
0623          else{
0624             bstree_algo::rotate_left(z, z_right, z_parent, header);
0625          }
0626          ++n;
0627          z_left  = NodeTraits::get_left(z);
0628          z_right = NodeTraits::get_right(z);
0629       }
0630       rb.release();
0631    }
0632 
0633    template<class NodePtrPriorityCompare>
0634    static void rebalance_check_and_commit
0635       (node_ptr h, node_ptr new_node, NodePtrPriorityCompare pcomp, insert_commit_data &commit_data)
0636    {
0637       rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
0638       //No-throw
0639       bstree_algo::insert_unique_commit(h, new_node, commit_data);
0640       rotate_up_n(h, new_node, commit_data.rotations);
0641    }
0642 
0643    template<class Key, class KeyNodePriorityCompare>
0644    static void rebalance_after_insertion_check
0645       (const_node_ptr header, const_node_ptr up, const Key &k
0646       , KeyNodePriorityCompare pcomp, std::size_t &num_rotations)
0647    {
0648       const_node_ptr upnode(up);
0649       //First check rotations since pcomp can throw
0650       num_rotations = 0;
0651       std::size_t n = 0;
0652       while(upnode != header && pcomp(k, upnode)){
0653          ++n;
0654          upnode = NodeTraits::get_parent(upnode);
0655       }
0656       num_rotations = n;
0657    }
0658 
0659    template<class NodePtrPriorityCompare>
0660    static bool check_invariant(const_node_ptr header, NodePtrPriorityCompare pcomp)
0661    {
0662       node_ptr beg = begin_node(header);
0663       node_ptr end = end_node(header);
0664 
0665       while(beg != end){
0666          node_ptr p = NodeTraits::get_parent(beg);
0667          if(p != header){
0668             if(pcomp(beg, p))
0669                return false;
0670          }
0671          beg = next_node(beg);
0672       }
0673       return true;
0674    }
0675 
0676    /// @endcond
0677 };
0678 
0679 /// @cond
0680 
0681 template<class NodeTraits>
0682 struct get_algo<TreapAlgorithms, NodeTraits>
0683 {
0684    typedef treap_algorithms<NodeTraits> type;
0685 };
0686 
0687 template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
0688 struct get_node_checker<TreapAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
0689 {
0690    typedef detail::bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
0691 };
0692 
0693 /// @endcond
0694 
0695 } //namespace intrusive
0696 } //namespace boost
0697 
0698 #include <boost/intrusive/detail/config_end.hpp>
0699 
0700 #endif //BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP