|  | Home | Libraries | People | FAQ | More | 
As explained in the Concepts section, Boost.Intrusive containers are implemented using node algorithms that work on generic nodes.
Sometimes, the use of intrusive containers is expensive for some environments and the programmer might want to avoid all the template instantiations related to Boost.Intrusive containers. However, the user can still benefit from Boost.Intrusive using the node algorithms, because some of those algorithms, like red-black tree algorithms, are not trivial to write.
      All node algorithm classes are templatized by a NodeTraits
      class. This class encapsulates the needed internal type declarations and operations
      to make a node compatible with node algorithms. Each type of node algorithms
      has its own requirements:
    
        These algorithms are static members of the circular_slist_algorithms
        class:
      
template<class NodeTraits> struct circular_slist_algorithms;
        An empty list is formed by a node whose pointer to the next node points to
        itself. circular_slist_algorithms
        is configured with a NodeTraits class, which encapsulates the information
        about the node to be manipulated. NodeTraits must support the following interface:
      
Typedefs:
node: The type of the
            node that forms the circular list
          node_ptr: The type of
            a pointer to a node (usually node*)
          const_node_ptr: The type
            of a pointer to a const node (usually const node*)
          Static functions:
static node_ptr
            get_next(const_node_ptr n);: Returns a pointer to the next node
            stored in "n".
          static void
            set_next(node_ptr n, node_ptr
            next);:
            Sets the pointer to the next node stored in "n" to "next".
          Once we have a node traits configuration we can use Boost.Intrusive algorithms with our nodes:
#include <boost/intrusive/circular_slist_algorithms.hpp> #include <cassert> struct my_node { my_node *next_; //other members... }; //Define our own slist_node_traits struct my_slist_node_traits { typedef my_node node; typedef my_node * node_ptr; typedef const my_node * const_node_ptr; static node_ptr get_next(const_node_ptr n) { return n->next_; } static void set_next(node_ptr n, node_ptr next) { n->next_ = next; } }; int main() { typedef boost::intrusive::circular_slist_algorithms<my_slist_node_traits> algo; my_node one, two, three; //Create an empty singly linked list container: //"one" will be the first node of the container algo::init_header(&one); assert(algo::count(&one) == 1); //Now add a new node algo::link_after(&one, &two); assert(algo::count(&one) == 2); //Now add a new node after "one" algo::link_after(&one, &three); assert(algo::count(&one) == 3); //Now unlink the node after one algo::unlink_after(&one); assert(algo::count(&one) == 2); //Now unlink two algo::unlink(&two); assert(algo::count(&one) == 1); return 0; }
        For a complete list of functions see circular_slist_algorithms
        reference.
      
        These algorithms are static members of the circular_list_algorithms
        class:
      
template<class NodeTraits> struct circular_list_algorithms;
        An empty list is formed by a node whose pointer to the next node points to
        itself. circular_list_algorithms
        is configured with a NodeTraits class, which encapsulates the information
        about the node to be manipulated. NodeTraits must support the following interface:
      
Typedefs:
node: The type of the
            node that forms the circular list
          node_ptr: The type of
            a pointer to a node (usually node*)
          const_node_ptr: The type
            of a pointer to a const node (usually const node*)
          Static functions:
static node_ptr
            get_next(const_node_ptr n);: Returns a pointer to the next node
            stored in "n".
          static void
            set_next(node_ptr n, node_ptr
            next);:
            Sets the pointer to the next node stored in "n" to "next".
          static node_ptr
            get_previous(const_node_ptr n);: Returns a pointer to the previous
            node stored in "n".
          static void
            set_previous(node_ptr n, node_ptr
            prev);:
            Sets the pointer to the previous node stored in "n" to "prev".
          Once we have a node traits configuration we can use Boost.Intrusive algorithms with our nodes:
#include <boost/intrusive/circular_list_algorithms.hpp> #include <cassert> struct my_node { my_node *next_, *prev_; //other members... }; //Define our own list_node_traits struct my_list_node_traits { typedef my_node node; typedef my_node * node_ptr; typedef const my_node * const_node_ptr; static node_ptr get_next(const_node_ptr n) { return n->next_; } static void set_next(node_ptr n, node_ptr next) { n->next_ = next; } static node *get_previous(const_node_ptr n) { return n->prev_; } static void set_previous(node_ptr n, node_ptr prev){ n->prev_ = prev; } }; int main() { typedef boost::intrusive::circular_list_algorithms<my_list_node_traits> algo; my_node one, two, three; //Create an empty doubly linked list container: //"one" will be the first node of the container algo::init_header(&one); assert(algo::count(&one) == 1); //Now add a new node before "one" algo::link_before(&one, &two); assert(algo::count(&one) == 2); //Now add a new node after "two" algo::link_after(&two, &three); assert(algo::count(&one) == 3); //Now unlink the node after one algo::unlink(&three); assert(algo::count(&one) == 2); //Now unlink two algo::unlink(&two); assert(algo::count(&one) == 1); //Now unlink one algo::unlink(&one); assert(algo::count(&one) == 1); return 0; }
        For a complete list of functions see circular_list_algorithms
        reference.
      
        These algorithms are static members of the rbtree_algorithms
        class:
      
template<class NodeTraits> struct rbtree_algorithms;
        An empty tree is formed by a node whose pointer to the parent node is null,
        the left and right node pointers point to itself, and whose color is red.
        rbtree_algorithms
        is configured with a NodeTraits class, which encapsulates the information
        about the node to be manipulated. NodeTraits must support the following interface:
      
Typedefs:
node: The type of the
            node that forms the circular rbtree
          node_ptr: The type of
            a pointer to a node (usually node*)
          const_node_ptr: The type
            of a pointer to a const node (usually const node*)
          color: The type that
            can store the color of a node
          Static functions:
static node_ptr
            get_parent(const_node_ptr n);: Returns a pointer to the parent node
            stored in "n".
          static void
            set_parent(node_ptr n, node_ptr
            p);:
            Sets the pointer to the parent node stored in "n" to "p".
          static node_ptr
            get_left(const_node_ptr n);: Returns a pointer to the left node
            stored in "n".
          static void
            set_left(node_ptr n, node_ptr
            l);:
            Sets the pointer to the left node stored in "n" to "l".
          static node_ptr
            get_right(const_node_ptr n);: Returns a pointer to the right node
            stored in "n".
          static void
            set_right(node_ptr n, node_ptr
            r);:
            Sets the pointer to the right node stored in "n" to "r".
          static color
            get_color(const_node_ptr n);: Returns the color stored in "n".
          static void
            set_color(node_ptr n, color c);:
            Sets the color stored in "n" to "c".
          static color
            black();:
            Returns a value representing the black color.
          static color
            red();:
            Returns a value representing the red color.
          Once we have a node traits configuration we can use Boost.Intrusive algorithms with our nodes:
#include <boost/intrusive/rbtree_algorithms.hpp> #include <cassert> struct my_node { my_node(int i = 0) : int_(i) {} my_node *parent_, *left_, *right_; int color_; //other members int int_; }; //Define our own rbtree_node_traits struct my_rbtree_node_traits { typedef my_node node; typedef my_node * node_ptr; typedef const my_node * const_node_ptr; typedef int color; static node_ptr get_parent(const_node_ptr n) { return n->parent_; } static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; } static node_ptr get_left(const_node_ptr n) { return n->left_; } static void set_left(node_ptr n, node_ptr left) { n->left_ = left; } static node_ptr get_right(const_node_ptr n) { return n->right_; } static void set_right(node_ptr n, node_ptr right) { n->right_ = right; } static color get_color(const_node_ptr n) { return n->color_; } static void set_color(node_ptr n, color c) { n->color_ = c; } static color black() { return color(0); } static color red() { return color(1); } }; struct node_ptr_compare { bool operator()(const my_node *a, const my_node *b) { return a->int_ < b->int_; } }; int main() { typedef boost::intrusive::rbtree_algorithms<my_rbtree_node_traits> algo; my_node header, two(2), three(3); //Create an empty rbtree container: //"header" will be the header node of the tree algo::init_header(&header); //Now insert node "two" in the tree using the sorting functor algo::insert_equal_upper_bound(&header, &two, node_ptr_compare()); //Now insert node "three" in the tree using the sorting functor algo::insert_equal_lower_bound(&header, &three, node_ptr_compare()); //Now take the first node (the left node of the header) my_node *n = header.left_; assert(n == &two); //Now go to the next node n = algo::next_node(n); assert(n == &three); //Erase a node just using a pointer to it algo::unlink(&two); //Erase a node using also the header (faster) algo::erase(&header, &three); return 0; }
        For a complete list of functions see rbtree_algorithms
        reference.
      
        These algorithms are static members of the splaytree_algorithms
        class:
      
template<class NodeTraits> struct splaytree_algorithms;
        An empty tree is formed by a node whose pointer to the parent node is null,
        and whose left and right nodes pointers point to itself. splaytree_algorithms
        is configured with a NodeTraits class, which encapsulates the information
        about the node to be manipulated. NodeTraits must support the following interface:
      
Typedefs:
node: The type of the
            node that forms the circular splaytree
          node_ptr: The type of
            a pointer to a node (usually node*)
          const_node_ptr: The type
            of a pointer to a const node (usually const node*)
          Static functions:
static node_ptr
            get_parent(const_node_ptr n);: Returns a pointer to the parent node
            stored in "n".
          static void
            set_parent(node_ptr n, node_ptr
            p);:
            Sets the pointer to the parent node stored in "n" to "p".
          static node_ptr
            get_left(const_node_ptr n);: Returns a pointer to the left node
            stored in "n".
          static void
            set_left(node_ptr n, node_ptr
            l);:
            Sets the pointer to the left node stored in "n" to "l".
          static node_ptr
            get_right(const_node_ptr n);: Returns a pointer to the right node
            stored in "n".
          static void
            set_right(node_ptr n, node_ptr
            r);:
            Sets the pointer to the right node stored in "n" to "r".
          Once we have a node traits configuration we can use Boost.Intrusive algorithms with our nodes:
#include <boost/intrusive/splaytree_algorithms.hpp> #include <cassert> struct my_node { my_node(int i = 0) : int_(i) {} my_node *parent_, *left_, *right_; //other members int int_; }; //Define our own splaytree_node_traits struct my_splaytree_node_traits { typedef my_node node; typedef my_node * node_ptr; typedef const my_node * const_node_ptr; static node_ptr get_parent(const_node_ptr n) { return n->parent_; } static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; } static node_ptr get_left(const_node_ptr n) { return n->left_; } static void set_left(node_ptr n, node_ptr left) { n->left_ = left; } static node_ptr get_right(const_node_ptr n) { return n->right_; } static void set_right(node_ptr n, node_ptr right) { n->right_ = right; } }; struct node_ptr_compare { bool operator()(const my_node *a, const my_node *b) { return a->int_ < b->int_; } }; int main() { typedef boost::intrusive::splaytree_algorithms<my_splaytree_node_traits> algo; my_node header, two(2), three(3); //Create an empty splaytree container: //"header" will be the header node of the tree algo::init_header(&header); //Now insert node "two" in the tree using the sorting functor algo::insert_equal_upper_bound(&header, &two, node_ptr_compare()); //Now insert node "three" in the tree using the sorting functor algo::insert_equal_lower_bound(&header, &three, node_ptr_compare()); //Now take the first node (the left node of the header) my_node *n = header.left_; assert(n == &two); //Now go to the next node n = algo::next_node(n); assert(n == &three); //Erase a node just using a pointer to it algo::unlink(&two); //Erase a node using also the header (faster) algo::erase(&header, &three); return 0; }
        For a complete list of functions see splaytree_algorithms
        reference.
      
        avltree_algorithms
        have the same interface as rbtree_algorithms.
      
template<class NodeTraits> struct avltree_algorithms;
        avltree_algorithms
        is configured with a NodeTraits class, which encapsulates the information
        about the node to be manipulated. NodeTraits must support the following interface:
      
Typedefs:
node: The type of the
            node that forms the circular avltree
          node_ptr: The type of
            a pointer to a node (usually node*)
          const_node_ptr: The type
            of a pointer to a const node (usually const node*)
          balance: A type that
            can represent 3 balance types (usually an integer)
          Static functions:
static node_ptr
            get_parent(const_node_ptr n);: Returns a pointer to the parent node
            stored in "n".
          static void
            set_parent(node_ptr n, node_ptr
            p);:
            Sets the pointer to the parent node stored in "n" to "p".
          static node_ptr
            get_left(const_node_ptr n);: Returns a pointer to the left node
            stored in "n".
          static void
            set_left(node_ptr n, node_ptr
            l);:
            Sets the pointer to the left node stored in "n" to "l".
          static node_ptr
            get_right(const_node_ptr n);: Returns a pointer to the right node
            stored in "n".
          static void
            set_right(node_ptr n, node_ptr
            r);:
            Sets the pointer to the right node stored in "n" to "r".
          static balance
            get_balance(const_node_ptr n);: Returns the balance factor stored
            in "n".
          static void
            set_balance(node_ptr n, balance
            b);:
            Sets the balance factor stored in "n" to "b".
          static balance
            negative();:
            Returns a value representing a negative balance factor.
          static balance
            zero();:
            Returns a value representing a zero balance factor.
          static balance
            positive();:
            Returns a value representing a positive balance factor.
          Once we have a node traits configuration we can use Boost.Intrusive algorithms with our nodes:
#include <boost/intrusive/avltree_algorithms.hpp> #include <cassert> struct my_node { my_node(int i = 0) : int_(i) {} my_node *parent_, *left_, *right_; int balance_; //other members int int_; }; //Define our own avltree_node_traits struct my_avltree_node_traits { typedef my_node node; typedef my_node * node_ptr; typedef const my_node * const_node_ptr; typedef int balance; static node_ptr get_parent(const_node_ptr n) { return n->parent_; } static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; } static node_ptr get_left(const_node_ptr n) { return n->left_; } static void set_left(node_ptr n, node_ptr left) { n->left_ = left; } static node_ptr get_right(const_node_ptr n) { return n->right_; } static void set_right(node_ptr n, node_ptr right) { n->right_ = right; } static balance get_balance(const_node_ptr n) { return n->balance_; } static void set_balance(node_ptr n, balance b) { n->balance_ = b; } static balance negative() { return -1; } static balance zero() { return 0; } static balance positive() { return 1; } }; struct node_ptr_compare { bool operator()(const my_node *a, const my_node *b) { return a->int_ < b->int_; } }; int main() { typedef boost::intrusive::avltree_algorithms<my_avltree_node_traits> algo; my_node header, two(2), three(3); //Create an empty avltree container: //"header" will be the header node of the tree algo::init_header(&header); //Now insert node "two" in the tree using the sorting functor algo::insert_equal_upper_bound(&header, &two, node_ptr_compare()); //Now insert node "three" in the tree using the sorting functor algo::insert_equal_lower_bound(&header, &three, node_ptr_compare()); //Now take the first node (the left node of the header) my_node *n = header.left_; assert(n == &two); //Now go to the next node n = algo::next_node(n); assert(n == &three); //Erase a node just using a pointer to it algo::unlink(&two); //Erase a node using also the header (faster) algo::erase(&header, &three); return 0; }
        For a complete list of functions see avltree_algorithms
        reference.
      
        treap_algorithms
        have the same interface as rbtree_algorithms.
      
template<class NodeTraits> struct treap_algorithms;
        treap_algorithms
        is configured with a NodeTraits class, which encapsulates the information
        about the node to be manipulated. NodeTraits must support the following interface:
      
Typedefs:
node: The type of the
            node that forms the circular treap
          node_ptr: The type of
            a pointer to a node (usually node*)
          const_node_ptr: The type
            of a pointer to a const node (usually const node*)
          Static functions:
static node_ptr
            get_parent(const_node_ptr n);: Returns a pointer to the parent node
            stored in "n".
          static void
            set_parent(node_ptr n, node_ptr
            p);:
            Sets the pointer to the parent node stored in "n" to "p".
          static node_ptr
            get_left(const_node_ptr n);: Returns a pointer to the left node
            stored in "n".
          static void
            set_left(node_ptr n, node_ptr
            l);:
            Sets the pointer to the left node stored in "n" to "l".
          static node_ptr
            get_right(const_node_ptr n);: Returns a pointer to the right node
            stored in "n".
          static void
            set_right(node_ptr n, node_ptr
            r);:
            Sets the pointer to the right node stored in "n" to "r".
          Once we have a node traits configuration we can use Boost.Intrusive algorithms with our nodes:
#include <boost/intrusive/treap_algorithms.hpp> #include <cassert> struct my_node { my_node(int i = 0, unsigned int priority = 0) : prio_(priority), int_(i) {} my_node *parent_, *left_, *right_; int prio_; //other members int int_; }; //Define our own treap_node_traits struct my_treap_node_traits { typedef my_node node; typedef my_node * node_ptr; typedef const my_node * const_node_ptr; static node_ptr get_parent(const_node_ptr n) { return n->parent_; } static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; } static node_ptr get_left(const_node_ptr n) { return n->left_; } static void set_left(node_ptr n, node_ptr left) { n->left_ = left; } static node_ptr get_right(const_node_ptr n) { return n->right_; } static void set_right(node_ptr n, node_ptr right) { n->right_ = right; } }; struct node_ptr_compare { bool operator()(const my_node *a, const my_node *b) { return a->int_ < b->int_; } }; struct node_ptr_priority { bool operator()(const my_node *a, const my_node *b) { return a->prio_ < b->prio_;} }; int main() { typedef boost::intrusive::treap_algorithms<my_treap_node_traits> algo; my_node header, two(2, 5), three(3, 1); //Create an empty treap container: //"header" will be the header node of the tree algo::init_header(&header); //Now insert node "two" in the tree using the sorting functor algo::insert_equal_upper_bound(&header, &two, node_ptr_compare(), node_ptr_priority()); //Now insert node "three" in the tree using the sorting functor algo::insert_equal_lower_bound(&header, &three, node_ptr_compare(), node_ptr_priority()); //Now take the first node (the left node of the header) my_node *n = header.left_; assert(n == &two); //Now go to the next node n = algo::next_node(n); assert(n == &three); //Erase a node just using a pointer to it algo::unlink(&two, node_ptr_priority()); //Erase a node using also the header (faster) algo::erase(&header, &three, node_ptr_priority()); return 0; }
        For a complete list of functions see treap_algorithms
        reference.