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:

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:

staticnode_ptrget_next(const_node_ptrn);: Returns a pointer to the next node stored
in "n".

staticvoidset_next(node_ptrn,node_ptrnext);:
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>structmy_node{my_node*next_;//other members...
};//Define our own slist_node_traits
structmy_slist_node_traits{typedefmy_nodenode;typedefmy_node*node_ptr;typedefconstmy_node*const_node_ptr;staticnode_ptrget_next(const_node_ptrn){returnn->next_;}staticvoidset_next(node_ptrn,node_ptrnext){n->next_=next;}};intmain(){typedefboost::intrusive::circular_slist_algorithms<my_slist_node_traits>algo;my_nodeone,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);return0;}

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:

staticnode_ptrget_next(const_node_ptrn);: Returns a pointer to the next node stored
in "n".

staticvoidset_next(node_ptrn,node_ptrnext);:
Sets the pointer to the next node stored in "n" to "next".

staticnode_ptrget_previous(const_node_ptrn);: Returns a pointer to the previous node
stored in "n".

staticvoidset_previous(node_ptrn,node_ptrprev);:
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>structmy_node{my_node*next_,*prev_;//other members...
};//Define our own list_node_traits
structmy_list_node_traits{typedefmy_nodenode;typedefmy_node*node_ptr;typedefconstmy_node*const_node_ptr;staticnode_ptrget_next(const_node_ptrn){returnn->next_;}staticvoidset_next(node_ptrn,node_ptrnext){n->next_=next;}staticnode*get_previous(const_node_ptrn){returnn->prev_;}staticvoidset_previous(node_ptrn,node_ptrprev){n->prev_=prev;}};intmain(){typedefboost::intrusive::circular_list_algorithms<my_list_node_traits>algo;my_nodeone,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);return0;}

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:

staticnode_ptrget_parent(const_node_ptrn);: Returns a pointer to the parent node
stored in "n".

staticvoidset_parent(node_ptrn,node_ptrp);:
Sets the pointer to the parent node stored in "n" to "p".

staticnode_ptrget_left(const_node_ptrn);: Returns a pointer to the left node stored
in "n".

staticvoidset_left(node_ptrn,node_ptrl);:
Sets the pointer to the left node stored in "n" to "l".

staticnode_ptrget_right(const_node_ptrn);: Returns a pointer to the right node
stored in "n".

staticvoidset_right(node_ptrn,node_ptrr);:
Sets the pointer to the right node stored in "n" to "r".

staticvoidset_color(node_ptrn,colorc);:
Sets the color stored in "n" to "c".

staticcolorblack();:
Returns a value representing the black color.

staticcolorred();:
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>structmy_node{my_node(inti=0):int_(i){}my_node*parent_,*left_,*right_;intcolor_;//other members
intint_;};//Define our own rbtree_node_traits
structmy_rbtree_node_traits{typedefmy_nodenode;typedefmy_node*node_ptr;typedefconstmy_node*const_node_ptr;typedefintcolor;staticnode_ptrget_parent(const_node_ptrn){returnn->parent_;}staticvoidset_parent(node_ptrn,node_ptrparent){n->parent_=parent;}staticnode_ptrget_left(const_node_ptrn){returnn->left_;}staticvoidset_left(node_ptrn,node_ptrleft){n->left_=left;}staticnode_ptrget_right(const_node_ptrn){returnn->right_;}staticvoidset_right(node_ptrn,node_ptrright){n->right_=right;}staticcolorget_color(const_node_ptrn){returnn->color_;}staticvoidset_color(node_ptrn,colorc){n->color_=c;}staticcolorblack(){returncolor(0);}staticcolorred(){returncolor(1);}};structnode_ptr_compare{booloperator()(constmy_node*a,constmy_node*b){returna->int_<b->int_;}};intmain(){typedefboost::intrusive::rbtree_algorithms<my_rbtree_node_traits>algo;my_nodeheader,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);return0;}

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:

staticnode_ptrget_parent(const_node_ptrn);: Returns a pointer to the parent node
stored in "n".

staticvoidset_parent(node_ptrn,node_ptrp);:
Sets the pointer to the parent node stored in "n" to "p".

staticnode_ptrget_left(const_node_ptrn);: Returns a pointer to the left node stored
in "n".

staticvoidset_left(node_ptrn,node_ptrl);:
Sets the pointer to the left node stored in "n" to "l".

staticnode_ptrget_right(const_node_ptrn);: Returns a pointer to the right node
stored in "n".

staticvoidset_right(node_ptrn,node_ptrr);:
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>structmy_node{my_node(inti=0):int_(i){}my_node*parent_,*left_,*right_;//other members
intint_;};//Define our own splaytree_node_traits
structmy_splaytree_node_traits{typedefmy_nodenode;typedefmy_node*node_ptr;typedefconstmy_node*const_node_ptr;staticnode_ptrget_parent(const_node_ptrn){returnn->parent_;}staticvoidset_parent(node_ptrn,node_ptrparent){n->parent_=parent;}staticnode_ptrget_left(const_node_ptrn){returnn->left_;}staticvoidset_left(node_ptrn,node_ptrleft){n->left_=left;}staticnode_ptrget_right(const_node_ptrn){returnn->right_;}staticvoidset_right(node_ptrn,node_ptrright){n->right_=right;}};structnode_ptr_compare{booloperator()(constmy_node*a,constmy_node*b){returna->int_<b->int_;}};intmain(){typedefboost::intrusive::splaytree_algorithms<my_splaytree_node_traits>algo;my_nodeheader,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);return0;}

Once we have a node traits configuration we can use Boost.Intrusive
algorithms with our nodes:

#include<boost/intrusive/avltree_algorithms.hpp>#include<cassert>structmy_node{my_node(inti=0):int_(i){}my_node*parent_,*left_,*right_;intbalance_;//other members
intint_;};//Define our own avltree_node_traits
structmy_avltree_node_traits{typedefmy_nodenode;typedefmy_node*node_ptr;typedefconstmy_node*const_node_ptr;typedefintbalance;staticnode_ptrget_parent(const_node_ptrn){returnn->parent_;}staticvoidset_parent(node_ptrn,node_ptrparent){n->parent_=parent;}staticnode_ptrget_left(const_node_ptrn){returnn->left_;}staticvoidset_left(node_ptrn,node_ptrleft){n->left_=left;}staticnode_ptrget_right(const_node_ptrn){returnn->right_;}staticvoidset_right(node_ptrn,node_ptrright){n->right_=right;}staticbalanceget_balance(const_node_ptrn){returnn->balance_;}staticvoidset_balance(node_ptrn,balanceb){n->balance_=b;}staticbalancenegative(){return-1;}staticbalancezero(){return0;}staticbalancepositive(){return1;}};structnode_ptr_compare{booloperator()(constmy_node*a,constmy_node*b){returna->int_<b->int_;}};intmain(){typedefboost::intrusive::avltree_algorithms<my_avltree_node_traits>algo;my_nodeheader,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);return0;}

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:

staticnode_ptrget_parent(const_node_ptrn);: Returns a pointer to the parent node
stored in "n".

staticvoidset_parent(node_ptrn,node_ptrp);:
Sets the pointer to the parent node stored in "n" to "p".

staticnode_ptrget_left(const_node_ptrn);: Returns a pointer to the left node stored
in "n".

staticvoidset_left(node_ptrn,node_ptrl);:
Sets the pointer to the left node stored in "n" to "l".

staticnode_ptrget_right(const_node_ptrn);: Returns a pointer to the right node
stored in "n".

staticvoidset_right(node_ptrn,node_ptrr);:
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>structmy_node{my_node(inti=0,unsignedintpriority=0):prio_(priority),int_(i){}my_node*parent_,*left_,*right_;intprio_;//other members
intint_;};//Define our own treap_node_traits
structmy_treap_node_traits{typedefmy_nodenode;typedefmy_node*node_ptr;typedefconstmy_node*const_node_ptr;staticnode_ptrget_parent(const_node_ptrn){returnn->parent_;}staticvoidset_parent(node_ptrn,node_ptrparent){n->parent_=parent;}staticnode_ptrget_left(const_node_ptrn){returnn->left_;}staticvoidset_left(node_ptrn,node_ptrleft){n->left_=left;}staticnode_ptrget_right(const_node_ptrn){returnn->right_;}staticvoidset_right(node_ptrn,node_ptrright){n->right_=right;}};structnode_ptr_compare{booloperator()(constmy_node*a,constmy_node*b){returna->int_<b->int_;}};structnode_ptr_priority{booloperator()(constmy_node*a,constmy_node*b){returna->prio_<b->prio_;}};intmain(){typedefboost::intrusive::treap_algorithms<my_treap_node_traits>algo;my_nodeheader,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());return0;}