Boost logo

Boost-Commit :

From: igaztanaga_at_[hidden]
Date: 2007-09-26 13:38:35


Author: igaztanaga
Date: 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
New Revision: 39550
URL: http://svn.boost.org/trac/boost/changeset/39550

Log:
Changes introduced by the new intrusive version.
Added:
   trunk/libs/intrusive/example/doc_bucket_traits.cpp (contents, props changed)
   trunk/libs/intrusive/example/doc_external_value_traits.cpp (contents, props changed)
   trunk/libs/intrusive/example/doc_stateful_value_traits.cpp (contents, props changed)
   trunk/libs/intrusive/test/custom_bucket_traits_test.cpp (contents, props changed)
   trunk/libs/intrusive/test/default_hook_test.cpp (contents, props changed)
   trunk/libs/intrusive/test/external_value_traits_test.cpp (contents, props changed)
   trunk/libs/intrusive/test/make_functions_test.cpp (contents, props changed)
   trunk/libs/intrusive/test/stateful_value_traits_test.cpp (contents, props changed)
   trunk/libs/intrusive/test/virtual_base_test.cpp (contents, props changed)
Text files modified:
   trunk/libs/intrusive/example/doc_advanced_value_traits.cpp | 12
   trunk/libs/intrusive/example/doc_advanced_value_traits2.cpp | 6
   trunk/libs/intrusive/example/doc_assoc_optimized_code.cpp | 76 ++++------
   trunk/libs/intrusive/example/doc_auto_unlink.cpp | 33 ++--
   trunk/libs/intrusive/example/doc_clone_from.cpp | 24 +-
   trunk/libs/intrusive/example/doc_entity.cpp | 27 +-
   trunk/libs/intrusive/example/doc_erasing_and_disposing.cpp | 17 -
   trunk/libs/intrusive/example/doc_how_to_use.cpp | 47 ++----
   trunk/libs/intrusive/example/doc_iterator_from_value.cpp | 59 ++++---
   trunk/libs/intrusive/example/doc_list.cpp | 50 ++----
   trunk/libs/intrusive/example/doc_offset_ptr.cpp | 103 ++++++++------
   trunk/libs/intrusive/example/doc_set.cpp | 61 +++-----
   trunk/libs/intrusive/example/doc_slist.cpp | 49 ++----
   trunk/libs/intrusive/example/doc_unordered_set.cpp | 75 ++++------
   trunk/libs/intrusive/example/doc_value_traits.cpp | 15 +
   trunk/libs/intrusive/example/doc_window.cpp | 12
   trunk/libs/intrusive/perf/perf_list.cpp | 103 ++++++++------
   trunk/libs/intrusive/test/list_test.cpp | 221 +++++++++++++++++++-----------
   trunk/libs/intrusive/test/multiset_test.cpp | 226 +++++++++++++++++++------------
   trunk/libs/intrusive/test/set_test.cpp | 215 ++++++++++++++++-------------
   trunk/libs/intrusive/test/slist_test.cpp | 208 ++++++++++++++++++----------
   trunk/libs/intrusive/test/unordered_multiset_test.cpp | 284 ++++++++++++++++++---------------------
   trunk/libs/intrusive/test/unordered_set_test.cpp | 277 ++++++++++++++++++--------------------
   23 files changed, 1145 insertions(+), 1055 deletions(-)

Modified: trunk/libs/intrusive/example/doc_advanced_value_traits.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_advanced_value_traits.cpp (original)
+++ trunk/libs/intrusive/example/doc_advanced_value_traits.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -10,7 +10,7 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 //[doc_advanced_value_traits_code
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/list.hpp>
 #include <vector>
 
@@ -46,7 +46,7 @@
 
 //A templatized value traits for value_1 and value_2
 template<class ValueType>
-struct value_traits
+struct simple_value_traits
 {
    typedef simple_node_traits node_traits;
    typedef node_traits::node_ptr node_ptr;
@@ -54,7 +54,7 @@
    typedef ValueType value_type;
    typedef ValueType * pointer;
    typedef const ValueType * const_pointer;
- enum { linking_policy = boost::intrusive::normal_link };
+ static const boost::intrusive::link_mode_type link_mode = boost::intrusive::normal_link;
    static node_ptr to_node_ptr (value_type &value) { return node_ptr(&value); }
    static const_node_ptr to_node_ptr (const value_type &value) { return const_node_ptr(&value); }
    static pointer to_value_ptr(node_ptr n) { return static_cast<value_type*>(n); }
@@ -65,8 +65,10 @@
 //[doc_advanced_value_traits_containers
 //Now define two intrusive lists. Both lists will use the same algorithms:
 // circular_list_algorithms<simple_node_traits>
-typedef boost::intrusive::list <value_traits<value_1> > Value1List;
-typedef boost::intrusive::list <value_traits<value_2> > Value2List;
+
+using namespace boost::intrusive;
+typedef list <value_1, value_traits<simple_value_traits<value_1> > > Value1List;
+typedef list <value_2, value_traits<simple_value_traits<value_2> > > Value2List;
 //]
 
 //[doc_advanced_value_traits_test

Modified: trunk/libs/intrusive/example/doc_advanced_value_traits2.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_advanced_value_traits2.cpp (original)
+++ trunk/libs/intrusive/example/doc_advanced_value_traits2.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -9,7 +9,7 @@
 // See http://www.boost.org/libs/intrusive for documentation.
 //
 /////////////////////////////////////////////////////////////////////////////
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/list.hpp>
 #include <boost/intrusive/member_value_traits.hpp>
 #include <vector>
@@ -57,8 +57,8 @@
 
 //Now define two intrusive lists. Both lists will use the same algorithms:
 // circular_list_algorithms<simple_node_traits>
-typedef boost::intrusive::list <ValueTraits1> Value1List;
-typedef boost::intrusive::list <ValueTraits2> Value2List;
+typedef list <value_1, value_traits<ValueTraits1> > Value1List;
+typedef list <value_2, value_traits<ValueTraits2> > Value2List;
 //]
 
 //[doc_advanced_value_traits2_test

Modified: trunk/libs/intrusive/example/doc_assoc_optimized_code.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_assoc_optimized_code.cpp (original)
+++ trunk/libs/intrusive/example/doc_assoc_optimized_code.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -51,24 +51,21 @@
 };
 
 // A set and unordered_set that store Expensive objects
-typedef set<set_base_hook<>::value_traits<Expensive> > Set;
-typedef unordered_set<unordered_set_base_hook<>::
- value_traits<Expensive> > UnorderedSet;
+typedef set<Expensive> Set;
+typedef unordered_set<Expensive> UnorderedSet;
 
 // Search functions
-Expensive *get_from_set(const char* key, Set &set)
+Expensive *get_from_set(const char* key, Set &set_object)
 {
- Set::iterator it = set.find(Expensive(key));
- if( it == set.end() ) return 0;
+ Set::iterator it = set_object.find(Expensive(key));
+ if( it == set_object.end() ) return 0;
    return &*it;
 }
 
-Expensive *get_from_unordered_set
- (const char* key, UnorderedSet &unordered_set)
+Expensive *get_from_uset(const char* key, UnorderedSet &uset_object)
 {
- UnorderedSet::iterator it =
- unordered_set.find(Expensive (key));
- if( it == unordered_set.end() ) return 0;
+ UnorderedSet::iterator it = uset_object.find(Expensive (key));
+ if( it == uset_object.end() ) return 0;
    return &*it;
 }
 //]
@@ -94,38 +91,35 @@
 };
 
 // Optimized search functions
-Expensive *get_from_set_optimized(const char* key, Set &set)
+Expensive *get_from_set_optimized(const char* key, Set &set_object)
 {
- Set::iterator it = set.find(key, StrExpComp());
- if( it == set.end() ) return 0;
+ Set::iterator it = set_object.find(key, StrExpComp());
+ if( it == set_object.end() ) return 0;
    return &*it;
 }
 
-Expensive *get_from_unordered_set_optimized
- (const char* key, UnorderedSet &unordered_set)
+Expensive *get_from_uset_optimized(const char* key, UnorderedSet &uset_object)
 {
- UnorderedSet::iterator it =
- unordered_set.find(key, StrHasher(), StrExpEqual());
- if( it == unordered_set.end() ) return 0;
+ UnorderedSet::iterator it = uset_object.find(key, StrHasher(), StrExpEqual());
+ if( it == uset_object.end() ) return 0;
    return &*it;
 }
 //]
 
 //[doc_assoc_optimized_code_normal_insert
 // Insertion functions
-bool insert_to_set(const char* key, Set &set)
+bool insert_to_set(const char* key, Set &set_object)
 {
    Expensive *pobject = new Expensive(key);
- bool success = set.insert(*pobject).second;
+ bool success = set_object.insert(*pobject).second;
    if(!success) delete pobject;
    return success;
 }
 
-bool insert_to_unordered_set
- (const char* key, UnorderedSet &unordered_set)
+bool insert_to_uset(const char* key, UnorderedSet &uset_object)
 {
    Expensive *pobject = new Expensive(key);
- bool success = unordered_set.insert(*pobject).second;
+ bool success = uset_object.insert(*pobject).second;
    if(!success) delete pobject;
    return success;
 }
@@ -133,24 +127,20 @@
 
 //[doc_assoc_optimized_code_optimized_insert
 // Optimized insertion functions
-bool insert_to_set_optimized(const char* key, Set &set)
+bool insert_to_set_optimized(const char* key, Set &set_object)
 {
    Set::insert_commit_data insert_data;
- bool success = set.insert_check
- (key, StrExpComp(), insert_data).second;
- if(success)
- set.insert_commit(*new Expensive(key), insert_data);
+ bool success = set_object.insert_check(key, StrExpComp(), insert_data).second;
+ if(success) set_object.insert_commit(*new Expensive(key), insert_data);
    return success;
 }
 
-bool insert_to_unordered_set_optimized
- (const char* key, UnorderedSet &unordered_set)
+bool insert_to_uset_optimized(const char* key, UnorderedSet &uset_object)
 {
    UnorderedSet::insert_commit_data insert_data;
- bool success = unordered_set.insert_check
+ bool success = uset_object.insert_check
       (key, StrHasher(), StrExpEqual(), insert_data).second;
- if(success)
- unordered_set.insert_commit(*new Expensive(key), insert_data);
+ if(success) uset_object.insert_commit(*new Expensive(key), insert_data);
    return success;
 }
 //]
@@ -159,7 +149,7 @@
 {
    Set set;
    UnorderedSet::bucket_type buckets[10];
- UnorderedSet unordered_set(buckets, 10);
+ UnorderedSet unordered_set(UnorderedSet::bucket_traits(buckets, 10));
 
    const char * const expensive_key
       = "A long string that avoids small string optimization";
@@ -170,7 +160,7 @@
       return 1;
    }
 
- if(get_from_unordered_set(expensive_key, unordered_set)){
+ if(get_from_uset(expensive_key, unordered_set)){
       return 1;
    }
 
@@ -178,7 +168,7 @@
       return 1;
    }
 
- if(get_from_unordered_set_optimized(expensive_key, unordered_set)){
+ if(get_from_uset_optimized(expensive_key, unordered_set)){
       return 1;
    }
 
@@ -189,7 +179,7 @@
       return 1;
    }
 
- if(!get_from_unordered_set(expensive_key, unordered_set)){
+ if(!get_from_uset(expensive_key, unordered_set)){
       return 1;
    }
 
@@ -197,7 +187,7 @@
       return 1;
    }
 
- if(!get_from_unordered_set_optimized(expensive_key, unordered_set)){
+ if(!get_from_uset_optimized(expensive_key, unordered_set)){
       return 1;
    }
 
@@ -208,7 +198,7 @@
       return 1;
    }
 
- if(!insert_to_unordered_set(expensive_key, unordered_set)){
+ if(!insert_to_uset(expensive_key, unordered_set)){
       return 1;
    }
 
@@ -228,7 +218,7 @@
       return 1;
    }
 
- if(!insert_to_unordered_set_optimized(expensive_key, unordered_set)){
+ if(!insert_to_uset_optimized(expensive_key, unordered_set)){
       return 1;
    }
 
@@ -251,7 +241,7 @@
       return 1;
    }
 
- if(insert_to_unordered_set(expensive_key, unordered_set)){
+ if(insert_to_uset(expensive_key, unordered_set)){
       return 1;
    }
 
@@ -259,7 +249,7 @@
       return 1;
    }
 
- if(insert_to_unordered_set_optimized(expensive_key, unordered_set)){
+ if(insert_to_uset_optimized(expensive_key, unordered_set)){
       return 1;
    }
 

Modified: trunk/libs/intrusive/example/doc_auto_unlink.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_auto_unlink.cpp (original)
+++ trunk/libs/intrusive/example/doc_auto_unlink.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -15,39 +15,38 @@
 
 using namespace boost::intrusive;
 
-class MyClass : public list_base_hook<tag, auto_unlink>
+typedef list_base_hook<link_mode<auto_unlink> > auto_unlink_hook;
+
+class MyClass : public auto_unlink_hook
                //This hook removes the node in the destructor
 {
    int int_;
 
    public:
    MyClass(int i = 0) : int_(i) {}
- void unlink() { list_base_hook<tag, auto_unlink>::unlink(); }
- bool is_linked() { return list_base_hook<tag, auto_unlink>::is_linked(); }
- int get() const { return int_; }
+ void unlink() { auto_unlink_hook::unlink(); }
+ bool is_linked() { return auto_unlink_hook::is_linked(); }
 };
 
-//Define a list that will store MyClass
-//using the public base hook
+//Define a list that will store values using the base hook
 //The list can't have constant-time size!
-typedef list< list_base_hook<tag, auto_unlink>::
- value_traits<MyClass>, false > List;
+typedef list< MyClass, constant_time_size<false> > List;
 
 int main()
 {
    //Create the list
- List list;
+ List l;
    {
       //Create myclass and check it's linked
       MyClass myclass;
       assert(myclass.is_linked() == false);
 
       //Insert the object
- list.push_back(myclass);
+ l.push_back(myclass);
 
       //Check that we have inserted the object
- assert(list.empty() == false);
- assert(&list.front() == &myclass);
+ assert(l.empty() == false);
+ assert(&l.front() == &myclass);
       assert(myclass.is_linked() == true);
 
       //Now myclass' destructor will unlink it
@@ -55,7 +54,7 @@
    }
 
    //Check auto-unlink has been executed
- assert(list.empty() == true);
+ assert(l.empty() == true);
 
    {
       //Now test the unlink() function
@@ -65,18 +64,18 @@
       assert(myclass.is_linked() == false);
 
       //Insert the object
- list.push_back(myclass);
+ l.push_back(myclass);
 
       //Check that we have inserted the object
- assert(list.empty() == false);
- assert(&list.front() == &myclass);
+ assert(l.empty() == false);
+ assert(&l.front() == &myclass);
       assert(myclass.is_linked() == true);
 
       //Now unlink the node
       myclass.unlink();
 
       //Check auto-unlink has been executed
- assert(list.empty() == true);
+ assert(l.empty() == true);
    }
    return 0;
 }

Added: trunk/libs/intrusive/example/doc_bucket_traits.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/example/doc_bucket_traits.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,83 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+//[doc_bucket_traits
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/functional/hash.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+//A class to be inserted in an unordered_set
+class MyClass : public unordered_set_base_hook<>
+{
+ int int_;
+
+ public:
+ MyClass(int i = 0) : int_(i)
+ {}
+
+ friend bool operator==(const MyClass &l, const MyClass &r)
+ { return l.int_ == r.int_; }
+ friend std::size_t hash_value(const MyClass &v)
+ { return boost::hash_value(v.int_); }
+};
+
+//Define the base hook option
+typedef base_hook< unordered_set_base_hook<> > BaseHookOption;
+
+//Obtain the types of the bucket and the bucket pointer
+typedef unordered_bucket<BaseHookOption>::type BucketType;
+typedef unordered_bucket_ptr<BaseHookOption>::type BucketPtr;
+
+//The custom bucket traits.
+class custom_bucket_traits
+{
+ public:
+ static const int NumBuckets = 100;
+
+ custom_bucket_traits(BucketPtr buckets)
+ : buckets_(buckets)
+ {}
+
+ //Functions to be implemented by custom bucket traits
+ BucketPtr bucket_begin() const { return buckets_; }
+ std::size_t bucket_count() const { return NumBuckets;}
+
+ private:
+ BucketPtr buckets_;
+};
+
+//Define the container using the custom bucket traits
+typedef unordered_set<MyClass, bucket_traits<custom_bucket_traits> > BucketTraitsUset;
+
+int main()
+{
+ typedef std::vector<MyClass>::iterator VectIt;
+ std::vector<MyClass> values;
+
+ //Fill values
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
+
+ //Now create the bucket array and the custom bucket traits object
+ BucketType buckets[custom_bucket_traits::NumBuckets];
+ custom_bucket_traits btraits(buckets);
+
+ //Now create the unordered set
+ BucketTraitsUset uset(btraits);
+
+ //Insert the values in the unordered set
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
+ uset.insert(*it);
+
+ return 0;
+}
+//]

Modified: trunk/libs/intrusive/example/doc_clone_from.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_clone_from.cpp (original)
+++ trunk/libs/intrusive/example/doc_clone_from.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -14,9 +14,10 @@
 #include <iostream>
 #include <vector>
 
+using namespace boost::intrusive;
+
 //A class that can be inserted in an intrusive list
-class my_class
- : public boost::intrusive::list_base_hook<>
+class my_class : public list_base_hook<>
 {
    public:
    friend bool operator==(const my_class &a, const my_class &b)
@@ -28,20 +29,18 @@
 };
 
 //Definition of the intrusive list
-typedef boost::intrusive::list< my_class::value_traits<my_class> > my_class_list;
+typedef list<my_class> my_class_list;
 
 //Cloner object function
-class new_cloner
+struct new_cloner
 {
- public:
    my_class *operator()(const my_class &clone_this)
    { return new my_class(clone_this); }
 };
 
 //The disposer object function
-class delete_disposer
+struct delete_disposer
 {
- public:
    void operator()(my_class *delete_this)
    { delete delete_this; }
 };
@@ -54,9 +53,8 @@
    //Fill all the nodes and insert them in the list
    my_class_list list;
 
- for(int i = 0; i < MaxElem; ++i){
- nodes[i].int_ = i;
- }
+ for(int i = 0; i < MaxElem; ++i) nodes[i].int_ = i;
+
    list.insert(list.end(), nodes.begin(), nodes.end());
 
    //Now clone "list" using "new" and "delete" object functions
@@ -64,12 +62,10 @@
    cloned_list.clone_from(list, new_cloner(), delete_disposer());
 
    //Test that both are equal
- if(cloned_list != list){
+ if(cloned_list != list)
       std::cout << "Both lists are different" << std::endl;
- }
- else{
+ else
       std::cout << "Both lists are equal" << std::endl;
- }
 
    //Don't forget to free the memory from the second list
    cloned_list.clear_and_dispose(delete_disposer());

Modified: trunk/libs/intrusive/example/doc_entity.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_entity.cpp (original)
+++ trunk/libs/intrusive/example/doc_entity.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -12,9 +12,10 @@
 //[doc_entity_code
 #include <boost/intrusive/list.hpp>
 
+using namespace boost::intrusive;
+
 //A class that can be inserted in an intrusive list
-class entity
- : public boost::intrusive::list_base_hook<>
+class entity : public list_base_hook<>
 {
    public:
    virtual ~entity();
@@ -26,25 +27,25 @@
 {/**/};
 
 //Definition of the intrusive list
-typedef boost::intrusive::list< entity::value_traits<entity> > entity_list;
+typedef list<entity> entity_list;
 
 //A global list
-entity_list list;
+entity_list global_list;
 
-//The destructor removes itself from the list
+//The destructor removes itself from the global list
 entity::~entity()
-{ list.erase(entity_list::iterator_to(*this)); }
+{ global_list.erase(entity_list::s_iterator_to(*this)); }
 
-//Function to insert a new "some_entity" in the list
+//Function to insert a new "some_entity" in the global list
 void insert_some_entity()
-{ list.push_back (*new some_entity(/*...*/)); }
+{ global_list.push_back (*new some_entity(/*...*/)); }
 
-//Function to clear an entity from the intrusive list
+//Function to clear an entity from the intrusive global list
 void clear_list ()
 {
- // entity's destructor removes itself from the list implicitly
- while (!list.empty())
- delete &list.front();
+ // entity's destructor removes itself from the global list implicitly
+ while (!global_list.empty())
+ delete &global_list.front();
 }
 
 int main()
@@ -52,7 +53,7 @@
    //Insert some new entities
    insert_some_entity();
    insert_some_entity();
- //list's destructor will free objects
+ //global_list's destructor will free objects
    return 0;
 }
 

Modified: trunk/libs/intrusive/example/doc_erasing_and_disposing.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_erasing_and_disposing.cpp (original)
+++ trunk/libs/intrusive/example/doc_erasing_and_disposing.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -12,9 +12,10 @@
 //[doc_erasing_and_disposing
 #include <boost/intrusive/list.hpp>
 
+using namespace boost::intrusive;
+
 //A class that can be inserted in an intrusive list
-class my_class
- : public boost::intrusive::list_base_hook<>
+class my_class : public list_base_hook<>
 {
    public:
    my_class(int i)
@@ -26,20 +27,18 @@
 };
 
 //Definition of the intrusive list
-typedef boost::intrusive::list< my_class::value_traits<my_class> > my_class_list;
+typedef list<my_class> my_class_list;
 
 //The predicate function
-class is_even
+struct is_even
 {
- public:
    bool operator()(const my_class &c) const
    { return 0 == (c.int_ % 2); }
 };
 
 //The disposer object function
-class delete_disposer
+struct delete_disposer
 {
- public:
    void operator()(my_class *delete_this)
    { delete delete_this; }
 };
@@ -53,9 +52,7 @@
 
    try{
       //Insert new objects in the container
- for(int i = 0; i < MaxElem; ++i){
- list.push_back(*new my_class(i));
- }
+ for(int i = 0; i < MaxElem; ++i) list.push_back(*new my_class(i));
 
       //Now use remove_and_dispose_if to erase and delete the objects
       list.remove_and_dispose_if(is_even(), delete_disposer());

Added: trunk/libs/intrusive/example/doc_external_value_traits.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/example/doc_external_value_traits.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,129 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+//[doc_external_value_traits
+#include <boost/intrusive/list.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+//This type is not modifiable so we can't store hooks or custom nodes
+typedef int identifier_t;
+
+//This value traits will associate elements from an array of identifiers with
+//elements of an array of nodes. The element i of the value array will use the
+//node i of the node array:
+class external_traits
+{
+ //Non-copyable
+ external_traits(const external_traits &);
+ external_traits& operator=(const external_traits &);
+
+ public:
+ typedef list_node_traits<void*> node_traits;
+ typedef node_traits::node node;
+ typedef node * node_ptr;
+ typedef const node * const_node_ptr;
+ typedef identifier_t value_type;
+ typedef identifier_t * pointer;
+ typedef const identifier_t * const_pointer;
+ static const link_mode_type link_mode = normal_link;
+
+ external_traits(pointer ids, std::size_t NumElements)
+ : ids_(ids), nodes_(NumElements)
+ {}
+
+ ///Note: non static functions!
+ node_ptr to_node_ptr (value_type &value)
+ { return &this->nodes_[0] + (&value - this->ids_); }
+ const_node_ptr to_node_ptr (const value_type &value) const
+ { return &this->nodes_[0] + (&value - this->ids_); }
+ pointer to_value_ptr(node_ptr n)
+ { return this->ids_ + (n - &this->nodes_[0]); }
+ const_pointer to_value_ptr(const_node_ptr n) const
+ { return this->ids_ + (n - &this->nodes_[0]); }
+
+ private:
+ pointer ids_;
+ //This is an array of nodes that is necessary to form the linked list
+ std::vector<list_node_traits<void*>::node> nodes_;
+};
+
+//This is the value traits class that will be stored in the container
+//and that will lead to the external traits using the address
+//of the container.
+struct internal_traits
+{
+ static const bool external_value_traits = true;
+ typedef external_traits value_traits;
+
+ template<class Container>
+ value_traits &get_value_traits(Container &cont);
+
+ template<class Container>
+ const value_traits &get_value_traits(const Container &cont) const;
+};
+
+//The intrusive list that will use external value traits
+typedef list<identifier_t, value_traits<internal_traits> > List;
+
+class data_holder
+ : public List
+{
+ public:
+ data_holder(identifier_t *ids, std::size_t NumElements)
+ : List()
+ , external_traits_(ids, NumElements)
+ {}
+ external_traits external_traits_;
+};
+
+template<class Container>
+internal_traits::value_traits &internal_traits::get_value_traits(Container &cont)
+{ return static_cast<data_holder&>(cont).external_traits_; }
+
+template<class Container>
+const internal_traits::value_traits &internal_traits::get_value_traits(const Container &cont) const
+{ return static_cast<const data_holder&>(cont).external_traits_; }
+
+int main()
+{
+ const int NumElements = 100;
+
+ //This is an array of ids that we want to "store"
+ identifier_t ids [NumElements];
+
+ //Initialize id objects, each one with a different number
+ for(int i = 0; i != NumElements; ++i) ids[i] = i;
+
+ //The data holding the list and the external traits
+ data_holder data(ids, NumElements);
+
+ //This list will store ids without modifying identifier_t instances
+ //Stateful value traits must be explicitly passed in the constructor.
+ List &my_list = data;
+
+ //Insert ids in reverse order in the list
+ for(identifier_t * it(&ids[0]), *itend(&ids[NumElements]); it != itend; ++it)
+ my_list.push_front(*it);
+
+ //Now test lists
+ List::const_iterator list_it (my_list.cbegin());
+ identifier_t *it_val(&ids[NumElements]-1), *it_rbeg_val(&ids[0] -1);
+
+ //Test the objects inserted in the base hook list
+ for(; it_val != it_rbeg_val; --it_val, ++list_it){
+ if(&*list_it != &*it_val) return 1;
+ }
+
+ return 0;
+}
+//]

Modified: trunk/libs/intrusive/example/doc_how_to_use.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_how_to_use.cpp (original)
+++ trunk/libs/intrusive/example/doc_how_to_use.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -15,7 +15,7 @@
 
 using namespace boost::intrusive;
 
-class MyClass : public list_base_hook<>
+class MyClass : public list_base_hook<>
 {
    int int_;
 
@@ -23,62 +23,51 @@
    list_member_hook<> member_hook_;
 
    MyClass(int i) : int_(i) {}
- int get() const { return int_; }
 };
 
 //Define a list that will store MyClass using the base hook
-typedef list< list_base_hook<>::value_traits<MyClass> >
- BaseList;
+typedef list<MyClass> BaseList;
 
 //Define a list that will store MyClass using the member hook
-typedef list< list_member_hook<>::
- value_traits<MyClass, &MyClass::member_hook_>
- > MemberList;
+typedef member_hook
+ < MyClass, list_member_hook<>, &MyClass::member_hook_> MemberOption;
+typedef list<MyClass, MemberOption> MemberList;
 
 int main()
 {
- typedef std::vector<MyClass> Vect;
- typedef Vect::iterator VectIt;
- typedef Vect::reverse_iterator VectRit;
-
- //Create several MyClass objects, each one
- //with a different internal number
- Vect myclassvector;
- for(int i = 0; i < 100; ++i)
- myclassvector.push_back(MyClass(i));
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create several MyClass objects, each one with a different value
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
 
    BaseList baselist;
    MemberList memberlist;
 
- //Now insert them in the reverse order
- //in the base hook intrusive list
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
+ //Now insert them in the reverse order in the base hook list
+ for(VectIt it(values.begin()), itend(values.end())
       ; it != itend ; ++it){
       baselist.push_front(*it);
    }
 
- //Now insert them in the same order as in vector in the
- //member hook intrusive list
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
- ; it != itend; ++it){
+ //Now insert them in the same order as in vector in the member hook list
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
       memberlist.push_back(*it);
- }
 
    //Now test lists
    {
       BaseList::reverse_iterator rbit(baselist.rbegin()), rbitend(baselist.rend());
       MemberList::iterator mit(memberlist.begin()), mitend(memberlist.end());
- VectIt it(myclassvector.begin()), itend(myclassvector.end());
+ VectIt it(values.begin()), itend(values.end());
 
       //Test the objects inserted in the base hook list
- for(; it != itend; ++it, ++rbit){
+ for(; it != itend; ++it, ++rbit)
          if(&*rbit != &*it) return 1;
- }
 
       //Test the objects inserted in the member hook list
- for(it = myclassvector.begin(); it != itend; ++it, ++mit){
+ for(it = values.begin(); it != itend; ++it, ++mit)
          if(&*mit != &*it) return 1;
- }
    }
 
    return 0;

Modified: trunk/libs/intrusive/example/doc_iterator_from_value.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_iterator_from_value.cpp (original)
+++ trunk/libs/intrusive/example/doc_iterator_from_value.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -15,43 +15,44 @@
 #include <boost/functional/hash.hpp>
 #include <vector>
 
+using namespace boost::intrusive;
+
 class intrusive_data
 {
    int data_id_;
    public:
 
- int get() const { return data_id_; }
    void set(int id) { data_id_ = id; }
 
    //This class can be inserted in an intrusive list
- typedef boost::intrusive::
- list_member_hook<> list_member_hook_t;
- list_member_hook_t list_hook_;
+ list_member_hook<> list_hook_;
 
    //This class can be inserted in an intrusive unordered_set
- typedef boost::intrusive::
- unordered_set_member_hook<> unordered_set_member_hook_t;
- unordered_set_member_hook_t unordered_set_hook_;
+ unordered_set_member_hook<> unordered_set_hook_;
 
    //Comparison operators
    friend bool operator==(const intrusive_data &a, const intrusive_data &b)
- { return a.get() == b.get(); }
+ { return a.data_id_ == b.data_id_; }
 
    friend bool operator!=(const intrusive_data &a, const intrusive_data &b)
- { return a.get() != b.get(); }
-};
+ { return a.data_id_ != b.data_id_; }
 
-//The hash function
-std::size_t hash_value(const intrusive_data &i)
-{ return boost::hash<int>()(i.get()); }
+ //The hash function
+ friend std::size_t hash_value(const intrusive_data &i)
+ { return boost::hash<int>()(i.data_id_); }
+};
 
 //Definition of the intrusive list that will hold intrusive_data
-typedef boost::intrusive::list< intrusive_data::list_member_hook_t::
- value_traits<intrusive_data, &intrusive_data::list_hook_> > list_t;
+typedef member_hook<intrusive_data, list_member_hook<>
+ , &intrusive_data::list_hook_> MemberListOption;
+typedef list<intrusive_data, MemberListOption> list_t;
 
 //Definition of the intrusive unordered_set that will hold intrusive_data
-typedef boost::intrusive::unordered_set< intrusive_data::unordered_set_member_hook_t::
- value_traits<intrusive_data, &intrusive_data::unordered_set_hook_> > unordered_set_t;
+typedef member_hook
+ < intrusive_data, unordered_set_member_hook<>
+ , &intrusive_data::unordered_set_hook_> MemberUsetOption;
+typedef boost::intrusive::unordered_set
+ < intrusive_data, MemberUsetOption> unordered_set_t;
 
 int main()
 {
@@ -62,30 +63,32 @@
    //Declare the intrusive containers
    list_t list;
    unordered_set_t::bucket_type buckets[MaxElem];
- unordered_set_t unordered_set(buckets, MaxElem);
+ unordered_set_t unordered_set
+ (unordered_set_t::bucket_traits(buckets, MaxElem));
 
    //Initialize all the nodes
- for(int i = 0; i < MaxElem; ++i)
- nodes[i].set(i);
+ for(int i = 0; i < MaxElem; ++i) nodes[i].set(i);
 
    //Now insert them in both intrusive containers
    list.insert(list.end(), nodes.begin(), nodes.end());
    unordered_set.insert(nodes.begin(), nodes.end());
 
- //Now check list::iterator_to
- //which is an static member function
+ //Now check the iterator_to function
    list_t::iterator list_it(list.begin());
    for(int i = 0; i < MaxElem; ++i, ++list_it)
- if(list_t::iterator_to(nodes[i]) != list_it)
+ if(list.iterator_to(nodes[i]) != list_it ||
+ list_t::s_iterator_to(nodes[i]) != list_it)
          return 1;
 
- //Now check unordered_set::iterator_to (which is a member function)
- //and unordered_set::local_current (which is an static member function)
+ //Now check unordered_set::s_iterator_to (which is a member function)
+ //and unordered_set::s_local_iterator_to (which is an static member function)
    unordered_set_t::iterator unordered_set_it(unordered_set.begin());
- for(int i = 0; i < MaxElem; ++i, ++unordered_set_it){
- if(unordered_set.iterator_to(nodes[i]) != unordered_set.find(nodes[i]))
+ for(int i = 0; i < MaxElem; ++i){
+ unordered_set_it = unordered_set.find(nodes[i]);
+ if(unordered_set.iterator_to(nodes[i]) != unordered_set_it)
          return 1;
- if(*unordered_set_t::local_iterator_to(nodes[i]) != *unordered_set.find(nodes[i]))
+ if(*unordered_set.local_iterator_to(nodes[i]) != *unordered_set_it ||
+ *unordered_set_t::s_local_iterator_to(nodes[i]) != *unordered_set_it )
          return 1;
    }
 

Modified: trunk/libs/intrusive/example/doc_list.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_list.cpp (original)
+++ trunk/libs/intrusive/example/doc_list.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -15,7 +15,7 @@
 
 using namespace boost::intrusive;
 
-class MyClass : public list_base_hook<> //This is a derivation hook
+class MyClass : public list_base_hook<> //This is a derivation hook
 {
    int int_;
 
@@ -26,63 +26,49 @@
    MyClass(int i)
       : int_(i)
    {}
-
- int get() const
- { return int_; }
 };
 
 //Define a list that will store MyClass using the public base hook
-typedef list< list_base_hook<>::value_traits<MyClass> > BaseList;
+typedef list<MyClass> BaseList;
 
 //Define a list that will store MyClass using the public member hook
-typedef list< list_member_hook<>::value_traits<MyClass, &MyClass::member_hook_> > MemberList;
+typedef list< MyClass
+ , member_hook< MyClass, list_member_hook<>, &MyClass::member_hook_>
+ > MemberList;
 
 int main()
 {
- typedef std::vector<MyClass> Vect;
- typedef Vect::iterator VectIt;
- typedef Vect::reverse_iterator VectRit;
-
- //Create several MyClass objects, each one
- //with a different internal number
- Vect myclassvector;
- for(int i = 0; i < 100; ++i)
- myclassvector.push_back(MyClass(i));
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create several MyClass objects, each one with a different value
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
 
    BaseList baselist;
    MemberList memberlist;
 
- //Now insert them in the reverse order
- //in the base hook intrusive list
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
- ; it != itend
- ; ++it){
+ //Now insert them in the reverse order in the base hook list
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
       baselist.push_front(*it);
- }
 
- //Now insert them in the same order as in vector in the
- //member hook intrusive list
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
- ; it != itend
- ; ++it){
+ //Now insert them in the same order as in vector in the member hook list
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
       memberlist.push_back(*it);
- }
 
    //Now test lists
    {
       BaseList::reverse_iterator rbit(baselist.rbegin()), rbitend(baselist.rend());
       MemberList::iterator mit(memberlist.begin()), mitend(memberlist.end());
- VectIt it(myclassvector.begin()), itend(myclassvector.end());
+ VectIt it(values.begin()), itend(values.end());
 
       //Test the objects inserted in the base hook list
- for(; it != itend; ++it, ++rbit){
+ for(; it != itend; ++it, ++rbit)
          if(&*rbit != &*it) return 1;
- }
 
       //Test the objects inserted in the member hook list
- for(it = myclassvector.begin(); it != itend; ++it, ++mit){
+ for(it = values.begin(); it != itend; ++it, ++mit)
          if(&*mit != &*it) return 1;
- }
    }
 
    return 0;

Modified: trunk/libs/intrusive/example/doc_offset_ptr.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_offset_ptr.cpp (original)
+++ trunk/libs/intrusive/example/doc_offset_ptr.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -9,35 +9,49 @@
 // See http://www.boost.org/libs/intrusive for documentation.
 //
 /////////////////////////////////////////////////////////////////////////////
+
+//This is needed to allow concurrent test execution in
+//several platforms. The shared memory must be unique
+//for each process...
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <sstream>
+
+const char *get_shared_memory_name()
+{
+ std::stringstream s;
+ s << "process_" << boost::interprocess::detail::get_current_process_id();
+ static std::string str = s.str();
+ return str.c_str();
+}
+
 //[doc_offset_ptr_0
 #include <boost/intrusive/list.hpp>
 #include <boost/interprocess/offset_ptr.hpp>
 
+using namespace boost::intrusive;
+namespace ip = boost::interprocess;
+
 class shared_memory_data
+ //Declare the hook with an offset_ptr from Boost.Interprocess
+ //to make this class compatible with shared memory
+ : public list_base_hook< void_pointer< ip::offset_ptr<void> > >
 {
    int data_id_;
    public:
 
    int get() const { return data_id_; }
    void set(int id) { data_id_ = id; }
-
- //Declare the hook with an offset_ptr from Boost.Interprocess
- //to make this class compatible with shared memory
- typedef boost::intrusive::list_member_hook
- < boost::intrusive::safe_link
- , boost::interprocess::offset_ptr<void> > member_hook_t;
- member_hook_t list_hook_;
 };
 //]
 
 //[doc_offset_ptr_1
 #include <boost/interprocess/managed_shared_memory.hpp>
 #include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/containers/list.hpp>
 #include <boost/interprocess/allocators/allocator.hpp>
 
 //Definition of the shared memory friendly intrusive list
-typedef boost::intrusive::list< shared_memory_data::member_hook_t::
- value_traits<shared_memory_data, &shared_memory_data::list_hook_> > shm_list_t;
+typedef ip::list<shared_memory_data> shm_list_t;
 
 int main()
 {
@@ -45,45 +59,42 @@
    //nodes and the container itself must be created in shared memory
    const int MaxElem = 100;
    const int ShmSize = 50000;
- const char *ShmName = "SharedMemoryName";
-
- using namespace boost::interprocess;
-
- //Erase all old shared memory
- shared_memory_object::remove(ShmName);
- managed_shared_memory shm(create_only, ShmName, ShmSize);
-
- //Create all nodes in shared memory using a shared memory vector
- //See Boost.Interprocess documentation for more information on this
- typedef allocator< shared_memory_data
- , managed_shared_memory::segment_manager> shm_allocator_t;
- typedef vector<shared_memory_data, shm_allocator_t> shm_vector_t;
- shm_allocator_t shm_alloc(shm.get_segment_manager());
- shm_vector_t *pshm_vect = shm.construct<shm_vector_t>(anonymous_instance)(shm_alloc);
- pshm_vect->resize(MaxElem);
-
- //Initialize all the nodes
- for(int i = 0; i < MaxElem; ++i){
- (*pshm_vect)[i].set(i);
- }
-
- //Now create the shared memory intrusive list
- shm_list_t *plist = shm.construct<shm_list_t>(anonymous_instance)();
- plist->insert(plist->end(), pshm_vect->begin(), pshm_vect->end());
-
- //Check all the inserted nodes
- int checker = 0;
- for( shm_list_t::const_iterator it = plist->begin(), itend(plist->end())
- ; it != itend
- ; ++it, ++checker){
- if(it->get() != checker){
- return false;
+ const char *ShmName = get_shared_memory_name();
+ {
+ //Erase all old shared memory
+ ip::shared_memory_object::remove(ShmName);
+ ip::managed_shared_memory shm(ip::create_only, ShmName, ShmSize);
+
+ //Create all nodes in shared memory using a shared memory vector
+ //See Boost.Interprocess documentation for more information on this
+ typedef ip::allocator
+ < shared_memory_data, ip::managed_shared_memory::segment_manager>
+ shm_allocator_t;
+ typedef ip::vector<shared_memory_data, shm_allocator_t> shm_vector_t;
+ shm_allocator_t shm_alloc(shm.get_segment_manager());
+ shm_vector_t *pshm_vect =
+ shm.construct<shm_vector_t>(ip::anonymous_instance)(shm_alloc);
+ pshm_vect->resize(MaxElem);
+
+ //Initialize all the nodes
+ for(int i = 0; i < MaxElem; ++i) (*pshm_vect)[i].set(i);
+
+ //Now create the shared memory intrusive list
+ shm_list_t *plist = shm.construct<shm_list_t>(ip::anonymous_instance)();
+ plist->insert(plist->end(), pshm_vect->begin(), pshm_vect->end());
+
+ //Check all the inserted nodes
+ int checker = 0;
+ for( shm_list_t::const_iterator it = plist->begin(), itend(plist->end())
+ ; it != itend; ++it, ++checker){
+ if(it->get() != checker) return false;
       }
- }
 
- //Now delete the list and after that, the nodes
- shm.destroy_ptr(plist);
- shm.destroy_ptr(pshm_vect);
+ //Now delete the list and after that, the nodes
+ shm.destroy_ptr(plist);
+ shm.destroy_ptr(pshm_vect);
+ }
+ ip::shared_memory_object::remove(ShmName);
    return 0;
 }
 //]

Modified: trunk/libs/intrusive/example/doc_set.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_set.cpp (original)
+++ trunk/libs/intrusive/example/doc_set.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -17,7 +17,7 @@
 using namespace boost::intrusive;
 
                   //This is a base hook
-class MyClass : public set_base_hook<>
+class MyClass : public set_base_hook<>
 {
    int int_;
 
@@ -28,69 +28,54 @@
    MyClass(int i)
       : int_(i)
       {}
- int get() const
- { return int_; }
    friend bool operator< (const MyClass &a, const MyClass &b)
- { return a.get() < b.get(); }
+ { return a.int_ < b.int_; }
    friend bool operator> (const MyClass &a, const MyClass &b)
- { return a.get() > b.get(); }
+ { return a.int_ > b.int_; }
    friend bool operator== (const MyClass &a, const MyClass &b)
- { return a.get() < b.get(); }
+ { return a.int_ < b.int_; }
 };
 
-//Define an set that will store MyClass
-//in reverse order using the public base hook
-typedef set< set_base_hook<>::value_traits<MyClass>
- , std::greater<MyClass> > BaseSet;
-
-//Define an multiset that will store MyClass
-//using the public member hook
-typedef multiset< set_member_hook<>::
- value_traits<MyClass, &MyClass::member_hook_>
- , std::less<MyClass> > MemberIMultiset;
+//Define an set using the base hook that will store values in reverse order
+typedef set< MyClass, compare<std::greater<MyClass> > > BaseSet;
+
+//Define an multiset using the member hook
+typedef member_hook<MyClass, set_member_hook<>, &MyClass::member_hook_> MemberOption;
+typedef multiset< MyClass, MemberOption> MemberIMultiset;
 
 int main()
 {
- typedef std::vector<MyClass> Vect;
- typedef Vect::iterator VectIt;
- typedef Vect::reverse_iterator VectRit;
-
- //Create several MyClass objects, each one
- //with a different internal number
- Vect myclassvector;
- for(int i = 0; i < 100; ++i)
- myclassvector.push_back(MyClass(i));
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create several MyClass objects, each one with a different value
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
 
    BaseSet baseset;
    MemberIMultiset membermultiset;
 
- //Now insert them in the reverse order
- //in the base hook intrusive set
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
- ; it != itend; ++it)
+ //Now insert them in the reverse order in the base hook set
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
       baseset.insert(*it);
 
- //Now insert them in the same order as in vector in the
- //member hook intrusive set
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
- ; it != itend; ++it)
+ //Now insert them in the same order as in vector in the member hook set
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
       membermultiset.insert(*it);
 
    //Now test sets
    {
       BaseSet::reverse_iterator rbit(baseset.rbegin()), rbitend(baseset.rend());
       MemberIMultiset::iterator mit(membermultiset.begin()), mitend(membermultiset.end());
- VectIt it(myclassvector.begin()), itend(myclassvector.end());
+ VectIt it(values.begin()), itend(values.end());
 
       //Test the objects inserted in the base hook set
- for(; it != itend; ++it, ++rbit){
+ for(; it != itend; ++it, ++rbit)
          if(&*rbit != &*it) return 1;
- }
 
       //Test the objects inserted in the member hook set
- for(it = myclassvector.begin(); it != itend; ++it, ++mit){
+ for(it = values.begin(); it != itend; ++it, ++mit)
          if(&*mit != &*it) return 1;
- }
    }
    return 0;
 }

Modified: trunk/libs/intrusive/example/doc_slist.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_slist.cpp (original)
+++ trunk/libs/intrusive/example/doc_slist.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -16,7 +16,7 @@
 using namespace boost::intrusive;
 
                   //This is a base hook
-class MyClass : public slist_base_hook<>
+class MyClass : public slist_base_hook<>
 {
    int int_;
 
@@ -27,45 +27,34 @@
    MyClass(int i)
       : int_(i)
    {}
-
- int get() const
- { return int_; }
 };
 
 //Define an slist that will store MyClass using the public base hook
-typedef slist< slist_base_hook<>::value_traits<MyClass> > BaseList;
+typedef slist<MyClass> BaseList;
 
 //Define an slist that will store MyClass using the public member hook
-typedef slist< slist_member_hook<>::value_traits<MyClass, &MyClass::member_hook_> > MemberList;
+typedef member_hook<MyClass, slist_member_hook<>, &MyClass::member_hook_> MemberOption;
+typedef slist<MyClass, MemberOption> MemberList;
 
 int main()
 {
- typedef std::vector<MyClass> Vect;
- typedef Vect::iterator VectIt;
- typedef Vect::reverse_iterator VectRit;
-
- //Create several MyClass objects, each one
- //with a different internal number
- Vect myclassvector;
- for(int i = 0; i < 100; ++i)
- myclassvector.push_back(MyClass(i));
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create several MyClass objects, each one with a different value
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
 
    BaseList baselist;
    MemberList memberlist;
 
- //Now insert them in the reverse order
- //in the base hook intrusive list
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
- ; it != itend
- ; ++it){
+ //Now insert them in the reverse order in the base hook list
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
       baselist.push_front(*it);
- }
 
- //Now insert them in the same order as in vector in the
- //member hook intrusive list
+ //Now insert them in the same order as in vector in the member hook list
    for(BaseList::iterator it(baselist.begin()), itend(baselist.end())
- ; it != itend
- ; ++it){
+ ; it != itend; ++it){
       memberlist.push_front(*it);
    }
 
@@ -73,18 +62,16 @@
    {
       BaseList::iterator bit(baselist.begin()), bitend(baselist.end());
       MemberList::iterator mit(memberlist.begin()), mitend(memberlist.end());
- VectRit rit(myclassvector.rbegin()), ritend(myclassvector.rend());
- VectIt it(myclassvector.begin()), itend(myclassvector.end());
+ VectRit rit(values.rbegin()), ritend(values.rend());
+ VectIt it(values.begin()), itend(values.end());
 
       //Test the objects inserted in the base hook list
- for(; rit != ritend; ++rit, ++bit){
+ for(; rit != ritend; ++rit, ++bit)
          if(&*bit != &*rit) return 1;
- }
 
       //Test the objects inserted in the member hook list
- for(; it != itend; ++it, ++mit){
+ for(; it != itend; ++it, ++mit)
          if(&*mit != &*it) return 1;
- }
    }
 
    return 0;

Added: trunk/libs/intrusive/example/doc_stateful_value_traits.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/example/doc_stateful_value_traits.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,87 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+//[doc_stateful_value_traits
+#include <boost/intrusive/list.hpp>
+
+using namespace boost::intrusive;
+
+//This type is not modifiable so we can't store hooks or custom nodes
+typedef int identifier_t;
+
+//This value traits will associate elements from an array of identifiers with
+//elements of an array of nodes. The element i of the value array will use the
+//node i of the node array:
+struct stateful_value_traits
+{
+ typedef list_node_traits<void*> node_traits;
+ typedef node_traits::node node;
+ typedef node * node_ptr;
+ typedef const node * const_node_ptr;
+ typedef identifier_t value_type;
+ typedef identifier_t * pointer;
+ typedef const identifier_t * const_pointer;
+ static const link_mode_type link_mode = normal_link;
+
+ stateful_value_traits(pointer ids, node_ptr node_array)
+ : ids_(ids), nodes_(node_array)
+ {}
+
+ ///Note: non static functions!
+ node_ptr to_node_ptr (value_type &value)
+ { return this->nodes_ + (&value - this->ids_); }
+ const_node_ptr to_node_ptr (const value_type &value) const
+ { return this->nodes_ + (&value - this->ids_); }
+ pointer to_value_ptr(node_ptr n)
+ { return this->ids_ + (n - this->nodes_); }
+ const_pointer to_value_ptr(const_node_ptr n) const
+ { return this->ids_ + (n - this->nodes_); }
+
+ private:
+ pointer ids_;
+ node_ptr nodes_;
+};
+
+int main()
+{
+ const int NumElements = 100;
+
+ //This is an array of ids that we want to "store"
+ identifier_t ids [NumElements];
+
+ //This is an array of nodes that is necessary to form the linked list
+ list_node_traits<void*>::node nodes [NumElements];
+
+ //Initialize id objects, each one with a different number
+ for(int i = 0; i != NumElements; ++i) ids[i] = i;
+
+ //Define a list that will "link" identifiers using external nodes
+ typedef list<identifier_t, value_traits<stateful_value_traits> > List;
+
+ //This list will store ids without modifying identifier_t instances
+ //Stateful value traits must be explicitly passed in the constructor.
+ List my_list (stateful_value_traits (ids, nodes));
+
+ //Insert ids in reverse order in the list
+ for(identifier_t * it(&ids[0]), *itend(&ids[NumElements]); it != itend; ++it)
+ my_list.push_front(*it);
+
+ //Now test lists
+ List::const_iterator list_it (my_list.cbegin());
+ identifier_t *it_val(&ids[NumElements-1]), *it_rbeg_val(&ids[0]-1);
+
+ //Test the objects inserted in the base hook list
+ for(; it_val != it_rbeg_val; --it_val, ++list_it)
+ if(&*list_it != &*it_val) return 1;
+
+ return 0;
+}
+//]

Modified: trunk/libs/intrusive/example/doc_unordered_set.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_unordered_set.cpp (original)
+++ trunk/libs/intrusive/example/doc_unordered_set.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -17,56 +17,43 @@
 
 using namespace boost::intrusive;
 
- //This is a derivation hook
-class MyClass : public unordered_set_base_hook<>
-{
+class MyClass : public unordered_set_base_hook<>
+{ //This is a derivation hook
    int int_;
 
    public:
- //This is a member hook
- unordered_set_member_hook<> member_hook_;
+ unordered_set_member_hook<> member_hook_; //This is a member hook
 
    MyClass(int i)
       : int_(i)
    {}
 
- int get() const
- { return int_; }
-
    friend bool operator== (const MyClass &a, const MyClass &b)
- { return a.get() == b.get(); }
+ { return a.int_ == b.int_; }
 
- friend bool operator> (const MyClass &a, const MyClass &b)
- { return a.get() > b.get(); }
+ friend std::size_t hash_value(const MyClass &value)
+ { return std::size_t(value.int_); }
 };
 
-std::size_t hash_value(const MyClass &value)
-{ return std::size_t(value.get()); }
+//Define an unordered_set that will store MyClass objects using the base hook
+typedef unordered_set<MyClass> BaseSet;
 
-//Define an unordered_set that will store MyClass
-//in reverse order using the public base hook
-typedef unordered_set< unordered_set_base_hook<>::
- value_traits<MyClass> > BaseSet;
-
-//Define an unordered_multiset that will store MyClass
-//using the public member hook
-typedef unordered_multiset< unordered_set_member_hook<>::
- value_traits<MyClass, &MyClass::member_hook_> > MemberMultiSet;
+//Define an unordered_multiset that will store MyClass using the member hook
+typedef member_hook<MyClass, unordered_set_member_hook<>, &MyClass::member_hook_>
+ MemberOption;
+typedef unordered_multiset< MyClass, MemberOption> MemberMultiSet;
 
 int main()
 {
- typedef std::vector<MyClass> Vect;
- typedef Vect::iterator VectIt;
- typedef Vect::reverse_iterator VectRit;
-
- //Create a vector with 100 different MyClass objects,
- //each one with a different internal number
- Vect myclassvector;
- for(int i = 0; i < 100; ++i)
- myclassvector.push_back(MyClass(i));
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create a vector with 100 different MyClass objects
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
 
    //Create a copy of the vector
- Vect myclassvector2(myclassvector);
+ std::vector<MyClass> values2(values);
 
    //Create a bucket array for base_set
    BaseSet::bucket_type base_buckets[100];
@@ -74,20 +61,18 @@
    //Create a bucket array for member_multi_set
    MemberMultiSet::bucket_type member_buckets[200];
 
- //Create a the unordered_set and unordered_multiset,
- //taking buckets as arguments
- BaseSet base_set(base_buckets, 100);
- MemberMultiSet member_multi_set(member_buckets, 200);
-
- //Now insert myclassvector's elements in the unordered_set
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end())
- ; it != itend; ++it){
+ //Create unordered containers taking buckets as arguments
+ BaseSet base_set(BaseSet::bucket_traits(base_buckets, 100));
+ MemberMultiSet member_multi_set
+ (MemberMultiSet::bucket_traits(member_buckets, 200));
+
+ //Now insert values's elements in the unordered_set
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
       base_set.insert(*it);
- }
 
- //Now insert myclassvector's and myclassvector2's elements in the unordered_multiset
- for(VectIt it(myclassvector.begin()), itend(myclassvector.end()),
- it2(myclassvector2.begin()),itend2(myclassvector2.end())
+ //Now insert values's and values2's elements in the unordered_multiset
+ for(VectIt it(values.begin()), itend(values.end()),
+ it2(values2.begin()),itend2(values2.end())
       ; it != itend; ++it, ++it2){
       member_multi_set.insert(*it);
       member_multi_set.insert(*it2);
@@ -95,7 +80,7 @@
 
    //Now find every element
    {
- VectIt it(myclassvector.begin()), itend(myclassvector.end());
+ VectIt it(values.begin()), itend(values.end());
 
       for(; it != itend; ++it){
          //base_set should contain one element for each key

Modified: trunk/libs/intrusive/example/doc_value_traits.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_value_traits.cpp (original)
+++ trunk/libs/intrusive/example/doc_value_traits.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -10,7 +10,7 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 //[doc_value_traits_code_legacy
-#include <boost/intrusive/linking_policy.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/list.hpp>
 #include <boost/intrusive/slist.hpp>
 #include <vector>
@@ -30,6 +30,9 @@
 //Define our own NodeTraits that will configure singly and doubly linked
 //list algorithms. Note that this node traits is compatible with
 //circular_slist_algorithms and circular_list_algorithms.
+
+namespace bi = boost::intrusive;
+
 struct legacy_node_traits
 {
    typedef legacy_value node;
@@ -54,7 +57,7 @@
    typedef legacy_value value_type;
    typedef legacy_value * pointer;
    typedef const legacy_value * const_pointer;
- enum { linking_policy = boost::intrusive::normal_link };
+ static const bi::link_mode_type link_mode = bi::normal_link;
    static node_ptr to_node_ptr (value_type &value) { return node_ptr(&value); }
    static const_node_ptr to_node_ptr (const value_type &value) { return const_node_ptr(&value); }
    static pointer to_value_ptr(node_ptr n) { return pointer(n); }
@@ -65,8 +68,9 @@
 
 //[doc_value_traits_test
 //Now define an intrusive list and slist that will store legacy_value objects
-typedef boost::intrusive::list <legacy_value_traits> LegacyAbiList;
-typedef boost::intrusive::slist<legacy_value_traits> LegacyAbiSlist;
+typedef bi::value_traits<legacy_value_traits> ValueTraitsOption;
+typedef bi::list<legacy_value, ValueTraitsOption> LegacyAbiList;
+typedef bi::slist<legacy_value, ValueTraitsOption> LegacyAbiSlist;
 
 template<class List>
 bool test_list()
@@ -87,9 +91,8 @@
    typename Vect::const_iterator it(legacy_vector.begin()), itend(legacy_vector.end());
 
    //Test the objects inserted in our list
- for(; it != itend; ++it, ++bit){
+ for(; it != itend; ++it, ++bit)
       if(&*bit != &*it) return false;
- }
    return true;
 }
 

Modified: trunk/libs/intrusive/example/doc_window.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_window.cpp (original)
+++ trunk/libs/intrusive/example/doc_window.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -15,11 +15,11 @@
 using namespace boost::intrusive;
 
 //An abstract class that can be inserted in an intrusive list
-class Window : public list_base_hook<>
+class Window : public list_base_hook<>
 {
    public:
    //This is a container those value is an abstract class: you can't do this with std::list.
- typedef list< list_base_hook<>::value_traits<Window> > win_list;
+ typedef list<Window> win_list;
 
    //An static intrusive list declaration
    static win_list all_windows;
@@ -27,7 +27,7 @@
    //Constructor. Includes this window in the list
    Window() { all_windows.push_back(*this); }
    //Destructor. Removes this node from the list
- virtual ~Window() { all_windows.erase(win_list::iterator_to(*this)); }
+ virtual ~Window() { all_windows.erase(win_list::s_iterator_to(*this)); }
    //Pure virtual function to be implemented by derived classes
    virtual void Paint() = 0;
 };
@@ -71,15 +71,13 @@
 //Main function
 int main()
 {
- //When each Window class is created, is
- //automatically registered in the global list
+ //When a Window class is created, is automatically registered in the global list
    MainWindow window;
 
    //Paint all the windows, sub-windows and so on
    paint_all_windows();
 
- //All the windows are automatically unregistered
- //in their destructors.
+ //All the windows are automatically unregistered in their destructors.
    return 0;
 }
 //]

Modified: trunk/libs/intrusive/perf/perf_list.cpp
==============================================================================
--- trunk/libs/intrusive/perf/perf_list.cpp (original)
+++ trunk/libs/intrusive/perf/perf_list.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -11,6 +11,7 @@
 /////////////////////////////////////////////////////////////////////////////
 
 //Includes for tests
+#include <boost/config.hpp>
 #include <list>
 #include <functional>
 #include <iostream>
@@ -26,11 +27,8 @@
 
 using namespace boost::intrusive;
 
-template<bool BigSize>
-struct filler { int dummy[10]; };
-
-template <>
-struct filler<false> {};
+template<bool BigSize> struct filler { int dummy[10]; };
+template <> struct filler<false> {};
 
 template<bool BigSize> //The object for non-intrusive containers
 struct test_class : private filler<BigSize>
@@ -42,8 +40,9 @@
    friend bool operator >(const test_class &l, const test_class &r) { return l.i_ > r.i_; }
 };
 
-template <bool BigSize, linking_policy Policy> //The object for intrusive containers
-struct itest_class : public list_base_hook<tag, Policy>, public test_class<BigSize>
+template <bool BigSize, link_mode_type LinkMode>
+struct itest_class //The object for intrusive containers
+ : public list_base_hook<link_mode<LinkMode> >, public test_class<BigSize>
 {
    itest_class() {}
    itest_class(int i) : test_class<BigSize>(i) {}
@@ -60,11 +59,10 @@
 };
 //]
 
-template <bool BigSize, linking_policy Policy>
+template <bool BigSize, link_mode_type LinkMode>
 struct get_ilist //Helps to define an intrusive list from a policy
 {
- typedef list_base_hook<tag, Policy> hook;
- typedef list<typename hook::template value_traits<itest_class<BigSize, Policy> >, false> type;
+ typedef list<itest_class<BigSize, LinkMode>, constant_time_size<false> > type;
 };
 
 template <bool BigSize> //Helps to define an std list
@@ -73,17 +71,16 @@
 template <bool BigSize> //Helps to define an std pointer list
 struct get_ptrlist { typedef std::list<test_class<BigSize>*> type; };
 
-
 ////////////////////////////////////////////////////////////////////////
 //
 // PUSH_BACK
 //
 ////////////////////////////////////////////////////////////////////////
 
-template <bool BigSize, linking_policy Policy>
+template <bool BigSize, link_mode_type LinkMode>
 void test_intrusive_list_push_back()
 {
- typedef typename get_ilist<BigSize, Policy>::type ilist;
+ typedef typename get_ilist<BigSize, LinkMode>::type ilist;
    ptime tini = microsec_clock::universal_time();
    for(int i = 0; i < NumIter; ++i){
       //First create the elements and insert them in the intrusive list
@@ -93,11 +90,12 @@
       for(int i = 0; i < NumElements; ++i)
          l.push_back(objects[i]);
       //Elements are unlinked in ilist's destructor
- //Elements are disposed in vector's destructor
+ //Elements are destroyed in vector's destructor
       //]
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "link_mode: " << LinkMode << ", usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -111,11 +109,12 @@
       stdlist l;
       for(int i = 0; i < NumElements; ++i)
          l.push_back(typename stdlist::value_type(i));
- //Elements unlinked and disposed in stdlist's destructor
+ //Elements unlinked and destroyed in stdlist's destructor
       //]
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -132,12 +131,13 @@
       stdptrlist l;
       for(int i = 0; i < NumElements; ++i)
          l.push_back(&objects[i]);
- //Pointers to elements unlinked and disposed in stdptrlist's destructor
- //Elements disposed in vector's destructor
+ //Pointers to elements unlinked and destroyed in stdptrlist's destructor
+ //Elements destroyed in vector's destructor
       //]
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "compact std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -155,12 +155,13 @@
          objects.push_back(typename stdlist::value_type(i));
          l.push_back(&objects.back());
       }
- //Pointers to elements unlinked and disposed in stdptrlist's destructor
- //Elements unlinked and disposed in stdlist's destructor
+ //Pointers to elements unlinked and destroyed in stdptrlist's destructor
+ //Elements unlinked and destroyed in stdlist's destructor
       //]
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "disperse std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 ////////////////////////////////////////////////////////////////////////
@@ -170,10 +171,10 @@
 ////////////////////////////////////////////////////////////////////////
 
 //[perf_list_reverse
-template <bool BigSize, linking_policy Policy>
+template <bool BigSize, link_mode_type LinkMode>
 void test_intrusive_list_reverse()
 {
- typedef typename get_ilist<BigSize, Policy>::type ilist;
+ typedef typename get_ilist<BigSize, LinkMode>::type ilist;
    //First create the elements
    std::vector<typename ilist::value_type> objects(NumElements);
 
@@ -186,7 +187,8 @@
       l.reverse();
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "link_mode: " << LinkMode << ", usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -205,7 +207,8 @@
       l.reverse();
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -228,7 +231,8 @@
       l.reverse();
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "compact std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -252,7 +256,8 @@
       l.reverse();
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "disperse std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 //]
 
@@ -263,10 +268,10 @@
 ////////////////////////////////////////////////////////////////////////
 
 //[perf_list_sort
-template <bool BigSize, linking_policy Policy>
+template <bool BigSize, link_mode_type LinkMode>
 void test_intrusive_list_sort()
 {
- typedef typename get_ilist<BigSize, Policy>::type ilist;
+ typedef typename get_ilist<BigSize, LinkMode>::type ilist;
 
    //First create the elements
    std::vector<typename ilist::value_type> objects(NumElements);
@@ -287,7 +292,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "link_mode: " << LinkMode << ", usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -311,7 +317,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -340,7 +347,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "compact std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -368,7 +376,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "disperse std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 //]
 
@@ -378,10 +387,10 @@
 //
 ////////////////////////////////////////////////////////////////////////
 //[perf_list_write_access
-template <bool BigSize, linking_policy Policy>
+template <bool BigSize, link_mode_type LinkMode>
 void test_intrusive_list_write_access()
 {
- typedef typename get_ilist<BigSize, Policy>::type ilist;
+ typedef typename get_ilist<BigSize, LinkMode>::type ilist;
 
    //First create the elements
    std::vector<typename ilist::value_type> objects(NumElements);
@@ -401,7 +410,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "link_mode: " << LinkMode << ", usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -423,7 +433,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -452,7 +463,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "compact std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 
 template <bool BigSize>
@@ -479,7 +491,8 @@
       }
    }
    ptime tend = microsec_clock::universal_time();
- std::cout << "usecs/iteration: " << (tend-tini).total_microseconds()/NumIter << std::endl;
+ std::cout << "disperse std::list usecs/iteration: "
+ << (tend-tini).total_microseconds()/NumIter << std::endl;
 }
 //]
 
@@ -491,7 +504,7 @@
 template<bool BigSize>
 void do_all_tests()
 {
- std::cout << "Testing push back() with BigSize:" << BigSize << std::endl;
+ std::cout << "\n\nTesting push back() with BigSize:" << BigSize << std::endl;
    test_intrusive_list_push_back<BigSize, normal_link>();
    test_intrusive_list_push_back<BigSize, safe_link>();
    test_intrusive_list_push_back<BigSize, auto_unlink>();
@@ -499,7 +512,7 @@
    test_compact_std_ptrlist_push_back<BigSize>();
    test_disperse_std_ptrlist_push_back<BigSize>();
    //reverse
- std::cout << "Testing reverse() with BigSize:" << BigSize << std::endl;
+ std::cout << "\n\nTesting reverse() with BigSize:" << BigSize << std::endl;
    test_intrusive_list_reverse<BigSize, normal_link>();
    test_intrusive_list_reverse<BigSize, safe_link>();
    test_intrusive_list_reverse<BigSize, auto_unlink>();
@@ -507,7 +520,7 @@
    test_compact_std_ptrlist_reverse<BigSize>();
    test_disperse_std_ptrlist_reverse<BigSize>();
    //sort
- std::cout << "Testing sort() with BigSize:" << BigSize << std::endl;
+ std::cout << "\n\nTesting sort() with BigSize:" << BigSize << std::endl;
    test_intrusive_list_sort<BigSize, normal_link>();
    test_intrusive_list_sort<BigSize, safe_link>();
    test_intrusive_list_sort<BigSize, auto_unlink>();
@@ -515,7 +528,7 @@
    test_compact_std_ptrlist_sort<BigSize>();
    test_disperse_std_ptrlist_sort<BigSize>();
    //write_access
- std::cout << "Testing write_access() with BigSize:" << BigSize << std::endl;
+ std::cout << "\n\nTesting write_access() with BigSize:" << BigSize << std::endl;
    test_intrusive_list_write_access<BigSize, normal_link>();
    test_intrusive_list_write_access<BigSize, safe_link>();
    test_intrusive_list_write_access<BigSize, auto_unlink>();

Added: trunk/libs/intrusive/test/custom_bucket_traits_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/test/custom_bucket_traits_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,127 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/functional/hash.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass : public unordered_set_base_hook<>
+{
+ int int_;
+
+ public:
+ MyClass(int i = 0) : int_(i)
+ {}
+ unordered_set_member_hook<> member_hook_;
+
+ friend bool operator==(const MyClass &l, const MyClass &r)
+ { return l.int_ == r.int_; }
+
+ friend std::size_t hash_value(const MyClass &v)
+ { return boost::hash_value(v.int_); }
+};
+
+struct uset_value_traits
+{
+ typedef slist_node_traits<void*> node_traits;
+ typedef node_traits::node_ptr node_ptr;
+ typedef node_traits::const_node_ptr const_node_ptr;
+ typedef MyClass value_type;
+ typedef MyClass * pointer;
+ typedef const MyClass * const_pointer;
+ static const link_mode_type link_mode = normal_link;
+
+ static node_ptr to_node_ptr (value_type &value)
+ { return node_ptr(&value); }
+ static const_node_ptr to_node_ptr (const value_type &value)
+ { return const_node_ptr(&value); }
+ static pointer to_value_ptr(node_ptr n)
+ { return static_cast<value_type*>(n); }
+ static const_pointer to_value_ptr(const_node_ptr n)
+ { return static_cast<const value_type*>(n); }
+};
+
+//Base
+typedef base_hook< unordered_set_base_hook<> > BaseHook;
+typedef unordered_bucket<BaseHook>::type BaseBucketType;
+typedef unordered_set<MyClass, BaseHook> BaseUset;
+//Member
+typedef member_hook
+ < MyClass, unordered_set_member_hook<>
+ , &MyClass::member_hook_ > MemberHook;
+typedef unordered_bucket<MemberHook>::type MemberBucketType;
+typedef unordered_set<MyClass, MemberHook> MemberUset;
+//Explicit
+typedef value_traits< uset_value_traits > Traits;
+typedef unordered_bucket<Traits>::type TraitsBucketType;
+typedef unordered_set<MyClass, Traits> TraitsUset;
+
+struct uset_bucket_traits
+{
+ //Power of two bucket length
+ static const std::size_t NumBuckets = 128;
+
+ uset_bucket_traits(BaseBucketType *buckets)
+ : buckets_(buckets)
+ {}
+
+ uset_bucket_traits(const uset_bucket_traits &other)
+ : buckets_(other.buckets_)
+ {}
+
+ BaseBucketType * bucket_begin() const
+ { return buckets_; }
+
+ std::size_t bucket_count() const
+ { return NumBuckets; }
+
+ BaseBucketType *buckets_;
+};
+
+typedef unordered_set
+ <MyClass, bucket_traits<uset_bucket_traits>, power_2_buckets<true> >
+ BucketTraitsUset;
+
+int main()
+{
+ if(!detail::is_same<BaseUset::bucket_type, BaseBucketType>::value)
+ return 1;
+ if(!detail::is_same<MemberUset::bucket_type, MemberBucketType>::value)
+ return 1;
+ if(!detail::is_same<TraitsUset::bucket_type, TraitsBucketType>::value)
+ return 1;
+ if(!detail::is_same<BaseBucketType, MemberBucketType>::value)
+ return 1;
+ if(!detail::is_same<BaseBucketType, TraitsBucketType>::value)
+ return 1;
+
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+ std::vector<MyClass> values;
+
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
+
+ BaseBucketType buckets[uset_bucket_traits::NumBuckets];
+ uset_bucket_traits btraits(buckets);
+ BucketTraitsUset uset(btraits);
+
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
+ uset.insert(*it);
+
+ for( VectRit it(values.rbegin()), itend(values.rend()); it != itend; ++it){
+ if(uset.find(*it) == uset.cend()) return 1;
+ }
+
+ return 0;
+}

Added: trunk/libs/intrusive/test/default_hook_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/test/default_hook_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,97 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include "smart_ptr.hpp"
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+
+: public list_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+, public slist_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+, public set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+, public unordered_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >
+{
+ int int_;
+
+ public:
+ MyClass(int i)
+ : int_(i)
+ {}
+
+ friend bool operator<(const MyClass &l, const MyClass &r)
+ { return l.int_ < r.int_; }
+
+ friend bool operator==(const MyClass &l, const MyClass &r)
+ { return l.int_ == r.int_; }
+
+ friend std::size_t hash_value(const MyClass &v)
+ { return boost::hash_value(v.int_); }
+};
+
+//Define a list that will store MyClass using the public base hook
+typedef list<MyClass> List;
+typedef slist<MyClass> Slist;
+typedef set<MyClass> Set;
+typedef unordered_set<MyClass> USet;
+
+int main()
+{
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create several MyClass objects, each one with a different value
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
+
+ USet::bucket_type buckets[100];
+
+ List my_list;
+ Slist my_slist;
+ Set my_set;
+ USet my_uset(USet::bucket_traits(buckets, 100));
+
+ //Now insert them in the reverse order
+ //in the base hook intrusive list
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
+ my_list.push_front(*it);
+ my_slist.push_front(*it);
+ my_set.insert(*it);
+ my_uset.insert(*it);
+ }
+
+ //Now test lists
+ {
+ List::const_iterator list_it(my_list.cbegin());
+ Slist::const_iterator slist_it(my_slist.cbegin());
+ Set::const_reverse_iterator set_rit(my_set.crbegin());
+ VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+
+ //Test the objects inserted in the base hook list
+ for(; vect_it != vect_itend; ++vect_it, ++list_it, ++slist_it, ++set_rit){
+ if(&*list_it != &*vect_it) return 1;
+ if(&*slist_it != &*vect_it) return 1;
+ if(&*set_rit != &*vect_it) return 1;
+ if(my_uset.find(*set_rit) == my_uset.cend()) return 1;
+ }
+ }
+
+ return 0;
+}

Added: trunk/libs/intrusive/test/external_value_traits_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/test/external_value_traits_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,240 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/rbtree.hpp>
+#include <boost/intrusive/hashtable.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <functional>
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+{
+ public:
+ int int_;
+
+ MyClass(int i = 0)
+ : int_(i)
+ {}
+ friend bool operator > (const MyClass &l, const MyClass &r)
+ { return l.int_ > r.int_; }
+ friend bool operator == (const MyClass &l, const MyClass &r)
+ { return l.int_ == r.int_; }
+ friend std::size_t hash_value(const MyClass &v)
+ { return boost::hash_value(v.int_); }
+};
+
+const int NumElements = 100;
+
+template<class NodeTraits>
+struct external_traits
+{
+ typedef NodeTraits node_traits;
+ typedef typename node_traits::node node;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename node_traits::const_node_ptr const_node_ptr;
+ typedef MyClass value_type;
+ typedef typename boost::pointer_to_other
+ <node_ptr, MyClass>::type pointer;
+ typedef typename boost::pointer_to_other
+ <node_ptr, const MyClass>::type const_pointer;
+ static const link_mode_type link_mode = normal_link;
+
+ external_traits(pointer values, std::size_t NumElem)
+ : values_(values), node_array_(NumElem)
+ {}
+
+ node_ptr to_node_ptr (value_type &value)
+ { return (&node_array_[0]) + (&value - values_); }
+
+ const_node_ptr to_node_ptr (const value_type &value) const
+ { return &node_array_[0] + (&value - values_); }
+
+ pointer to_value_ptr(node_ptr n)
+ { return values_ + (n - &node_array_[0]); }
+
+ const_pointer to_value_ptr(const_node_ptr n) const
+ { return values_ + (n - &node_array_[0]); }
+
+ pointer values_;
+ std::vector<node> node_array_;
+};
+
+template<class NodeTraits>
+struct value_traits_proxy;
+
+template<class T>
+struct traits_holder
+ : public T
+{};
+
+typedef value_traits_proxy<list_node_traits<void*> > list_value_traits_proxy;
+typedef value_traits_proxy<slist_node_traits<void*> > slist_value_traits_proxy;
+typedef value_traits_proxy<rbtree_node_traits<void*> > rbtree_value_traits_proxy;
+typedef value_traits_proxy<traits_holder<slist_node_traits<void*> > > hash_value_traits_proxy;
+
+struct uset_bucket_traits
+{
+ private:
+ typedef unordered_bucket<value_traits<external_traits
+ <traits_holder<slist_node_traits<void*> > > > >::type bucket_type;
+
+ //Non-copyable
+ uset_bucket_traits(const uset_bucket_traits &other);
+ uset_bucket_traits & operator=(const uset_bucket_traits &other);
+
+ public:
+ static const std::size_t NumBuckets = 100;
+
+ uset_bucket_traits(){}
+
+ bucket_type * bucket_begin() const
+ { return buckets_; }
+
+ std::size_t bucket_count() const
+ { return NumBuckets; }
+
+ mutable bucket_type buckets_[NumBuckets];
+};
+
+struct bucket_traits_proxy
+{
+ static const bool external_bucket_traits = true;
+ typedef uset_bucket_traits bucket_traits;
+
+ template<class Container>
+ bucket_traits &get_bucket_traits(Container &cont);
+
+ template<class Container>
+ const bucket_traits &get_bucket_traits(const Container &cont) const;
+};
+
+//Define a list that will store MyClass using the external hook
+typedef list<MyClass, value_traits<list_value_traits_proxy> > List;
+//Define a slist that will store MyClass using the external hook
+typedef slist<MyClass, value_traits<slist_value_traits_proxy> > Slist;
+//Define a rbtree that will store MyClass using the external hook
+typedef rbtree< MyClass
+ , value_traits<rbtree_value_traits_proxy>
+ , compare<std::greater<MyClass> > > Rbtree;
+//Define a hashtable that will store MyClass using the external hook
+typedef hashtable< MyClass
+ , value_traits<hash_value_traits_proxy>
+ , bucket_traits<bucket_traits_proxy>
+ > Hash;
+
+template<class NodeTraits>
+struct value_traits_proxy
+{
+ static const bool external_value_traits = true;
+ typedef external_traits<NodeTraits> value_traits;
+
+ template<class Container>
+ const value_traits &get_value_traits(const Container &cont) const;
+
+ template<class Container>
+ value_traits &get_value_traits(Container &cont);
+};
+
+struct ContainerHolder
+ : public uset_bucket_traits
+ , public List
+ , public external_traits<list_node_traits<void*> >
+ , public Slist
+ , public external_traits<slist_node_traits<void*> >
+ , public Rbtree
+ , public external_traits<rbtree_node_traits<void*> >
+ , public Hash
+ , public external_traits<traits_holder<slist_node_traits<void*> > >
+{
+ static const std::size_t NumBucket = 100;
+ ContainerHolder(MyClass *values, std::size_t num_elem)
+ : uset_bucket_traits()
+ , List()
+ , external_traits<list_node_traits<void*> >(values, num_elem)
+ , Slist()
+ , external_traits<slist_node_traits<void*> >(values, num_elem)
+ , Rbtree()
+ , external_traits<rbtree_node_traits<void*> >(values, num_elem)
+ , Hash(Hash::bucket_traits())
+ , external_traits<traits_holder<slist_node_traits<void*> > >(values, num_elem)
+ {}
+};
+
+template<class NodeTraits>
+template<class Container>
+typename value_traits_proxy<NodeTraits>::value_traits &
+ value_traits_proxy<NodeTraits>::get_value_traits(Container &cont)
+{ return static_cast<value_traits&>(static_cast<ContainerHolder&>(cont)); }
+
+template<class NodeTraits>
+template<class Container>
+const typename value_traits_proxy<NodeTraits>::value_traits &
+ value_traits_proxy<NodeTraits>::get_value_traits(const Container &cont) const
+{ return static_cast<const value_traits&>(static_cast<const ContainerHolder&>(cont)); }
+
+template<class Container>
+typename bucket_traits_proxy::bucket_traits &
+ bucket_traits_proxy::get_bucket_traits(Container &cont)
+{ return static_cast<bucket_traits&>(static_cast<ContainerHolder&>(cont)); }
+
+template<class Container>
+const typename bucket_traits_proxy::bucket_traits &
+ bucket_traits_proxy::get_bucket_traits(const Container &cont) const
+{ return static_cast<const bucket_traits&>(static_cast<const ContainerHolder&>(cont)); }
+
+int main()
+{
+ MyClass values [NumElements];
+ //Create several MyClass objects, each one with a different value
+ for(int i = 0; i < NumElements; ++i)
+ values[i].int_ = i;
+
+ ContainerHolder cont_holder(values, NumElements);
+ List &my_list = static_cast<List &> (cont_holder);
+ Slist &my_slist = static_cast<Slist &> (cont_holder);
+ Rbtree &my_rbtree = static_cast<Rbtree &> (cont_holder);
+ Hash &my_hash = static_cast<Hash &> (cont_holder);
+
+ //Now insert them in the reverse order
+ //in the base hook intrusive list
+ for(MyClass * it(&values[0]), *itend(&values[NumElements])
+ ; it != itend; ++it){
+ my_list.push_front(*it);
+ my_slist.push_front(*it);
+ my_rbtree.insert_unique(*it);
+ my_hash.insert_unique(*it);
+ }
+
+ //Now test lists
+ {
+ List::const_iterator list_it (my_list.cbegin());
+ Slist::const_iterator slist_it (my_slist.cbegin());
+ Rbtree::const_iterator rbtree_it (my_rbtree.cbegin());
+ Hash::const_iterator hash_it (my_hash.cbegin());
+ MyClass *it_val(&values[NumElements] - 1), *it_rbeg_val(&values[0]-1);
+
+ //Test the objects inserted in the base hook list
+ for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++rbtree_it){
+ if(&*list_it != &*it_val) return 1;
+ if(&*slist_it != &*it_val) return 1;
+ if(&*rbtree_it != &*it_val) return 1;
+ hash_it = my_hash.find(*it_val);
+ if(hash_it == my_hash.cend() || &*hash_it != &*it_val)
+ return 1;
+ }
+ }
+
+ return 0;
+}

Modified: trunk/libs/intrusive/test/list_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/list_test.cpp (original)
+++ trunk/libs/intrusive/test/list_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -35,17 +35,19 @@
    static void test_shift(std::vector<value_type>& values);
    static void test_swap(std::vector<value_type>& values);
    static void test_clone(std::vector<value_type>& values);
+ static void test_container_from_end(std::vector<value_type>& values);
 };
 
 template<class ValueTraits>
 void test_list<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::list
- < ValueTraits
- , ValueTraits::value_type::constant_time_size
- , std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
-
    {
       list_type list(values.begin(), values.end());
       test::test_container(list);
@@ -60,9 +62,15 @@
    test_shift(values);
    test_swap(values);
    test_clone(values);
-
- list_type testlist(values.begin(), values.end());
- list_type testlist2;
+ test_container_from_end(values);
+/*
+ const char *list_name = typeid(list_type).name();
+ std::cout << list_name << std::endl << strlen(list_name) << std::endl;
+ const char *value_t = typeid(typename list_type::value_traits).name();
+ std::cout << value_t << std::endl << strlen(value_t) << std::endl;
+ const char *list_it_name = typeid(typename list_type::iterator).name();
+ std::cout << list_it_name << std::endl << strlen(list_it_name ) << std::endl;
+*/
 }
 
 //test: push_front, pop_front, push_back, pop_back, front, back, size, empty:
@@ -70,10 +78,12 @@
 void test_list<ValueTraits>
    ::test_front_back(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::list
- < ValueTraits
- , ValueTraits::value_type::constant_time_size
- , std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist;
    BOOST_TEST (testlist.empty());
@@ -104,12 +114,12 @@
 void test_list<ValueTraits>
    ::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- std::vector<int> expected;
- typedef boost::intrusive::list
- < ValueTraits
- , ValueTraits::value_type::constant_time_size
- , std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist(values.begin(), values.end());
 
@@ -125,17 +135,17 @@
       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
 }
   
-//test: assign, insert, const_iterator, const_reverse_iterator, erase, iterator_to:
+//test: assign, insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
 template<class ValueTraits>
 void test_list<ValueTraits>
    ::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- std::vector<int> expected;
- typedef boost::intrusive::list
- < ValueTraits
- , ValueTraits::value_type::constant_time_size
- , std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist;
    testlist.assign (&values[0] + 2, &values[0] + 5);
@@ -159,6 +169,9 @@
    i = testlist.iterator_to (values[4]);
    BOOST_TEST (&*i == &values[4]);
 
+ i = list_type::s_iterator_to (values[4]);
+ BOOST_TEST (&*i == &values[4]);
+
    i = testlist.erase (i);
    BOOST_TEST (i == testlist.end());
 
@@ -170,15 +183,14 @@
 void test_list<ValueTraits>
    ::test_shift(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::list
- < ValueTraits
- , ValueTraits::value_type::constant_time_size
- , std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist;
- std::vector<int> expected;
-
    const int num_values = (int)values.size();
    std::vector<int> expected_values(num_values);
 
@@ -210,12 +222,13 @@
 void test_list<ValueTraits>
    ::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::list
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
- std::vector<int> expected;
    {
       list_type testlist1 (&values[0], &values[0] + 2);
       list_type testlist2;
@@ -269,21 +282,38 @@
 
 template<class ValueTraits>
 void test_list<ValueTraits>
- ::test_clone(std::vector<typename ValueTraits::value_type>& values)
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- std::vector<int> expected;
- typedef boost::intrusive::list
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
+ list_type testlist1 (&values[0], &values[0] + values.size());
+ BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end()));
+ BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend()));
+}
+
 
+template<class ValueTraits>
+void test_list<ValueTraits>
+ ::test_clone(std::vector<typename ValueTraits::value_type>& values)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
+ > list_type;
       list_type testlist1 (&values[0], &values[0] + values.size());
       list_type testlist2;
 
- testlist2.clone_from(testlist1, test::new_cloner(), test::delete_disposer());
+ testlist2.clone_from(testlist1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       BOOST_TEST (testlist2 == testlist1);
- testlist2.clear_and_dispose(test::delete_disposer());
+ testlist2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testlist2.empty());
 }
 
@@ -293,17 +323,24 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
- std::vector<testvalue_t> data (5);
+ typedef testvalue<VoidPointer, constant_time_size> value_type;
+ std::vector<value_type> data (5);
       for (int i = 0; i < 5; ++i)
          data[i].value_ = i + 1;
 
- test_list <typename testvalue_t::list_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_list <typename testvalue_t::list_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::list_node_> >::test_all(data);
-
+ test_list < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::list_base_hook_t
+ >::type
+ >::test_all(data);
+ test_list < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::list_member_hook_t
+ , &value_type::list_node_
+ >
+ >::type
+ >::test_all(data);
       return 0;
    }
 };
@@ -314,48 +351,64 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, false> testvalue_t;
- std::vector<testvalue_t> data (5);
+ typedef testvalue<VoidPointer, false> value_type;
+ std::vector<value_type> data (5);
       for (int i = 0; i < 5; ++i)
          data[i].value_ = i + 1;
 
- test_list <typename testvalue_t::list_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_list <typename testvalue_t::list_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::list_node_> >::test_all(data);
-
- test_list <typename testvalue_t::list_auto_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_list <typename testvalue_t::list_auto_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::list_auto_node_> >::test_all(data);
+ test_list < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::list_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_list < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::list_member_hook_t
+ , &value_type::list_node_
+ >
+ >::type
+ >::test_all(data);
+/*
+ test_list<stateful_value_traits
+ < value_type
+ , list_node_traits<VoidPointer>
+ , safe_link>
+ >::test_all(data);
+*/
+ test_list < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::list_auto_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_list < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::list_auto_member_hook_t
+ , &value_type::list_auto_node_
+ >
+ >::type
+ >::test_all(data);
+/*
+ test_list<stateful_value_traits
+ < value_type
+ , list_node_traits<VoidPointer>
+ , auto_unlink>
+ >::test_all(data);
+*/
       return 0;
    }
 };
 
-//Explicit instantiations of non-counted classes
-//template class boost::intrusive::list<list_base_raw, false>;
-//template class boost::intrusive::list<list_member_raw, false>;
-//template class boost::intrusive::list<list_auto_base_raw, false>;
-//template class boost::intrusive::list<list_auto_member_raw, false>;
-//template class boost::intrusive::list<list_base_smart, false>;
-//template class boost::intrusive::list<list_member_smart, false>;
-//template class boost::intrusive::list<list_auto_base_smart, false>;
-//template class boost::intrusive::list<list_auto_member_smart, false>;
-
-//Explicit instantiation of counted classes
-//template class boost::intrusive::list<list_base_raw_t, true>;
-//template class boost::intrusive::list<list_member_raw_t, true>;
-//template class boost::intrusive::list<list_base_smart_t, true>;
-//template class boost::intrusive::list<list_member_smart_t, true>;
-
 int main( int, char* [] )
 {
    test_main_template<void*, false>()();
- test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+ test_main_template<smart_ptr<void>, false>()();
    test_main_template<void*, true>()();
- test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+ test_main_template<smart_ptr<void>, true>()();
+
    return boost::report_errors();
 }
 #include <boost/intrusive/detail/config_end.hpp>

Added: trunk/libs/intrusive/test/make_functions_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/test/make_functions_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,148 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "smart_ptr.hpp"
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+: public make_list_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+, public make_slist_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+, public make_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+, public make_unordered_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+{
+ int int_;
+
+ public:
+ MyClass(int i)
+ : int_(i)
+ {}
+
+ friend bool operator<(const MyClass &l, const MyClass &r)
+ { return l.int_ < r.int_; }
+
+ friend bool operator==(const MyClass &l, const MyClass &r)
+ { return l.int_ == r.int_; }
+
+ friend std::size_t hash_value(const MyClass &v)
+ { return boost::hash_value(v.int_); }
+};
+
+//Define a list that will store MyClass using the public base hook
+typedef make_list<MyClass>::type List;
+typedef make_slist<MyClass>::type Slist;
+typedef make_set<MyClass>::type Set;
+typedef make_unordered_set<MyClass>::type USet;
+
+int main()
+{
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create several MyClass objects, each one with a different value
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
+
+ USet::bucket_type buckets[100];
+
+ List my_list;
+ Slist my_slist;
+ Set my_set;
+ USet my_uset(USet::bucket_traits(buckets, 100));
+
+ //Now insert them in the reverse order
+ //in the base hook intrusive list
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
+ my_list.push_front(*it);
+ my_slist.push_front(*it);
+ my_set.insert(*it);
+ my_uset.insert(*it);
+ }
+
+ //Now test lists
+ {
+ List::const_iterator list_it(my_list.cbegin());
+ Slist::const_iterator slist_it(my_slist.cbegin());
+ Set::const_reverse_iterator set_rit(my_set.crbegin());
+ VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+
+ //Test the objects inserted in the base hook list
+ for(; vect_it != vect_itend; ++vect_it, ++list_it, ++slist_it, ++set_rit){
+ if(&*list_it != &*vect_it) return 1;
+ if(&*slist_it != &*vect_it) return 1;
+ if(&*set_rit != &*vect_it) return 1;
+ if(my_uset.find(*set_rit) == my_uset.cend()) return 1;
+ }
+ }
+
+ //Check defined types and implicitly defined types are equal
+ if(detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_list_base_hook<>::type
+ >::value == false){
+ return 1;
+ }
+
+ if(detail::is_same<make_slist_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_slist_base_hook<>::type
+ >::value == false){
+ return 1;
+ }
+
+ if(detail::is_same<make_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_set_base_hook<>::type
+ >::value == false){
+ return 1;
+ }
+
+ if(detail::is_same<make_unordered_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_unordered_set_base_hook<>::type
+ >::value == false){
+ return 1;
+ }
+
+ //Check defined types and implicitly defined types are unequal
+ if(detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_list_base_hook<>::type
+ >::value == true){
+ return 1;
+ }
+
+ if(detail::is_same<make_slist_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_slist_base_hook<>::type
+ >::value == true){
+ return 1;
+ }
+
+ if(detail::is_same<make_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_set_base_hook<>::type
+ >::value == true){
+ return 1;
+ }
+
+ if(detail::is_same<make_unordered_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_unordered_set_base_hook<>::type
+ >::value == true){
+ return 1;
+ }
+
+
+ return 0;
+}

Modified: trunk/libs/intrusive/test/multiset_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/multiset_test.cpp (original)
+++ trunk/libs/intrusive/test/multiset_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -10,6 +10,7 @@
 // See http://www.boost.org/libs/intrusive for documentation.
 //
 /////////////////////////////////////////////////////////////////////////////
+
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/set.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
@@ -22,7 +23,6 @@
 #include "test_container.hpp"
 
 using namespace boost::intrusive;
-
 template<class ValueTraits>
 struct test_multiset
 {
@@ -34,15 +34,17 @@
    static void test_find(std::vector<value_type>& values);
    static void test_impl();
    static void test_clone(std::vector<value_type>& values);
+ static void test_container_from_end(std::vector<value_type>& values);
 };
 
 template<class ValueTraits>
 void test_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
 {
+ typedef typename ValueTraits::value_type value_type;
    typedef multiset
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type;
    {
       multiset_type testset(values.begin(), values.end());
@@ -63,21 +65,24 @@
    test_find(values);
    test_impl();
    test_clone(values);
+ test_container_from_end(values);
 }
 
 //test case due to an error in tree implementation:
 template<class ValueTraits>
 void test_multiset<ValueTraits>::test_impl()
 {
- typedef typename ValueTraits::value_type testvalue_t;
- std::vector<testvalue_t> values (5);
+ typedef typename ValueTraits::value_type value_type;
+ std::vector<value_type> values (5);
    for (int i = 0; i < 5; ++i)
       values[i].value_ = i;
+ typedef typename ValueTraits::value_type value_type;
    typedef multiset
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type;
+
    multiset_type testset;
    for (int i = 0; i < 5; ++i)
       testset.insert (values[i]);
@@ -94,12 +99,13 @@
 template<class ValueTraits>
 void test_multiset<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
+ typedef typename ValueTraits::value_type value_type;
    typedef multiset
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type;
+
    multiset_type testset1 (values.begin(), values.end());
    { int init_values [] = { 1, 2, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
@@ -108,9 +114,10 @@
    BOOST_TEST (testset1.empty());
 
    typedef multiset
- <ValueTraits
- ,even_odd
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ <value_type
+ , compare<even_odd>
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type2;
    multiset_type2 testset2 (&values[0], &values[0] + 6);
    { int init_values [] = { 5, 3, 1, 4, 2, 2 };
@@ -124,11 +131,12 @@
 template<class ValueTraits>
 void test_multiset<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
+ typedef typename ValueTraits::value_type value_type;
    typedef multiset
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type;
 
    multiset_type testset;
@@ -147,6 +155,10 @@
 
    i = testset.iterator_to (values[2]);
    BOOST_TEST (&*i == &values[2]);
+
+ i = multiset_type::s_iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+
    testset.erase(i);
 
    { int init_values [] = { 1, 3, 5 };
@@ -157,11 +169,12 @@
 template<class ValueTraits>
 void test_multiset<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
+ typedef typename ValueTraits::value_type value_type;
    typedef multiset
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type;
    multiset_type testset1 (&values[0], &values[0] + 2);
    multiset_type testset2;
@@ -182,16 +195,17 @@
 template<class ValueTraits>
 void test_multiset<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
+ typedef typename ValueTraits::value_type value_type;
    typedef multiset
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type;
    multiset_type testset (values.begin(), values.end());
    typedef typename multiset_type::iterator iterator;
 
- testvalue_t cmp_val;
+ value_type cmp_val;
    cmp_val.value_ = 2;
    iterator i = testset.find (cmp_val);
    BOOST_TEST (i->value_ == 2);
@@ -210,20 +224,37 @@
 void test_multiset<ValueTraits>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
+ typedef typename ValueTraits::value_type value_type;
    typedef multiset
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> multiset_type;
+ multiset_type testmultiset1 (&values[0], &values[0] + values.size());
+ multiset_type testmultiset2;
 
- multiset_type testmultiset1 (&values[0], &values[0] + values.size());
- multiset_type testmultiset2;
+ testmultiset2.clone_from(testmultiset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST (testmultiset2 == testmultiset1);
+ testmultiset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testmultiset2.empty());
+}
 
- testmultiset2.clone_from(testmultiset1, test::new_cloner(), test::delete_disposer());
- BOOST_TEST (testmultiset2 == testmultiset1);
- testmultiset2.clear_and_dispose(test::delete_disposer());
- BOOST_TEST (testmultiset2.empty());
+template<class ValueTraits>
+void test_multiset<ValueTraits>
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef multiset
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
+ > multiset_type;
+
+ multiset_type testmultiset (&values[0], &values[0] + values.size());
+ BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.end()));
+ BOOST_TEST (testmultiset == multiset_type::container_from_end_iterator(testmultiset.cend()));
 }
 
 template<class VoidPointer, bool constant_time_size>
@@ -232,18 +263,25 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
+ typedef testvalue<VoidPointer, constant_time_size> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_multiset <typename testvalue_t::set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_multiset <typename testvalue_t::set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
-
+ test_multiset < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::set_base_hook_t
+ >::type
+ >::test_all(data);
+ test_multiset < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::set_member_hook_t
+ , &value_type::set_node_
+ >
+ >::type
+ >::test_all(data);
       return 0;
    }
 };
@@ -254,55 +292,73 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, false> testvalue_t;
+ typedef testvalue<VoidPointer, false> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, false> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_multiset <typename testvalue_t::set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_multiset <typename testvalue_t::set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
-
- test_multiset <typename testvalue_t::set_auto_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_multiset <typename testvalue_t::set_auto_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::set_auto_node_> >::test_all(data);
+ test_multiset < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::set_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_multiset < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::set_member_hook_t
+ , &value_type::set_node_
+ >
+ >::type
+ >::test_all(data);
+
+ test_multiset < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::set_auto_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_multiset < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::set_auto_member_hook_t
+ , &value_type::set_auto_node_
+ >
+ >::type
+ >::test_all(data);
       return 0;
    }
 };
-/*
+
 //Explicit instantiations of non-counted classes
-template class multiset
- <set_base_raw, std::less<set_base_raw::value_type>, false>;
-template class multiset
- <set_member_raw, std::less<set_member_raw::value_type>, false>;
-template class multiset
- <set_auto_base_raw, std::less<set_auto_base_raw::value_type>, false>;
-template class multiset
- <set_auto_member_raw, std::less<set_auto_member_raw::value_type>, false>;
-template class multiset
- <set_base_smart, std::less<set_base_smart::value_type>, false>;
-template class multiset
- <set_member_smart, std::less<set_member_smart::value_type>, false>;
-template class multiset
- <set_auto_base_smart, std::less<set_auto_base_smart::value_type>, false>;
-template class multiset
- <set_auto_member_smart, std::less<set_auto_member_smart::value_type>, false>;
+//template class multiset
+// <set_base_raw, std::less<set_base_raw::value_type>, false>;
+//template class multiset
+// <set_member_raw, std::less<set_member_raw::value_type>, false>;
+//template class multiset
+// <set_auto_base_raw, std::less<set_auto_base_raw::value_type>, false>;
+//template class multiset
+// <set_auto_member_raw, std::less<set_auto_member_raw::value_type>, false>;
+//template class multiset
+// <set_base_smart, std::less<set_base_smart::value_type>, false>;
+//template class multiset
+// <set_member_smart, std::less<set_member_smart::value_type>, false>;
+//template class multiset
+// <set_auto_base_smart, std::less<set_auto_base_smart::value_type>, false>;
+//template class multiset
+// <set_auto_member_smart, std::less<set_auto_member_smart::value_type>, false>;
 
 //Explicit instantiation of counted classes
-template class multiset
- <set_base_raw_t, std::less<set_base_raw_t::value_type>, true>;
-template class multiset
- <set_member_raw_t, std::less<set_member_raw_t::value_type>, true>;
-template class multiset
- <set_base_smart_t, std::less<set_base_smart_t::value_type>, true>;
-template class multiset
- <set_member_smart_t, std::less<set_member_smart_t::value_type>, true>;
-*/
+//template class multiset
+// <set_base_raw_t, std::less<set_base_raw_t::value_type>, true>;
+//template class multiset
+// <set_member_raw_t, std::less<set_member_raw_t::value_type>, true>;
+//template class multiset
+// <set_base_smart_t, std::less<set_base_smart_t::value_type>, true>;
+//template class multiset
+// <set_member_smart_t, std::less<set_member_smart_t::value_type>, true>;
+
 int main( int, char* [] )
 {
    test_main_template<void*, false>()();
@@ -311,5 +367,3 @@
    test_main_template<smart_ptr<void>, true>()();
    return boost::report_errors();
 }
-
-#include <boost/intrusive/detail/config_end.hpp>

Modified: trunk/libs/intrusive/test/set_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/set_test.cpp (original)
+++ trunk/libs/intrusive/test/set_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -34,15 +34,17 @@
    static void test_find(std::vector<value_type>& values);
    static void test_impl();
    static void test_clone(std::vector<value_type>& values);
+ static void test_container_from_end(std::vector<value_type>& values);
 };
 
 template<class ValueTraits>
 void test_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::set
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type;
    {
       set_type testset(values.begin(), values.end());
@@ -63,21 +65,23 @@
    test_find(values);
    test_impl();
    test_clone(values);
+ test_container_from_end(values);
 }
 
 //test case due to an error in tree implementation:
 template<class ValueTraits>
 void test_set<ValueTraits>::test_impl()
 {
- typedef typename ValueTraits::value_type testvalue_t;
- std::vector<testvalue_t> values (5);
+ typedef typename ValueTraits::value_type value_type;
+ std::vector<value_type> values (5);
    for (int i = 0; i < 5; ++i)
       values[i].value_ = i;
 
- typedef boost::intrusive::set
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type;
    set_type testset;
    for (int i = 0; i < 5; ++i)
@@ -95,11 +99,11 @@
 template<class ValueTraits>
 void test_set<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::set
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type;
    set_type testset1 (values.begin(), values.end());
    { int init_values [] = { 1, 2, 3, 4, 5 };
@@ -108,10 +112,12 @@
    testset1.clear();
    BOOST_TEST (testset1.empty());
 
- typedef boost::intrusive::set
- <ValueTraits
- ,even_odd
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , compare<even_odd>
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type2;
    set_type2 testset2 (&values[0], &values[0] + 6);
    { int init_values [] = { 5, 3, 1, 4, 2 };
@@ -120,15 +126,15 @@
    BOOST_TEST (testset2.rbegin()->value_ == 5);
 }
   
-//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
+//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
 template<class ValueTraits>
 void test_set<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::set
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type;
    set_type testset;
    testset.insert(&values[0] + 2, &values[0] + 5);
@@ -149,6 +155,9 @@
    i = testset.iterator_to (values[2]);
    BOOST_TEST (&*i == &values[2]);
 
+ i = set_type::s_iterator_to(values[2]);
+ BOOST_TEST (&*i == &values[2]);
+
    testset.erase (i);
    { int init_values [] = { 1, 3, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); }
@@ -158,11 +167,11 @@
 template<class ValueTraits>
 void test_set<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::set
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type;
    set_type testset1 (&values[0], &values[0] + 2);
    set_type testset2;
@@ -185,16 +194,16 @@
 template<class ValueTraits>
 void test_set<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::set
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type;
    set_type testset (values.begin(), values.end());
    typedef typename set_type::iterator iterator;
 
- testvalue_t cmp_val;
+ value_type cmp_val;
    cmp_val.value_ = 2;
    iterator i = testset.find (cmp_val);
    BOOST_TEST (i->value_ == 2);
@@ -213,20 +222,35 @@
 void test_set<ValueTraits>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::set
- <ValueTraits
- ,std::less<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> set_type;
 
- set_type testset1 (&values[0], &values[0] + values.size());
- set_type testset2;
+ set_type testset1 (&values[0], &values[0] + values.size());
+ set_type testset2;
 
- testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer());
- BOOST_TEST (testset2 == testset1);
- testset2.clear_and_dispose(test::delete_disposer());
- BOOST_TEST (testset2.empty());
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST (testset2 == testset1);
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+}
+
+template<class ValueTraits>
+void test_set<ValueTraits>
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef set
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
+ > set_type;
+ set_type testset (&values[0], &values[0] + values.size());
+ BOOST_TEST (testset == set_type::container_from_end_iterator(testset.end()));
+ BOOST_TEST (testset == set_type::container_from_end_iterator(testset.cend()));
 }
 
 template<class VoidPointer, bool constant_time_size>
@@ -235,18 +259,25 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
+ typedef testvalue<VoidPointer, constant_time_size> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_set <typename testvalue_t::set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_set <typename testvalue_t::set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
-
+ test_set < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::set_base_hook_t
+ >::type
+ >::test_all(data);
+ test_set < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::set_member_hook_t
+ , &value_type::set_node_
+ >
+ >::type
+ >::test_all(data);
       return 0;
    }
 };
@@ -257,61 +288,53 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, false> testvalue_t;
+ typedef testvalue<VoidPointer, false> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, false> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_set <typename testvalue_t::set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
+ test_set < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::set_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_set < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::set_member_hook_t
+ , &value_type::set_node_
+ >
+ >::type
+ >::test_all(data);
+
+ test_set < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::set_auto_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_set < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::set_auto_member_hook_t
+ , &value_type::set_auto_node_
+ >
+ >::type
+ >::test_all(data);
 
- test_set <typename testvalue_t::set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::set_node_> >::test_all(data);
-
- test_set <typename testvalue_t::set_auto_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_set <typename testvalue_t::set_auto_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::set_auto_node_> >::test_all(data);
       return 0;
    }
 };
-/*
-//Explicit instantiations of non-counted classes
-template class boost::intrusive::set
- <set_base_raw, std::less<set_base_raw::value_type>, false>;
-template class boost::intrusive::set
- <set_member_raw, std::less<set_member_raw::value_type>, false>;
-template class boost::intrusive::set
- <set_auto_base_raw, std::less<set_auto_base_raw::value_type>, false>;
-template class boost::intrusive::set
- <set_auto_member_raw, std::less<set_auto_member_raw::value_type>, false>;
-template class boost::intrusive::set
- <set_base_smart, std::less<set_base_smart::value_type>, false>;
-template class boost::intrusive::set
- <set_member_smart, std::less<set_member_smart::value_type>, false>;
-template class boost::intrusive::set
- <set_auto_base_smart, std::less<set_auto_base_smart::value_type>, false>;
-template class boost::intrusive::set
- <set_auto_member_smart, std::less<set_auto_member_smart::value_type>, false>;
-
-//Explicit instantiation of counted classes
-template class boost::intrusive::set
- <set_base_raw_t, std::less<set_base_raw_t::value_type>, true>;
-template class boost::intrusive::set
- <set_member_raw_t, std::less<set_member_raw_t::value_type>, true>;
-template class boost::intrusive::set
- <set_base_smart_t, std::less<set_base_smart_t::value_type>, true>;
-template class boost::intrusive::set
- <set_member_smart_t, std::less<set_member_smart_t::value_type>, true>;
-*/
+
 int main( int, char* [] )
 {
+
    test_main_template<void*, false>()();
- test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+ test_main_template<smart_ptr<void>, false>()();
    test_main_template<void*, true>()();
- test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+ test_main_template<smart_ptr<void>, true>()();
    return boost::report_errors();
 }
 #include <boost/intrusive/detail/config_end.hpp>

Modified: trunk/libs/intrusive/test/slist_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/slist_test.cpp (original)
+++ trunk/libs/intrusive/test/slist_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -10,6 +10,7 @@
 // See http://www.boost.org/libs/intrusive for documentation.
 //
 /////////////////////////////////////////////////////////////////////////////
+
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/slist.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
@@ -36,15 +37,19 @@
    static void test_swap(std::vector<value_type>& values);
    static void test_slow_insert (std::vector<value_type>& values);
    static void test_clone (std::vector<value_type>& values);
+ static void test_container_from_end(std::vector<value_type> &values);
 };
 
 template<class ValueTraits>
 void test_slist<ValueTraits>
    ::test_all (std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    {
       list_type list(values.begin(), values.end());
@@ -61,6 +66,7 @@
    test_slow_insert (values);
    test_swap(values);
    test_clone(values);
+ test_container_from_end(values);
 }
 
 //test: push_front, pop_front, front, size, empty:
@@ -68,9 +74,12 @@
 void test_slist<ValueTraits>
    ::test_front_back (std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist;
    BOOST_TEST (testlist.empty());
@@ -96,10 +105,12 @@
 void test_slist<ValueTraits>
    ::test_merge (std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist1, testlist2;
    testlist1.push_front (values[0]);
@@ -117,10 +128,12 @@
 void test_slist<ValueTraits>
    ::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist (values.begin(), values.end());
 
@@ -136,15 +149,17 @@
       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
 }
   
-//test: assign, insert_after, const_iterator, erase_after, iterator_to, previous:
+//test: assign, insert_after, const_iterator, erase_after, s_iterator_to, previous:
 template<class ValueTraits>
 void test_slist<ValueTraits>
    ::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist;
    testlist.assign (&values[0] + 2, &values[0] + 5);
@@ -162,6 +177,8 @@
 
    i = testlist.iterator_to (values[4]);
    BOOST_TEST (&*i == &values[4]);
+ i = list_type::s_iterator_to (values[4]);
+ BOOST_TEST (&*i == &values[4]);
    i = testlist.previous (i);
    BOOST_TEST (&*i == &values[0]);
 
@@ -171,15 +188,17 @@
       TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
 }
 
-//test: insert, const_iterator, erase, iterator_to:
+//test: insert, const_iterator, erase, siterator_to:
 template<class ValueTraits>
 void test_slist<ValueTraits>
    ::test_slow_insert (std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist;
    testlist.push_front (values[4]);
@@ -199,6 +218,9 @@
    i = testlist.iterator_to (values[4]);
    BOOST_TEST (&*i == &values[4]);
 
+ i = list_type::s_iterator_to (values[4]);
+ BOOST_TEST (&*i == &values[4]);
+
    i = testlist.erase (i);
    BOOST_TEST (i == testlist.end());
 
@@ -214,10 +236,12 @@
 void test_slist<ValueTraits>
    ::test_shift(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    list_type testlist;
 
@@ -254,10 +278,12 @@
 void test_slist<ValueTraits>
    ::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
    {
       list_type testlist1 (&values[0], &values[0] + 2);
@@ -306,37 +332,63 @@
 void test_slist<ValueTraits>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::slist
- <ValueTraits
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
> list_type;
 
       list_type testlist1 (&values[0], &values[0] + values.size());
       list_type testlist2;
 
- testlist2.clone_from(testlist1, test::new_cloner(), test::delete_disposer());
+ testlist2.clone_from(testlist1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       BOOST_TEST (testlist2 == testlist1);
- testlist2.clear_and_dispose(test::delete_disposer());
+ testlist2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testlist2.empty());
 }
 
+template<class ValueTraits>
+void test_slist<ValueTraits>
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
+ > list_type;
+ list_type testlist1 (&values[0], &values[0] + values.size());
+ BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end()));
+ BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend()));
+}
+
 template<class VoidPointer, bool constant_time_size>
 class test_main_template
 {
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
- std::vector<testvalue_t> data (5);
+ typedef testvalue<VoidPointer, constant_time_size> value_type;
+ std::vector<value_type> data (5);
       for (int i = 0; i < 5; ++i)
          data[i].value_ = i + 1;
 
- test_slist <typename testvalue_t::slist_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_slist <typename testvalue_t::slist_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::slist_node_> >::test_all(data);
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ >::test_all(data);
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ >::test_all(data);
 
       return 0;
    }
@@ -348,48 +400,50 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, false> testvalue_t;
- std::vector<testvalue_t> data (5);
+ typedef testvalue<VoidPointer, false> value_type;
+ std::vector<value_type> data (5);
       for (int i = 0; i < 5; ++i)
          data[i].value_ = i + 1;
 
- test_slist <typename testvalue_t::slist_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_slist <typename testvalue_t::slist_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::slist_node_> >::test_all(data);
-
- test_slist <typename testvalue_t::slist_auto_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_slist <typename testvalue_t::slist_auto_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::slist_auto_node_> >::test_all(data);
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ >::test_all(data);
+
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_auto_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_auto_member_hook_t
+ , &value_type::slist_auto_node_
+ >
+ >::type
+ >::test_all(data);
       return 0;
    }
 };
-/*
-//Explicit instantiations of non-counted classes
-template class boost::intrusive::slist<slist_base_raw, false>;
-template class boost::intrusive::slist<slist_member_raw, false>;
-template class boost::intrusive::slist<slist_auto_base_raw, false>;
-template class boost::intrusive::slist<slist_auto_member_raw, false>;
-template class boost::intrusive::slist<slist_base_smart, false>;
-template class boost::intrusive::slist<slist_member_smart, false>;
-template class boost::intrusive::slist<slist_auto_base_smart, false>;
-template class boost::intrusive::slist<slist_auto_member_smart, false>;
-
-//Explicit instantiation of counted classes
-template class boost::intrusive::slist<slist_base_raw_t, true>;
-template class boost::intrusive::slist<slist_member_raw_t, true>;
-template class boost::intrusive::slist<slist_base_smart_t, true>;
-template class boost::intrusive::slist<slist_member_smart_t, true>;
-*/
+
 int main(int, char* [])
 {
    test_main_template<void*, false>()();
- test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+ test_main_template<smart_ptr<void>, false>()();
    test_main_template<void*, true>()();
- test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+ test_main_template<smart_ptr<void>, true>()();
    return boost::report_errors();
 }
 #include <boost/intrusive/detail/config_end.hpp>

Added: trunk/libs/intrusive/test/stateful_value_traits_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/test/stateful_value_traits_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,148 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+{
+ public:
+ int int_;
+
+ MyClass(int i = 0)
+ : int_(i)
+ {}
+
+ friend bool operator<(const MyClass &l, const MyClass &r)
+ { return l.int_ < r.int_; }
+
+ friend bool operator==(const MyClass &l, const MyClass &r)
+ { return l.int_ == r.int_; }
+
+ friend std::size_t hash_value(const MyClass &v)
+ { return boost::hash_value(v.int_); }
+};
+
+template<class T, class NodeTraits>
+struct stateful_value_traits
+{
+ typedef NodeTraits node_traits;
+ typedef typename node_traits::node node;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename node_traits::const_node_ptr const_node_ptr;
+ typedef T value_type;
+ typedef typename boost::pointer_to_other
+ <node_ptr, T>::type pointer;
+ typedef typename boost::pointer_to_other
+ <node_ptr, const T>::type const_pointer;
+ static const link_mode_type link_mode = normal_link;
+
+ stateful_value_traits(pointer values, node_ptr node_array)
+ : values_(values), node_array_(node_array)
+ {}
+
+ node_ptr to_node_ptr (value_type &value)
+ { return node_array_ + (&value - values_); }
+
+ const_node_ptr to_node_ptr (const value_type &value) const
+ { return node_array_ + (&value - values_); }
+
+ pointer to_value_ptr(node_ptr n)
+ { return values_ + (n - node_array_); }
+
+ const_pointer to_value_ptr(const_node_ptr n) const
+ { return values_ + (n - node_array_); }
+
+ pointer values_;
+ node_ptr node_array_;
+};
+
+//Define a list that will store MyClass using the external hook
+typedef stateful_value_traits< MyClass, list_node_traits<void*> > list_traits;
+typedef list<MyClass, value_traits<list_traits> > List;
+
+//Define a slist that will store MyClass using the external hook
+typedef stateful_value_traits< MyClass, slist_node_traits<void*> > slist_traits;
+typedef slist<MyClass, value_traits<slist_traits> > Slist;
+
+//Define a set that will store MyClass using the external hook
+typedef stateful_value_traits< MyClass, rbtree_node_traits<void*> > rbtree_traits;
+typedef set<MyClass, value_traits<rbtree_traits> > Set;
+
+//uset uses the same traits as slist
+typedef unordered_set<MyClass, value_traits<slist_traits> > Uset;
+
+
+typedef list_traits::node list_node_t;
+typedef slist_traits::node slist_node_t;
+typedef rbtree_traits::node rbtree_node_t;
+
+const int NumElements = 100;
+
+MyClass values [NumElements];
+list_node_t list_hook_array [NumElements];
+slist_node_t slist_hook_array [NumElements];
+rbtree_node_t rbtree_hook_array [NumElements];
+slist_node_t uset_hook_array [NumElements];
+
+int main()
+{
+ //Create several MyClass objects, each one with a different value
+ for(int i = 0; i < NumElements; ++i)
+ values[i].int_ = i;
+
+ Uset::bucket_type buckets[NumElements];
+
+ List my_list (list_traits (values, list_hook_array));
+ Slist my_slist(slist_traits(values, slist_hook_array));
+ Set my_set (std::less<MyClass>(), rbtree_traits(values, rbtree_hook_array));
+ Uset my_uset ( Uset::bucket_traits(buckets, NumElements)
+ , boost::hash<MyClass>()
+ , std::equal_to<MyClass>()
+ , slist_traits(values, uset_hook_array)
+ );
+
+ //Now insert them in the reverse order
+ //in the base hook intrusive list
+ for(MyClass * it(&values[0]), *itend(&values[NumElements])
+ ; it != itend
+ ; ++it){
+ my_list.push_front(*it);
+ my_slist.push_front(*it);
+ my_set.insert(*it);
+ my_uset.insert(*it);
+ }
+
+ //Now test lists
+ {
+ List::const_iterator list_it (my_list.cbegin());
+ Slist::const_iterator slist_it(my_slist.cbegin());
+ Set::const_reverse_iterator set_rit(my_set.crbegin());
+ MyClass *it_val(&values[NumElements-1]), *it_rbeg_val(&values[0]-1);
+
+ //Test the objects inserted in the base hook list
+ for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++set_rit){
+ if(&*list_it != &*it_val) return 1;
+ if(&*slist_it != &*it_val) return 1;
+ if(&*set_rit != &*it_val) return 1;
+ if(my_uset.find(*it_val) == my_uset.cend()) return 1;
+ }
+ }
+
+ return 0;
+}

Modified: trunk/libs/intrusive/test/unordered_multiset_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/unordered_multiset_test.cpp (original)
+++ trunk/libs/intrusive/test/unordered_multiset_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -44,15 +44,16 @@
 template<class ValueTraits>
 void test_unordered_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_multiset_type;
    {
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
       typename unordered_multiset_type::bucket_type buckets [BucketSize];
- unordered_multiset_type testset(buckets, BucketSize);
+ unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
       testset.insert(values.begin(), values.end());
       test::test_container(testset);
       testset.clear();
@@ -78,18 +79,20 @@
 template<class ValueTraits>
 void test_unordered_multiset<ValueTraits>::test_impl()
 {
- typedef typename ValueTraits::value_type testvalue_t;
- std::vector<testvalue_t> values (5);
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
+ > unordered_multiset_type;
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
+ std::vector<value_type> values (5);
    for (int i = 0; i < 5; ++i)
       values[i].value_ = i;
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
- > unordered_multiset_type;
+
    typename unordered_multiset_type::bucket_type buckets [BucketSize];
- unordered_multiset_type testset(buckets, BucketSize);
+ unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
 
    for (int i = 0; i < 5; ++i)
       testset.insert (values[i]);
@@ -106,15 +109,16 @@
 template<class ValueTraits>
 void test_unordered_multiset<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_multiset_type;
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
    typename unordered_multiset_type::bucket_type buckets [BucketSize];
- unordered_multiset_type testset1(buckets, BucketSize, values.begin(), values.end());
+ unordered_multiset_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
 
    { int init_values [] = { 1, 2, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
@@ -126,16 +130,16 @@
 template<class ValueTraits>
 void test_unordered_multiset<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_multiset_type;
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
    typename unordered_multiset_type::bucket_type buckets [BucketSize];
- unordered_multiset_type testset(buckets, BucketSize);
- typedef typename unordered_multiset_type::value_type value_type;
+ unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
 
    testset.insert(&values[0] + 2, &values[0] + 5);
 
@@ -170,7 +174,7 @@
 
    //Now with a single bucket
    typename unordered_multiset_type::bucket_type single_bucket[1];
- unordered_multiset_type testset2(single_bucket, 1);
+ unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
    testset2.insert(&values[0], &values[0] + values.size());
    BOOST_TEST (testset2.erase(5) == 1);
    BOOST_TEST (testset2.erase(2) == 2);
@@ -184,18 +188,18 @@
 template<class ValueTraits>
 void test_unordered_multiset<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_multiset_type;
- typename unordered_multiset_type::bucket_type buckets [BucketSize];
- unordered_multiset_type testset1(buckets, BucketSize, &values[0], &values[0] + 2);
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
 
+ typename unordered_multiset_type::bucket_type buckets [BucketSize];
    typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
- unordered_multiset_type testset2(buckets2, BucketSize);
+ unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
+ unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
 
    testset2.insert (&values[0] + 2, &values[0] + 6);
    testset1.swap (testset2);
@@ -216,40 +220,41 @@
 template<class ValueTraits>
 void test_unordered_multiset<ValueTraits>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_multiset_type;
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
 
    typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
- unordered_multiset_type testset1(buckets1, BucketSize, &values[0], &values[0] + 6);
+ typename unordered_multiset_type::bucket_type buckets2 [2];
+ typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
+
+ unordered_multiset_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
    BOOST_TEST (testset1.size() == 6);
    { int init_values [] = { 1, 2, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
- typename unordered_multiset_type::bucket_type buckets2 [2];
- testset1.rehash(buckets2, 2);
+ testset1.rehash(bucket_traits(buckets2, 2));
    BOOST_TEST (testset1.size() == 6);
    { int init_values [] = { 4, 2, 2, 5, 3, 1 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
- typename unordered_multiset_type::bucket_type buckets3 [BucketSize*2];
- testset1.rehash(buckets3, BucketSize*2);
+ testset1.rehash(bucket_traits(buckets3, BucketSize*2));
    BOOST_TEST (testset1.size() == 6);
    { int init_values [] = { 1, 2, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
    //Now rehash reducing the buckets
- testset1.rehash(buckets3, 2);
+ testset1.rehash(bucket_traits(buckets3, 2));
    BOOST_TEST (testset1.size() == 6);
    { int init_values [] = { 4, 2, 2, 5, 3, 1 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
    //Now rehash increasing the buckets
- testset1.rehash(buckets3, BucketSize*2);
+ testset1.rehash(bucket_traits(buckets3, BucketSize*2));
    BOOST_TEST (testset1.size() == 6);
    { int init_values [] = { 1, 2, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
@@ -259,19 +264,20 @@
 template<class ValueTraits>
 void test_unordered_multiset<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_multiset_type;
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+
    typename unordered_multiset_type::bucket_type buckets[BucketSize];
- unordered_multiset_type testset(buckets, BucketSize, values.begin(), values.end());
+ unordered_multiset_type testset(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
 
    typedef typename unordered_multiset_type::iterator iterator;
 
- testvalue_t cmp_val;
+ value_type cmp_val;
    cmp_val.value_ = 2;
    iterator i = testset.find (cmp_val);
    BOOST_TEST (i->value_ == 2);
@@ -291,61 +297,62 @@
 void test_unordered_multiset<ValueTraits>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::unordered_multiset
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_multiset
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_multiset_type;
+ typedef typename unordered_multiset_type::bucket_traits bucket_traits;
    {
       //Test with equal bucket arrays
       typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
       typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
- unordered_multiset_type testset1 (buckets1, BucketSize, values.begin(), values.end());
- unordered_multiset_type testset2 (buckets2, BucketSize);
+ unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
+ unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize));
 
- testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer());
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       //Ordering is not guarantee in the cloning so insert data in a set and test
       std::multiset<typename ValueTraits::value_type>
          src(testset1.begin(), testset1.end());
       std::multiset<typename ValueTraits::value_type>
          dst(testset2.begin(), testset2.end());
       BOOST_TEST (src == dst);
- testset2.clear_and_dispose(test::delete_disposer());
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testset2.empty());
    }
    {
       //Test with bigger source bucket arrays
       typename unordered_multiset_type::bucket_type buckets1 [BucketSize*2];
       typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
- unordered_multiset_type testset1 (buckets1, BucketSize*2, values.begin(), values.end());
- unordered_multiset_type testset2 (buckets2, BucketSize);
+ unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize*2));
+ unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize));
 
- testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer());
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       //Ordering is not guarantee in the cloning so insert data in a set and test
       std::multiset<typename ValueTraits::value_type>
          src(testset1.begin(), testset1.end());
       std::multiset<typename ValueTraits::value_type>
          dst(testset2.begin(), testset2.end());
       BOOST_TEST (src == dst);
- testset2.clear_and_dispose(test::delete_disposer());
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testset2.empty());
    }
    {
       //Test with smaller source bucket arrays
       typename unordered_multiset_type::bucket_type buckets1 [BucketSize];
       typename unordered_multiset_type::bucket_type buckets2 [BucketSize*2];
- unordered_multiset_type testset1 (buckets1, BucketSize, values.begin(), values.end());
- unordered_multiset_type testset2 (buckets2, BucketSize*2);
+ unordered_multiset_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
+ unordered_multiset_type testset2 (bucket_traits(buckets2, BucketSize*2));
 
- testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer());
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       //Ordering is not guarantee in the cloning so insert data in a set and test
       std::multiset<typename ValueTraits::value_type>
          src(testset1.begin(), testset1.end());
       std::multiset<typename ValueTraits::value_type>
          dst(testset2.begin(), testset2.end());
       BOOST_TEST (src == dst);
- testset2.clear_and_dispose(test::delete_disposer());
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testset2.empty());
    }
 }
@@ -356,17 +363,26 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
+ typedef testvalue<VoidPointer, constant_time_size> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_unordered_multiset <typename testvalue_t::unordered_set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_unordered_multiset <typename testvalue_t::unordered_set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
+ test_unordered_multiset < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::unordered_set_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_unordered_multiset < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::unordered_set_member_hook_t
+ , &value_type::unordered_set_node_
+ >
+ >::type
+ >::test_all(data);
 
       return 0;
    }
@@ -378,87 +394,51 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, false> testvalue_t;
+ typedef testvalue<VoidPointer, false> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, false> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_unordered_multiset <typename testvalue_t::unordered_set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_unordered_multiset <typename testvalue_t::unordered_set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
-
- test_unordered_multiset <typename testvalue_t::unordered_set_auto_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_unordered_multiset <typename testvalue_t::unordered_set_auto_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::unordered_set_auto_node_> >::test_all(data);
+ test_unordered_multiset < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::unordered_set_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_unordered_multiset < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::unordered_set_member_hook_t
+ , &value_type::unordered_set_node_
+ >
+ >::type
+ >::test_all(data);
+
+ test_unordered_multiset < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::unordered_set_auto_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_unordered_multiset < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::unordered_set_auto_member_hook_t
+ , &value_type::unordered_set_auto_node_
+ >
+ >::type
+ >::test_all(data);
       return 0;
    }
 };
 
-/*
-//Explicit instantiations of non-counted classes
-template class boost::intrusive::unordered_multiset
- < unordered_set_base_raw_t
- , boost::hash<unordered_set_base_raw_t::value_type>
- , std::equal_to<unordered_set_base_raw_t::value_type>, false>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_member_raw_t
- , boost::hash<unordered_set_member_raw_t::value_type>
- , std::equal_to<unordered_set_member_raw_t::value_type>, false>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_auto_base_raw
- , boost::hash<unordered_set_auto_base_raw::value_type>
- , std::equal_to<unordered_set_auto_base_raw::value_type>, false>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_auto_member_raw
- , boost::hash<unordered_set_auto_member_raw::value_type>
- , std::equal_to<unordered_set_auto_member_raw::value_type>, false>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_base_smart
- , boost::hash<unordered_set_base_smart::value_type>
- , std::equal_to<unordered_set_base_smart::value_type>, false>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_member_smart
- , boost::hash<unordered_set_member_smart::value_type>
- , std::equal_to<unordered_set_member_smart::value_type>, false>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_auto_base_smart
- , boost::hash<unordered_set_auto_base_smart::value_type>
- , std::equal_to<unordered_set_auto_base_smart::value_type>, false>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_auto_member_smart
- , boost::hash<unordered_set_auto_member_smart::value_type>
- , std::equal_to<unordered_set_auto_member_smart::value_type>, false>;
-
-//Explicit instantiation of counted classes
-template class boost::intrusive::unordered_multiset
- < unordered_set_base_raw_t
- , boost::hash<unordered_set_base_raw_t::value_type>
- , std::equal_to<unordered_set_base_raw_t::value_type>, true>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_member_raw_t
- , boost::hash<unordered_set_base_raw_t::value_type>
- , std::equal_to<unordered_set_member_raw_t::value_type>, true>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_base_smart_t
- , boost::hash<unordered_set_base_smart_t::value_type>
- , std::equal_to<unordered_set_base_smart_t::value_type>, true>;
-template class boost::intrusive::unordered_multiset
- < unordered_set_member_smart_t
- , boost::hash<unordered_set_member_smart_t::value_type>
- , std::equal_to<unordered_set_member_smart_t::value_type>, true>;
-*/
-
 int main( int, char* [] )
 {
    test_main_template<void*, false>()();
- test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+ test_main_template<smart_ptr<void>, false>()();
    test_main_template<void*, true>()();
- test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+ test_main_template<smart_ptr<void>, true>()();
    return boost::report_errors();
 }
 

Modified: trunk/libs/intrusive/test/unordered_set_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/unordered_set_test.cpp (original)
+++ trunk/libs/intrusive/test/unordered_set_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -43,15 +43,16 @@
 template<class ValueTraits>
 void test_unordered_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
    {
       typename unordered_set_type::bucket_type buckets [BucketSize];
- unordered_set_type testset(buckets, BucketSize);
+ unordered_set_type testset(bucket_traits(buckets, BucketSize));
       testset.insert(values.begin(), values.end());
       test::test_container(testset);
       testset.clear();
@@ -77,19 +78,20 @@
 template<class ValueTraits>
 void test_unordered_set<ValueTraits>::test_impl()
 {
- typedef typename ValueTraits::value_type testvalue_t;
- std::vector<testvalue_t> values (5);
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
+ > unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
+
+ std::vector<value_type> values (5);
    for (int i = 0; i < 5; ++i)
       values[i].value_ = i;
 
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
- > unordered_set_type;
    typename unordered_set_type::bucket_type buckets [BucketSize];
- unordered_set_type testset(buckets, BucketSize);
+ unordered_set_type testset(bucket_traits(buckets, BucketSize));
    for (int i = 0; i < 5; ++i)
       testset.insert (values[i]);
 
@@ -104,15 +106,16 @@
 template<class ValueTraits>
 void test_unordered_set<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
+
    typename unordered_set_type::bucket_type buckets [BucketSize];
- unordered_set_type testset1(buckets, BucketSize, values.begin(), values.end());
+ unordered_set_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));
    
    BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));
    { int init_values [] = { 1, 2, 3, 4, 5 };
@@ -126,15 +129,16 @@
 template<class ValueTraits>
 void test_unordered_set<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
+
    typename unordered_set_type::bucket_type buckets [BucketSize];
- unordered_set_type testset(buckets, BucketSize);
+ unordered_set_type testset(bucket_traits(buckets, BucketSize));
    testset.insert(&values[0] + 2, &values[0] + 5);
 
    const unordered_set_type& const_testset = testset;
@@ -160,19 +164,18 @@
 template<class ValueTraits>
 void test_unordered_set<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
 
    typename unordered_set_type::bucket_type buckets1 [BucketSize];
- unordered_set_type testset1(buckets1, BucketSize, &values[0], &values[0] + 2);
-
    typename unordered_set_type::bucket_type buckets2 [BucketSize];
- unordered_set_type testset2(buckets2, BucketSize);
+ unordered_set_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets1, BucketSize));
+ unordered_set_type testset2(bucket_traits(buckets2, BucketSize));
 
    testset2.insert (&values[0] + 2, &values[0] + 6);
    testset1.swap (testset2);
@@ -192,40 +195,41 @@
 template<class ValueTraits>
 void test_unordered_set<ValueTraits>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
 
    typename unordered_set_type::bucket_type buckets1 [BucketSize];
- unordered_set_type testset1(buckets1, BucketSize, &values[0], &values[0] + 6);
+ typename unordered_set_type::bucket_type buckets2 [2];
+ typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
+
+ unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));
    BOOST_TEST (testset1.size() == 5);
    { int init_values [] = { 1, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
- typename unordered_set_type::bucket_type buckets2 [2];
- testset1.rehash(buckets2, 2);
+ testset1.rehash(bucket_traits(buckets2, 2));
    BOOST_TEST (testset1.size() == 5);
    { int init_values [] = { 4, 2, 5, 3, 1 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
- typename unordered_set_type::bucket_type buckets3 [BucketSize*2];
- testset1.rehash(buckets3, BucketSize*2);
+ testset1.rehash(bucket_traits(buckets3, BucketSize*2));
    BOOST_TEST (testset1.size() == 5);
    { int init_values [] = { 1, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
    //Now rehash reducing the buckets
- testset1.rehash(buckets3, 2);
+ testset1.rehash(bucket_traits(buckets3, 2));
    BOOST_TEST (testset1.size() == 5);
    { int init_values [] = { 4, 2, 5, 3, 1 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
    //Now rehash increasing the buckets
- testset1.rehash(buckets3, BucketSize*2);
+ testset1.rehash(bucket_traits(buckets3, BucketSize*2));
    BOOST_TEST (testset1.size() == 5);
    { int init_values [] = { 1, 2, 3, 4, 5 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
@@ -236,18 +240,19 @@
 template<class ValueTraits>
 void test_unordered_set<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef typename ValueTraits::value_type testvalue_t;
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
+
    typename unordered_set_type::bucket_type buckets [BucketSize];
- unordered_set_type testset (buckets, BucketSize, values.begin(), values.end());
+ unordered_set_type testset (values.begin(), values.end(), bucket_traits(buckets, BucketSize));
    typedef typename unordered_set_type::iterator iterator;
 
- testvalue_t cmp_val;
+ value_type cmp_val;
    cmp_val.value_ = 2;
    iterator i = testset.find (cmp_val);
    BOOST_TEST (i->value_ == 2);
@@ -266,61 +271,62 @@
 void test_unordered_set<ValueTraits>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
- typedef boost::intrusive::unordered_set
- <ValueTraits
- ,boost::hash<typename ValueTraits::value_type>
- ,std::equal_to<typename ValueTraits::value_type>
- ,ValueTraits::value_type::constant_time_size, std::size_t
+ typedef typename ValueTraits::value_type value_type;
+ typedef unordered_set
+ <value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
> unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
    {
       //Test with equal bucket arrays
       typename unordered_set_type::bucket_type buckets1 [BucketSize];
       typename unordered_set_type::bucket_type buckets2 [BucketSize];
- unordered_set_type testset1 (buckets1, BucketSize, values.begin(), values.end());
- unordered_set_type testset2 (buckets2, BucketSize);
+ unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
+ unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
 
- testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer());
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       //Ordering is not guarantee in the cloning so insert data in a set and test
       std::set<typename ValueTraits::value_type>
          src(testset1.begin(), testset1.end());
       std::set<typename ValueTraits::value_type>
          dst(testset2.begin(), testset2.end());
       BOOST_TEST (src == dst );
- testset2.clear_and_dispose(test::delete_disposer());
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testset2.empty());
    }
    {
       //Test with bigger source bucket arrays
       typename unordered_set_type::bucket_type buckets1 [BucketSize*2];
       typename unordered_set_type::bucket_type buckets2 [BucketSize];
- unordered_set_type testset1 (buckets1, BucketSize*2, values.begin(), values.end());
- unordered_set_type testset2 (buckets2, BucketSize);
+ unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize*2));
+ unordered_set_type testset2 (bucket_traits(buckets2, BucketSize));
 
- testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer());
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       //Ordering is not guarantee in the cloning so insert data in a set and test
       std::set<typename ValueTraits::value_type>
          src(testset1.begin(), testset1.end());
       std::set<typename ValueTraits::value_type>
          dst(testset2.begin(), testset2.end());
       BOOST_TEST (src == dst );
- testset2.clear_and_dispose(test::delete_disposer());
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testset2.empty());
    }
    {
       //Test with smaller source bucket arrays
       typename unordered_set_type::bucket_type buckets1 [BucketSize];
       typename unordered_set_type::bucket_type buckets2 [BucketSize*2];
- unordered_set_type testset1 (buckets1, BucketSize, values.begin(), values.end());
- unordered_set_type testset2 (buckets2, BucketSize*2);
+ unordered_set_type testset1 (values.begin(), values.end(), bucket_traits(buckets1, BucketSize));
+ unordered_set_type testset2 (bucket_traits(buckets2, BucketSize*2));
 
- testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer());
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
       //Ordering is not guarantee in the cloning so insert data in a set and test
       std::set<typename ValueTraits::value_type>
          src(testset1.begin(), testset1.end());
       std::set<typename ValueTraits::value_type>
          dst(testset2.begin(), testset2.end());
       BOOST_TEST (src == dst );
- testset2.clear_and_dispose(test::delete_disposer());
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
       BOOST_TEST (testset2.empty());
    }
 }
@@ -331,17 +337,25 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, constant_time_size> testvalue_t;
+ typedef testvalue<VoidPointer, constant_time_size> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, constant_time_size> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_unordered_set <typename testvalue_t::unordered_set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_unordered_set <typename testvalue_t::unordered_set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
+ test_unordered_set < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::unordered_set_base_hook_t
+ >::type
+ >::test_all(data);
+ test_unordered_set < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::unordered_set_member_hook_t
+ , &value_type::unordered_set_node_
+ >
+ >::type
+ >::test_all(data);
 
       return 0;
    }
@@ -353,84 +367,51 @@
    public:
    int operator()()
    {
- typedef testvalue<VoidPointer, false> testvalue_t;
+ typedef testvalue<VoidPointer, false> value_type;
       static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
       std::vector<testvalue<VoidPointer, false> > data (6);
       for (int i = 0; i < 6; ++i)
          data[i].value_ = random_init[i];
 
- test_unordered_set <typename testvalue_t::unordered_set_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_unordered_set <typename testvalue_t::unordered_set_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::unordered_set_node_> >::test_all(data);
-
- test_unordered_set <typename testvalue_t::unordered_set_auto_base_hook_t::template
- value_traits<testvalue_t> >::test_all(data);
-
- test_unordered_set <typename testvalue_t::unordered_set_auto_member_hook_t::template
- value_traits<testvalue_t, &testvalue_t::unordered_set_auto_node_> >::test_all(data);
+ test_unordered_set < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::unordered_set_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_unordered_set < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::unordered_set_member_hook_t
+ , &value_type::unordered_set_node_
+ >
+ >::type
+ >::test_all(data);
+
+ test_unordered_set < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::unordered_set_auto_base_hook_t
+ >::type
+ >::test_all(data);
+
+ test_unordered_set < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::unordered_set_auto_member_hook_t
+ , &value_type::unordered_set_auto_node_
+ >
+ >::type
+ >::test_all(data);
       return 0;
    }
 };
-/*
-template class boost::intrusive::unordered_set
- < unordered_set_base_raw_t
- , boost::hash<unordered_set_base_raw_t::value_type>
- , std::equal_to<unordered_set_base_raw_t::value_type>, false>;
-template class boost::intrusive::unordered_set
- < unordered_set_member_raw_t
- , boost::hash<unordered_set_member_raw_t::value_type>
- , std::equal_to<unordered_set_member_raw_t::value_type>, false>;
-template class boost::intrusive::unordered_set
- < unordered_set_auto_base_raw
- , boost::hash<unordered_set_auto_base_raw::value_type>
- , std::equal_to<unordered_set_auto_base_raw::value_type>, false>;
-template class boost::intrusive::unordered_set
- < unordered_set_auto_member_raw
- , boost::hash<unordered_set_auto_member_raw::value_type>
- , std::equal_to<unordered_set_auto_member_raw::value_type>, false>;
-template class boost::intrusive::unordered_set
- < unordered_set_base_smart
- , boost::hash<unordered_set_base_smart::value_type>
- , std::equal_to<unordered_set_base_smart::value_type>, false>;
-template class boost::intrusive::unordered_set
- < unordered_set_member_smart
- , boost::hash<unordered_set_member_smart::value_type>
- , std::equal_to<unordered_set_member_smart::value_type>, false>;
-template class boost::intrusive::unordered_set
- < unordered_set_auto_base_smart
- , boost::hash<unordered_set_auto_base_smart::value_type>
- , std::equal_to<unordered_set_auto_base_smart::value_type>, false>;
-template class boost::intrusive::unordered_set
- < unordered_set_auto_member_smart
- , boost::hash<unordered_set_auto_member_smart::value_type>
- , std::equal_to<unordered_set_auto_member_smart::value_type>, false>;
-
-//Explicit instantiation of counted classes
-template class boost::intrusive::unordered_set
- < unordered_set_base_raw_t
- , boost::hash<unordered_set_base_raw_t::value_type>
- , std::equal_to<unordered_set_base_raw_t::value_type>, true>;
-template class boost::intrusive::unordered_set
- < unordered_set_member_raw_t
- , boost::hash<unordered_set_base_raw_t::value_type>
- , std::equal_to<unordered_set_member_raw_t::value_type>, true>;
-template class boost::intrusive::unordered_set
- < unordered_set_base_smart_t
- , boost::hash<unordered_set_base_smart_t::value_type>
- , std::equal_to<unordered_set_base_smart_t::value_type>, true>;
-template class boost::intrusive::unordered_set
- < unordered_set_member_smart_t
- , boost::hash<unordered_set_member_smart_t::value_type>
- , std::equal_to<unordered_set_member_smart_t::value_type>, true>;
-*/
+
 int main( int, char* [] )
 {
    test_main_template<void*, false>()();
- test_main_template<boost::intrusive::smart_ptr<void>, false>()();
+ test_main_template<smart_ptr<void>, false>()();
    test_main_template<void*, true>()();
- test_main_template<boost::intrusive::smart_ptr<void>, true>()();
+ test_main_template<smart_ptr<void>, true>()();
    return boost::report_errors();
 }
 #include <boost/intrusive/detail/config_end.hpp>

Added: trunk/libs/intrusive/test/virtual_base_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/intrusive/test/virtual_base_test.cpp 2007-09-26 13:38:32 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,85 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <vector>
+
+using namespace boost::intrusive;
+
+struct VirtualBase
+{
+ virtual ~VirtualBase(){}
+};
+
+struct VirtualBase2
+{
+ virtual ~VirtualBase2(){}
+};
+
+struct VirtualBase3
+{
+};
+
+class NonVirtualBase
+ : public virtual VirtualBase
+ , public virtual VirtualBase2
+{
+ public:
+ int dummy[10];
+};
+
+class MyClass
+ : public NonVirtualBase
+ , public virtual VirtualBase3
+{
+ int int_;
+ public:
+ list_member_hook<> list_hook_;
+ MyClass(int i = 0)
+ : int_(i)
+ {}
+};
+
+//Define a list that will store MyClass using the public base hook
+typedef member_hook< MyClass, list_member_hook<>, &MyClass::list_hook_ > MemberHook;
+typedef list<MyClass, MemberHook> List;
+
+int main()
+{
+ typedef std::vector<MyClass>::iterator VectIt;
+ typedef std::vector<MyClass>::reverse_iterator VectRit;
+
+ //Create several MyClass objects, each one with a different value
+ std::vector<MyClass> values;
+ for(int i = 0; i < 100; ++i) values.push_back(MyClass(i));
+
+ List my_list;
+
+ //Now insert them in the reverse order
+ //in the base hook intrusive list
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it)
+ my_list.push_front(*it);
+
+ //Now test lists
+ {
+ List::const_iterator list_it(my_list.cbegin());
+ VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+
+ //Test the objects inserted in the base hook list
+ for(; vect_it != vect_itend; ++vect_it, ++list_it)
+ if(&*list_it != &*vect_it) return 1;
+ }
+
+ return 0;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk