Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:36:10

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       inline insert_commit_data()
0176          : bstree_algo::insert_commit_data(), rotations()
0177       {}
0178 
0179       std::size_t rotations;
0180       /// @endcond
0181    };
0182 
0183    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0184 
0185    //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const_node_ptr)
0186    static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
0187 
0188    //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
0189    static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
0190 
0191    //! @copydoc ::boost::intrusive::bstree_algorithms::end_node
0192    static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
0193 
0194    //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
0195    static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
0196 
0197    //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr)
0198    static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT;
0199 
0200    //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(node_ptr,node_ptr,node_ptr,node_ptr)
0201    static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT;
0202 
0203    //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr)
0204    static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT;
0205 
0206    //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(node_ptr,node_ptr,node_ptr)
0207    static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT;
0208    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0209 
0210    //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(node_ptr)
0211    template<class NodePtrPriorityCompare>
0212    static void unlink(node_ptr n, NodePtrPriorityCompare pcomp)
0213    {
0214       node_ptr x = NodeTraits::get_parent(n);
0215       if(x){
0216          while(!bstree_algo::is_header(x))
0217             x = NodeTraits::get_parent(x);
0218          erase(x, n, pcomp);
0219       }
0220    }
0221 
0222    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0223    //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
0224    static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
0225 
0226    //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const_node_ptr)
0227    static bool unique(const_node_ptr n) BOOST_NOEXCEPT;
0228 
0229    //! @copydoc ::boost::intrusive::bstree_algorithms::size(const_node_ptr)
0230    static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
0231 
0232    //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(node_ptr)
0233    static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT;
0234 
0235    //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(node_ptr)
0236    static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT;
0237 
0238    //! @copydoc ::boost::intrusive::bstree_algorithms::init(node_ptr)
0239    static void init(node_ptr n) BOOST_NOEXCEPT;
0240 
0241    //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(node_ptr)
0242    static void init_header(node_ptr header) BOOST_NOEXCEPT;
0243    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0244 
0245    //! @copydoc ::boost::intrusive::bstree_algorithms::erase(node_ptr,node_ptr)
0246    template<class NodePtrPriorityCompare>
0247    static node_ptr erase(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
0248    {
0249       rebalance_for_erasure(header, z, pcomp);
0250       bstree_algo::erase(header, z);
0251       return z;
0252    }
0253 
0254    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0255    //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const_node_ptr,node_ptr,Cloner,Disposer)
0256    template <class Cloner, class Disposer>
0257    static void clone
0258       (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer);
0259 
0260    //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(node_ptr,Disposer)
0261    template<class Disposer>
0262    static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
0263 
0264    //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0265    template<class KeyType, class KeyNodePtrCompare>
0266    static node_ptr lower_bound
0267       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0268 
0269    //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0270    template<class KeyType, class KeyNodePtrCompare>
0271    static node_ptr upper_bound
0272       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0273 
0274    //! @copydoc ::boost::intrusive::bstree_algorithms::find(const_node_ptr, const KeyType&,KeyNodePtrCompare)
0275    template<class KeyType, class KeyNodePtrCompare>
0276    static node_ptr find
0277       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0278 
0279    //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0280    template<class KeyType, class KeyNodePtrCompare>
0281    static std::pair<node_ptr, node_ptr> equal_range
0282       (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0283 
0284    //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const_node_ptr,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
0285    template<class KeyType, class KeyNodePtrCompare>
0286    static std::pair<node_ptr, node_ptr> bounded_range
0287       (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
0288       , bool left_closed, bool right_closed);
0289 
0290    //! @copydoc ::boost::intrusive::bstree_algorithms::count(const_node_ptr,const KeyType&,KeyNodePtrCompare)
0291    template<class KeyType, class KeyNodePtrCompare>
0292    static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0293 
0294    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0295 
0296    //! <b>Requires</b>: "h" must be the header node of a tree.
0297    //!   NodePtrCompare is a function object that induces a strict weak
0298    //!   ordering compatible with the strict weak ordering used to create the
0299    //!   the tree. NodePtrCompare compares two node_ptrs.
0300    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0301    //!   ordering compatible with the one used to create the
0302    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0303    //!
0304    //! <b>Effects</b>: Inserts new_node into the tree before the upper bound
0305    //!   according to "comp" and rotates the tree according to "pcomp".
0306    //!
0307    //! <b>Complexity</b>: Average complexity for insert element is at
0308    //!   most logarithmic.
0309    //!
0310    //! <b>Throws</b>: If "comp" throw or "pcomp" throw.
0311    template<class NodePtrCompare, class NodePtrPriorityCompare>
0312    static node_ptr insert_equal_upper_bound
0313       (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
0314    {
0315       insert_commit_data commit_data;
0316       bstree_algo::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
0317       rebalance_check_and_commit(h, new_node, pcomp, commit_data);
0318       return new_node;
0319    }
0320 
0321    //! <b>Requires</b>: "h" must be the header node of a tree.
0322    //!   NodePtrCompare is a function object that induces a strict weak
0323    //!   ordering compatible with the strict weak ordering used to create the
0324    //!   the tree. NodePtrCompare compares two node_ptrs.
0325    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0326    //!   ordering compatible with the one used to create the
0327    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0328    //!
0329    //! <b>Effects</b>: Inserts new_node into the tree before the upper bound
0330    //!   according to "comp" and rotates the tree according to "pcomp".
0331    //!
0332    //! <b>Complexity</b>: Average complexity for insert element is at
0333    //!   most logarithmic.
0334    //!
0335    //! <b>Throws</b>: If "comp" throws.
0336    template<class NodePtrCompare, class NodePtrPriorityCompare>
0337    static node_ptr insert_equal_lower_bound
0338       (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
0339    {
0340       insert_commit_data commit_data;
0341       bstree_algo::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
0342       rebalance_check_and_commit(h, new_node, pcomp, commit_data);
0343       return new_node;
0344    }
0345 
0346    //! <b>Requires</b>: "header" must be the header node of a tree.
0347    //!   NodePtrCompare is a function object that induces a strict weak
0348    //!   ordering compatible with the strict weak ordering used to create the
0349    //!   the tree. NodePtrCompare compares two node_ptrs. "hint" is node from
0350    //!   the "header"'s tree.
0351    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0352    //!   ordering compatible with the one used to create the
0353    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0354    //!
0355    //! <b>Effects</b>: Inserts new_node into the tree, using "hint" as a hint to
0356    //!   where it will be inserted. If "hint" is the upper_bound
0357    //!   the insertion takes constant time (two comparisons in the worst case).
0358    //!   Rotates the tree according to "pcomp".
0359    //!
0360    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
0361    //!   constant time if new_node is inserted immediately before "hint".
0362    //!
0363    //! <b>Throws</b>: If "comp" throw or "pcomp" throw.
0364    template<class NodePtrCompare, class NodePtrPriorityCompare>
0365    static node_ptr insert_equal
0366       (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
0367    {
0368       insert_commit_data commit_data;
0369       bstree_algo::insert_equal_check(h, hint, new_node, comp, commit_data);
0370       rebalance_check_and_commit(h, new_node, pcomp, commit_data);
0371       return new_node;
0372    }
0373 
0374    //! <b>Requires</b>: "header" must be the header node of a tree.
0375    //!   "pos" must be a valid node of the tree (including header end) node.
0376    //!   "pos" must be a node pointing to the successor to "new_node"
0377    //!   once inserted according to the order of already inserted nodes. This function does not
0378    //!   check "pos" and this precondition must be guaranteed by the caller.
0379    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0380    //!   ordering compatible with the one used to create the
0381    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0382    //!
0383    //! <b>Effects</b>: Inserts new_node into the tree before "pos"
0384    //!   and rotates the tree according to "pcomp".
0385    //!
0386    //! <b>Complexity</b>: Constant-time.
0387    //!
0388    //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
0389    //!
0390    //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
0391    //! tree invariants might be broken.
0392    template<class NodePtrPriorityCompare>
0393    static node_ptr insert_before
0394       (node_ptr header, node_ptr pos, node_ptr new_node, NodePtrPriorityCompare pcomp)
0395    {
0396       insert_commit_data commit_data;
0397       bstree_algo::insert_before_check(header, pos, commit_data);
0398       rebalance_check_and_commit(header, new_node, pcomp, commit_data);
0399       return new_node;
0400    }
0401 
0402    //! <b>Requires</b>: "header" must be the header node of a tree.
0403    //!   "new_node" must be, according to the used ordering no less than the
0404    //!   greatest inserted key.
0405    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0406    //!   ordering compatible with the one used to create the
0407    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0408    //!
0409    //! <b>Effects</b>: Inserts x into the tree in the last position
0410    //!   and rotates the tree according to "pcomp".
0411    //!
0412    //! <b>Complexity</b>: Constant-time.
0413    //!
0414    //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
0415    //!
0416    //! <b>Note</b>: If "new_node" is less than the greatest inserted key
0417    //! tree invariants are broken. This function is slightly faster than
0418    //! using "insert_before".
0419    template<class NodePtrPriorityCompare>
0420    static void push_back(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
0421    {
0422       insert_commit_data commit_data;
0423       bstree_algo::push_back_check(header, commit_data);
0424       rebalance_check_and_commit(header, new_node, pcomp, commit_data);
0425    }
0426 
0427    //! <b>Requires</b>: "header" must be the header node of a tree.
0428    //!   "new_node" must be, according to the used ordering, no greater than the
0429    //!   lowest inserted key.
0430    //!   NodePtrPriorityCompare is a priority function object that induces a strict weak
0431    //!   ordering compatible with the one used to create the
0432    //!   the tree. NodePtrPriorityCompare compares two node_ptrs.
0433    //!
0434    //! <b>Effects</b>: Inserts x into the tree in the first position
0435    //!   and rotates the tree according to "pcomp".
0436    //!
0437    //! <b>Complexity</b>: Constant-time.
0438    //!
0439    //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
0440    //!
0441    //! <b>Note</b>: If "new_node" is greater than the lowest inserted key
0442    //! tree invariants are broken. This function is slightly faster than
0443    //! using "insert_before".
0444    template<class NodePtrPriorityCompare>
0445    static void push_front(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
0446    {
0447       insert_commit_data commit_data;
0448       bstree_algo::push_front_check(header, commit_data);
0449       rebalance_check_and_commit(header, new_node, pcomp, commit_data);
0450    }
0451 
0452    //! <b>Requires</b>: "header" must be the header node of a tree.
0453    //!   KeyNodePtrCompare is a function object that induces a strict weak
0454    //!   ordering compatible with the strict weak ordering used to create the
0455    //!   the tree. NodePtrCompare compares KeyType with a node_ptr.
0456    //!
0457    //! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
0458    //!   tree according to "comp" and obtains the needed information to realize
0459    //!   a constant-time node insertion if there is no equivalent node.
0460    //!
0461    //! <b>Returns</b>: If there is an equivalent value
0462    //!   returns a pair containing a node_ptr to the already present node
0463    //!   and false. If there is not equivalent key can be inserted returns true
0464    //!   in the returned pair's boolean and fills "commit_data" that is meant to
0465    //!   be used with the "insert_commit" function to achieve a constant-time
0466    //!   insertion function.
0467    //!
0468    //! <b>Complexity</b>: Average complexity is at most logarithmic.
0469    //!
0470    //! <b>Throws</b>: If "comp" throws.
0471    //!
0472    //! <b>Notes</b>: This function is used to improve performance when constructing
0473    //!   a node is expensive and the user does not want to have two equivalent nodes
0474    //!   in the tree: if there is an equivalent value
0475    //!   the constructed object must be discarded. Many times, the part of the
0476    //!   node that is used to impose the order is much cheaper to construct
0477    //!   than the node and this function offers the possibility to use that part
0478    //!   to check if the insertion will be successful.
0479    //!
0480    //!   If the check is successful, the user can construct the node and use
0481    //!   "insert_commit" to insert the node in constant-time. This gives a total
0482    //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
0483    //!
0484    //!   "commit_data" remains valid for a subsequent "insert_unique_commit" only
0485    //!   if no more objects are inserted or erased from the set.
0486    template<class KeyType, class KeyNodePtrCompare, class PrioType, class PrioNodePtrPrioCompare>
0487    static std::pair<node_ptr, bool> insert_unique_check
0488       ( const_node_ptr header
0489       , const KeyType &key, KeyNodePtrCompare comp
0490       , const PrioType &prio, PrioNodePtrPrioCompare pcomp
0491       , insert_commit_data &commit_data)
0492    {
0493       std::pair<node_ptr, bool> ret =
0494          bstree_algo::insert_unique_check(header, key, comp, commit_data);
0495       if(ret.second)
0496          rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations);
0497       return ret;
0498    }
0499 
0500    //! <b>Requires</b>: "header" must be the header node of a tree.
0501    //!   KeyNodePtrCompare is a function object that induces a strict weak
0502    //!   ordering compatible with the strict weak ordering used to create the
0503    //!   the tree. NodePtrCompare compares KeyType with a node_ptr.
0504    //!   "hint" is node from the "header"'s tree.
0505    //!
0506    //! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
0507    //!   tree according to "comp" using "hint" as a hint to where it should be
0508    //!   inserted and obtains the needed information to realize
0509    //!   a constant-time node insertion if there is no equivalent node.
0510    //!   If "hint" is the upper_bound the function has constant time
0511    //!   complexity (two comparisons in the worst case).
0512    //!
0513    //! <b>Returns</b>: If there is an equivalent value
0514    //!   returns a pair containing a node_ptr to the already present node
0515    //!   and false. If there is not equivalent key can be inserted returns true
0516    //!   in the returned pair's boolean and fills "commit_data" that is meant to
0517    //!   be used with the "insert_commit" function to achieve a constant-time
0518    //!   insertion function.
0519    //!
0520    //! <b>Complexity</b>: Average complexity is at most logarithmic, but it is
0521    //!   amortized constant time if new_node should be inserted immediately before "hint".
0522    //!
0523    //! <b>Throws</b>: If "comp" throws.
0524    //!
0525    //! <b>Notes</b>: This function is used to improve performance when constructing
0526    //!   a node is expensive and the user does not want to have two equivalent nodes
0527    //!   in the tree: if there is an equivalent value
0528    //!   the constructed object must be discarded. Many times, the part of the
0529    //!   node that is used to impose the order is much cheaper to construct
0530    //!   than the node and this function offers the possibility to use that part
0531    //!   to check if the insertion will be successful.
0532    //!
0533    //!   If the check is successful, the user can construct the node and use
0534    //!   "insert_commit" to insert the node in constant-time. This gives a total
0535    //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
0536    //!
0537    //!   "commit_data" remains valid for a subsequent "insert_unique_commit" only
0538    //!   if no more objects are inserted or erased from the set.
0539    template<class KeyType, class KeyNodePtrCompare, class PrioType, class PrioNodePtrPrioCompare>
0540    static std::pair<node_ptr, bool> insert_unique_check
0541       ( const_node_ptr header, node_ptr hint
0542       , const KeyType &key, KeyNodePtrCompare comp
0543       , const PrioType &prio, PrioNodePtrPrioCompare pcomp
0544       , insert_commit_data &commit_data)
0545    {
0546       std::pair<node_ptr, bool> ret =
0547          bstree_algo::insert_unique_check(header, hint, key, comp, commit_data);
0548       if(ret.second)
0549          rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations);
0550       return ret;
0551    }
0552 
0553    //! <b>Requires</b>: "header" must be the header node of a tree.
0554    //!   "commit_data" must have been obtained from a previous call to
0555    //!   "insert_unique_check". No objects should have been inserted or erased
0556    //!   from the set between the "insert_unique_check" that filled "commit_data"
0557    //!   and the call to "insert_commit".
0558    //!
0559    //!
0560    //! <b>Effects</b>: Inserts new_node in the set using the information obtained
0561    //!   from the "commit_data" that a previous "insert_check" filled.
0562    //!
0563    //! <b>Complexity</b>: Constant time.
0564    //!
0565    //! <b>Throws</b>: Nothing.
0566    //!
0567    //! <b>Notes</b>: This function has only sense if a "insert_unique_check" has been
0568    //!   previously executed to fill "commit_data". No value should be inserted or
0569    //!   erased between the "insert_check" and "insert_commit" calls.
0570    static void insert_unique_commit
0571       (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data) BOOST_NOEXCEPT
0572    {
0573       bstree_algo::insert_unique_commit(header, new_node, commit_data);
0574       rotate_up_n(header, new_node, commit_data.rotations);
0575    }
0576 
0577    //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique
0578    template<class NodePtrCompare, class PrioNodePtrPrioCompare>
0579    static bool transfer_unique
0580       (node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z)
0581    {
0582       insert_commit_data commit_data;
0583       bool const transferable = insert_unique_check(header1, z, comp, z, pcomp, commit_data).second;
0584       if(transferable){
0585          erase(header2, z, pcomp);
0586          insert_unique_commit(header1, z, commit_data);         
0587       }
0588       return transferable;
0589    }
0590 
0591    //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal
0592    template<class NodePtrCompare, class PrioNodePtrPrioCompare>
0593    static void transfer_equal
0594       (node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z)
0595    {
0596       insert_commit_data commit_data;
0597       bstree_algo::insert_equal_upper_bound_check(header1, z, comp, commit_data);
0598       rebalance_after_insertion_check(header1, commit_data.node, z, pcomp, commit_data.rotations);
0599       rebalance_for_erasure(header2, z, pcomp);
0600       bstree_algo::erase(header2, z);
0601       bstree_algo::insert_unique_commit(header1, z, commit_data);
0602       rotate_up_n(header1, z, commit_data.rotations);
0603    }
0604 
0605    #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0606 
0607    //! @copydoc ::boost::intrusive::bstree_algorithms::is_header
0608    static bool is_header(const_node_ptr p) BOOST_NOEXCEPT;
0609    #endif   //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0610 
0611    /// @cond
0612    private:
0613 
0614    template<class NodePtrPriorityCompare>
0615    static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
0616    {
0617       std::size_t n = 0;
0618       rerotate_on_destroy rb(header, z, n);
0619 
0620       node_ptr z_left  = NodeTraits::get_left(z);
0621       node_ptr z_right = NodeTraits::get_right(z);
0622       while(z_left || z_right){
0623          const node_ptr z_parent(NodeTraits::get_parent(z));
0624          if(!z_right || (z_left && pcomp(z_left, z_right))){
0625             bstree_algo::rotate_right(z, z_left, z_parent, header);
0626          }
0627          else{
0628             bstree_algo::rotate_left(z, z_right, z_parent, header);
0629          }
0630          ++n;
0631          z_left  = NodeTraits::get_left(z);
0632          z_right = NodeTraits::get_right(z);
0633       }
0634       rb.release();
0635    }
0636 
0637    template<class NodePtrPriorityCompare>
0638    static void rebalance_check_and_commit
0639       (node_ptr h, node_ptr new_node, NodePtrPriorityCompare pcomp, insert_commit_data &commit_data)
0640    {
0641       rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
0642       //No-throw
0643       bstree_algo::insert_unique_commit(h, new_node, commit_data);
0644       rotate_up_n(h, new_node, commit_data.rotations);
0645    }
0646 
0647    template<class Key, class KeyNodePriorityCompare>
0648    static void rebalance_after_insertion_check
0649       (const_node_ptr header, const_node_ptr up, const Key &k
0650       , KeyNodePriorityCompare pcomp, std::size_t &num_rotations)
0651    {
0652       const_node_ptr upnode(up);
0653       //First check rotations since pcomp can throw
0654       num_rotations = 0;
0655       std::size_t n = 0;
0656       while(upnode != header && pcomp(k, upnode)){
0657          ++n;
0658          upnode = NodeTraits::get_parent(upnode);
0659       }
0660       num_rotations = n;
0661    }
0662 
0663    template<class NodePtrPriorityCompare>
0664    static bool check_invariant(const_node_ptr header, NodePtrPriorityCompare pcomp)
0665    {
0666       node_ptr beg = begin_node(header);
0667       node_ptr end = end_node(header);
0668 
0669       while(beg != end){
0670          node_ptr p = NodeTraits::get_parent(beg);
0671          if(p != header){
0672             if(pcomp(beg, p))
0673                return false;
0674          }
0675          beg = next_node(beg);
0676       }
0677       return true;
0678    }
0679 
0680    /// @endcond
0681 };
0682 
0683 /// @cond
0684 
0685 template<class NodeTraits>
0686 struct get_algo<TreapAlgorithms, NodeTraits>
0687 {
0688    typedef treap_algorithms<NodeTraits> type;
0689 };
0690 
0691 template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
0692 struct get_node_checker<TreapAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
0693 {
0694    typedef detail::bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
0695 };
0696 
0697 /// @endcond
0698 
0699 } //namespace intrusive
0700 } //namespace boost
0701 
0702 #include <boost/intrusive/detail/config_end.hpp>
0703 
0704 #endif //BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP