1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga  2007-2013
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 //    (See accompanying file LICENSE_1_0.txt or copy at
7 //          http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // See http://www.boost.org/libs/intrusive for documentation.
10 //
11 /////////////////////////////////////////////////////////////////////////////
12 //[doc_stateful_value_traits
13 #include <boost/intrusive/list.hpp>
14 
15 using namespace boost::intrusive;
16 
17 //This type is not modifiable so we can't store hooks or custom nodes
18 typedef int identifier_t;
19 
20 //This value traits will associate elements from an array of identifiers with
21 //elements of an array of nodes. The element i of the value array will use the
22 //node i of the node array:
23 struct stateful_value_traits
24 {
25    typedef list_node_traits<void*>           node_traits;
26    typedef node_traits::node                 node;
27    typedef node *                            node_ptr;
28    typedef const node *                      const_node_ptr;
29    typedef identifier_t                      value_type;
30    typedef identifier_t *                    pointer;
31    typedef const identifier_t *              const_pointer;
32    static const link_mode_type link_mode =   normal_link;
33 
stateful_value_traitsstateful_value_traits34    stateful_value_traits(pointer ids, node_ptr node_array)
35       :  ids_(ids),  nodes_(node_array)
36    {}
37 
38    ///Note: non static functions!
to_node_ptrstateful_value_traits39    node_ptr to_node_ptr (value_type &value) const
40       {  return this->nodes_ + (&value - this->ids_); }
to_node_ptrstateful_value_traits41    const_node_ptr to_node_ptr (const value_type &value) const
42       {  return this->nodes_ + (&value - this->ids_); }
to_value_ptrstateful_value_traits43    pointer to_value_ptr(node_ptr n) const
44       {  return this->ids_ + (n - this->nodes_); }
to_value_ptrstateful_value_traits45    const_pointer to_value_ptr(const_node_ptr n) const
46       {  return this->ids_ + (n - this->nodes_); }
47 
48    private:
49    pointer  ids_;
50    node_ptr nodes_;
51 };
52 
main()53 int main()
54 {
55    const int NumElements = 100;
56 
57    //This is an array of ids that we want to "store"
58    identifier_t                  ids   [NumElements];
59 
60    //This is an array of nodes that is necessary to form the linked list
61    list_node_traits<void*>::node nodes [NumElements];
62 
63    //Initialize id objects, each one with a different number
64    for(int i = 0; i != NumElements; ++i)   ids[i] = i;
65 
66    //Define a list that will "link" identifiers using external nodes
67    typedef list<identifier_t, value_traits<stateful_value_traits> > List;
68 
69    //This list will store ids without modifying identifier_t instances
70    //Stateful value traits must be explicitly passed in the constructor.
71    List  my_list (stateful_value_traits (ids, nodes));
72 
73    //Insert ids in reverse order in the list
74    for(identifier_t * it(&ids[0]), *itend(&ids[NumElements]); it != itend; ++it)
75       my_list.push_front(*it);
76 
77    //Now test lists
78    List::const_iterator   list_it (my_list.cbegin());
79    identifier_t *it_val(&ids[NumElements-1]), *it_rbeg_val(&ids[0]-1);
80 
81    //Test the objects inserted in the base hook list
82    for(; it_val != it_rbeg_val; --it_val, ++list_it)
83       if(&*list_it  != &*it_val)   return 1;
84 
85    return 0;
86 }
87 //]
88