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()53int 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]), *it_rbeg_val(&ids[0]); 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[-1]) return 1; 84 85 return 0; 86 } 87 //] 88