Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga  2014-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_BSTREE_ALGORITHMS_BASE_HPP
0014 #define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP
0015 
0016 #ifndef BOOST_CONFIG_HPP
0017 #  include <boost/config.hpp>
0018 #endif
0019 
0020 #if defined(BOOST_HAS_PRAGMA_ONCE)
0021 #  pragma once
0022 #endif
0023 
0024 #include <boost/intrusive/detail/uncast.hpp>
0025 
0026 namespace boost {
0027 namespace intrusive {
0028 
0029 template<class NodeTraits>
0030 class bstree_algorithms_base
0031 {
0032    public:
0033    typedef typename NodeTraits::node            node;
0034    typedef NodeTraits                           node_traits;
0035    typedef typename NodeTraits::node_ptr        node_ptr;
0036    typedef typename NodeTraits::const_node_ptr  const_node_ptr;
0037 
0038    //! <b>Requires</b>: 'n' is a node from the tree except the header.
0039    //!
0040    //! <b>Effects</b>: Returns the next node of the tree.
0041    //!
0042    //! <b>Complexity</b>: Average constant time.
0043    //!
0044    //! <b>Throws</b>: Nothing.
0045    static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT
0046    {
0047       node_ptr const n_right(NodeTraits::get_right(n));
0048       if(n_right){
0049          return minimum(n_right);
0050       }
0051       else {
0052          node_ptr p(NodeTraits::get_parent(n));
0053          while(n == NodeTraits::get_right(p)){
0054             n = p;
0055             p = NodeTraits::get_parent(p);
0056          }
0057          return NodeTraits::get_right(n) != p ? p : n;
0058       }
0059    }
0060 
0061    //! <b>Requires</b>: 'n' is a node from the tree except the leftmost node.
0062    //!
0063    //! <b>Effects</b>: Returns the previous node of the tree.
0064    //!
0065    //! <b>Complexity</b>: Average constant time.
0066    //!
0067    //! <b>Throws</b>: Nothing.
0068    static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT
0069    {
0070       if(is_header(n)){
0071          return NodeTraits::get_right(n);
0072       }
0073       else if(NodeTraits::get_left(n)){
0074          return maximum(NodeTraits::get_left(n));
0075       }
0076       else {
0077          node_ptr p(n);
0078          node_ptr x = NodeTraits::get_parent(p);
0079          while(p == NodeTraits::get_left(x)){
0080             p = x;
0081             x = NodeTraits::get_parent(x);
0082          }
0083          return x;
0084       }
0085    }
0086 
0087    //! <b>Requires</b>: 'n' is a node of a tree but not the header.
0088    //!
0089    //! <b>Effects</b>: Returns the minimum node of the subtree starting at p.
0090    //!
0091    //! <b>Complexity</b>: Logarithmic to the size of the subtree.
0092    //!
0093    //! <b>Throws</b>: Nothing.
0094    static node_ptr minimum(node_ptr n)
0095    {
0096       for(node_ptr p_left = NodeTraits::get_left(n)
0097          ;p_left
0098          ;p_left = NodeTraits::get_left(n)){
0099          n = p_left;
0100       }
0101       return n;
0102    }
0103 
0104    //! <b>Requires</b>: 'n' is a node of a tree but not the header.
0105    //!
0106    //! <b>Effects</b>: Returns the maximum node of the subtree starting at p.
0107    //!
0108    //! <b>Complexity</b>: Logarithmic to the size of the subtree.
0109    //!
0110    //! <b>Throws</b>: Nothing.
0111    static node_ptr maximum(node_ptr n)
0112    {
0113       for(node_ptr p_right = NodeTraits::get_right(n)
0114          ;p_right
0115          ;p_right = NodeTraits::get_right(n)){
0116          n = p_right;
0117       }
0118       return n;
0119    }
0120 
0121    //! <b>Requires</b>: p is a node of a tree.
0122    //!
0123    //! <b>Effects</b>: Returns true if p is the header of the tree.
0124    //!
0125    //! <b>Complexity</b>: Constant.
0126    //!
0127    //! <b>Throws</b>: Nothing.
0128    static bool is_header(const_node_ptr p) BOOST_NOEXCEPT
0129    {
0130       node_ptr p_left (NodeTraits::get_left(p));
0131       node_ptr p_right(NodeTraits::get_right(p));
0132       if(!NodeTraits::get_parent(p) || //Header condition when empty tree
0133          (p_left && p_right &&         //Header always has leftmost and rightmost
0134             (p_left == p_right ||      //Header condition when only node
0135                (NodeTraits::get_parent(p_left)  != p ||
0136                 NodeTraits::get_parent(p_right) != p ))
0137                //When tree size > 1 headers can't be leftmost's
0138                //and rightmost's parent
0139           )){
0140          return true;
0141       }
0142       return false;
0143    }
0144 
0145    //! <b>Requires</b>: 'n' is a node of the tree or a header node.
0146    //!
0147    //! <b>Effects</b>: Returns the header of the tree.
0148    //!
0149    //! <b>Complexity</b>: Logarithmic.
0150    //!
0151    //! <b>Throws</b>: Nothing.
0152    static node_ptr get_header(const_node_ptr n)
0153    {
0154       node_ptr nn(detail::uncast(n));
0155       node_ptr p(NodeTraits::get_parent(n));
0156       //If p is null, then nn is the header of an empty tree
0157       if(p){
0158          //Non-empty tree, check if nn is neither root nor header
0159          node_ptr pp(NodeTraits::get_parent(p));
0160          //If granparent is not equal to nn, then nn is neither root nor header,
0161          //the try the fast path
0162          if(nn != pp){
0163             do{
0164                nn = p;
0165                p = pp;
0166                pp = NodeTraits::get_parent(pp);
0167             }while(nn != pp);
0168             nn = p;
0169          }
0170          //Check if nn is root or header when size() > 0
0171          else if(!bstree_algorithms_base::is_header(nn)){
0172             nn = p;
0173          }
0174       }
0175       return nn;
0176    }
0177 };
0178 
0179 }  //namespace intrusive
0180 }  //namespace boost
0181 
0182 #endif //BOOST_INTRUSIVE_BSTREE_ALGORITHMS_BASE_HPP