summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/intrusive/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/intrusive/test
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/intrusive/test')
-rw-r--r--src/boost/libs/intrusive/test/Jamfile.v234
-rw-r--r--src/boost/libs/intrusive/test/any_test.cpp188
-rw-r--r--src/boost/libs/intrusive/test/avl_multiset_test.cpp156
-rw-r--r--src/boost/libs/intrusive/test/avl_set_test.cpp156
-rw-r--r--src/boost/libs/intrusive/test/avl_test_common.hpp45
-rw-r--r--src/boost/libs/intrusive/test/bounded_pointer.hpp429
-rw-r--r--src/boost/libs/intrusive/test/bptr_value.hpp270
-rw-r--r--src/boost/libs/intrusive/test/bs_multiset_test.cpp157
-rw-r--r--src/boost/libs/intrusive/test/bs_set_test.cpp155
-rw-r--r--src/boost/libs/intrusive/test/bs_test_common.hpp67
-rw-r--r--src/boost/libs/intrusive/test/common_functors.hpp88
-rw-r--r--src/boost/libs/intrusive/test/container_size_test.cpp226
-rw-r--r--src/boost/libs/intrusive/test/custom_bucket_traits_test.cpp129
-rw-r--r--src/boost/libs/intrusive/test/default_hook_test.cpp166
-rw-r--r--src/boost/libs/intrusive/test/function_hook_test.cpp150
-rw-r--r--src/boost/libs/intrusive/test/generic_assoc_test.hpp372
-rw-r--r--src/boost/libs/intrusive/test/generic_multiset_test.hpp322
-rw-r--r--src/boost/libs/intrusive/test/generic_set_test.hpp405
-rw-r--r--src/boost/libs/intrusive/test/has_member_function_callable_with.cpp234
-rw-r--r--src/boost/libs/intrusive/test/has_member_function_callable_with_no_decltype.cpp12
-rw-r--r--src/boost/libs/intrusive/test/has_member_function_callable_with_no_variadic.cpp12
-rw-r--r--src/boost/libs/intrusive/test/int_holder.hpp117
-rw-r--r--src/boost/libs/intrusive/test/iterator_test.hpp375
-rw-r--r--src/boost/libs/intrusive/test/itestvalue.hpp284
-rw-r--r--src/boost/libs/intrusive/test/list_test.cpp515
-rw-r--r--src/boost/libs/intrusive/test/make_functions_test.cpp213
-rw-r--r--src/boost/libs/intrusive/test/multiset_test.cpp155
-rw-r--r--src/boost/libs/intrusive/test/nonhook_node.hpp121
-rw-r--r--src/boost/libs/intrusive/test/null_iterator_test.cpp95
-rw-r--r--src/boost/libs/intrusive/test/pack_options_test.cpp55
-rw-r--r--src/boost/libs/intrusive/test/parent_from_member_test.cpp172
-rw-r--r--src/boost/libs/intrusive/test/pointer_traits_test.cpp223
-rw-r--r--src/boost/libs/intrusive/test/rb_test_common.hpp45
-rw-r--r--src/boost/libs/intrusive/test/recursive_test.cpp71
-rw-r--r--src/boost/libs/intrusive/test/scary_iterators_test.cpp314
-rw-r--r--src/boost/libs/intrusive/test/set_test.cpp156
-rw-r--r--src/boost/libs/intrusive/test/sg_multiset_test.cpp148
-rw-r--r--src/boost/libs/intrusive/test/sg_set_test.cpp147
-rw-r--r--src/boost/libs/intrusive/test/slist_test.cpp660
-rw-r--r--src/boost/libs/intrusive/test/smart_ptr.hpp311
-rw-r--r--src/boost/libs/intrusive/test/splay_multiset_test.cpp155
-rw-r--r--src/boost/libs/intrusive/test/splay_set_test.cpp155
-rw-r--r--src/boost/libs/intrusive/test/stateful_value_traits_test.cpp157
-rw-r--r--src/boost/libs/intrusive/test/test_common.hpp57
-rw-r--r--src/boost/libs/intrusive/test/test_container.hpp572
-rw-r--r--src/boost/libs/intrusive/test/test_macros.hpp81
-rw-r--r--src/boost/libs/intrusive/test/treap_multiset_test.cpp157
-rw-r--r--src/boost/libs/intrusive/test/treap_set_test.cpp156
-rw-r--r--src/boost/libs/intrusive/test/unordered_multiset_test.cpp167
-rw-r--r--src/boost/libs/intrusive/test/unordered_set_test.cpp167
-rw-r--r--src/boost/libs/intrusive/test/unordered_test.hpp751
-rw-r--r--src/boost/libs/intrusive/test/unordered_test_common.hpp69
-rw-r--r--src/boost/libs/intrusive/test/virtual_base_test.cpp100
-rw-r--r--src/boost/libs/intrusive/test/voidptr_key_test.cpp94
54 files changed, 10788 insertions, 0 deletions
diff --git a/src/boost/libs/intrusive/test/Jamfile.v2 b/src/boost/libs/intrusive/test/Jamfile.v2
new file mode 100644
index 00000000..8193d27a
--- /dev/null
+++ b/src/boost/libs/intrusive/test/Jamfile.v2
@@ -0,0 +1,34 @@
+# Boost Intrusive Library Test Jamfile
+# (C) Copyright Ion Gaztanaga 2006.
+# Use, modification and distribution are subject to 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)
+
+# Adapted from John Maddock's TR1 Jamfile.v2
+# Copyright John Maddock 2005.
+# Use, modification and distribution are subject to 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)
+
+# this rule enumerates through all the sources and invokes
+# the run rule for each source, the result is a list of all
+# the run rules, which we can pass on to the test_suite rule:
+
+rule test_all
+{
+ local all_rules = ;
+
+ for local fileb in [ glob *.cpp ]
+ {
+ all_rules += [ run $(fileb)
+ : # additional args
+ : # test-files
+ : # requirements
+ <host-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
+ ] ;
+ }
+
+ return $(all_rules) ;
+}
+
+test-suite intrusive_test : [ test_all r ] : ; \ No newline at end of file
diff --git a/src/boost/libs/intrusive/test/any_test.cpp b/src/boost/libs/intrusive/test/any_test.cpp
new file mode 100644
index 00000000..75528993
--- /dev/null
+++ b/src/boost/libs/intrusive/test/any_test.cpp
@@ -0,0 +1,188 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2013.
+//
+// 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/any_hook.hpp>
+#include<boost/intrusive/slist.hpp>
+#include<boost/intrusive/rbtree.hpp>
+#include<boost/intrusive/list.hpp>
+#include<boost/intrusive/avltree.hpp>
+#include<boost/intrusive/sgtree.hpp>
+#include<boost/intrusive/splaytree.hpp>
+#include<boost/intrusive/treap.hpp>
+#include<boost/intrusive/hashtable.hpp>
+#include<boost/functional/hash.hpp>
+#include <vector> //std::vector
+#include <cstddef> //std::size_t
+
+using namespace boost::intrusive;
+
+class MyClass : public any_base_hook<>
+{
+ int int_;
+
+ public:
+ //This is a member hook
+ any_member_hook<> member_hook_;
+
+ MyClass(int i = 0)
+ : int_(i)
+ {}
+
+ int get() const
+ { return this->int_; }
+
+ 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 &o)
+ { return boost::hash<int>()(o.get()); }
+
+ friend bool priority_order(const MyClass &a, const MyClass &b)
+ { return a.int_ < b.int_; }
+};
+
+
+void instantiation_test()
+{
+ typedef member_hook< MyClass, any_member_hook<>, &MyClass::member_hook_> MemberHook;
+ typedef base_hook< any_base_hook<> > BaseHook;
+
+ MyClass myclass;
+ {
+ slist < MyClass, any_to_slist_hook< BaseHook > > slist_base;
+ slist_base.push_front(myclass);
+ }
+ {
+ slist < MyClass, any_to_slist_hook< MemberHook > > slist_member;
+ slist_member.push_front(myclass);
+ }
+ {
+ list < MyClass, any_to_list_hook< BaseHook > > list_base;
+ list_base.push_front(myclass);
+ }
+ {
+ list < MyClass, any_to_list_hook< MemberHook > > list_member;
+ list_member.push_front(myclass);
+ }
+ {
+ rbtree < MyClass, any_to_set_hook< BaseHook > > rbtree_base;
+ rbtree_base.insert_unique(myclass);
+ }
+ {
+ rbtree < MyClass, any_to_set_hook< MemberHook > > rbtree_member;
+ rbtree_member.insert_unique(myclass);
+ }
+ {
+ avltree < MyClass, any_to_avl_set_hook< BaseHook > > avltree_base;
+ avltree_base.insert_unique(myclass);
+ }
+ {
+ avltree < MyClass, any_to_avl_set_hook< MemberHook > > avltree_member;
+ avltree_member.insert_unique(myclass);
+ }
+ {
+ sgtree < MyClass, any_to_bs_set_hook< BaseHook > > sgtree_base;
+ sgtree_base.insert_unique(myclass);
+ }
+ {
+ sgtree < MyClass, any_to_bs_set_hook< MemberHook > > sgtree_member;
+ sgtree_member.insert_unique(myclass);
+ }
+ {
+ treap < MyClass, any_to_bs_set_hook< BaseHook > > treap_base;
+ treap_base.insert_unique(myclass);
+ }
+ {
+ treap < MyClass, any_to_bs_set_hook< MemberHook > > treap_member;
+ treap_member.insert_unique(myclass);
+ }
+ {
+ splaytree < MyClass, any_to_bs_set_hook< BaseHook > > splaytree_base;
+ splaytree_base.insert_unique(myclass);
+ }
+ {
+ splaytree < MyClass, any_to_bs_set_hook< MemberHook > > splaytree_member;
+ splaytree_member.insert_unique(myclass);
+ }
+ typedef unordered_bucket<any_to_unordered_set_hook< BaseHook > >::type bucket_type;
+ typedef unordered_default_bucket_traits<any_to_unordered_set_hook< BaseHook > >::type bucket_traits;
+ bucket_type buckets[2];
+ {
+ hashtable < MyClass, any_to_unordered_set_hook< BaseHook > >
+ hashtable_base(bucket_traits(&buckets[0], 1));
+ hashtable_base.insert_unique(myclass);
+ }
+ {
+ hashtable < MyClass, any_to_unordered_set_hook< MemberHook > >
+ hashtable_member(bucket_traits(&buckets[1], 1));
+ hashtable_member.insert_unique(myclass);
+ }
+}
+
+bool simple_slist_test()
+{
+ //Define an slist that will store MyClass using the public base hook
+ typedef any_to_slist_hook< base_hook< any_base_hook<> > >BaseOption;
+ typedef slist<MyClass, BaseOption, constant_time_size<false> > BaseList;
+
+ //Define an slist that will store MyClass using the public member hook
+ typedef any_to_slist_hook< member_hook<MyClass, any_member_hook<>, &MyClass::member_hook_> > MemberOption;
+ typedef slist<MyClass, MemberOption> MemberList;
+
+ 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 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 list
+ for(BaseList::iterator it(baselist.begin()), itend(baselist.end())
+ ; it != itend; ++it){
+ memberlist.push_front(*it);
+ }
+
+ //Now test lists
+ {
+ BaseList::iterator bit(baselist.begin());
+ MemberList::iterator mit(memberlist.begin());
+ 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)
+ if(&*bit != &*rit) return false;
+
+ //Test the objects inserted in the member hook list
+ for(; it != itend; ++it, ++mit)
+ if(&*mit != &*it) return false;
+ }
+ return true;
+}
+
+int main()
+{
+ if(!simple_slist_test())
+ return 1;
+ instantiation_test();
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/avl_multiset_test.cpp b/src/boost/libs/intrusive/test/avl_multiset_test.cpp
new file mode 100644
index 00000000..c2dce57d
--- /dev/null
+++ b/src/boost/libs/intrusive/test/avl_multiset_test.cpp
@@ -0,0 +1,156 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/avl_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "avl_test_common.hpp"
+#include "generic_multiset_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef avl_multiset
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< avl_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_multiset
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< avl_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_multiset
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< avl_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_multiset
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< AVLTree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_multiset
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/avl_set_test.cpp b/src/boost/libs/intrusive/test/avl_set_test.cpp
new file mode 100644
index 00000000..677232b1
--- /dev/null
+++ b/src/boost/libs/intrusive/test/avl_set_test.cpp
@@ -0,0 +1,156 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/avl_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "avl_test_common.hpp"
+#include "generic_set_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef avl_set
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< avl_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_set
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< avl_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_set
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< avl_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_set
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< AVLTree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_set
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/avl_test_common.hpp b/src/boost/libs/intrusive/test/avl_test_common.hpp
new file mode 100644
index 00000000..eed1659d
--- /dev/null
+++ b/src/boost/libs/intrusive/test/avl_test_common.hpp
@@ -0,0 +1,45 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_TEST_AVL_TEST_COMMON_HPP
+#define BOOST_INTRUSIVE_TEST_AVL_TEST_COMMON_HPP
+
+#include <boost/intrusive/avl_set_hook.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "bs_test_common.hpp"
+
+namespace boost {
+namespace intrusive {
+
+template<class VoidPointer>
+struct avl_hooks
+{
+ typedef avl_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+ typedef avl_set_base_hook
+ <link_mode<auto_unlink>
+ , void_pointer<VoidPointer>
+ , tag<void>
+ , optimize_size<true> > auto_base_hook_type;
+ typedef avl_set_member_hook
+ <void_pointer<VoidPointer>
+ , optimize_size<true> > member_hook_type;
+ typedef avl_set_member_hook
+ < link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+ typedef nonhook_node_member< avltree_node_traits<VoidPointer>,
+ avltree_algorithms
+ > nonhook_node_member_type;
+};
+
+} //namespace intrusive {
+} //namespace boost {
+
+#endif //BOOST_INTRUSIVE_TEST_AVL_TEST_COMMON_HPP
diff --git a/src/boost/libs/intrusive/test/bounded_pointer.hpp b/src/boost/libs/intrusive/test/bounded_pointer.hpp
new file mode 100644
index 00000000..008c414d
--- /dev/null
+++ b/src/boost/libs/intrusive/test/bounded_pointer.hpp
@@ -0,0 +1,429 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Matei David 2014
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOUNDED_POINTER_HPP
+#define BOUNDED_POINTER_HPP
+
+#include <iostream>
+#include <cstdlib>
+#include <cassert>
+#include <boost/container/vector.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/move/adl_move_swap.hpp>
+
+template < typename T >
+class bounded_pointer;
+
+template < typename T >
+class bounded_reference;
+
+template < typename T >
+class bounded_allocator;
+
+
+template < typename T >
+class bounded_pointer
+{
+ private:
+ void unspecified_bool_type_func() const {}
+ typedef void (bounded_pointer::*unspecified_bool_type)() const;
+
+ public:
+ typedef typename boost::intrusive::detail::remove_const< T >::type mut_val_t;
+ typedef const mut_val_t const_val_t;
+
+ typedef bounded_reference<T> reference;
+
+ static const unsigned char max_offset = (unsigned char)-1;
+
+ bounded_pointer() : m_offset(max_offset) {}
+
+ bounded_pointer(const bounded_pointer& other)
+ : m_offset(other.m_offset)
+ {}
+
+ template<class T2>
+ bounded_pointer( const bounded_pointer<T2> &other
+ , typename boost::intrusive::detail::enable_if_convertible<T2*, T*>::type* = 0)
+ : m_offset(other.m_offset)
+ {}
+
+ bounded_pointer& operator = (const bounded_pointer& other)
+ { m_offset = other.m_offset; return *this; }
+
+ template <class T2>
+ typename boost::intrusive::detail::enable_if_convertible<T2*, T*, bounded_pointer&>::type
+ operator= (const bounded_pointer<T2> & other)
+ { m_offset = other.m_offset; return *this; }
+
+ const bounded_pointer< typename boost::intrusive::detail::remove_const< T >::type >& unconst() const
+ { return *reinterpret_cast< const bounded_pointer< typename boost::intrusive::detail::remove_const< T >::type >* >(this); }
+
+ bounded_pointer< typename boost::intrusive::detail::remove_const< T >::type >& unconst()
+ { return *reinterpret_cast< bounded_pointer< typename boost::intrusive::detail::remove_const< T >::type >* >(this); }
+
+ static mut_val_t* base()
+ {
+ assert(bounded_allocator< mut_val_t >::inited());
+ return &bounded_allocator< mut_val_t >::m_base[0];
+ }
+
+ static bounded_pointer pointer_to(bounded_reference< T > r) { return &r; }
+
+ template<class U>
+ static bounded_pointer const_cast_from(const bounded_pointer<U> &uptr)
+ { return uptr.unconst(); }
+
+ operator unspecified_bool_type() const
+ {
+ return m_offset != max_offset? &bounded_pointer::unspecified_bool_type_func : 0;
+ }
+
+ T* raw() const
+ { return base() + m_offset; }
+
+ bounded_reference< T > operator * () const
+ { return bounded_reference< T >(*this); }
+
+ T* operator -> () const
+ { return raw(); }
+
+ bounded_pointer& operator ++ ()
+ { ++m_offset; return *this; }
+
+ bounded_pointer operator ++ (int)
+ { bounded_pointer res(*this); ++(*this); return res; }
+
+ friend bool operator == (const bounded_pointer& lhs, const bounded_pointer& rhs)
+ { return lhs.m_offset == rhs.m_offset; }
+
+ friend bool operator != (const bounded_pointer& lhs, const bounded_pointer& rhs)
+ { return lhs.m_offset != rhs.m_offset; }
+
+ friend bool operator < (const bounded_pointer& lhs, const bounded_pointer& rhs)
+ { return lhs.m_offset < rhs.m_offset; }
+
+ friend bool operator <= (const bounded_pointer& lhs, const bounded_pointer& rhs)
+ { return lhs.m_offset <= rhs.m_offset; }
+
+ friend bool operator >= (const bounded_pointer& lhs, const bounded_pointer& rhs)
+ { return lhs.m_offset >= rhs.m_offset; }
+
+ friend bool operator > (const bounded_pointer& lhs, const bounded_pointer& rhs)
+ { return lhs.m_offset > rhs.m_offset; }
+
+ friend std::ostream& operator << (std::ostream& os, const bounded_pointer& ptr)
+ {
+ os << static_cast< int >(ptr.m_offset);
+ return os;
+ }
+ private:
+
+ template <typename> friend class bounded_pointer;
+ friend class bounded_reference< T >;
+ friend class bounded_allocator< T >;
+
+ unsigned char m_offset;
+}; // class bounded_pointer
+
+template < typename T >
+class bounded_reference
+{
+ public:
+ typedef typename boost::intrusive::detail::remove_const< T >::type mut_val_t;
+ typedef const mut_val_t const_val_t;
+ typedef bounded_pointer< T > pointer;
+ static const unsigned char max_offset = pointer::max_offset;
+
+
+ bounded_reference()
+ : m_offset(max_offset)
+ {}
+
+ bounded_reference(const bounded_reference& other)
+ : m_offset(other.m_offset)
+ {}
+
+ T& raw() const
+ { assert(m_offset != max_offset); return *(bounded_pointer< T >::base() + m_offset); }
+
+ operator T& () const
+ { assert(m_offset != max_offset); return raw(); }
+
+ bounded_pointer< T > operator & () const
+ { assert(m_offset != max_offset); bounded_pointer< T > res; res.m_offset = m_offset; return res; }
+
+ bounded_reference& operator = (const T& rhs)
+ { assert(m_offset != max_offset); raw() = rhs; return *this; }
+
+ bounded_reference& operator = (const bounded_reference& rhs)
+ { assert(m_offset != max_offset); raw() = rhs.raw(); return *this; }
+
+ template<class T2>
+ bounded_reference( const bounded_reference<T2> &other
+ , typename boost::intrusive::detail::enable_if_convertible<T2*, T*>::type* = 0)
+ : m_offset(other.m_offset)
+ {}
+
+ template <class T2>
+ typename boost::intrusive::detail::enable_if_convertible<T2*, T*, bounded_reference&>::type
+ operator= (const bounded_reference<T2> & other)
+ { m_offset = other.m_offset; return *this; }
+
+ friend std::ostream& operator << (std::ostream& os, const bounded_reference< T >& ref)
+ {
+ os << "[bptr=" << static_cast< int >(ref.m_offset) << ",deref=" << ref.raw() << "]";
+ return os;
+ }
+
+ // the copy asop is shallow; we need swap overload to shuffle a vector of references
+ friend void swap(bounded_reference& lhs, bounded_reference& rhs)
+ { ::boost::adl_move_swap(lhs.m_offset, rhs.m_offset); }
+
+ private:
+ template <typename> friend class bounded_reference;
+ friend class bounded_pointer< T >;
+ bounded_reference(bounded_pointer< T > bptr) : m_offset(bptr.m_offset) { assert(m_offset != max_offset); }
+
+ unsigned char m_offset;
+}; // class bounded_reference
+
+template < typename T >
+class bounded_allocator
+{
+ public:
+ typedef T value_type;
+ typedef bounded_pointer< T > pointer;
+
+ static const unsigned char max_offset = pointer::max_offset;
+
+ pointer allocate(size_t n)
+ {
+ assert(inited());
+ assert(n == 1);(void)n;
+ pointer p;
+ unsigned char i;
+ for (i = 0; i < max_offset && m_in_use[i]; ++i);
+ assert(i < max_offset);
+ p.m_offset = i;
+ m_in_use[p.m_offset] = true;
+ ++m_in_use_count;
+ return p;
+ }
+
+ void deallocate(pointer p, size_t n)
+ {
+ assert(inited());
+ assert(n == 1);(void)n;
+ assert(m_in_use[p.m_offset]);
+ m_in_use[p.m_offset] = false;
+ --m_in_use_count;
+ }
+
+ // static methods
+ static void init()
+ {
+ assert(m_in_use.empty());
+ m_in_use = boost::container::vector< bool >(max_offset, false);
+ // allocate non-constructed storage
+ m_base = static_cast< T* >(::operator new [] (max_offset * sizeof(T)));
+ }
+
+ static bool inited()
+ {
+ return m_in_use.size() == max_offset;
+ }
+
+ static bool is_clear()
+ {
+ assert(inited());
+ for (unsigned char i = 0; i < max_offset; ++i)
+ {
+ if (m_in_use[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static void destroy()
+ {
+ // deallocate storage without destructors
+ ::operator delete [] (m_base);
+ m_in_use.clear();
+ }
+
+ private:
+ friend class bounded_pointer< T >;
+ friend class bounded_pointer< const T >;
+ static T* m_base;
+ static boost::container::vector< bool > m_in_use;
+ static std::size_t m_in_use_count;
+}; // class bounded_allocator
+
+template <class BoundedAllocator>
+class bounded_allocator_scope
+{
+ public:
+ bounded_allocator_scope()
+ { BoundedAllocator::init(); }
+
+ ~bounded_allocator_scope()
+ {
+ assert(BoundedAllocator::is_clear());
+ BoundedAllocator::destroy();
+ }
+};
+
+template < typename T >
+T* bounded_allocator< T >::m_base = 0;
+
+template < typename T >
+boost::container::vector< bool > bounded_allocator< T >::m_in_use;
+
+template < typename T >
+std::size_t bounded_allocator< T >::m_in_use_count;
+
+template < typename T >
+class bounded_reference_cont
+ : private boost::container::vector< bounded_reference< T > >
+{
+ private:
+ typedef T val_type;
+ typedef boost::container::vector< bounded_reference< T > > Base;
+ typedef bounded_allocator< T > allocator_type;
+ typedef bounded_pointer< T > pointer;
+
+ public:
+ typedef typename Base::value_type value_type;
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ typedef typename Base::reference reference;
+ typedef typename Base::const_reference const_reference;
+ typedef typename Base::reverse_iterator reverse_iterator;
+ typedef typename Base::const_reverse_iterator const_reverse_iterator;
+
+ using Base::begin;
+ using Base::rbegin;
+ using Base::end;
+ using Base::rend;
+ using Base::front;
+ using Base::back;
+ using Base::size;
+ using Base::operator[];
+ using Base::push_back;
+
+ explicit bounded_reference_cont(size_t n = 0)
+ : Base(), m_allocator()
+ {
+ for (size_t i = 0; i < n; ++i){
+ pointer p = m_allocator.allocate(1);
+ BOOST_TRY{
+ new (p.raw()) val_type();
+ }
+ BOOST_CATCH(...){
+ m_allocator.deallocate(p, 1);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ Base::push_back(*p);
+ }
+ }
+
+ bounded_reference_cont(const bounded_reference_cont& other)
+ : Base(), m_allocator(other.m_allocator)
+ { *this = other; }
+
+ template < typename InputIterator >
+ bounded_reference_cont(InputIterator it_start, InputIterator it_end)
+ : Base(), m_allocator()
+ {
+ for (InputIterator it = it_start; it != it_end; ++it){
+ pointer p = m_allocator.allocate(1);
+ new (p.raw()) val_type(*it);
+ Base::push_back(*p);
+ }
+ }
+
+ template <typename InputIterator>
+ void assign(InputIterator it_start, InputIterator it_end)
+ {
+ this->clear();
+ for (InputIterator it = it_start; it != it_end;){
+ pointer p = m_allocator.allocate(1);
+ new (p.raw()) val_type(*it++);
+ Base::push_back(*p);
+ }
+ }
+
+ ~bounded_reference_cont()
+ { clear(); }
+
+ void clear()
+ {
+ while (!Base::empty()){
+ pointer p = &Base::back();
+ p->~val_type();
+ m_allocator.deallocate(p, 1);
+ Base::pop_back();
+ }
+ }
+
+ bounded_reference_cont& operator = (const bounded_reference_cont& other)
+ {
+ if (&other != this){
+ clear();
+ for (typename Base::const_iterator it = other.begin(); it != other.end(); ++it){
+ pointer p = m_allocator.allocate(1);
+ new (p.raw()) val_type(*it);
+ Base::push_back(*p);
+ }
+ }
+ return *this;
+ }
+
+ private:
+ allocator_type m_allocator;
+}; // class bounded_reference_cont
+
+template < typename T >
+class bounded_pointer_holder
+{
+ public:
+ typedef T value_type;
+ typedef bounded_pointer< value_type > pointer;
+ typedef bounded_pointer< const value_type > const_pointer;
+ typedef bounded_allocator< value_type > allocator_type;
+
+ bounded_pointer_holder() : _ptr(allocator_type().allocate(1))
+ { new (_ptr.raw()) value_type(); }
+
+ ~bounded_pointer_holder()
+ {
+ _ptr->~value_type();
+ allocator_type().deallocate(_ptr, 1);
+ }
+
+ const_pointer get_node () const
+ { return _ptr; }
+
+ pointer get_node ()
+ { return _ptr; }
+
+ private:
+ const pointer _ptr;
+}; // class bounded_pointer_holder
+
+#endif
diff --git a/src/boost/libs/intrusive/test/bptr_value.hpp b/src/boost/libs/intrusive/test/bptr_value.hpp
new file mode 100644
index 00000000..d4313c57
--- /dev/null
+++ b/src/boost/libs/intrusive/test/bptr_value.hpp
@@ -0,0 +1,270 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Matei David 2014
+// (C) Copyright Ion Gaztanaga 2014
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_BPTR_VALUE_HPP
+#define BOOST_INTRUSIVE_BPTR_VALUE_HPP
+
+#include <cassert>
+#include <iostream>
+#include "bounded_pointer.hpp"
+#include "common_functors.hpp"
+#include "int_holder.hpp"
+#include <boost/intrusive/link_mode.hpp>
+
+
+namespace boost {
+namespace intrusive {
+
+struct BPtr_Value
+{
+ static const bool constant_time_size = true;
+
+ explicit BPtr_Value(int value = 42)
+ : value_(value)
+ {}
+
+ BPtr_Value(const BPtr_Value& rhs)
+ : value_(rhs.value_)
+ {}
+
+ ~BPtr_Value()
+ {
+ if (is_linked())
+ {
+ assert(false);
+ }
+ }
+
+ // testvalue is used in boost::container::vector and thus prev and next
+ // have to be handled appropriately when copied:
+ BPtr_Value& operator = (const BPtr_Value& src)
+ {
+ if (is_linked())
+ {
+ assert(false);
+ }
+ value_ = src.value_;
+ return *this;
+ }
+
+ // value
+ int_holder value_;
+
+ // list node hooks
+ bounded_pointer< BPtr_Value > m_previous;
+ bounded_pointer< BPtr_Value > m_next;
+ // tree node hooks
+ bounded_pointer< BPtr_Value > m_parent;
+ bounded_pointer< BPtr_Value > m_l_child;
+ bounded_pointer< BPtr_Value > m_r_child;
+ signed char m_extra;
+
+ const int_holder &get_int_holder() const
+ { return value_; }
+
+ int int_value() const
+ { return value_.int_value(); }
+
+ bool is_linked() const
+ { return m_previous || m_next || m_parent || m_l_child || m_r_child; }
+
+ friend bool operator< (const BPtr_Value &other1, const BPtr_Value &other2)
+ { return other1.value_ < other2.value_; }
+
+ friend bool operator< (int other1, const BPtr_Value &other2)
+ { return other1 < other2.value_; }
+
+ friend bool operator< (const BPtr_Value &other1, int other2)
+ { return other1.value_ < other2; }
+
+ friend bool operator> (const BPtr_Value &other1, const BPtr_Value &other2)
+ { return other1.value_ > other2.value_; }
+
+ friend bool operator> (int other1, const BPtr_Value &other2)
+ { return other1 > other2.value_; }
+
+ friend bool operator> (const BPtr_Value &other1, int other2)
+ { return other1.value_ > other2; }
+
+ friend bool operator== (const BPtr_Value &other1, const BPtr_Value &other2)
+ { return other1.value_ == other2.value_; }
+
+ friend bool operator== (int other1, const BPtr_Value &other2)
+ { return other1 == other2.value_; }
+
+ friend bool operator== (const BPtr_Value &other1, int other2)
+ { return other1.value_ == other2; }
+
+ friend bool operator!= (const BPtr_Value &other1, const BPtr_Value &other2)
+ { return !(other1 == other2); }
+
+ friend bool operator!= (int other1, const BPtr_Value &other2)
+ { return !(other1 == other2.value_); }
+
+ friend bool operator!= (const BPtr_Value &other1, int other2)
+ { return !(other1.value_ == other2); }
+
+}; // class BPtr_Value
+
+std::ostream& operator<<(std::ostream& s, const BPtr_Value& t)
+{ return s << t.value_.int_value(); }
+
+template < typename Node_Algorithms >
+void swap_nodes(bounded_reference< BPtr_Value > lhs, bounded_reference< BPtr_Value > rhs)
+{
+ Node_Algorithms::swap_nodes(
+ boost::intrusive::pointer_traits< bounded_pointer< BPtr_Value > >::pointer_to(lhs),
+ boost::intrusive::pointer_traits< bounded_pointer< BPtr_Value > >::pointer_to(rhs));
+}
+
+struct List_BPtr_Node_Traits
+{
+ typedef BPtr_Value val_t;
+ typedef val_t node;
+ typedef bounded_pointer< val_t > node_ptr;
+ typedef bounded_pointer< const val_t > const_node_ptr;
+
+ static node_ptr get_previous(const_node_ptr p) { return p->m_previous; }
+ static void set_previous(node_ptr p, node_ptr prev) { p->m_previous = prev; }
+ static node_ptr get_next(const_node_ptr p) { return p->m_next; }
+ static void set_next(node_ptr p, node_ptr next) { p->m_next = next; }
+};
+
+struct Tree_BPtr_Node_Traits
+{
+ typedef BPtr_Value val_t;
+ typedef val_t node;
+ typedef bounded_pointer< val_t > node_ptr;
+ typedef bounded_pointer< const val_t > const_node_ptr;
+
+ static node_ptr get_parent(const_node_ptr p) { return p->m_parent; }
+ static void set_parent(node_ptr p, node_ptr parent) { p->m_parent = parent; }
+ static node_ptr get_left(const_node_ptr p) { return p->m_l_child; }
+ static void set_left(node_ptr p, node_ptr l_child) { p->m_l_child = l_child; }
+ static node_ptr get_right(const_node_ptr p) { return p->m_r_child; }
+ static void set_right(node_ptr p, node_ptr r_child) { p->m_r_child = r_child; }
+};
+
+struct RBTree_BPtr_Node_Traits
+ : public Tree_BPtr_Node_Traits
+{
+ typedef signed char color;
+ typedef Tree_BPtr_Node_Traits::node_ptr node_ptr;
+ typedef Tree_BPtr_Node_Traits::const_node_ptr const_node_ptr;
+ static color get_color(const_node_ptr p) { return p->m_extra; }
+ static void set_color(node_ptr p, color c) { p->m_extra = c; }
+ static color black() { return 0; }
+ static color red() { return 1; }
+};
+
+struct AVLTree_BPtr_Node_Traits
+ : public Tree_BPtr_Node_Traits
+{
+ typedef signed char balance;
+ typedef Tree_BPtr_Node_Traits::node_ptr node_ptr;
+ typedef Tree_BPtr_Node_Traits::const_node_ptr const_node_ptr;
+ static balance get_balance(const_node_ptr p) { return p->m_extra; }
+ static void set_balance(node_ptr p, balance b) { p->m_extra = b; }
+ static balance negative() { return -1; }
+ static balance zero() { return 0; }
+ static balance positive() { return 1; }
+};
+
+template < typename NodeTraits >
+struct BPtr_Value_Traits
+{
+ typedef NodeTraits node_traits;
+ typedef typename node_traits::val_t value_type;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename node_traits::const_node_ptr const_node_ptr;
+ typedef node_ptr pointer;
+ typedef const_node_ptr const_pointer;
+ typedef bounded_reference< value_type > reference;
+ typedef bounded_reference< const value_type > const_reference;
+ typedef BPtr_Value_Traits<NodeTraits> * value_traits_ptr;
+
+ static const boost::intrusive::link_mode_type link_mode = boost::intrusive::safe_link;
+
+ static const_node_ptr to_node_ptr(const_reference v) { return &v; }
+ static node_ptr to_node_ptr(reference v) { return &v; }
+ static const_pointer to_value_ptr(const_node_ptr p) { return p; }
+ static pointer to_value_ptr(node_ptr p) { return p; }
+};
+
+template < typename >
+struct ValueContainer;
+
+template <>
+struct ValueContainer< BPtr_Value >
+{
+ typedef bounded_reference_cont< BPtr_Value > type;
+};
+
+namespace test{
+
+template <>
+class new_cloner< BPtr_Value >
+{
+ public:
+ typedef BPtr_Value value_type;
+ typedef bounded_pointer< value_type > pointer;
+ typedef bounded_reference< const value_type > const_reference;
+ typedef bounded_allocator< value_type > allocator_type;
+
+ pointer operator () (const_reference r)
+ {
+ pointer p = allocator_type().allocate(1);
+ new (p.raw()) value_type(r);
+ return p;
+ }
+};
+
+template <>
+class new_nonconst_cloner< BPtr_Value >
+{
+ public:
+ typedef BPtr_Value value_type;
+ typedef bounded_pointer< value_type > pointer;
+ typedef bounded_reference< value_type > reference;
+ typedef bounded_allocator< value_type > allocator_type;
+
+ pointer operator () (reference r)
+ {
+ pointer p = allocator_type().allocate(1);
+ new (p.raw()) value_type(r);
+ return p;
+ }
+};
+
+template <>
+class delete_disposer< BPtr_Value >
+{
+ public:
+ typedef BPtr_Value value_type;
+ typedef bounded_pointer< value_type > pointer;
+ typedef bounded_allocator< value_type > allocator_type;
+
+ void operator () (pointer p)
+ {
+ p->~value_type();
+ allocator_type().deallocate(p, 1);
+ }
+};
+
+} // namespace test
+
+} // namespace intrusive
+} // namespace boost
+
+
+#endif
diff --git a/src/boost/libs/intrusive/test/bs_multiset_test.cpp b/src/boost/libs/intrusive/test/bs_multiset_test.cpp
new file mode 100644
index 00000000..beb91159
--- /dev/null
+++ b/src/boost/libs/intrusive/test/bs_multiset_test.cpp
@@ -0,0 +1,157 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/bs_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "bs_test_common.hpp"
+#include "generic_multiset_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef bs_multiset
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_multiset
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_multiset
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_multiset
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_multiset
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+ //test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/bs_set_test.cpp b/src/boost/libs/intrusive/test/bs_set_test.cpp
new file mode 100644
index 00000000..d2f4f4fb
--- /dev/null
+++ b/src/boost/libs/intrusive/test/bs_set_test.cpp
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/bs_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "generic_set_test.hpp"
+#include "bs_test_common.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef bs_set
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_set
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_set
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_set
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_set
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/bs_test_common.hpp b/src/boost/libs/intrusive/test/bs_test_common.hpp
new file mode 100644
index 00000000..69f7f758
--- /dev/null
+++ b/src/boost/libs/intrusive/test/bs_test_common.hpp
@@ -0,0 +1,67 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_TEST_BS_TEST_COMMON_HPP
+#define BOOST_INTRUSIVE_TEST_BS_TEST_COMMON_HPP
+
+#include <boost/intrusive/bs_set_hook.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "bptr_value.hpp"
+#include "test_common.hpp"
+
+namespace boost {
+namespace intrusive {
+
+template<class VoidPointer>
+struct bs_hooks
+{
+ typedef bs_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+ typedef bs_set_base_hook
+ <link_mode<auto_unlink>
+ , void_pointer<VoidPointer>
+ , tag<void> > auto_base_hook_type;
+ typedef bs_set_member_hook
+ <void_pointer<VoidPointer> > member_hook_type;
+ typedef bs_set_member_hook
+ < link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+ typedef nonhook_node_member< tree_node_traits<VoidPointer>,
+ bstree_algorithms
+ > nonhook_node_member_type;
+};
+
+template < class ValueTraits, bool DefaultHolder, bool Map >
+struct tree_rebinder_common
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef typename detail::if_c
+ < DefaultHolder
+ , typename detail::if_c
+ < detail::is_same<value_type, BPtr_Value>::value
+ , header_holder_type< bounded_pointer_holder< BPtr_Value > >
+ , void
+ >::type
+ , header_holder_type< heap_node_holder< typename ValueTraits::node_ptr > >
+ >::type holder_opt;
+ typedef typename detail::if_c
+ < Map, key_of_value<int_holder_key_of_value<value_type> >, void
+ >::type key_of_value_opt;
+
+ typedef typename detail::if_c
+ < Map, priority_of_value<int_priority_of_value<value_type> >, void
+ >::type prio_of_value_opt;
+};
+
+
+} //namespace intrusive {
+} //namespace boost {
+
+#endif //BOOST_INTRUSIVE_TEST_BS_TEST_COMMON_HPP
diff --git a/src/boost/libs/intrusive/test/common_functors.hpp b/src/boost/libs/intrusive/test/common_functors.hpp
new file mode 100644
index 00000000..b84a84a1
--- /dev/null
+++ b/src/boost/libs/intrusive/test/common_functors.hpp
@@ -0,0 +1,88 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2013
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_TEST_COMMON_FUNCTORS_HPP
+#define BOOST_INTRUSIVE_TEST_COMMON_FUNCTORS_HPP
+
+#include<boost/intrusive/detail/iterator.hpp>
+#include<boost/intrusive/detail/mpl.hpp>
+#include<boost/static_assert.hpp>
+#include<boost/move/detail/to_raw_pointer.hpp>
+
+namespace boost {
+namespace intrusive {
+namespace test {
+
+template<class T>
+class delete_disposer
+{
+ public:
+ template <class Pointer>
+ void operator()(Pointer p)
+ {
+ typedef typename boost::intrusive::iterator_traits<Pointer>::value_type value_type;
+ BOOST_STATIC_ASSERT(( detail::is_same<T, value_type>::value ));
+ delete boost::movelib::to_raw_pointer(p);
+ }
+};
+
+template<class T>
+class new_cloner
+{
+ public:
+ T *operator()(const T &t)
+ { return new T(t); }
+};
+
+template<class T>
+class new_nonconst_cloner
+{
+ public:
+ T *operator()(T &t)
+ { return new T(t); }
+};
+
+template<class T>
+class new_default_factory
+{
+ public:
+ T *operator()()
+ { return new T(); }
+};
+
+class empty_disposer
+{
+ public:
+ template<class T>
+ void operator()(const T &)
+ {}
+};
+
+struct any_less
+{
+ template<class T, class U>
+ bool operator()(const T &t, const U &u) const
+ { return t < u; }
+};
+
+struct any_greater
+{
+ template<class T, class U>
+ bool operator()(const T &t, const U &u) const
+ { return t > u; }
+};
+
+} //namespace test {
+} //namespace intrusive {
+} //namespace boost {
+
+#endif
diff --git a/src/boost/libs/intrusive/test/container_size_test.cpp b/src/boost/libs/intrusive/test/container_size_test.cpp
new file mode 100644
index 00000000..e320ff5e
--- /dev/null
+++ b/src/boost/libs/intrusive/test/container_size_test.cpp
@@ -0,0 +1,226 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014
+//
+// 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/detail/lightweight_test.hpp>
+#include <cstddef>
+
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include <boost/intrusive/bs_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include <boost/intrusive/unordered_set.hpp>
+#include <boost/static_assert.hpp>
+#include "itestvalue.hpp"
+
+using namespace boost::intrusive;
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reverse_iterator)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reverse_iterator)
+
+template<bool Value>
+struct boolean
+{
+ static const bool value = Value;
+};
+
+template<class A, class B>
+struct pow2_and_equal_sizes
+{
+ static const std::size_t a_size = sizeof(A);
+ static const std::size_t b_size = sizeof(B);
+ static const bool a_b_sizes_equal = a_size == b_size;
+ static const bool value = !(a_size & (a_size - 1u));
+};
+
+template<class Hook>
+struct node : Hook
+{};
+
+//Avoid testing for uncommon architectures
+void test_sizes(boolean<false>, std::size_t)
+{}
+
+template<class C>
+void test_iterator_sizes(std::size_t size)
+{
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+ (::, C, reverse_iterator, iterator) reverse_iterator;
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+ (::, C, const_reverse_iterator, const_iterator) const_reverse_iterator;
+
+ BOOST_TEST_EQ(sizeof(iterator), size);
+ BOOST_TEST_EQ(sizeof(const_iterator), size);
+ BOOST_TEST_EQ(sizeof(iterator), sizeof(reverse_iterator));
+ BOOST_TEST_EQ(sizeof(const_iterator), size);
+ BOOST_TEST_EQ(sizeof(const_iterator), sizeof(const_reverse_iterator));
+}
+
+//Test sizes for common 32 and 64 bit architectures
+void test_sizes(boolean<true>, std::size_t wordsize)
+{
+ { //list
+ typedef list<node<list_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef list<node<list_base_hook<> >, constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*2);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef list< node< list_base_hook<> >, header_holder_type< heap_node_holder< list_node<void*>* > > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*2);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef list< node< list_base_hook<> >, constant_time_size<false>, header_holder_type< heap_node_holder< list_node<void*>* > > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*1);
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //slist
+ typedef slist<node< slist_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*2);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef slist<node< slist_base_hook<> >, constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*1);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef slist<node< slist_base_hook<> >, cache_last<true> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //set
+ typedef set<node< set_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*5);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef set<node< set_base_hook<> > , constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*4);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef set<node< set_base_hook<optimize_size<true> > > , constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef set< node< set_base_hook<> >, header_holder_type< heap_node_holder< rbtree_node<void*>* > > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*2);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef set< node< set_base_hook<> >, constant_time_size<false>, header_holder_type< heap_node_holder< rbtree_node<void*>* > > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*1);
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //avl
+ typedef avl_set<node< avl_set_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*5);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef avl_set<node< avl_set_base_hook<> > , constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*4);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef avl_set<node< avl_set_base_hook<optimize_size<true> > > , constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef avl_set< node< avl_set_base_hook<> >, header_holder_type< heap_node_holder< avltree_node<void*>* > > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*2);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef avl_set< node< avl_set_base_hook<> >, constant_time_size<false>, header_holder_type< heap_node_holder< avltree_node<void*>* > > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*1);
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //bs
+ typedef bs_set<node< bs_set_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*4);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef bs_set<node< bs_set_base_hook<> > , constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //splay
+ typedef splay_set<node< bs_set_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*4);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef splay_set<node< bs_set_base_hook<> > , constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //scapegoat
+ typedef sg_set<node< bs_set_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), (wordsize*5+sizeof(float)*2));
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //treap
+ typedef treap_set<node< bs_set_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*4);
+ test_iterator_sizes<c>(wordsize);
+ }
+ {
+ typedef treap_set<node< bs_set_base_hook<> > , constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize);
+ }
+ { //unordered
+ typedef unordered_set<node< unordered_set_base_hook<> > > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize*2);
+ }
+ {
+ typedef unordered_set<node< unordered_set_base_hook<> > , power_2_buckets<true> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*3);
+ test_iterator_sizes<c>(wordsize*2);
+ }
+ {
+ typedef unordered_set<node< unordered_set_base_hook<> >, constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*2);
+ test_iterator_sizes<c>(wordsize*2);
+ }
+ {
+ typedef unordered_set<node< unordered_set_base_hook< optimize_multikey<true> > >, constant_time_size<false> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*2);
+ test_iterator_sizes<c>(wordsize*2);
+ }
+ {
+ typedef unordered_set<node< unordered_set_base_hook< optimize_multikey<true> > >, incremental<true> > c;
+ BOOST_TEST_EQ(sizeof(c), wordsize*4);
+ test_iterator_sizes<c>(wordsize*2);
+ }
+}
+
+int main()
+{
+ test_sizes(boolean< pow2_and_equal_sizes<std::size_t, void*>::value >(), sizeof(std::size_t));
+ return ::boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/custom_bucket_traits_test.cpp b/src/boost/libs/intrusive/test/custom_bucket_traits_test.cpp
new file mode 100644
index 00000000..843cf849
--- /dev/null
+++ b/src/boost/libs/intrusive/test/custom_bucket_traits_test.cpp
@@ -0,0 +1,129 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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 <boost/static_assert.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_bucket_ptr<BaseHook>::type BaseBucketPtrType;
+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_bucket_ptr<MemberHook>::type MemberBucketPtrType;
+typedef unordered_set<MyClass, MemberHook> MemberUset;
+//Explicit
+typedef value_traits< uset_value_traits > Traits;
+typedef unordered_bucket<Traits>::type TraitsBucketType;
+typedef unordered_bucket_ptr<Traits>::type TraitsBucketPtrType;
+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()
+{
+ BOOST_STATIC_ASSERT((detail::is_same<BaseUset::bucket_type, BaseBucketType>::value));
+ BOOST_STATIC_ASSERT((detail::is_same<MemberUset::bucket_type, MemberBucketType>::value));
+ BOOST_STATIC_ASSERT((detail::is_same<TraitsUset::bucket_type, TraitsBucketType>::value));
+ BOOST_STATIC_ASSERT((detail::is_same<BaseBucketType, MemberBucketType>::value));
+ BOOST_STATIC_ASSERT((detail::is_same<BaseBucketType, TraitsBucketType>::value));
+ BOOST_STATIC_ASSERT((detail::is_same<BaseBucketPtrType, TraitsBucketPtrType>::value));
+ BOOST_STATIC_ASSERT((detail::is_same<BaseBucketPtrType, MemberBucketPtrType>::value));
+ BOOST_STATIC_ASSERT((detail::is_same<BaseBucketPtrType, BaseBucketType*>::value));
+
+ 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;
+}
diff --git a/src/boost/libs/intrusive/test/default_hook_test.cpp b/src/boost/libs/intrusive/test/default_hook_test.cpp
new file mode 100644
index 00000000..a8efa994
--- /dev/null
+++ b/src/boost/libs/intrusive/test/default_hook_test.cpp
@@ -0,0 +1,166 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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/splay_set.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include <boost/intrusive/bs_set.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include "smart_ptr.hpp"
+#include <vector>
+
+using namespace boost::intrusive;
+
+class MyClass
+
+: public list_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<safe_link> >
+, public slist_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<safe_link> >
+, public set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<safe_link> >
+, public unordered_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<safe_link> >
+, public avl_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<safe_link> >
+, public bs_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<safe_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_); }
+
+ friend bool priority_order(const MyClass &l, const MyClass &r)
+ { return l.int_ < r.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;
+typedef avl_set<MyClass> AvlSet;
+typedef splay_set<MyClass> SplaySet;
+typedef treap_set<MyClass> TreapSet;
+typedef sg_set<MyClass> SgSet;
+typedef bs_set<MyClass> BsSet;
+
+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;
+ Slist my_slist;
+ Set my_set;
+ USet::bucket_type buckets[100];
+ USet my_uset(USet::bucket_traits(pointer_traits<USet::bucket_ptr>::pointer_to(*buckets), 100));
+ AvlSet my_avlset;
+ SplaySet my_splayset;
+
+ //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);
+ my_avlset.insert(*it);
+ my_splayset.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());
+ AvlSet::const_reverse_iterator avl_set_rit(my_avlset.crbegin());
+ SplaySet::const_reverse_iterator splay_set_rit(my_splayset.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
+ , ++avl_set_rit
+ , ++splay_set_rit
+ ){
+ if(&*list_it != &*vect_it) return 1;
+ if(&*slist_it != &*vect_it) return 1;
+ if(&*set_rit != &*vect_it) return 1;
+ if(&*avl_set_rit != &*vect_it) return 1;
+ if(&*splay_set_rit != &*vect_it)return 1;
+ if(my_uset.find(*set_rit) == my_uset.cend()) return 1;
+ }
+ }
+ }
+ //Since treap_set, sg_set & bs_set reuse the hook, treat them apart
+ {
+ TreapSet my_treapset;
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
+ my_treapset.insert(*it);
+ }
+
+ TreapSet::const_reverse_iterator treap_set_rit(my_treapset.crbegin());
+ VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+ for(; vect_it != vect_itend; ++vect_it, ++treap_set_rit){
+ if(&*treap_set_rit != &*vect_it) return 1;
+ }
+ }
+ {
+ SgSet my_sgset;
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
+ my_sgset.insert(*it);
+ }
+
+ SgSet::const_reverse_iterator sg_set_rit(my_sgset.crbegin());
+ VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+ for(; vect_it != vect_itend; ++vect_it, ++sg_set_rit){
+ if(&*sg_set_rit != &*vect_it) return 1;
+ }
+ }
+ {
+ BsSet my_bsset;
+ for(VectIt it(values.begin()), itend(values.end()); it != itend; ++it){
+ my_bsset.insert(*it);
+ }
+
+ BsSet::const_reverse_iterator bs_set_rit(my_bsset.crbegin());
+ VectRit vect_it(values.rbegin()), vect_itend(values.rend());
+ for(; vect_it != vect_itend; ++vect_it, ++bs_set_rit){
+ if(&*bs_set_rit != &*vect_it) return 1;
+ }
+ }
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/function_hook_test.cpp b/src/boost/libs/intrusive/test/function_hook_test.cpp
new file mode 100644
index 00000000..9b16395c
--- /dev/null
+++ b/src/boost/libs/intrusive/test/function_hook_test.cpp
@@ -0,0 +1,150 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2010-2013
+//
+// 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/parent_from_member.hpp>
+#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>
+
+using namespace boost::intrusive;
+
+struct MyClass
+{
+ MyClass() : order(0) {}
+ int order;
+
+ //This internal type has two hooks
+ struct InnerNode : public list_base_hook<>, public slist_base_hook<>
+ , public set_base_hook<>, public unordered_set_base_hook<>
+ {
+ list_member_hook<> listhook;
+ slist_member_hook<> slisthook;
+ set_member_hook<> sethook;
+ unordered_set_member_hook<> usethook;
+ } inner;
+
+ friend bool operator < (const MyClass &l, const MyClass &r)
+ { return l.order < r.order; }
+ friend bool operator == (const MyClass &l, const MyClass &r)
+ { return l.order == r.order; }
+ friend std::size_t hash_value(const MyClass &value)
+ { return std::size_t(value.order); }
+};
+
+//This functor converts between MyClass and the InnerNode member hook
+#define InnerMemberHook(TAG, HOOKTYPE, MEMBERNAME)\
+ struct InnerMemberHookFunctor##TAG \
+ {\
+ typedef HOOKTYPE hook_type;\
+ typedef hook_type* hook_ptr;\
+ typedef const hook_type* const_hook_ptr;\
+ typedef MyClass value_type;\
+ typedef value_type* pointer;\
+ typedef const value_type* const_pointer;\
+ \
+ static hook_ptr to_hook_ptr (value_type &value)\
+ { return &value.inner.MEMBERNAME; }\
+ static const_hook_ptr to_hook_ptr(const value_type &value)\
+ { return &value.inner.MEMBERNAME; }\
+ static pointer to_value_ptr(hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>\
+ (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
+ ,&MyClass::inner\
+ );\
+ }\
+ static const_pointer to_value_ptr(const_hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>\
+ (get_parent_from_member<MyClass::InnerNode>(n, &MyClass::InnerNode::MEMBERNAME)\
+ ,&MyClass::inner\
+ );\
+ }\
+ };\
+//
+
+
+//This functor converts between MyClass and the InnerNode base hook
+#define InnerBaseHook(TAG, HOOKTYPE)\
+ struct InnerBaseHookFunctor##TAG \
+ {\
+ typedef HOOKTYPE hook_type;\
+ typedef hook_type* hook_ptr;\
+ typedef const hook_type* const_hook_ptr;\
+ typedef MyClass value_type;\
+ typedef value_type* pointer;\
+ typedef const value_type* const_pointer;\
+ \
+ static hook_ptr to_hook_ptr (value_type &value)\
+ { return &value.inner; }\
+ static const_hook_ptr to_hook_ptr(const value_type &value)\
+ { return &value.inner; }\
+ static pointer to_value_ptr(hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>(static_cast<MyClass::InnerNode*>(n),&MyClass::inner);\
+ }\
+ static const_pointer to_value_ptr(const_hook_ptr n)\
+ {\
+ return get_parent_from_member<MyClass>(static_cast<const MyClass::InnerNode*>(n),&MyClass::inner);\
+ }\
+ };\
+//
+
+//List
+InnerMemberHook(List, list_member_hook<>, listhook)
+InnerBaseHook(List, list_base_hook<>)
+//Slist
+InnerMemberHook(Slist, slist_member_hook<>, slisthook)
+InnerBaseHook(Slist, slist_base_hook<>)
+//Set
+InnerMemberHook(Set, set_member_hook<>, sethook)
+InnerBaseHook(Set, set_base_hook<>)
+//Unordered Set
+InnerMemberHook(USet, unordered_set_member_hook<>, usethook)
+InnerBaseHook(USet, unordered_set_base_hook<>)
+
+//Define containers
+typedef list < MyClass, function_hook< InnerMemberHookFunctorList> > CustomListMember;
+typedef list < MyClass, function_hook< InnerBaseHookFunctorList > > CustomListBase;
+typedef slist< MyClass, function_hook< InnerMemberHookFunctorSlist> > CustomSlistMember;
+typedef slist< MyClass, function_hook< InnerBaseHookFunctorSlist > > CustomSlistBase;
+typedef set < MyClass, function_hook< InnerMemberHookFunctorSet> > CustomSetMember;
+typedef set < MyClass, function_hook< InnerBaseHookFunctorSet > > CustomSetBase;
+typedef unordered_set< MyClass, function_hook< InnerMemberHookFunctorUSet> > CustomUSetMember;
+typedef unordered_set< MyClass, function_hook< InnerBaseHookFunctorUSet > > CustomUSetBase;
+
+int main()
+{
+ MyClass n;
+ CustomListBase listbase;
+ CustomListMember listmember;
+ CustomSlistBase slistbase;
+ CustomSlistMember slistmember;
+ CustomSetBase setbase;
+ CustomSetMember setmember;
+ CustomUSetBase::bucket_type buckets_uset[1];
+ CustomUSetBase usetbase(CustomUSetBase::bucket_traits(buckets_uset, 1));
+ CustomUSetBase::bucket_type buckets_umultiset[1];
+ CustomUSetMember usetmember(CustomUSetMember::bucket_traits(buckets_umultiset, 1));
+
+ listbase.insert(listbase.begin(), n);
+ listmember.insert(listmember.begin(), n);
+ slistbase.insert(slistbase.begin(), n);
+ slistmember.insert(slistmember.begin(), n);
+ setbase.insert(n);
+ setmember.insert(n);
+ usetbase.insert(n);
+ usetmember.insert(n);
+
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/generic_assoc_test.hpp b/src/boost/libs/intrusive/test/generic_assoc_test.hpp
new file mode 100644
index 00000000..74b4c5f8
--- /dev/null
+++ b/src/boost/libs/intrusive/test/generic_assoc_test.hpp
@@ -0,0 +1,372 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2013.
+//
+// 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/container/vector.hpp> //vector
+#include <boost/intrusive/detail/config_begin.hpp>
+#include "common_functors.hpp"
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(has_splay, splay)
+
+BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(has_rebalance, rebalance)
+
+BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(has_insert_before, insert_before)
+
+BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(is_treap, priority_comp)
+
+template<class ContainerDefiner>
+struct test_generic_assoc
+{
+ typedef typename ContainerDefiner::value_cont_type value_cont_type;
+
+ static void test_all(value_cont_type&);
+ static void test_root(value_cont_type&);
+ static void test_clone(value_cont_type&);
+ static void test_insert_erase_burst();
+ static void test_container_from_end(value_cont_type&, detail::true_type);
+ static void test_container_from_end(value_cont_type&, detail::false_type) {}
+ static void test_splay_up(value_cont_type&, detail::true_type);
+ static void test_splay_up(value_cont_type&, detail::false_type) {}
+ static void test_splay_down(value_cont_type&, detail::true_type);
+ static void test_splay_down(value_cont_type&, detail::false_type) {}
+ static void test_rebalance(value_cont_type&, detail::true_type);
+ static void test_rebalance(value_cont_type&, detail::false_type) {}
+ static void test_insert_before(value_cont_type&, detail::true_type);
+ static void test_insert_before(value_cont_type&, detail::false_type) {}
+ static void test_container_from_iterator(value_cont_type&, detail::true_type);
+ static void test_container_from_iterator(value_cont_type&, detail::false_type) {}
+};
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::
+ test_container_from_iterator(value_cont_type& values, detail::true_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+ assoc_type testset(values.begin(), values.end());
+ typedef typename assoc_type::iterator it_type;
+ typedef typename assoc_type::const_iterator cit_type;
+ typedef typename assoc_type::size_type sz_type;
+ sz_type sz = testset.size();
+ for(it_type b(testset.begin()), e(testset.end()); b != e; ++b)
+ {
+ assoc_type &s = assoc_type::container_from_iterator(b);
+ const assoc_type &cs = assoc_type::container_from_iterator(cit_type(b));
+ BOOST_TEST(&s == &cs);
+ BOOST_TEST(&s == &testset);
+ s.erase(b);
+ BOOST_TEST(testset.size() == (sz-1));
+ s.insert(*b);
+ BOOST_TEST(testset.size() == sz);
+ }
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_insert_erase_burst()
+{
+ //value_cont_type values;
+ const std::size_t MaxValues = 200;
+ value_cont_type values(MaxValues);
+ for(std::size_t i = 0; i != MaxValues; ++i){
+ (&values[i])->value_ = i;
+ }
+
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+ typedef typename assoc_type::iterator iterator;
+
+ { //Ordered insertion + erasure
+ assoc_type testset (values.begin(), values.begin() + values.size());
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin());
+ testset.check();
+ iterator it(testset.begin()), itend(testset.end());
+ for(std::size_t i = 0; it != itend; ++i){
+ BOOST_TEST(&*it == &values[i]);
+ it = testset.erase(it);
+ testset.check();
+ }
+ BOOST_TEST(testset.empty());
+ }
+
+ { //Now random insertions + erasure
+ assoc_type testset;
+ typedef typename value_cont_type::iterator vec_iterator;
+ boost::container::vector<vec_iterator> it_vector;
+ //Random insertion
+ for(vec_iterator it(values.begin()), itend(values.end())
+ ; it != itend
+ ; ++it){
+ it_vector.push_back(it);
+ }
+ for(std::size_t i = 0; i != MaxValues; ++i){
+ testset.insert(*it_vector[i]);
+ testset.check();
+ }
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin());
+ //Random erasure
+ random_shuffle(it_vector.begin(), it_vector.end());
+ for(std::size_t i = 0; i != MaxValues; ++i){
+ testset.erase(testset.iterator_to(*it_vector[i]));
+ testset.check();
+ }
+ BOOST_TEST(testset.empty());
+ }
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_all(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+ test_root(values);
+ test_clone(values);
+ test_container_from_end(values, detail::bool_< assoc_type::has_container_from_iterator >());
+ test_splay_up(values, detail::bool_< has_splay< assoc_type >::value >());
+ test_splay_down(values, detail::bool_< has_splay< assoc_type >::value >());
+ test_rebalance(values, detail::bool_< has_rebalance< assoc_type >::value >());
+ test_insert_before(values, detail::bool_< has_insert_before< assoc_type >::value >());
+ test_insert_erase_burst();
+ test_container_from_iterator(values, detail::bool_< assoc_type::has_container_from_iterator >());
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_root(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container<>::type assoc_type;
+ typedef typename assoc_type::iterator iterator;
+ typedef typename assoc_type::const_iterator const_iterator;
+
+ assoc_type testset1;
+ const assoc_type &ctestset1 = testset1;;
+
+ BOOST_TEST( testset1.root() == testset1.end());
+ BOOST_TEST(ctestset1.root() == ctestset1.cend());
+ BOOST_TEST( testset1.croot() == ctestset1.cend());
+
+
+ testset1.insert(values.begin(), values.begin() + values.size());
+
+ iterator i = testset1.root();
+ iterator i2(i);
+ BOOST_TEST( i.go_parent().go_parent() == i2);
+
+ const_iterator ci = ctestset1.root();
+ const_iterator ci2(ci);
+ BOOST_TEST( ci.go_parent().go_parent() == ci2);
+
+ ci = testset1.croot();
+ ci2 = ci;
+ BOOST_TEST( ci.go_parent().go_parent() == ci2);
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_clone(value_cont_type& values)
+{
+ {
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+ typedef typename assoc_type::value_type value_type;
+ typedef typename assoc_type::size_type size_type;
+
+ assoc_type testset1 (values.begin(), values.begin() + values.size());
+ assoc_type testset2;
+
+
+ size_type const testset1_oldsize = testset1.size();
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST (testset1.size() == testset1_oldsize);
+ BOOST_TEST (testset2 == testset1);
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+
+ //Now test move clone
+ testset2.clone_from(boost::move(testset1), test::new_nonconst_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 ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>
+ ::test_container_from_end(value_cont_type& values, detail::true_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+ assoc_type testset (values.begin(), values.begin() + values.size());
+ BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.end()));
+ BOOST_TEST (testset == assoc_type::container_from_end_iterator(testset.cend()));
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_splay_up
+(value_cont_type& values, detail::true_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+
+ typedef typename assoc_type::iterator iterator;
+ typedef value_cont_type orig_set_t;
+ std::size_t num_values;
+ orig_set_t original_testset;
+ {
+ assoc_type testset (values.begin(), values.end());
+ num_values = testset.size();
+ original_testset = value_cont_type(testset.begin(), testset.end());
+ }
+
+ for(std::size_t i = 0; i != num_values; ++i){
+ assoc_type testset (values.begin(), values.end());
+ {
+ iterator it = testset.begin();
+ for(std::size_t j = 0; j != i; ++j, ++it){}
+ testset.splay_up(it);
+ }
+ BOOST_TEST (testset.size() == num_values);
+ iterator it = testset.begin();
+ for( typename orig_set_t::const_iterator origit = original_testset.begin()
+ , origitend = original_testset.end()
+ ; origit != origitend
+ ; ++origit, ++it){
+ BOOST_TEST(*origit == *it);
+ }
+ }
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_splay_down
+(value_cont_type& values, detail::true_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+
+ typedef typename assoc_type::iterator iterator;
+ typedef value_cont_type orig_set_t;
+ std::size_t num_values;
+ orig_set_t original_testset;
+ {
+ assoc_type testset (values.begin(), values.end());
+ num_values = testset.size();
+ original_testset = value_cont_type(testset.begin(), testset.end());
+ }
+
+ for(std::size_t i = 0; i != num_values; ++i){
+ assoc_type testset (values.begin(), values.end());
+ BOOST_TEST(testset.size() == num_values);
+ {
+ iterator it = testset.begin();
+ for(std::size_t j = 0; j != i; ++j, ++it){}
+ BOOST_TEST(*it == *testset.splay_down(*it));
+ }
+ BOOST_TEST (testset.size() == num_values);
+ iterator it = testset.begin();
+ for( typename orig_set_t::const_iterator origit = original_testset.begin()
+ , origitend = original_testset.end()
+ ; origit != origitend
+ ; ++origit, ++it){
+ BOOST_TEST(*origit == *it);
+ }
+ }
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_rebalance
+(value_cont_type& values, detail::true_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+ typedef value_cont_type orig_set_t;
+ orig_set_t original_testset;
+ {
+ assoc_type testset (values.begin(), values.end());
+ original_testset.assign(testset.begin(), testset.end());
+ }
+ {
+ assoc_type testset(values.begin(), values.end());
+ testset.rebalance();
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin());
+ }
+
+ {
+ std::size_t numdata;
+ {
+ assoc_type testset(values.begin(), values.end());
+ numdata = testset.size();
+ }
+
+ for(int i = 0; i != (int)numdata; ++i){
+ assoc_type testset(values.begin(), values.end());
+ typename assoc_type::iterator it = testset.begin();
+ for(int j = 0; j != i; ++j) ++it;
+ testset.rebalance_subtree(it);
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(original_testset, testset.begin());
+ }
+ }
+}
+
+template<class ContainerDefiner>
+void test_generic_assoc<ContainerDefiner>::test_insert_before
+(value_cont_type& values, detail::true_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type assoc_type;
+ {
+ assoc_type testset;
+ typedef typename value_cont_type::iterator vec_iterator;
+ for(vec_iterator it(values.begin()), itend(values.end())
+ ; it != itend
+ ; ++it){
+ testset.push_back(*it);
+ }
+ BOOST_TEST(testset.size() == values.size());
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin());
+ }
+ {
+ assoc_type testset;
+ typedef typename value_cont_type::iterator vec_iterator;
+
+ for(vec_iterator it(--values.end()); true; --it){
+ testset.push_front(*it);
+ if(it == values.begin()){
+ break;
+ }
+ }
+ BOOST_TEST(testset.size() == values.size());
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin());
+ }
+ {
+ assoc_type testset;
+ typedef typename value_cont_type::iterator vec_iterator;
+ typename assoc_type::iterator it_pos =
+ testset.insert_before(testset.end(), *values.rbegin());
+ testset.insert_before(testset.begin(), *values.begin());
+ for(vec_iterator it(++values.begin()), itend(--values.end())
+ ; it != itend
+ ; ++it){
+ testset.insert_before(it_pos, *it);
+ }
+ BOOST_TEST(testset.size() == values.size());
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(values, testset.begin());
+ }
+}
+
+}}} //namespace boost::intrusive::test
+
+#include <boost/intrusive/detail/config_end.hpp>
diff --git a/src/boost/libs/intrusive/test/generic_multiset_test.hpp b/src/boost/libs/intrusive/test/generic_multiset_test.hpp
new file mode 100644
index 00000000..2a0ee286
--- /dev/null
+++ b/src/boost/libs/intrusive/test/generic_multiset_test.hpp
@@ -0,0 +1,322 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2013.
+//
+// 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/container/vector.hpp>
+#include <boost/intrusive/detail/config_begin.hpp>
+#include "common_functors.hpp"
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include "generic_assoc_test.hpp"
+#include <typeinfo>
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+template<class ContainerDefiner>
+struct test_generic_multiset
+{
+ typedef typename ContainerDefiner::value_cont_type value_cont_type;
+
+ static void test_all();
+ static void test_sort(value_cont_type&);
+ static void test_insert(value_cont_type&);
+ static void test_swap(value_cont_type&);
+ static void test_merge(value_cont_type&);
+ static void test_find(value_cont_type&);
+ static void test_impl();
+};
+
+template<class ContainerDefiner>
+void test_generic_multiset<ContainerDefiner>::test_all ()
+{
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ value_cont_type values (6);
+ for (int i = 0; i < 6; ++i)
+ (&values[i])->value_ = random_init[i];
+ typedef typename ContainerDefiner::template container
+ <>::type multiset_type;
+ {
+ multiset_type testset(values.begin(), values.end());
+ test::test_container(testset);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_common_unordered_and_associative_container(testset, values);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_associative_container(testset, values);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_non_unique_container(testset, values);
+ }
+ test_sort(values);
+ test_insert(values);
+ test_swap(values);
+ test_merge(values);
+ test_find(values);
+ test_impl();
+ test_generic_assoc<ContainerDefiner>::test_all(values);
+}
+
+//test case due to an error in tree implementation:
+template<class ContainerDefiner>
+void test_generic_multiset<ContainerDefiner>::test_impl()
+{
+ value_cont_type values (5);
+ for (int i = 0; i < 5; ++i)
+ (&values[i])->value_ = i;
+ typedef typename ContainerDefiner::template container
+ <>::type multiset_type;
+
+ multiset_type testset;
+ for (int i = 0; i < 5; ++i)
+ testset.insert (values[i]);
+
+ testset.erase (testset.iterator_to (values[0]));
+ testset.erase (testset.iterator_to (values[1]));
+ testset.insert (values[1]);
+
+ testset.erase (testset.iterator_to (values[2]));
+ testset.erase (testset.iterator_to (values[3]));
+}
+
+//test: constructor, iterator, clear, reverse_iterator, front, back, size:
+template<class ContainerDefiner>
+void test_generic_multiset<ContainerDefiner>::test_sort(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type 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() ); }
+
+ testset1.clear();
+ BOOST_TEST (testset1.empty());
+
+ typedef typename ContainerDefiner::template container
+ <compare<even_odd>
+ >::type multiset_type2;
+
+ multiset_type2 testset2 (values.begin(), values.begin() + 6);
+ { int init_values [] = { 5, 3, 1, 4, 2, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); }
+
+ BOOST_TEST (testset2.begin()->value_ == 2);
+ BOOST_TEST (testset2.rbegin()->value_ == 5);
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
+template<class ContainerDefiner>
+void test_generic_multiset<ContainerDefiner>::test_insert(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type multiset_type;
+
+ multiset_type testset;
+ testset.insert(values.begin() + 2, values.begin() + 5);
+ testset.check();
+ { int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); }
+
+ typename multiset_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 1);
+
+ i = testset.insert (i, values[0]);
+ testset.check();
+ BOOST_TEST (&*i == &values[0]);
+
+ { int init_values [] = { 5, 4, 3, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); }
+
+ 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);
+ testset.check();
+
+ { int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); }
+}
+
+//test: insert (seq-version), swap, erase (seq-version), size:
+template<class ContainerDefiner>
+void test_generic_multiset<ContainerDefiner>::test_swap(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type multiset_type;
+ multiset_type testset1 (values.begin(), values.begin() + 2);
+ multiset_type testset2;
+ testset2.insert (values.begin() + 2, values.begin() + 6);
+ testset1.swap (testset2);
+
+ { int init_values [] = { 1, 2, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ { int init_values [] = { 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+
+ testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ BOOST_TEST (&*testset1.begin() == &values[3]);
+}
+
+template<class ContainerDefiner>
+void test_generic_multiset<ContainerDefiner>::test_merge(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type multiset_type;
+ typedef typename multiset_type::key_of_value key_of_value;
+ typedef typename multiset_type::key_type key_type;
+
+ typedef typename ContainerDefiner::template container
+ < compare< std::greater<key_type> > >::type multiset_greater_type;
+
+ //original vector: 3, 2, 4, 1, 5, 2
+ //2,3
+ multiset_type testset1 (values.begin(), values.begin() + 2);
+ //5, 4, 2, 1
+ multiset_greater_type testset2;
+ testset2.insert (values.begin() + 2, values.begin() + 6);
+
+ testset2.merge(testset1);
+ testset1.check();
+ testset2.check();
+
+ BOOST_TEST (testset1.empty());
+ BOOST_TEST (testset2.size() == 6);
+ { int init_values [] = { 5, 4, 3, 2, 2, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+
+ value_cont_type cmp_val_cont(1);
+ typename value_cont_type::reference cmp_val = cmp_val_cont.front();
+ (&cmp_val)->value_ = 2;
+
+ BOOST_TEST (*testset2.find(key_of_value()(cmp_val)) == values[5]);
+ BOOST_TEST (*testset2.find(2, any_greater()) == values[5]);
+ BOOST_TEST (&*(++testset2.find(key_of_value()(cmp_val))) == &values[1]);
+
+ testset1.merge(testset2);
+ testset1.check();
+ testset2.check();
+
+ BOOST_TEST (testset1.size() == 6);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ BOOST_TEST (*testset1.find(key_of_value()(cmp_val)) == values[5]);
+ BOOST_TEST (*testset1.find(2, any_less()) == values[5]);
+ BOOST_TEST (&*(++testset1.find(key_of_value()(cmp_val))) == &values[1]);
+ BOOST_TEST (testset2.empty());
+}
+
+//test: find, equal_range (lower_bound, upper_bound):
+template<class ContainerDefiner>
+void test_generic_multiset<ContainerDefiner>::test_find(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type multiset_type;
+ typedef typename multiset_type::key_of_value key_of_value;
+ multiset_type testset (values.begin(), values.end());
+ typedef typename multiset_type::iterator iterator;
+ typedef typename multiset_type::const_iterator const_iterator;
+
+ {
+ value_cont_type cmp_val_cont(1);
+ typename value_cont_type::reference cmp_val = cmp_val_cont.front();
+ (&cmp_val)->value_ = 2;
+ iterator i = testset.find (key_of_value()(cmp_val));
+ BOOST_TEST (i == testset.find (2, any_less()));
+ BOOST_TEST (i->value_ == 2);
+ BOOST_TEST ((++i)->value_ == 2);
+ std::pair<iterator,iterator> range = testset.equal_range (key_of_value()(cmp_val));
+ BOOST_TEST(range == testset.equal_range (2, any_less()));
+
+ BOOST_TEST (range.first->value_ == 2);
+ BOOST_TEST (range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 2);
+
+ (&cmp_val)->value_ = 7;
+ BOOST_TEST (testset.find(key_of_value()(cmp_val)) == testset.end());
+ BOOST_TEST (testset.find (7, any_less()) == testset.end());
+ }
+ { //1, 2, 2, 3, 4, 5
+ const multiset_type &const_testset = testset;
+ std::pair<iterator,iterator> range;
+ std::pair<const_iterator, const_iterator> const_range;
+ value_cont_type cmp_val_cont(2);
+ typename value_cont_type::reference cmp_val_lower = cmp_val_cont.front();
+ typename value_cont_type::reference cmp_val_upper = cmp_val_cont.back();
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ //left-closed, right-closed
+ range = testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, true);
+ BOOST_TEST (range == testset.bounded_range (1, 2, any_less(), true, true));
+ BOOST_TEST (range.first->value_ == 1);
+ BOOST_TEST (range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 3);
+ }
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ const_range = const_testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, false);
+ BOOST_TEST (const_range == const_testset.bounded_range (1, 2, any_less(), true, false));
+ BOOST_TEST (const_range.first->value_ == 1);
+ BOOST_TEST (const_range.second->value_ == 2);
+ BOOST_TEST (boost::intrusive::iterator_distance (const_range.first, const_range.second) == 1);
+
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 3;
+ range = testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, false);
+ BOOST_TEST (range == testset.bounded_range (1, 3, any_less(), true, false));
+ BOOST_TEST (range.first->value_ == 1);
+ BOOST_TEST (range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 3);
+ }
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ const_range = const_testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), false, true);
+ BOOST_TEST (const_range == const_testset.bounded_range (1, 2, any_less(), false, true));
+ BOOST_TEST (const_range.first->value_ == 2);
+ BOOST_TEST (const_range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (const_range.first, const_range.second) == 2);
+ }
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ range = testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), false, false);
+ BOOST_TEST (range == testset.bounded_range (1, 2, any_less(), false, false));
+ BOOST_TEST (range.first->value_ == 2);
+ BOOST_TEST (range.second->value_ == 2);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 0);
+ }
+ {
+ (&cmp_val_lower)->value_ = 5;
+ (&cmp_val_upper)->value_ = 6;
+ const_range = const_testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, false);
+ BOOST_TEST (const_range == const_testset.bounded_range (5, 6, any_less(), true, false));
+ BOOST_TEST (const_range.first->value_ == 5);
+ BOOST_TEST (const_range.second == const_testset.end());
+ BOOST_TEST (boost::intrusive::iterator_distance (const_range.first, const_range.second) == 1);
+ }
+ }
+}
+
+}}} //namespace boost::intrusive::test
+
+#include <boost/intrusive/detail/config_end.hpp>
diff --git a/src/boost/libs/intrusive/test/generic_set_test.hpp b/src/boost/libs/intrusive/test/generic_set_test.hpp
new file mode 100644
index 00000000..92360194
--- /dev/null
+++ b/src/boost/libs/intrusive/test/generic_set_test.hpp
@@ -0,0 +1,405 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2013.
+//
+// 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/container/vector.hpp>
+#include <boost/intrusive/detail/config_begin.hpp>
+#include "common_functors.hpp"
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include "generic_assoc_test.hpp"
+#include <typeinfo>
+#include <boost/intrusive/priority_compare.hpp>
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+template<class ContainerDefiner>
+struct test_generic_set
+{
+ static void test_all();
+ private:
+ typedef typename ContainerDefiner::value_cont_type value_cont_type;
+ static void test_sort(value_cont_type&);
+ static void test_insert(value_cont_type&);
+ static void test_insert_advanced(value_cont_type&, detail::true_type);
+ static void test_insert_advanced(value_cont_type&, detail::false_type);
+ static void test_swap(value_cont_type&);
+ static void test_merge(value_cont_type&);
+ static void test_find(value_cont_type&);
+ static void test_impl();
+};
+
+
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_all()
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ {
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ value_cont_type values(6);
+ for (int i = 0; i < 6; ++i)
+ (&values[i])->value_ = random_init[i];
+
+ {
+ set_type testset(values.begin(), values.end());
+ test::test_container(testset);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_common_unordered_and_associative_container(testset, values);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_associative_container(testset, values);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_unique_container(testset, values);
+ }
+
+ test_sort(values);
+ test_insert(values);
+ test_insert_advanced(values, detail::bool_< is_treap< set_type >::value >());
+ test_swap(values);
+ test_merge(values);
+ test_find(values);
+ test_impl();
+ test_generic_assoc<ContainerDefiner>::test_all(values);
+ }
+ {
+ value_cont_type values(6);
+ for (int i = 0; i < 6; ++i)
+ (&values[i])->value_ = i+1;
+ set_type testset(values.begin(), values.end());
+ test::test_iterator_bidirectional(testset);
+ }
+}
+
+//test case due to an error in tree implementation:
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_impl()
+{
+ value_cont_type values (5);
+ for (int i = 0; i < 5; ++i)
+ (&values[i])->value_ = i;
+
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ set_type testset;
+ for (int i = 0; i < 5; ++i)
+ testset.insert (values[i]);
+
+ testset.erase (testset.iterator_to (values[0]));
+ testset.erase (testset.iterator_to (values[1]));
+ testset.insert (values[1]);
+
+ testset.erase (testset.iterator_to (values[2]));
+ testset.erase (testset.iterator_to (values[3]));
+}
+
+//test: constructor, iterator, clear, reverse_iterator, front, back, size:
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_sort(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+
+ set_type testset1 (values.begin(), values.end());
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ testset1.clear();
+ BOOST_TEST (testset1.empty());
+
+ typedef typename ContainerDefiner::template container
+ < compare<even_odd> >::type set_type2;
+
+ set_type2 testset2 (values.begin(), values.begin() + 6);
+ { int init_values [] = { 5, 3, 1, 4, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); }
+ BOOST_TEST (testset2.begin()->value_ == 2);
+ BOOST_TEST (testset2.rbegin()->value_ == 5);
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_insert(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ {
+ set_type testset;
+ testset.insert(values.begin() + 2, values.begin() + 5);
+ testset.check();
+
+ const set_type& const_testset = testset;
+ { int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+ typename set_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 1);
+
+ i = testset.insert (i, values[0]);
+ testset.check();
+ BOOST_TEST (&*i == &values[0]);
+
+ { int init_values [] = { 5, 4, 3, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset.rbegin() ); }
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+
+ i = set_type::s_iterator_to(values[2]);
+ BOOST_TEST (&*i == &values[2]);
+
+ typedef typename value_cont_type::const_reference const_reference;
+ typename set_type::const_iterator ic;
+ ic = testset.iterator_to (static_cast< const_reference >(values[2]));
+ BOOST_TEST (&*ic == &values[2]);
+ ic = set_type::s_iterator_to (static_cast< const_reference >(values[2]));
+ BOOST_TEST (&*ic == &values[2]);
+
+ testset.erase (i);
+ testset.check();
+ { int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); }
+ }
+}
+
+// treap version
+template<class ValueType, class KeyType>
+struct prio_comp
+ : priority_compare<int>
+{
+ bool operator()(const ValueType &v, const KeyType &k) const
+ { return this->priority_compare<int>::operator()(v.int_value(), k.int_value()); }
+
+ bool operator()(const KeyType &k, const ValueType &v) const
+ { return this->priority_compare<int>::operator()(k.int_value(), v.int_value()); }
+};
+
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_insert_advanced
+(value_cont_type& values, detail::true_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ typedef typename set_type::key_of_value key_of_value;
+ typedef typename set_type::priority_of_value priority_of_value;
+ typedef typename set_type::value_type value_type;
+ typedef priority_compare<> prio_comp_t;
+ {
+ set_type testset;
+ testset.insert(values.begin(), values.begin() + values.size());
+ testset.check();
+ value_type v(1);
+ typename set_type::insert_commit_data data;
+ BOOST_TEST ((!testset.insert_check(1, any_less(), 1, prio_comp_t(), data).second));
+ BOOST_TEST ((!testset.insert_check(testset.begin(), 1, any_less(), 1, prio_comp_t(), data).second));
+ BOOST_TEST ((!testset.insert_check(key_of_value()(v), priority_of_value()(v), data).second));
+ BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), priority_of_value()(v), data).second));
+ }
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_insert_advanced
+(value_cont_type& values, detail::false_type)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ typedef typename set_type::key_of_value key_of_value;
+ typedef typename set_type::value_type value_type;
+ {
+ set_type testset;
+ testset.insert(values.begin(), values.begin() + values.size());
+ testset.check();
+ value_type v(1);
+ typename set_type::insert_commit_data data;
+ BOOST_TEST ((!testset.insert_check(1, any_less(), data).second));
+ BOOST_TEST ((!testset.insert_check(key_of_value()(v), data).second));
+ BOOST_TEST ((!testset.insert_check(testset.begin(), 1, any_less(), data).second));
+ BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), data).second));
+ }
+}
+
+//test: insert (seq-version), swap, erase (seq-version), size:
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_swap(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ set_type testset1 (values.begin(), values.begin() + 2);
+ set_type testset2;
+ testset2.insert (values.begin() + 2, values.begin() + 6);
+ testset1.swap (testset2);
+
+ { int init_values [] = { 1, 2, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ { int init_values [] = { 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+
+ testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ // BOOST_TEST (&testset1.front() == &values[3]);
+ BOOST_TEST (&*testset1.begin() == &values[3]);
+}
+
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_merge(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ typedef typename set_type::key_type key_type;
+
+ typedef typename ContainerDefiner::template container
+ < compare< std::greater<key_type> > >::type set_greater_type;
+
+ //2,3
+ set_type testset1 (values.begin(), values.begin() + 2);
+ //5, 4, 2, 1
+ set_greater_type testset2;
+ testset2.insert (values.begin() + 2, values.begin() + 6);
+
+ testset2.merge(testset1);
+ testset1.check();
+ testset2.check();
+
+ BOOST_TEST (testset1.size() == 1);
+ { int init_values [] = { 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ BOOST_TEST (&*testset1.begin() == &values[1]);
+
+ BOOST_TEST (testset2.size() == 5);
+ { int init_values [] = { 5, 4, 3, 2, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+
+ testset1.merge(testset2);
+ testset1.check();
+ testset2.check();
+
+ BOOST_TEST (testset1.size() == 5);
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+
+ BOOST_TEST (testset2.size() == 1);
+ { int init_values [] = { 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+ BOOST_TEST (&*testset2.begin() == &values[5]);
+}
+
+//test: find, equal_range (lower_bound, upper_bound), bounded_range:
+template<class ContainerDefiner>
+void test_generic_set<ContainerDefiner>::test_find(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type set_type;
+ set_type testset (values.begin(), values.end());
+ typedef typename set_type::iterator iterator;
+ typedef typename set_type::const_iterator const_iterator;
+ typedef typename set_type::key_of_value key_of_value;
+ typedef typename value_cont_type::reference reference;
+
+ {
+ //value_type cmp_val;
+ value_cont_type cmp_val_cont(1);
+ reference cmp_val = cmp_val_cont.front();
+ (&cmp_val)->value_ = 2;
+ iterator i = testset.find(key_of_value()(cmp_val));
+ BOOST_TEST (i == testset.find(2, any_less()));
+ BOOST_TEST (i->value_ == 2);
+ BOOST_TEST ((++i)->value_ != 2);
+
+ std::pair<iterator,iterator> range = testset.equal_range (key_of_value()(cmp_val));
+ BOOST_TEST(range == testset.equal_range (2, any_less()));
+
+ BOOST_TEST (range.first->value_ == 2);
+ BOOST_TEST (range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 1);
+
+ (&cmp_val)->value_ = 7;
+ BOOST_TEST (testset.find (key_of_value()(cmp_val)) == testset.end());
+ BOOST_TEST (testset.find (7, any_less()) == testset.end());
+ }
+
+ {
+ const set_type &const_testset = testset;
+ std::pair<iterator,iterator> range;
+ std::pair<const_iterator, const_iterator> const_range;
+ //value_type cmp_val_lower, cmp_val_upper;
+ value_cont_type cmp_val_cont(2);
+ reference cmp_val_lower = cmp_val_cont.front();
+ reference cmp_val_upper = cmp_val_cont.back();
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ //left-closed, right-closed
+ range = testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, true);
+ BOOST_TEST (range == testset.bounded_range (1, 2, any_less(), true, true));
+ BOOST_TEST (range.first->value_ == 1);
+ BOOST_TEST (range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 2);
+ }
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ const_range = const_testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, false);
+ BOOST_TEST (const_range == const_testset.bounded_range (1, 2, any_less(), true, false));
+ BOOST_TEST (const_range.first->value_ == 1);
+ BOOST_TEST (const_range.second->value_ == 2);
+ BOOST_TEST (boost::intrusive::iterator_distance (const_range.first, const_range.second) == 1);
+
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 3;
+ range = testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, false);
+ BOOST_TEST (range == testset.bounded_range (1, 3, any_less(), true, false));
+ BOOST_TEST (range.first->value_ == 1);
+ BOOST_TEST (range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 2);
+ }
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ const_range = const_testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), false, true);
+ BOOST_TEST (const_range == const_testset.bounded_range (1, 2, any_less(), false, true));
+ BOOST_TEST (const_range.first->value_ == 2);
+ BOOST_TEST (const_range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (const_range.first, const_range.second) == 1);
+ }
+ {
+ (&cmp_val_lower)->value_ = 1;
+ (&cmp_val_upper)->value_ = 2;
+ range = testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), false, false);
+ BOOST_TEST (range == testset.bounded_range (1, 2, any_less(), false, false));
+ BOOST_TEST (range.first->value_ == 2);
+ BOOST_TEST (range.second->value_ == 2);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == 0);
+ }
+ {
+ (&cmp_val_lower)->value_ = 5;
+ (&cmp_val_upper)->value_ = 6;
+ const_range = const_testset.bounded_range (key_of_value()(cmp_val_lower), key_of_value()(cmp_val_upper), true, false);
+ BOOST_TEST (const_range == const_testset.bounded_range (5, 6, any_less(), true, false));
+ BOOST_TEST (const_range.first->value_ == 5);
+ BOOST_TEST (const_range.second == const_testset.end());
+ BOOST_TEST (boost::intrusive::iterator_distance (const_range.first, const_range.second) == 1);
+ }
+ }
+}
+
+}}} //namespace boost::intrusive::test
+
+#include <boost/intrusive/detail/config_end.hpp>
diff --git a/src/boost/libs/intrusive/test/has_member_function_callable_with.cpp b/src/boost/libs/intrusive/test/has_member_function_callable_with.cpp
new file mode 100644
index 00000000..41242a8b
--- /dev/null
+++ b/src/boost/libs/intrusive/test/has_member_function_callable_with.cpp
@@ -0,0 +1,234 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2014. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+//User define
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME func0to3
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 3
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace func0to3ns {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME func1to2
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace func1to2ns {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME func3to3
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 3
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 3
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace func3to3ns {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME func0to0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace func0to0ns {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+///////////////////
+///////////////////
+// TEST CODE
+///////////////////
+///////////////////
+
+struct functor
+{
+ //func0to3
+ void func0to3();
+ void func0to3(const int&);
+ void func0to3(const int&, const int&);
+ void func0to3(const int&, const int&, const int&);
+ //func1to2
+ void func1to2(const int&);
+ void func1to2(const int&, const int&);
+ //func3to3
+ void func3to3(const int&, const int&, const int&);
+ //func0to0
+ void func0to0();
+};
+
+struct functor2
+{
+ void func0to3(char*);
+ void func0to3(int, char*);
+ void func0to3(int, char*, double);
+ void func0to3(const int&, char*, void *);
+ //func1to2
+ void func1to2(char*);
+ void func1to2(int, char*);
+ void func1to2(int, char*, double);
+ //func3to3
+ void func3to3(const int&, char*, void *);
+};
+
+struct functor3
+{
+
+};
+
+struct functor4
+{
+ //func0to3
+ void func0to3(...);
+ template<class T> void func0to3(int, const T &);
+ template<class T> void func0to3(const T &);
+ template<class T, class U> void func0to3(int, const T &, const U &);
+ //func1to2
+ template<class T> void func1to2(int, const T &);
+ template<class T> void func1to2(const T &);
+ template<class T, class U> void func1to2(int, const T &, const U &);
+ //func3to3
+ void func3to3(...);
+ template<class T, class U> void func3to3(int, const T &, const U &);
+};
+
+int main()
+{
+ #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
+ { //func0to3 0 arg
+ using func0to3ns::has_member_function_callable_with_func0to3;
+ int check1[ has_member_function_callable_with_func0to3<functor>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func0to3<functor2>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func0to3<functor3>::value ? 1 : -1];
+ int check4[ has_member_function_callable_with_func0to3<functor4>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ (void)check4;
+ }
+ { //func0to0 0 arg
+ using func0to0ns::has_member_function_callable_with_func0to0;
+ int check1[ has_member_function_callable_with_func0to0<functor>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func0to0<functor2>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func0to0<functor3>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ }
+ #endif
+
+ { //func0to3 1arg
+ using func0to3ns::has_member_function_callable_with_func0to3;
+ int check1[ has_member_function_callable_with_func0to3<functor, int>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func0to3<functor, char*>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func0to3<functor2, int>::value ? 1 : -1];
+ int check4[ has_member_function_callable_with_func0to3<functor2, char*>::value ? 1 : -1];
+ int check5[!has_member_function_callable_with_func0to3<functor3, int>::value ? 1 : -1];
+ int check6[!has_member_function_callable_with_func0to3<functor3, char*>::value ? 1 : -1];
+ int check7[ has_member_function_callable_with_func0to3<functor4, int>::value ? 1 : -1];
+ int check8[ has_member_function_callable_with_func0to3<functor4, char*>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ (void)check4;
+ (void)check5;
+ (void)check6;
+ (void)check7;
+ (void)check8;
+ }
+
+ { //func1to2 1arg
+ using func1to2ns::has_member_function_callable_with_func1to2;
+ int check1[ has_member_function_callable_with_func1to2<functor, int>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func1to2<functor, char*>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func1to2<functor2, int>::value ? 1 : -1];
+ int check4[ has_member_function_callable_with_func1to2<functor2, char*>::value ? 1 : -1];
+ int check5[!has_member_function_callable_with_func1to2<functor3, int>::value ? 1 : -1];
+ int check6[!has_member_function_callable_with_func1to2<functor3, char*>::value ? 1 : -1];
+ int check7[ has_member_function_callable_with_func1to2<functor4, int>::value ? 1 : -1];
+ int check8[ has_member_function_callable_with_func1to2<functor4, char*>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ (void)check4;
+ (void)check5;
+ (void)check6;
+ (void)check7;
+ (void)check8;
+ }
+
+ { //func0to3 2arg
+ using func0to3ns::has_member_function_callable_with_func0to3;
+ int check1[ has_member_function_callable_with_func0to3<functor, int, int>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func0to3<functor, int, char*>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func0to3<functor2, int, int>::value ? 1 : -1];
+ int check4[ has_member_function_callable_with_func0to3<functor2, int, char*>::value ? 1 : -1];
+ int check5[!has_member_function_callable_with_func0to3<functor3, int, int>::value ? 1 : -1];
+ int check6[!has_member_function_callable_with_func0to3<functor3, int, char*>::value ? 1 : -1];
+ int check7[ has_member_function_callable_with_func0to3<functor4, int, char*>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ (void)check4;
+ (void)check5;
+ (void)check6;
+ (void)check7;
+ }
+
+ { //func1to2 2arg
+ using func1to2ns::has_member_function_callable_with_func1to2;
+ int check1[ has_member_function_callable_with_func1to2<functor, int, int>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func1to2<functor, int, char*>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func1to2<functor2, int, int>::value ? 1 : -1];
+ int check4[ has_member_function_callable_with_func1to2<functor2, int, char*>::value ? 1 : -1];
+ int check5[!has_member_function_callable_with_func1to2<functor3, int, int>::value ? 1 : -1];
+ int check6[!has_member_function_callable_with_func1to2<functor3, int, char*>::value ? 1 : -1];
+ int check7[ has_member_function_callable_with_func1to2<functor4, int, char*>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ (void)check4;
+ (void)check5;
+ (void)check6;
+ (void)check7;
+ }
+
+ { //func0to3 3arg
+ using func0to3ns::has_member_function_callable_with_func0to3;
+ int check1[ has_member_function_callable_with_func0to3<functor, int, int, int>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func0to3<functor, int, char*, int>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func0to3<functor2, int, int, int>::value ? 1 : -1];
+ int check4[ has_member_function_callable_with_func0to3<functor2, int, char*, void*>::value ? 1 : -1];
+ int check5[!has_member_function_callable_with_func0to3<functor3, int, int, int>::value ? 1 : -1];
+ int check6[!has_member_function_callable_with_func0to3<functor3, int, char*, void*>::value ? 1 : -1];
+ int check7[ has_member_function_callable_with_func0to3<functor4, int, char*, int>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ (void)check4;
+ (void)check5;
+ (void)check6;
+ (void)check7;
+ }
+
+ { //func3to3 3arg
+ using func3to3ns::has_member_function_callable_with_func3to3;
+ int check1[ has_member_function_callable_with_func3to3<functor, int, int, int>::value ? 1 : -1];
+ int check2[!has_member_function_callable_with_func3to3<functor, int, char*, int>::value ? 1 : -1];
+ int check3[!has_member_function_callable_with_func3to3<functor2, int, int, int>::value ? 1 : -1];
+ int check4[ has_member_function_callable_with_func3to3<functor2, int, char*, void*>::value ? 1 : -1];
+ int check5[!has_member_function_callable_with_func3to3<functor3, int, int, int>::value ? 1 : -1];
+ int check6[!has_member_function_callable_with_func3to3<functor3, int, char*, void*>::value ? 1 : -1];
+ int check7[ has_member_function_callable_with_func3to3<functor4, int, char*, int>::value ? 1 : -1];
+ (void)check1;
+ (void)check2;
+ (void)check3;
+ (void)check4;
+ (void)check5;
+ (void)check6;
+ (void)check7;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/has_member_function_callable_with_no_decltype.cpp b/src/boost/libs/intrusive/test/has_member_function_callable_with_no_decltype.cpp
new file mode 100644
index 00000000..98037ba1
--- /dev/null
+++ b/src/boost/libs/intrusive/test/has_member_function_callable_with_no_decltype.cpp
@@ -0,0 +1,12 @@
+#include <boost/config.hpp>
+
+#ifndef BOOST_NO_CXX11_DECLTYPE
+# define BOOST_NO_CXX11_DECLTYPE
+# include "has_member_function_callable_with.cpp"
+#else
+ int main()
+ {
+ return 0;
+ }
+#endif
+
diff --git a/src/boost/libs/intrusive/test/has_member_function_callable_with_no_variadic.cpp b/src/boost/libs/intrusive/test/has_member_function_callable_with_no_variadic.cpp
new file mode 100644
index 00000000..1be78322
--- /dev/null
+++ b/src/boost/libs/intrusive/test/has_member_function_callable_with_no_variadic.cpp
@@ -0,0 +1,12 @@
+#include <boost/config.hpp>
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+# define BOOST_NO_CXX11_VARIADIC_TEMPLATES
+# include "has_member_function_callable_with.cpp"
+#else
+ int main()
+ {
+ return 0;
+ }
+#endif
+
diff --git a/src/boost/libs/intrusive/test/int_holder.hpp b/src/boost/libs/intrusive/test/int_holder.hpp
new file mode 100644
index 00000000..785a3672
--- /dev/null
+++ b/src/boost/libs/intrusive/test/int_holder.hpp
@@ -0,0 +1,117 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_DETAIL_INT_HOLDER_HPP
+#define BOOST_INTRUSIVE_DETAIL_INT_HOLDER_HPP
+
+#include <boost/functional/hash/hash.hpp>
+
+namespace boost{
+namespace intrusive{
+
+struct int_holder
+{
+ explicit int_holder(int value = 0)
+ : int_(value)
+ {}
+
+ int_holder &operator=(int value)
+ { int_ = value; return *this; }
+
+ int int_value() const
+ { return int_; }
+
+ friend bool operator==(const int_holder &l, const int_holder &r)
+ { return l.int_ == r.int_; }
+
+ friend bool operator!=(const int_holder &l, const int_holder &r)
+ { return l.int_ != r.int_; }
+
+ friend bool operator<(const int_holder &l, const int_holder &r)
+ { return l.int_ < r.int_; }
+
+ friend bool operator>(const int_holder &l, const int_holder &r)
+ { return l.int_ > r.int_; }
+
+ friend bool operator<=(const int_holder &l, const int_holder &r)
+ { return l.int_ <= r.int_; }
+
+ friend bool operator>=(const int_holder &l, const int_holder &r)
+ { return l.int_ >= r.int_; }
+
+///
+ friend bool operator==(int l, const int_holder &r)
+ { return l == r.int_; }
+
+ friend bool operator!=(int l, const int_holder &r)
+ { return l != r.int_; }
+
+ friend bool operator<(int l, const int_holder &r)
+ { return l < r.int_; }
+
+ friend bool operator>(int l, const int_holder &r)
+ { return l > r.int_; }
+
+ friend bool operator<=(int l, const int_holder &r)
+ { return l <= r.int_; }
+
+ friend bool operator>=(int l, const int_holder &r)
+ { return l >= r.int_; }
+
+ bool operator< (int i) const
+ { return int_ < i; }
+
+ bool operator> (int i) const
+ { return int_ > i; }
+
+ bool operator<= (int i) const
+ { return int_ <= i; }
+
+ bool operator>= (int i) const
+ { return int_ >= i; }
+
+ bool operator== (int i) const
+ { return int_ == i; }
+
+ bool operator!= (int i) const
+ { return int_ != i; }
+
+ friend std::size_t hash_value(const int_holder &t)
+ {
+ boost::hash<int> hasher;
+ return hasher((&t)->int_value());
+ }
+
+ int int_;
+};
+
+template<class ValueType>
+struct int_holder_key_of_value
+{
+ typedef int_holder type;
+
+ type operator()(const ValueType &tv) const
+ { return tv.get_int_holder(); }
+};
+
+template<class ValueType>
+struct int_priority_of_value
+{
+ typedef int type;
+
+ type operator()(const ValueType &tv) const
+ { return tv.int_value(); }
+};
+
+} //namespace boost{
+} //namespace intrusive{
+
+#endif //BOOST_INTRUSIVE_DETAIL_INT_HOLDER_HPP
diff --git a/src/boost/libs/intrusive/test/iterator_test.hpp b/src/boost/libs/intrusive/test/iterator_test.hpp
new file mode 100644
index 00000000..486cdd81
--- /dev/null
+++ b/src/boost/libs/intrusive/test/iterator_test.hpp
@@ -0,0 +1,375 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015. 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/detail/iterator.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost{ namespace intrusive { namespace test{
+
+//////////////////////////////////////////////
+//
+// Some traits to avoid special cases with
+// containers without bidirectional iterators
+//
+//////////////////////////////////////////////
+template<class C>
+struct has_member_reverse_iterator
+{
+ typedef char yes_type;
+ struct no_type{ char _[2]; };
+
+ template<typename D> static no_type test(...);
+ template<typename D> static yes_type test(typename D::reverse_iterator const*);
+ static const bool value = sizeof(test<C>(0)) == sizeof(yes_type);
+};
+
+template<class C>
+struct has_member_const_reverse_iterator
+{
+ typedef char yes_type;
+ struct no_type{ char _[2]; };
+
+ template<typename D> static no_type test(...);
+ template<typename D> static yes_type test(typename D::const_reverse_iterator const*);
+ static const bool value = sizeof(test<C>(0)) == sizeof(yes_type);
+};
+
+template<class C, bool = has_member_reverse_iterator<C>::value>
+struct get_reverse_iterator
+{
+ typedef typename C::reverse_iterator type;
+ static type begin(C &c) { return c.rbegin(); }
+ static type end(C &c) { return c.rend(); }
+};
+
+template<class C>
+struct get_reverse_iterator<C, false>
+{
+ typedef typename C::iterator type;
+ static type begin(C &c) { return c.begin(); }
+ static type end(C &c) { return c.end(); }
+};
+
+template<class C, bool = has_member_const_reverse_iterator<C>::value>
+struct get_const_reverse_iterator
+{
+ typedef typename C::const_reverse_iterator type;
+ static type begin(C &c) { return c.crbegin(); }
+ static type end(C &c) { return c.crend(); }
+};
+
+template<class C>
+struct get_const_reverse_iterator<C, false>
+{
+ typedef typename C::const_iterator type;
+ static type begin(C &c) { return c.cbegin(); }
+ static type end(C &c) { return c.cend(); }
+};
+
+//////////////////////////////////////////////
+//
+// Iterator tests
+//
+//////////////////////////////////////////////
+
+template<class I>
+void test_iterator_operations(I b, I e)
+{
+ //Test the range is not empty
+ BOOST_TEST(b != e);
+ BOOST_TEST(!(b == e));
+ {
+ I i;
+ I i2(b); //CopyConstructible
+ i = i2; //Assignable
+ //Destructible
+ (void)i;
+ (void)i2;
+ }
+
+ typedef typename iterator_traits<I>::reference reference;
+ reference r = *b;
+ (void)r;
+ typedef typename iterator_traits<I>::pointer pointer;
+ pointer p = (iterator_arrow_result)(b);
+ (void)p;
+ I &ri= ++b;
+ (void)ri;
+ const I &cri= b++;
+ (void)cri;
+}
+
+template<class C>
+void test_iterator_compatible(C &c)
+{
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef typename get_reverse_iterator<C>::type reverse_iterator;
+ typedef typename get_const_reverse_iterator<C>::type const_reverse_iterator;
+ //Basic operations
+ test_iterator_operations(c. begin(), c. end());
+ test_iterator_operations(c.cbegin(), c.cend());
+ test_iterator_operations(get_reverse_iterator<C>::begin(c), get_reverse_iterator<C>::end(c));
+ test_iterator_operations(get_const_reverse_iterator<C>::begin(c), get_const_reverse_iterator<C>::end(c));
+ //Make sure dangeous conversions are not possible
+ BOOST_STATIC_ASSERT((!boost::intrusive::detail::is_convertible<const_iterator, iterator>::value));
+ BOOST_STATIC_ASSERT((!boost::intrusive::detail::is_convertible<const_reverse_iterator, reverse_iterator>::value));
+ //Test iterator conversions
+ {
+ const_iterator ci;
+ iterator i(c.begin());
+ ci = i;
+ (void)ci;
+ BOOST_ASSERT(ci == i);
+ BOOST_ASSERT(*ci == *i);
+ const_iterator ci2(i);
+ BOOST_ASSERT(ci2 == i);
+ BOOST_ASSERT(*ci2 == *i);
+ (void)ci2;
+ }
+ //Test reverse_iterator conversions
+ {
+ const_reverse_iterator cr;
+ reverse_iterator r(get_reverse_iterator<C>::begin(c));
+ cr = r;
+ BOOST_ASSERT(cr == r);
+ BOOST_ASSERT(*cr == *r);
+ const_reverse_iterator cr2(r);
+ BOOST_ASSERT(cr2 == r);
+ BOOST_ASSERT(*cr2 == *r);
+ (void)cr2;
+ }
+}
+
+template<class C>
+void test_iterator_input_and_compatible(C &c)
+{
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef typename get_reverse_iterator<C>::type reverse_iterator;
+ typedef typename get_const_reverse_iterator<C>::type const_reverse_iterator;
+ typedef iterator_traits<iterator> nit_traits;
+ typedef iterator_traits<const_iterator> cit_traits;
+ typedef iterator_traits<reverse_iterator> rnit_traits;
+ typedef iterator_traits<const_reverse_iterator> crit_traits;
+
+ using boost::move_detail::is_same;
+ //Trivial typedefs
+ BOOST_STATIC_ASSERT((!is_same<iterator, const_iterator>::value));
+ BOOST_STATIC_ASSERT((!is_same<reverse_iterator, const_reverse_iterator>::value));
+ //difference_type
+ typedef typename C::difference_type difference_type;
+ BOOST_STATIC_ASSERT((is_same<difference_type, typename nit_traits::difference_type>::value));
+ BOOST_STATIC_ASSERT((is_same<difference_type, typename cit_traits::difference_type>::value));
+ BOOST_STATIC_ASSERT((is_same<difference_type, typename rnit_traits::difference_type>::value));
+ BOOST_STATIC_ASSERT((is_same<difference_type, typename crit_traits::difference_type>::value));
+ //value_type
+ typedef typename C::value_type value_type;
+ BOOST_STATIC_ASSERT((is_same<value_type, typename nit_traits::value_type>::value));
+ BOOST_STATIC_ASSERT((is_same<value_type, typename cit_traits::value_type>::value));
+ BOOST_STATIC_ASSERT((is_same<value_type, typename rnit_traits::value_type>::value));
+ BOOST_STATIC_ASSERT((is_same<value_type, typename crit_traits::value_type>::value));
+ //pointer
+ typedef typename C::pointer pointer;
+ typedef typename C::const_pointer const_pointer;
+ BOOST_STATIC_ASSERT((is_same<pointer, typename nit_traits::pointer>::value));
+ BOOST_STATIC_ASSERT((is_same<const_pointer, typename cit_traits::pointer>::value));
+ BOOST_STATIC_ASSERT((is_same<pointer, typename rnit_traits::pointer>::value));
+ BOOST_STATIC_ASSERT((is_same<const_pointer, typename crit_traits::pointer>::value));
+ //reference
+ typedef typename C::reference reference;
+ typedef typename C::const_reference const_reference;
+ BOOST_STATIC_ASSERT((is_same<reference, typename nit_traits::reference>::value));
+ BOOST_STATIC_ASSERT((is_same<const_reference, typename cit_traits::reference>::value));
+ BOOST_STATIC_ASSERT((is_same<reference, typename rnit_traits::reference>::value));
+ BOOST_STATIC_ASSERT((is_same<const_reference, typename crit_traits::reference>::value));
+ //Dynamic tests
+ test_iterator_compatible(c);
+}
+
+template<class C, class I>
+void test_iterator_forward_functions(C const &c, I const b, I const e)
+{
+ typedef typename C::size_type size_type;
+ {
+ size_type i = 0;
+ I it = b;
+ for(I it2 = b; i != c.size(); ++it, ++i){
+ BOOST_TEST(it == it2++);
+ I ittmp(it);
+ I *iaddr = &ittmp;
+ BOOST_TEST(&(++ittmp) == iaddr);
+ BOOST_TEST(ittmp == it2);
+ }
+ BOOST_TEST(i == c.size());
+ BOOST_TEST(it == e);
+ }
+}
+
+template<class C>
+void test_iterator_forward_and_compatible(C &c)
+{
+ test_iterator_input_and_compatible(c);
+ test_iterator_forward_functions(c, c.begin(), c.end());
+ test_iterator_forward_functions(c, c.cbegin(), c.cend());
+ test_iterator_forward_functions(c, get_reverse_iterator<C>::begin(c), get_reverse_iterator<C>::end(c));
+ test_iterator_forward_functions(c, get_const_reverse_iterator<C>::begin(c), get_const_reverse_iterator<C>::end(c));
+}
+
+template<class C, class I>
+void test_iterator_bidirectional_functions(C const &c, I const b, I const e)
+{
+ typedef typename C::size_type size_type;
+ {
+ size_type i = 0;
+ I it = e;
+ for(I it2 = e; i != c.size(); --it, ++i){
+ BOOST_TEST(it == it2--);
+ I ittmp(it);
+ I*iaddr = &ittmp;
+ BOOST_TEST(&(--ittmp) == iaddr);
+ BOOST_TEST(ittmp == it2);
+ BOOST_TEST((++ittmp) == it);
+ }
+ BOOST_TEST(i == c.size());
+ BOOST_TEST(it == b);
+ }
+}
+
+template<class C>
+void test_iterator_bidirectional_and_compatible(C &c)
+{
+ test_iterator_forward_and_compatible(c);
+ test_iterator_bidirectional_functions(c, c.begin(), c.end());
+ test_iterator_bidirectional_functions(c, c.cbegin(), c.cend());
+ test_iterator_bidirectional_functions(c, c.rbegin(), c.rend());
+ test_iterator_bidirectional_functions(c, c.crbegin(), c.crend());
+}
+
+template<class C, class I>
+void test_iterator_random_functions(C const &c, I const b, I const e)
+{
+ typedef typename C::size_type size_type;
+ {
+ I it = b;
+ for(size_type i = 0, m = c.size(); i != m; ++i, ++it){
+ BOOST_TEST(i == size_type(it - b));
+ BOOST_TEST(b[i] == *it);
+ BOOST_TEST(&b[i] == &*it);
+ BOOST_TEST((b + i) == it);
+ BOOST_TEST((i + b) == it);
+ BOOST_TEST(b == (it - i));
+ I tmp(b);
+ BOOST_TEST((tmp+=i) == it);
+ tmp = it;
+ BOOST_TEST(b == (tmp-=i));
+ }
+ BOOST_TEST(c.size() == size_type(e - b));
+ }
+ {
+ I it(b), itb(b);
+ if(b != e){
+ for(++it; it != e; ++it){
+ BOOST_TEST(itb < it);
+ BOOST_TEST(itb <= it);
+ BOOST_TEST(!(itb > it));
+ BOOST_TEST(!(itb >= it));
+ BOOST_TEST(it > itb);
+ BOOST_TEST(it >= itb);
+ BOOST_TEST(!(it < itb));
+ BOOST_TEST(!(it <= itb));
+ BOOST_TEST(it >= it);
+ BOOST_TEST(it <= it);
+ itb = it;
+ }
+ }
+ }
+}
+
+template<class C>
+void test_iterator_random_and_compatible(C &c)
+{
+ test_iterator_bidirectional_and_compatible(c);
+ test_iterator_random_functions(c, c.begin(), c.end());
+ test_iterator_random_functions(c, c.cbegin(), c.cend());
+ test_iterator_random_functions(c, c.rbegin(), c.rend());
+ test_iterator_random_functions(c, c.crbegin(), c.crend());
+}
+
+////////////////////////
+
+template<class C>
+void test_iterator_forward(C &c)
+{
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef typename get_reverse_iterator<C>::type reverse_iterator;
+ typedef typename get_const_reverse_iterator<C>::type const_reverse_iterator;
+ typedef iterator_traits<iterator> nit_traits;
+ typedef iterator_traits<const_iterator> cit_traits;
+ typedef iterator_traits<reverse_iterator> rnit_traits;
+ typedef iterator_traits<const_reverse_iterator> crit_traits;
+
+ using boost::intrusive::detail::is_same;
+ //iterator_category
+ BOOST_STATIC_ASSERT((is_same<std::forward_iterator_tag, typename nit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::forward_iterator_tag, typename cit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::forward_iterator_tag, typename rnit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::forward_iterator_tag, typename crit_traits::iterator_category>::value));
+ //Test dynamic
+ test_iterator_forward_and_compatible(c);
+}
+
+template<class C>
+void test_iterator_bidirectional(C &c)
+{
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef typename C::reverse_iterator reverse_iterator;
+ typedef typename C::const_reverse_iterator const_reverse_iterator;
+ typedef iterator_traits<iterator> nit_traits;
+ typedef iterator_traits<const_iterator> cit_traits;
+ typedef iterator_traits<reverse_iterator> rnit_traits;
+ typedef iterator_traits<const_reverse_iterator> crit_traits;
+
+ using boost::intrusive::detail::is_same;
+ //iterator_category
+ BOOST_STATIC_ASSERT((is_same<std::bidirectional_iterator_tag, typename nit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::bidirectional_iterator_tag, typename cit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::bidirectional_iterator_tag, typename rnit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::bidirectional_iterator_tag, typename crit_traits::iterator_category>::value));
+ //Test dynamic
+ test_iterator_bidirectional_and_compatible(c);
+}
+
+template<class C>
+void test_iterator_random(C &c)
+{
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef typename C::reverse_iterator reverse_iterator;
+ typedef typename C::const_reverse_iterator const_reverse_iterator;
+ typedef iterator_traits<iterator> nit_traits;
+ typedef iterator_traits<const_iterator> cit_traits;
+ typedef iterator_traits<reverse_iterator> rnit_traits;
+ typedef iterator_traits<const_reverse_iterator> crit_traits;
+
+ using boost::intrusive::detail::is_same;
+ //iterator_category
+ BOOST_STATIC_ASSERT((is_same<std::random_access_iterator_tag, typename nit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::random_access_iterator_tag, typename cit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::random_access_iterator_tag, typename rnit_traits::iterator_category>::value));
+ BOOST_STATIC_ASSERT((is_same<std::random_access_iterator_tag, typename crit_traits::iterator_category>::value));
+ //Test dynamic
+ test_iterator_random_and_compatible(c);
+}
+
+}}} //boost::container::test
diff --git a/src/boost/libs/intrusive/test/itestvalue.hpp b/src/boost/libs/intrusive/test/itestvalue.hpp
new file mode 100644
index 00000000..1a4ecdae
--- /dev/null
+++ b/src/boost/libs/intrusive/test/itestvalue.hpp
@@ -0,0 +1,284 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2013.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP
+#define BOOST_INTRUSIVE_DETAIL_ITESTVALUE_HPP
+
+#include <iostream>
+#include <boost/intrusive/options.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include "nonhook_node.hpp"
+#include "int_holder.hpp"
+#include <boost/intrusive/detail/get_value_traits.hpp>
+#include <boost/container/vector.hpp>
+
+namespace boost{
+namespace intrusive{
+
+struct testvalue_filler
+{
+ void *dummy_[3];
+};
+
+template<class Hooks>
+struct testvalue
+ : testvalue_filler
+ , Hooks::base_hook_type
+ , Hooks::auto_base_hook_type
+{
+ typename Hooks::member_hook_type node_;
+ typename Hooks::auto_member_hook_type auto_node_;
+ typename Hooks::nonhook_node_member_type nhn_member_;
+
+ int_holder value_;
+
+ testvalue()
+ {}
+
+ explicit testvalue(int i)
+ : value_(i)
+ {}
+
+ testvalue (const testvalue& src)
+ : value_(src.value_)
+ {}
+
+ // testvalue is used in boost::container::vector and thus prev and next
+ // have to be handled appropriately when copied:
+ testvalue & operator= (const testvalue& src)
+ {
+ Hooks::base_hook_type::operator=(static_cast<const typename Hooks::base_hook_type&>(src));
+ Hooks::auto_base_hook_type::operator=(static_cast<const typename Hooks::auto_base_hook_type&>(src));
+ this->node_ = src.node_;
+ this->auto_node_ = src.auto_node_;
+ this->nhn_member_ = src.nhn_member_;
+ value_ = src.value_;
+ return *this;
+ }
+
+ void swap_nodes(testvalue &other)
+ {
+ Hooks::base_hook_type::swap_nodes(static_cast<typename Hooks::base_hook_type&>(other));
+ Hooks::auto_base_hook_type::swap_nodes(static_cast<typename Hooks::auto_base_hook_type&>(other));
+ node_.swap_nodes(other.node_);
+ auto_node_.swap_nodes(other.auto_node_);
+ nhn_member_.swap_nodes(other.nhn_member_);
+ }
+
+ bool is_linked() const
+ {
+ return Hooks::base_hook_type::is_linked() ||
+ Hooks::auto_base_hook_type::is_linked() ||
+ node_.is_linked() ||
+ auto_node_.is_linked() ||
+ nhn_member_.is_linked();
+ }
+
+ const int_holder &get_int_holder() const
+ { return value_; }
+
+ int int_value() const
+ { return value_.int_value(); }
+
+ ~testvalue()
+ {}
+
+ bool operator< (const testvalue &other) const
+ { return value_ < other.value_; }
+
+ bool operator> (const testvalue &other) const
+ { return value_ > other.value_; }
+
+ bool operator==(const testvalue &other) const
+ { return value_ == other.value_; }
+
+ bool operator!=(const testvalue &other) const
+ { return value_ != other.value_; }
+
+ friend bool operator< (int other1, const testvalue &other2)
+ { return other1 < other2.value_.int_; }
+
+ friend bool operator> (int other1, const testvalue &other2)
+ { return other1 > other2.value_.int_; }
+
+ friend bool operator< (const testvalue &other1, int other2)
+ { return other1.value_.int_ < other2; }
+
+ friend bool operator> (const testvalue &other1, int other2)
+ { return other1.value_.int_ > other2; }
+
+ friend bool operator== (int other1, const testvalue &other2)
+ { return other1 == other2.value_.int_; }
+
+ friend bool operator== (const testvalue &other1, int other2)
+ { return other1.value_.int_ == other2; }
+
+ friend bool operator!= (int other1, const testvalue &other2)
+ { return other1 != other2.value_.int_; }
+
+ friend bool operator!= (const testvalue &other1, int other2)
+ { return other1.value_.int_ != other2; }
+
+ friend std::size_t hash_value(const testvalue&t)
+ {
+ boost::hash<int> hasher;
+ return hasher((&t)->int_value());
+ }
+};
+
+template<class T>
+std::size_t priority_hash(const T &t)
+{ return boost::hash<int>()((&t)->int_value()); }
+
+std::size_t priority_hash(int i)
+{ return boost::hash<int>()(i); }
+
+template <class T, class U>
+bool priority_order(const T& t1, const U& t2)
+{
+ std::size_t hash1 = (priority_hash)(t1);
+ boost::hash_combine(hash1, -hash1);
+ std::size_t hash2 = (priority_hash)(t2);
+ boost::hash_combine(hash2, -hash2);
+ return hash1 < hash2;
+}
+
+template < typename Node_Algorithms, class Hooks>
+void swap_nodes(testvalue<Hooks>& lhs, testvalue<Hooks>& rhs)
+{
+ lhs.swap_nodes(rhs);
+}
+
+template<class Hooks>
+std::ostream& operator<<
+ (std::ostream& s, const testvalue<Hooks>& t)
+{ return s << t.value_.int_value(); }
+
+struct even_odd
+{
+ template < typename key_type_1, typename key_type_2 >
+ bool operator()
+ (const key_type_1& v1
+ ,const key_type_2& v2) const
+ {
+ if (((&v1)->int_value() & 1) == ((&v2)->int_value() & 1))
+ return (&v1)->int_value() < (&v2)->int_value();
+ else
+ return (&v2)->int_value() & 1;
+ }
+};
+
+struct is_even
+{
+ template <typename key_type>
+ bool operator()
+ (const key_type& v1) const
+ { return ((&v1)->int_value() & 1) == 0; }
+};
+
+struct is_odd
+{
+ template <typename key_type>
+ bool operator()
+ (const key_type& v1) const
+ { return ((&v1)->int_value() & 1) != 0; }
+};
+
+template <typename>
+struct ValueContainer;
+
+template < class Hooks>
+struct ValueContainer< testvalue<Hooks> >
+{
+ typedef boost::container::vector< testvalue<Hooks> > type;
+};
+
+template < typename Pointer >
+class heap_node_holder
+{
+ typedef typename pointer_traits<Pointer>::element_type element_type;
+ typedef Pointer pointer;
+ typedef typename pointer_rebind<pointer, const element_type>::type const_pointer;
+
+ public:
+ heap_node_holder()
+ : m_ptr(pointer_traits<Pointer>::pointer_to(*new element_type))
+ {}
+
+ ~heap_node_holder()
+ { delete &*m_ptr; }
+
+ const_pointer get_node() const
+ { return m_ptr; }
+
+ pointer get_node()
+ { return m_ptr; }
+
+ private:
+ pointer m_ptr;
+};
+
+template<class Hooks>
+struct testvalue_traits
+ : public Hooks
+{
+ typedef testvalue< Hooks > value_type;
+
+ //base
+ typedef typename detail::get_base_value_traits
+ < value_type
+ , typename Hooks::base_hook_type
+ >::type base_value_traits;
+ //auto-base
+ typedef typename detail::get_base_value_traits
+ < value_type
+ , typename Hooks::auto_base_hook_type
+ >::type auto_base_value_traits;
+ //member
+ typedef typename detail::get_member_value_traits
+ < member_hook
+ < value_type
+ , typename Hooks::member_hook_type
+ , &value_type::node_
+ >
+ >::type member_value_traits;
+ //auto-member
+ typedef typename detail::get_member_value_traits
+ < member_hook
+ < value_type
+ , typename Hooks::auto_member_hook_type
+ , &value_type::auto_node_
+ >
+ >::type auto_member_value_traits;
+ //nonmember
+ typedef nonhook_node_member_value_traits
+ < value_type
+ , typename Hooks::nonhook_node_member_type
+ , &value_type::nhn_member_
+ , safe_link
+ > nonhook_value_traits;
+};
+
+} //namespace intrusive{
+} //namespace boost{
+
+bool priority_order(int t1, int t2)
+{
+ std::size_t hash1 = boost::hash<int>()(t1);
+ boost::hash_combine(hash1, &t1);
+ std::size_t hash2 = boost::hash<int>()(t2);
+ boost::hash_combine(hash2, &t2);
+ return hash1 < hash2;
+}
+
+#endif
diff --git a/src/boost/libs/intrusive/test/list_test.cpp b/src/boost/libs/intrusive/test/list_test.cpp
new file mode 100644
index 00000000..e756a917
--- /dev/null
+++ b/src/boost/libs/intrusive/test/list_test.cpp
@@ -0,0 +1,515 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2013.
+//
+// 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/pointer_traits.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include <typeinfo>
+
+using namespace boost::intrusive;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef list_base_hook<void_pointer<VoidPointer> > base_hook_type;
+ typedef list_base_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer>, tag<void> > auto_base_hook_type;
+ typedef list_member_hook<void_pointer<VoidPointer>, tag<void> > member_hook_type;
+ typedef list_member_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+ typedef nonhook_node_member< list_node_traits< VoidPointer >,
+ circular_list_algorithms > nonhook_node_member_type;
+};
+
+
+template < typename ListType, typename ValueContainer >
+struct test_list
+{
+ typedef ListType list_type;
+ typedef typename list_type::value_traits value_traits;
+ typedef typename value_traits::value_type value_type;
+ typedef typename list_type::node_algorithms node_algorithms;
+
+ static void test_all(ValueContainer&);
+ static void test_front_back(ValueContainer&);
+ static void test_sort(ValueContainer&);
+ static void test_merge(ValueContainer&);
+ static void test_remove_unique(ValueContainer&);
+ static void test_insert(ValueContainer&);
+ static void test_shift(ValueContainer&);
+ static void test_swap(ValueContainer&);
+ static void test_clone(ValueContainer&);
+ static void test_container_from_end(ValueContainer&, detail::true_type);
+ static void test_container_from_end(ValueContainer&, detail::false_type) {}
+};
+
+template < typename ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >::test_all(ValueContainer& values)
+{
+ {
+ list_type list(values.begin(), values.end());
+ test::test_container(list);
+ list.clear();
+ list.insert(list.end(), values.begin(), values.end());
+ test::test_sequence_container(list, values);
+ }
+ {
+ list_type list(values.begin(), values.end());
+ test::test_iterator_bidirectional(list);
+ }
+
+ test_front_back(values);
+ test_sort(values);
+ test_merge(values);
+ test_remove_unique(values);
+ test_insert(values);
+ test_shift(values);
+ test_swap(values);
+ test_clone(values);
+ test_container_from_end(values, detail::bool_< ListType::has_container_from_iterator >());
+}
+
+//test: push_front, pop_front, push_back, pop_back, front, back, size, empty:
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_front_back(ValueContainer& values)
+{
+ list_type testlist;
+ BOOST_TEST (testlist.empty());
+
+ testlist.push_back (values[0]);
+ BOOST_TEST (testlist.size() == 1);
+ BOOST_TEST (&testlist.front() == &values[0]);
+ BOOST_TEST (&testlist.back() == &values[0]);
+
+ testlist.push_front (values[1]);
+ BOOST_TEST (testlist.size() == 2);
+ BOOST_TEST (&testlist.front() == &values[1]);
+ BOOST_TEST (&testlist.back() == &values[0]);
+
+ testlist.pop_back();
+ BOOST_TEST (testlist.size() == 1);
+ const list_type &const_testlist = testlist;
+ BOOST_TEST (&const_testlist.front() == &values[1]);
+ BOOST_TEST (&const_testlist.back() == &values[1]);
+
+ testlist.pop_front();
+ BOOST_TEST (testlist.empty());
+}
+
+//test: constructor, iterator, reverse_iterator, sort, reverse:
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_sort(ValueContainer& values)
+{
+ list_type testlist(values.begin(), values.end());
+
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
+
+ testlist.sort (even_odd());
+ { int init_values [] = { 5, 3, 1, 4, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist.rbegin() ); }
+
+ testlist.reverse();
+ { int init_values [] = { 5, 3, 1, 4, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
+}
+
+//test: merge due to error in merge implementation:
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_remove_unique (ValueContainer& values)
+{
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_if(is_even());
+ int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_if(is_odd());
+ int init_values [] = { 2, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_and_dispose_if(is_even(), test::empty_disposer());
+ int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_and_dispose_if(is_odd(), test::empty_disposer());
+ int init_values [] = { 2, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ ValueContainer values2(values);
+ list_type list(values.begin(), values.end());
+ list.insert(list.end(), values2.begin(), values2.end());
+ list.sort();
+ int init_values [] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ list.unique();
+ int init_values2 [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values2, list.begin() );
+ }
+}
+
+//test: merge due to error in merge implementation:
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_merge (ValueContainer& values)
+{
+ list_type testlist1, testlist2;
+ testlist1.push_front (values[0]);
+ testlist2.push_front (values[4]);
+ testlist2.push_front (values[3]);
+ testlist2.push_front (values[2]);
+ testlist1.merge (testlist2);
+
+ int init_values [] = { 1, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
+}
+
+//test: assign, insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_insert(ValueContainer& values)
+{
+ list_type testlist;
+ testlist.assign (values.begin() + 2, values.begin() + 5);
+
+ const list_type& const_testlist = testlist;
+ { int init_values [] = { 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+
+ typename list_type::iterator i = ++testlist.begin();
+ BOOST_TEST (i->value_ == 4);
+
+ {
+ typename list_type::const_iterator ci = typename list_type::iterator();
+ (void)ci;
+ }
+
+ testlist.insert (i, values[0]);
+ { int init_values [] = { 5, 4, 1, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.rbegin() ); }
+
+ i = testlist.iterator_to (values[4]);
+ BOOST_TEST (&*i == &values[4]);
+
+ i = list_type::s_iterator_to (values[4]);
+ BOOST_TEST (&*i == &values[4]);
+
+ typename list_type::const_iterator ic;
+ ic = testlist.iterator_to (static_cast< typename list_type::const_reference >(values[4]));
+ BOOST_TEST (&*ic == &values[4]);
+
+ ic = list_type::s_iterator_to (static_cast< typename list_type::const_reference >(values[4]));
+ BOOST_TEST (&*ic == &values[4]);
+
+ i = testlist.erase (i);
+ BOOST_TEST (i == testlist.end());
+
+ { int init_values [] = { 3, 1, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+}
+
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_shift(ValueContainer& values)
+{
+ list_type testlist;
+ const int num_values = (int)values.size();
+ std::vector<int> expected_values(num_values);
+
+ for(int s = 1; s <= num_values; ++s){
+ expected_values.resize(s);
+ //Shift forward all possible positions 3 times
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert(testlist.begin(), values.begin(), values.begin() + s);
+ testlist.shift_forward(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + s - i%s) % s] = (j + 1);
+ }
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
+ testlist.clear();
+ }
+
+ //Shift backwards all possible positions
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert(testlist.begin(), values.begin(), values.begin() + s);
+ testlist.shift_backwards(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + i) % s] = (j + 1);
+ }
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
+ testlist.clear();
+ }
+ }
+}
+
+//test: insert (seq-version), swap, splice, erase (seq-version):
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_swap(ValueContainer& values)
+{
+ {
+ list_type testlist1 (values.begin(), values.begin() + 2);
+ list_type testlist2;
+ testlist2.insert (testlist2.end(), values.begin() + 2, values.begin() + 5);
+ testlist1.swap (testlist2);
+
+ { int init_values [] = { 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ { int init_values [] = { 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+
+ testlist2.splice (++testlist2.begin(), testlist1);
+ { int init_values [] = { 1, 3, 4, 5, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+
+ BOOST_TEST (testlist1.empty());
+
+ testlist1.splice (testlist1.end(), testlist2, ++(++testlist2.begin()));
+ { int init_values [] = { 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ { int init_values [] = { 1, 3, 5, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+
+ testlist1.splice (testlist1.end(), testlist2,
+ testlist2.begin(), ----testlist2.end());
+ { int init_values [] = { 4, 1, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ { int init_values [] = { 5, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+
+ testlist1.erase (testlist1.iterator_to(values[0]), testlist1.end());
+ BOOST_TEST (testlist1.size() == 1);
+ BOOST_TEST (&testlist1.front() == &values[3]);
+ }
+ {
+ list_type testlist1 (values.begin(), values.begin() + 2);
+ list_type testlist2 (values.begin() + 3, values.begin() + 5);
+
+ swap_nodes< node_algorithms >(values[0], values[2]);
+ { int init_values [] = { 3, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[2], values[4]);
+ { int init_values [] = { 5, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ { int init_values [] = { 4, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+ }
+ {
+ list_type testlist1 (values.begin(), values.begin() + 1);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[1], values[2]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[0], values[2]);
+
+ { int init_values [] = { 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[0], values[2]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ }
+}
+
+template < class ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_container_from_end(ValueContainer& values, detail::true_type)
+{
+ list_type testlist1 (values.begin(), values.begin() + 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 ListType, typename ValueContainer >
+void test_list< ListType, ValueContainer >
+ ::test_clone(ValueContainer& values)
+{
+ list_type testlist1 (values.begin(), values.begin() + values.size());
+ list_type testlist2;
+
+ 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<value_type>());
+ BOOST_TEST (testlist2.empty());
+}
+
+template < typename ValueTraits, bool ConstantTimeSize, bool Default_Holder, typename ValueContainer >
+struct make_and_test_list
+ : test_list< list< typename ValueTraits::value_type,
+ value_traits< ValueTraits >,
+ size_type< std::size_t >,
+ constant_time_size< ConstantTimeSize >
+ >,
+ ValueContainer
+ >
+{};
+
+template < typename ValueTraits, bool ConstantTimeSize, typename ValueContainer >
+struct make_and_test_list< ValueTraits, ConstantTimeSize, false, ValueContainer >
+ : test_list< list< typename ValueTraits::value_type,
+ value_traits< ValueTraits >,
+ size_type< std::size_t >,
+ constant_time_size< ConstantTimeSize >,
+ header_holder_type< heap_node_holder< typename ValueTraits::pointer > >
+ >,
+ ValueContainer
+ >
+{};
+
+
+template < class VoidPointer, bool ConstantTimeSize, bool Default_Holder >
+class test_main_template
+{
+ public:
+ int operator()()
+ {
+ typedef testvalue< hooks<VoidPointer> > value_type;
+ std::vector<value_type> data (5);
+ for (int i = 0; i < 5; ++i)
+ data[i].value_ = i + 1;
+
+ make_and_test_list < typename detail::get_base_value_traits <
+ value_type,
+ typename hooks<VoidPointer>::base_hook_type
+ >::type,
+ ConstantTimeSize,
+ Default_Holder,
+ std::vector< value_type >
+ >::test_all(data);
+ make_and_test_list < typename detail::get_member_value_traits <
+ member_hook< value_type, typename hooks<VoidPointer>::member_hook_type, &value_type::node_>
+ >::type,
+ ConstantTimeSize,
+ Default_Holder,
+ std::vector< value_type >
+ >::test_all(data);
+ make_and_test_list< nonhook_node_member_value_traits <
+ value_type,
+ typename hooks<VoidPointer>::nonhook_node_member_type,
+ &value_type::nhn_member_,
+ safe_link
+ >,
+ ConstantTimeSize,
+ Default_Holder,
+ std::vector< value_type >
+ >::test_all(data);
+
+ return 0;
+ }
+};
+
+template < class VoidPointer, bool Default_Holder >
+class test_main_template< VoidPointer, false, Default_Holder >
+{
+ public:
+ int operator()()
+ {
+ typedef testvalue< hooks<VoidPointer> > value_type;
+ std::vector<value_type> data (5);
+ for (int i = 0; i < 5; ++i)
+ data[i].value_ = i + 1;
+
+ make_and_test_list < typename detail::get_base_value_traits <
+ value_type,
+ typename hooks<VoidPointer>::auto_base_hook_type
+ >::type,
+ false,
+ Default_Holder,
+ std::vector< value_type >
+ >::test_all(data);
+ make_and_test_list < typename detail::get_member_value_traits <
+ member_hook< value_type, typename hooks<VoidPointer>::auto_member_hook_type, &value_type::auto_node_>
+ >::type,
+ false,
+ Default_Holder,
+ std::vector< value_type >
+ >::test_all(data);
+
+ return 0;
+ }
+};
+
+template < bool ConstantTimeSize >
+struct test_main_template_bptr
+{
+ int operator()()
+ {
+ typedef BPtr_Value value_type;
+ typedef BPtr_Value_Traits< List_BPtr_Node_Traits > list_value_traits;
+ typedef typename list_value_traits::node_ptr node_ptr;
+ typedef bounded_allocator< value_type > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+
+ allocator_type allocator;
+
+ {
+ bounded_reference_cont< value_type > ref_cont;
+ for (int i = 0; i < 5; ++i)
+ {
+ node_ptr tmp = allocator.allocate(1);
+ new (tmp.raw()) value_type(i + 1);
+ ref_cont.push_back(*tmp);
+ }
+
+ test_list < list < value_type,
+ value_traits< list_value_traits >,
+ size_type< std::size_t >,
+ constant_time_size< ConstantTimeSize >,
+ header_holder_type< bounded_pointer_holder< value_type > >
+ >,
+ bounded_reference_cont< value_type >
+ >::test_all(ref_cont);
+ }
+
+ return 0;
+ }
+};
+
+int main()
+{
+ // test (plain/smart pointers) x (nonconst/const size) x (void node allocator)
+ test_main_template<void*, false, true>()();
+ test_main_template<boost::intrusive::smart_ptr<void>, false, true>()();
+ test_main_template<void*, true, true>()();
+ test_main_template<boost::intrusive::smart_ptr<void>, true, true>()();
+ // test (bounded pointers) x ((nonconst/const size) x (special node allocator)
+ test_main_template_bptr< true >()();
+ test_main_template_bptr< false >()();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/make_functions_test.cpp b/src/boost/libs/intrusive/test/make_functions_test.cpp
new file mode 100644
index 00000000..8d0fafbe
--- /dev/null
+++ b/src/boost/libs/intrusive/test/make_functions_test.cpp
@@ -0,0 +1,213 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/bs_set.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/static_assert.hpp>
+#include "smart_ptr.hpp"
+#include <vector>
+
+using namespace boost::intrusive;
+
+struct my_tag;
+struct my_tag2;
+struct my_tag3;
+
+typedef make_bs_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link>
+ , tag<my_tag> >::type TreapHook;
+typedef make_bs_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link>
+ , tag<my_tag2> >::type SplayHook;
+typedef make_bs_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link>
+ , tag<my_tag3> >::type BsHook;
+
+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
+, public make_avl_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+, public make_bs_set_base_hook
+ < void_pointer<smart_ptr<void> >, link_mode<normal_link> >::type
+, public TreapHook
+, public SplayHook
+, public BsHook
+{
+ 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_); }
+
+ friend bool priority_order(const MyClass &l, const MyClass &r)
+ { return l.int_ < r.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;
+
+typedef make_avl_set<MyClass>::type AvlSet;
+typedef make_sg_set<MyClass>::type SgSet;
+typedef make_treap_set<MyClass
+ , base_hook<TreapHook> >::type TreapSet;
+typedef make_splay_set<MyClass
+ , base_hook<SplayHook> >::type SplaySet;
+typedef make_bs_set<MyClass
+ , base_hook<BsHook> >::type BsSet;
+
+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
+ (pointer_traits<USet::bucket_ptr>::pointer_to(buckets[0]), 100));
+
+ AvlSet my_avlset;
+ SplaySet my_splayset;
+ BsSet my_bsset;
+ SgSet my_sgset;
+ TreapSet my_treapset;
+
+ //Now insert them in containers
+ 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);
+ my_avlset.insert(*it);
+ my_splayset.insert(*it);
+ my_bsset.insert(*it);
+ my_sgset.insert(*it);
+ my_treapset.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());
+
+ AvlSet::const_reverse_iterator avlset_rit(my_avlset.crbegin());
+ SplaySet::const_reverse_iterator splayset_rit(my_splayset.crbegin());
+ BsSet::const_reverse_iterator bsset_rit(my_bsset.crbegin());
+ SgSet::const_reverse_iterator sgset_rit(my_sgset.crbegin());
+ TreapSet::const_reverse_iterator treapset_rit(my_treapset.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
+ , ++avlset_rit, ++splayset_rit, ++bsset_rit, ++sgset_rit, ++treapset_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;
+ if(&*avlset_rit != &*vect_it) return 1;
+ if(&*splayset_rit != &*vect_it) return 1;
+ if(&*bsset_rit != &*vect_it) return 1;
+ if(&*sgset_rit != &*vect_it) return 1;
+ if(&*treapset_rit != &*vect_it) return 1;
+ }
+ }
+
+ //Check defined types and implicitly defined types are equal
+ BOOST_STATIC_ASSERT((detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_list_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT((detail::is_same<make_slist_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_slist_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT((detail::is_same<make_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_set_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT((detail::is_same<make_unordered_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_unordered_set_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT((detail::is_same<make_avl_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_avl_set_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT((detail::is_same<make_bs_set_base_hook<void_pointer<void*>, link_mode<safe_link> >::type
+ ,make_bs_set_base_hook<>::type
+ >::value));
+
+ //Check defined types and implicitly defined types are unequal
+ BOOST_STATIC_ASSERT(!(detail::is_same<make_list_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_list_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT(!(detail::is_same<make_slist_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_slist_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT(!(detail::is_same<make_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_set_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT(!(detail::is_same<make_unordered_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_unordered_set_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT(!(detail::is_same<make_avl_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_avl_set_base_hook<>::type
+ >::value));
+
+ BOOST_STATIC_ASSERT(!(detail::is_same<make_bs_set_base_hook<void_pointer<void*>, link_mode<normal_link> >::type
+ ,make_bs_set_base_hook<>::type
+ >::value));
+
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/multiset_test.cpp b/src/boost/libs/intrusive/test/multiset_test.cpp
new file mode 100644
index 00000000..a8ab6743
--- /dev/null
+++ b/src/boost/libs/intrusive/test/multiset_test.cpp
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "rb_test_common.hpp"
+#include "generic_multiset_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef multiset
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< rb_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_multiset
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< rb_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_multiset
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< rb_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_multiset
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< RBTree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_multiset
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/nonhook_node.hpp b/src/boost/libs/intrusive/test/nonhook_node.hpp
new file mode 100644
index 00000000..e2c666e7
--- /dev/null
+++ b/src/boost/libs/intrusive/test/nonhook_node.hpp
@@ -0,0 +1,121 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Matei David 2014-2014.
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP
+#define BOOST_INTRUSIVE_DETAIL_NONHOOK_NODE_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/detail/parent_from_member.hpp>
+
+#include <boost/move/detail/to_raw_pointer.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+namespace boost{
+namespace intrusive{
+
+//This node will only be used in safe or auto unlink modes
+//so test it's been properly released
+template < typename NodeTraits, template <typename> class Node_Algorithms >
+struct nonhook_node_member : public NodeTraits::node
+{
+ 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 Node_Algorithms< node_traits > node_algorithms;
+
+ nonhook_node_member()
+ {
+ node_algorithms::init(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this)));
+ }
+
+ nonhook_node_member(const nonhook_node_member& rhs)
+ {
+ BOOST_TEST(!rhs.is_linked());
+ node_algorithms::init(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this)));
+ }
+
+ nonhook_node_member& operator = (const nonhook_node_member& rhs)
+ {
+ BOOST_TEST(!this->is_linked() && !rhs.is_linked());
+ return *this;
+ }
+
+ ~nonhook_node_member()
+ {
+ BOOST_TEST(!this->is_linked());
+ node_algorithms::init(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this)));
+ }
+
+ void swap_nodes(nonhook_node_member& other)
+ {
+ node_algorithms::swap_nodes(pointer_traits<node_ptr>::pointer_to(static_cast< node& >(*this)),
+ pointer_traits<node_ptr>::pointer_to(static_cast< node& >(other)));
+ }
+
+ bool is_linked() const
+ {
+ return !node_algorithms::unique(pointer_traits<const_node_ptr>::pointer_to(static_cast< const node& >(*this)));
+ }
+};
+
+template < typename T, typename NonHook_Member, NonHook_Member T::* P, link_mode_type Link_Mode >
+struct nonhook_node_member_value_traits
+{
+ typedef T value_type;
+ typedef typename NonHook_Member::node_traits 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 typename pointer_traits<node_ptr>::
+ template rebind_pointer<T>::type pointer;
+ typedef typename pointer_traits<node_ptr>::
+ template rebind_pointer<const T>::type const_pointer;
+ typedef T & reference;
+ typedef const T & const_reference;
+
+ static const link_mode_type link_mode = Link_Mode;
+
+ BOOST_STATIC_ASSERT((Link_Mode == safe_link || Link_Mode == auto_unlink));
+
+ static node_ptr to_node_ptr(reference value)
+ {
+ return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(value.*P));
+ }
+
+ static const_node_ptr to_node_ptr(const_reference value)
+ {
+ return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node&>(value.*P));
+ }
+
+ static pointer to_value_ptr(node_ptr n)
+ {
+ return pointer_traits<pointer>::pointer_to
+ (*detail::parent_from_member<T, NonHook_Member>
+ (static_cast<NonHook_Member*>(boost::movelib::to_raw_pointer(n)), P));
+ }
+
+ static const_pointer to_value_ptr(const_node_ptr n)
+ {
+ return pointer_traits<const_pointer>::pointer_to
+ (*detail::parent_from_member<T, NonHook_Member>
+ (static_cast<const NonHook_Member*>(boost::movelib::to_raw_pointer(n)), P));
+ }
+};
+
+}
+}
+
+#endif
diff --git a/src/boost/libs/intrusive/test/null_iterator_test.cpp b/src/boost/libs/intrusive/test/null_iterator_test.cpp
new file mode 100644
index 00000000..1905a656
--- /dev/null
+++ b/src/boost/libs/intrusive/test/null_iterator_test.cpp
@@ -0,0 +1,95 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/bs_set.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/aligned_storage.hpp>
+#include <boost/static_assert.hpp>
+#include <cstring>
+#include <new>
+
+using namespace boost::intrusive;
+
+struct Type
+ : list_base_hook<>
+ , slist_base_hook<>
+ , set_base_hook<>
+ , avl_set_base_hook<>
+ , bs_set_base_hook<>
+{};
+
+typedef boost::aligned_storage<sizeof(void*)*4>::type buffer_t;
+
+static buffer_t buffer_0x00;
+static buffer_t buffer_0xFF;
+
+template<class Iterator>
+const Iterator &on_0x00_buffer()
+{
+ BOOST_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator));
+ return * ::new(std::memset(&buffer_0x00, 0x00, sizeof(buffer_0x00))) Iterator();
+}
+
+template<class Iterator>
+const Iterator &on_0xFF_buffer()
+{
+ BOOST_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator));
+ return * ::new(std::memset(&buffer_0xFF, 0xFF, sizeof(buffer_0xFF))) Iterator();
+}
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reverse_iterator)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reverse_iterator)
+
+
+template<class Container>
+void check_null_iterators()
+{
+ typedef typename Container::iterator iterator;
+ typedef typename Container::const_iterator const_iterator;
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+ (::, Container
+ ,reverse_iterator, iterator) reverse_iterator;
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
+ (::, Container
+ ,const_reverse_iterator, const_iterator) const_reverse_iterator;
+
+ BOOST_TEST(on_0xFF_buffer<iterator>() == on_0x00_buffer<iterator>());
+ BOOST_TEST(on_0xFF_buffer<const_iterator>() == on_0x00_buffer<const_iterator>());
+ BOOST_TEST(on_0xFF_buffer<reverse_iterator>() == on_0x00_buffer<reverse_iterator>());
+ BOOST_TEST(on_0xFF_buffer<const_reverse_iterator>() == on_0x00_buffer<const_reverse_iterator>());
+}
+
+int main()
+{
+ check_null_iterators< list<Type> >();
+ check_null_iterators< slist<Type> >();
+ check_null_iterators< bs_set<Type> >();
+ check_null_iterators< set<Type> >();
+ check_null_iterators< multiset<Type> >();
+ check_null_iterators< avl_set<Type> >();
+ check_null_iterators< avl_multiset<Type> >();
+ check_null_iterators< sg_set<Type> >();
+ check_null_iterators< sg_multiset<Type> >();
+ check_null_iterators< treap_set<Type> >();
+ check_null_iterators< treap_multiset<Type> >();
+ check_null_iterators< splay_set<Type> >();
+ check_null_iterators< splay_multiset<Type> >();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/pack_options_test.cpp b/src/boost/libs/intrusive/test/pack_options_test.cpp
new file mode 100644
index 00000000..2df1c0fe
--- /dev/null
+++ b/src/boost/libs/intrusive/test/pack_options_test.cpp
@@ -0,0 +1,55 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2013-2013. 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/pack_options.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/static_assert.hpp>
+
+struct empty_default{};
+
+using namespace boost::intrusive;
+
+//Test BOOST_INTRUSIVE_OPTION_CONSTANT
+BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
+const bool is_incremental_value = pack_options< empty_default, incremental<true> >::type::is_incremental;
+BOOST_STATIC_ASSERT(( is_incremental_value == true ));
+
+//Test BOOST_INTRUSIVE_OPTION_TYPE
+BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, typename boost::intrusive::detail::remove_pointer<VoidPointer>::type, my_pointer_type)
+typedef pack_options< empty_default, my_pointer<void*> >::type::my_pointer_type my_pointer_type;
+BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<my_pointer_type, void>::value ));
+
+//test combination of BOOST_INTRUSIVE_OPTION_CONSTANT and BOOST_INTRUSIVE_OPTION_TYPE
+// First add new options
+struct default_options
+{
+ static const long long_constant = -3;
+ typedef double * double_typedef;
+};
+
+BOOST_INTRUSIVE_OPTION_CONSTANT(incremental2, bool, Enabled, is_incremental2)
+BOOST_INTRUSIVE_OPTION_TYPE(my_pointer2, VoidPointer, typename boost::intrusive::detail::add_pointer<VoidPointer>::type, my_pointer_type2)
+typedef pack_options < default_options
+ , incremental<false>
+ , my_pointer<float*>
+ , incremental2<true>
+ , my_pointer2<const char*>
+ >::type combined_type;
+BOOST_STATIC_ASSERT(( combined_type::is_incremental == false ));
+BOOST_STATIC_ASSERT(( combined_type::is_incremental2 == true ));
+BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<combined_type::my_pointer_type, float >::value ));
+BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<combined_type::my_pointer_type2, const char**>::value ));
+
+//test packing the default options leads to a default options type
+BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<pack_options<default_options>::type, default_options>::value ));
+
+int main()
+{
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/parent_from_member_test.cpp b/src/boost/libs/intrusive/test/parent_from_member_test.cpp
new file mode 100644
index 00000000..3fbc01f3
--- /dev/null
+++ b/src/boost/libs/intrusive/test/parent_from_member_test.cpp
@@ -0,0 +1,172 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014
+//
+// 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/parent_from_member.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+struct POD
+{
+ int int_;
+ float float_;
+}pod;
+
+struct Derived
+ : public POD
+{
+ int derived_int_;
+ float derived_float_;
+}derived;
+
+struct Abstract
+{
+ int abstract_int_;
+ float abstract_float_;
+ virtual void virtual_func1() = 0;
+ virtual void virtual_func2() = 0;
+ virtual ~Abstract(){}
+};
+
+struct DerivedPoly
+ : public Abstract
+{
+ int derivedpoly_int_;
+ float derivedpoly_float_;
+ virtual void virtual_func1(){}
+ virtual void virtual_func2(){}
+ Abstract *abstract() { return this; }
+ Abstract const *abstract() const { return this; }
+} derivedpoly;
+
+struct MultiInheritance
+ : public Derived, public DerivedPoly
+{
+ int multiinheritance_int_;
+ float multiinheritance_float_;
+} multiinheritance;
+
+struct Abstract2
+{
+ int abstract2_int_;
+ float abstract2_float_;
+ virtual void virtual_func1() = 0;
+ virtual void virtual_func2() = 0;
+ virtual ~Abstract2(){}
+};
+
+struct DerivedPoly2
+ : public Abstract2
+{
+ int derivedpoly2_int_;
+ float derivedpoly2_float_;
+ virtual void virtual_func1(){}
+ virtual void virtual_func2(){}
+ Abstract2 *abstract2() { return this; }
+ Abstract2 const *abstract2() const { return this; }
+ virtual ~DerivedPoly2(){}
+} derivedpoly2;
+
+struct MultiInheritance2
+ : public DerivedPoly, public DerivedPoly2
+{
+ int multiinheritance2_int_;
+ float multiinheritance2_float_;
+} multiinheritance2;
+
+struct VirtualDerivedPoly
+ : public virtual Derived
+{
+ int virtualderivedpoly_int_;
+ float virtualderivedpoly_float_;
+ virtual void f1(){}
+ virtual void f2(){}
+ virtual ~VirtualDerivedPoly(){}
+} virtualderivedpoly;
+
+struct VirtualMultipleDerivedPoly
+ : public virtual Derived, virtual public DerivedPoly
+{
+ int virtualmultiplederivedpoly_int_;
+ float virtualmultiplederivedpoly_float_;
+ virtual void f1(){}
+ virtual void f2(){}
+ virtual ~VirtualMultipleDerivedPoly(){}
+} virtualmultiplederivedpoly;
+
+struct VirtualDerived
+ : public virtual Derived
+{
+ int virtualderived_int_;
+ float virtualderived_float_;
+ virtual void f1(){}
+ virtual void f2(){}
+ virtual ~VirtualDerived(){}
+} virtualderived;
+
+using namespace boost::intrusive;
+
+//Add new test with https://svn.boost.org/trac/boost/attachment/ticket/8512/Source1.cpp
+
+int main()
+{
+ //POD
+ BOOST_TEST(&pod == get_parent_from_member(&pod.int_, &POD::int_));
+ BOOST_TEST(&pod == get_parent_from_member(&pod.float_, &POD::float_));
+
+ //Derived
+ BOOST_TEST(&derived == get_parent_from_member(&derived.int_, &Derived::int_));
+ BOOST_TEST(&derived == get_parent_from_member(&derived.float_, &Derived::float_));
+ BOOST_TEST(&derived == get_parent_from_member(&derived.derived_int_, &Derived::derived_int_));
+ BOOST_TEST(&derived == get_parent_from_member(&derived.derived_float_, &Derived::derived_float_));
+
+ //Abstract
+ BOOST_TEST(derivedpoly.abstract() == get_parent_from_member(&derivedpoly.abstract_int_, &Abstract::abstract_int_));
+ BOOST_TEST(derivedpoly.abstract() == get_parent_from_member(&derivedpoly.abstract_float_, &Abstract::abstract_float_));
+
+ //DerivedPoly
+ BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.abstract_int_, &DerivedPoly::abstract_int_));
+ BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.abstract_float_, &DerivedPoly::abstract_float_));
+ BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.derivedpoly_int_, &DerivedPoly::derivedpoly_int_));
+ BOOST_TEST(&derivedpoly == get_parent_from_member(&derivedpoly.derivedpoly_float_, &DerivedPoly::derivedpoly_float_));
+
+ //MultiInheritance
+ BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_int_, &MultiInheritance::abstract_int_));
+ BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_float_, &MultiInheritance::abstract_float_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_int_, &MultiInheritance::derivedpoly_int_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_float_, &MultiInheritance::derivedpoly_float_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.int_, &MultiInheritance::int_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.float_, &MultiInheritance::float_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derived_int_, &MultiInheritance::derived_int_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derived_float_, &MultiInheritance::derived_float_));
+
+ BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_int_, &MultiInheritance::abstract_int_));
+ BOOST_TEST(multiinheritance.abstract() == get_parent_from_member(&multiinheritance.abstract_float_, &MultiInheritance::abstract_float_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_int_, &MultiInheritance::derivedpoly_int_));
+ BOOST_TEST(&multiinheritance == get_parent_from_member(&multiinheritance.derivedpoly_float_, &MultiInheritance::derivedpoly_float_));
+ BOOST_TEST(multiinheritance2.abstract2() == get_parent_from_member(&multiinheritance2.abstract2_int_, &MultiInheritance2::abstract2_int_));
+ BOOST_TEST(multiinheritance2.abstract2() == get_parent_from_member(&multiinheritance2.abstract2_float_, &MultiInheritance2::abstract2_float_));
+ BOOST_TEST(&multiinheritance2 == get_parent_from_member(&multiinheritance2.derivedpoly2_int_, &MultiInheritance2::derivedpoly2_int_));
+ BOOST_TEST(&multiinheritance2 == get_parent_from_member(&multiinheritance2.derivedpoly2_float_, &MultiInheritance2::derivedpoly2_float_));
+
+ //MSVC pointer to member data uses RTTI info even when not crossing virtual base boundaries
+ #ifndef BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER
+ BOOST_TEST(&virtualderived == get_parent_from_member(&virtualderived.virtualderived_int_, &VirtualDerived::virtualderived_int_));
+ BOOST_TEST(&virtualderived == get_parent_from_member(&virtualderived.virtualderived_float_, &VirtualDerived::virtualderived_float_));
+
+ BOOST_TEST(&virtualderivedpoly == get_parent_from_member(&virtualderivedpoly.virtualderivedpoly_int_, &VirtualDerivedPoly::virtualderivedpoly_int_));
+ BOOST_TEST(&virtualderivedpoly == get_parent_from_member(&virtualderivedpoly.virtualderivedpoly_float_, &VirtualDerivedPoly::virtualderivedpoly_float_));
+ BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.virtualmultiplederivedpoly_float_, &VirtualMultipleDerivedPoly::virtualmultiplederivedpoly_float_));
+ BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.virtualmultiplederivedpoly_int_, &VirtualMultipleDerivedPoly::virtualmultiplederivedpoly_int_));
+ BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.derivedpoly_float_, &VirtualMultipleDerivedPoly::derivedpoly_float_));
+ BOOST_TEST(&virtualmultiplederivedpoly == get_parent_from_member(&virtualmultiplederivedpoly.derivedpoly_int_, &VirtualMultipleDerivedPoly::derivedpoly_int_));
+ #endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/pointer_traits_test.cpp b/src/boost/libs/intrusive/test/pointer_traits_test.cpp
new file mode 100644
index 00000000..73ea4f8c
--- /dev/null
+++ b/src/boost/libs/intrusive/test/pointer_traits_test.cpp
@@ -0,0 +1,223 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2013. 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/detail/mpl.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+struct CompleteSmartPtrStats
+{
+ static unsigned static_cast_called;
+ static unsigned dynamic_cast_called;
+ static unsigned const_cast_called;
+ static unsigned pointer_to_called;
+
+ static void reset_stats()
+ {
+ static_cast_called = 0;
+ dynamic_cast_called = 0;
+ const_cast_called = 0;
+ pointer_to_called = 0;
+ }
+};
+
+unsigned CompleteSmartPtrStats::static_cast_called= 0;
+unsigned CompleteSmartPtrStats::dynamic_cast_called = 0;
+unsigned CompleteSmartPtrStats::const_cast_called = 0;
+unsigned CompleteSmartPtrStats::pointer_to_called = 0;
+
+template<class T>
+class CompleteSmartPtr
+{
+ template <class U>
+ friend class CompleteSmartPtr;
+ void unspecified_bool_type_func() const {}
+ typedef void (CompleteSmartPtr::*unspecified_bool_type)() const;
+
+ public:
+ #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+ template <class U> using rebind = CompleteSmartPtr<U>;
+ #else
+ template <class U> struct rebind
+ { typedef CompleteSmartPtr<U> other; };
+ #endif
+
+ typedef char difference_type;
+ typedef T element_type;
+
+ CompleteSmartPtr()
+ : ptr_(0)
+ {}
+
+ explicit CompleteSmartPtr(T &p)
+ : ptr_(&p)
+ {}
+
+ CompleteSmartPtr(const CompleteSmartPtr &c)
+ { this->ptr_ = c.ptr_; }
+
+ CompleteSmartPtr & operator=(const CompleteSmartPtr &c)
+ { this->ptr_ = c.ptr_; }
+
+ static CompleteSmartPtr pointer_to(T &r)
+ { ++CompleteSmartPtrStats::pointer_to_called; return CompleteSmartPtr(r); }
+
+ T * operator->() const
+ { return ptr_; }
+
+ T & operator *() const
+ { return *ptr_; }
+
+ operator unspecified_bool_type() const
+ { return ptr_? &CompleteSmartPtr::unspecified_bool_type_func : 0; }
+
+ template<class U>
+ static CompleteSmartPtr static_cast_from(const CompleteSmartPtr<U> &uptr)
+ {
+ ++CompleteSmartPtrStats::static_cast_called;
+ element_type* const p = static_cast<element_type*>(uptr.ptr_);
+ return p ? CompleteSmartPtr(*p) : CompleteSmartPtr();
+ }
+
+ template<class U>
+ static CompleteSmartPtr const_cast_from(const CompleteSmartPtr<U> &uptr)
+ {
+ ++CompleteSmartPtrStats::const_cast_called;
+ element_type* const p = const_cast<element_type*>(uptr.ptr_);
+ return p ? CompleteSmartPtr(*p) : CompleteSmartPtr();
+ }
+
+ template<class U>
+ static CompleteSmartPtr dynamic_cast_from(const CompleteSmartPtr<U> &uptr)
+ {
+ ++CompleteSmartPtrStats::dynamic_cast_called;
+ element_type* const p = dynamic_cast<element_type*>(uptr.ptr_);
+ return p ? CompleteSmartPtr(*p) : CompleteSmartPtr();
+ }
+
+ friend bool operator ==(const CompleteSmartPtr &l, const CompleteSmartPtr &r)
+ { return l.ptr_ == r.ptr_; }
+
+ friend bool operator !=(const CompleteSmartPtr &l, const CompleteSmartPtr &r)
+ { return l.ptr_ != r.ptr_; }
+
+ private:
+ T *ptr_;
+};
+
+
+template<class T>
+class SimpleSmartPtr
+{
+ void unspecified_bool_type_func() const {}
+ typedef void (SimpleSmartPtr::*unspecified_bool_type)() const;
+ public:
+
+ SimpleSmartPtr()
+ : ptr_(0)
+ {}
+
+ explicit SimpleSmartPtr(T *p)
+ : ptr_(p)
+ {}
+
+ SimpleSmartPtr(const SimpleSmartPtr &c)
+ { this->ptr_ = c.ptr_; }
+
+ SimpleSmartPtr & operator=(const SimpleSmartPtr &c)
+ { this->ptr_ = c.ptr_; }
+
+ friend bool operator ==(const SimpleSmartPtr &l, const SimpleSmartPtr &r)
+ { return l.ptr_ == r.ptr_; }
+
+ friend bool operator !=(const SimpleSmartPtr &l, const SimpleSmartPtr &r)
+ { return l.ptr_ != r.ptr_; }
+
+ T* operator->() const
+ { return ptr_; }
+
+ T & operator *() const
+ { return *ptr_; }
+
+ operator unspecified_bool_type() const
+ { return ptr_? &SimpleSmartPtr::unspecified_bool_type_func : 0; }
+
+ private:
+ T *ptr_;
+};
+
+class B{ public: virtual ~B(){} };
+class D : public B {};
+class DD : public virtual B {};
+
+int main()
+{
+ int dummy;
+
+ //Raw pointer
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ <int*>::element_type, int>::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ <int*>::pointer, int*>::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ <int*>::difference_type, std::ptrdiff_t>::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ <int*>::rebind_pointer<double>::type
+ , double*>::value ));
+ BOOST_TEST(boost::intrusive::pointer_traits<int*>::pointer_to(dummy) == &dummy);
+ BOOST_TEST(boost::intrusive::pointer_traits<D*>:: static_cast_from((B*)0) == 0);
+ BOOST_TEST(boost::intrusive::pointer_traits<D*>:: const_cast_from((const D*)0) == 0);
+ BOOST_TEST(boost::intrusive::pointer_traits<DD*>:: dynamic_cast_from((B*)0) == 0);
+
+ //Complete smart pointer
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < CompleteSmartPtr<int> >::element_type, int>::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < CompleteSmartPtr<int> >::pointer, CompleteSmartPtr<int> >::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < CompleteSmartPtr<int> >::difference_type, char>::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < CompleteSmartPtr<int> >::rebind_pointer<double>::type
+ , CompleteSmartPtr<double> >::value ));
+ //pointer_to
+ CompleteSmartPtrStats::reset_stats();
+ BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<int> >::pointer_to(dummy) == CompleteSmartPtr<int>(dummy));
+ BOOST_TEST(CompleteSmartPtrStats::pointer_to_called == 1);
+ //static_cast_from
+ CompleteSmartPtrStats::reset_stats();
+ BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >::static_cast_from(CompleteSmartPtr<B>()) == CompleteSmartPtr<D>());
+ BOOST_TEST(CompleteSmartPtrStats::static_cast_called == 1);
+ //const_cast_from
+ CompleteSmartPtrStats::reset_stats();
+ BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<D> >::const_cast_from(CompleteSmartPtr<const D>()) == CompleteSmartPtr<D>());
+ BOOST_TEST(CompleteSmartPtrStats::const_cast_called == 1);
+ //dynamic_cast_from
+ CompleteSmartPtrStats::reset_stats();
+ BOOST_TEST(boost::intrusive::pointer_traits< CompleteSmartPtr<DD> >::dynamic_cast_from(CompleteSmartPtr<B>()) == CompleteSmartPtr<DD>());
+ BOOST_TEST(CompleteSmartPtrStats::dynamic_cast_called == 1);
+
+ //Simple smart pointer
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < SimpleSmartPtr<int> >::element_type, int>::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < SimpleSmartPtr<int> >::pointer, SimpleSmartPtr<int> >::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < SimpleSmartPtr<int> >::difference_type, std::ptrdiff_t>::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same<boost::intrusive::pointer_traits
+ < SimpleSmartPtr<int> >::rebind_pointer<double>::type
+ , SimpleSmartPtr<double> >::value ));
+
+ BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<int> >::pointer_to(dummy) == SimpleSmartPtr<int>(&dummy));
+ BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<D> > ::static_cast_from(SimpleSmartPtr<B>()) == SimpleSmartPtr<D>());
+ BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<D> > ::const_cast_from(SimpleSmartPtr<const D>()) == SimpleSmartPtr<D>());
+ BOOST_TEST(boost::intrusive::pointer_traits< SimpleSmartPtr<DD> >::dynamic_cast_from(SimpleSmartPtr<B>()) == SimpleSmartPtr<DD>());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/rb_test_common.hpp b/src/boost/libs/intrusive/test/rb_test_common.hpp
new file mode 100644
index 00000000..f9aa5123
--- /dev/null
+++ b/src/boost/libs/intrusive/test/rb_test_common.hpp
@@ -0,0 +1,45 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_TEST_RB_TEST_COMMON_HPP
+#define BOOST_INTRUSIVE_TEST_RB_TEST_COMMON_HPP
+
+#include <boost/intrusive/set_hook.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "bs_test_common.hpp"
+
+namespace boost {
+namespace intrusive {
+
+template<class VoidPointer>
+struct rb_hooks
+{
+ typedef set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+ typedef set_base_hook
+ <link_mode<auto_unlink>
+ , void_pointer<VoidPointer>
+ , tag<void>
+ , optimize_size<true> > auto_base_hook_type;
+ typedef set_member_hook
+ <void_pointer<VoidPointer>
+ , optimize_size<true> > member_hook_type;
+ typedef set_member_hook
+ < link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+ typedef nonhook_node_member< rbtree_node_traits<VoidPointer>,
+ rbtree_algorithms
+ > nonhook_node_member_type;
+};
+
+} //namespace intrusive {
+} //namespace boost {
+
+#endif //BOOST_INTRUSIVE_TEST_RB_TEST_COMMON_HPP
diff --git a/src/boost/libs/intrusive/test/recursive_test.cpp b/src/boost/libs/intrusive/test/recursive_test.cpp
new file mode 100644
index 00000000..a6fe73a2
--- /dev/null
+++ b/src/boost/libs/intrusive/test/recursive_test.cpp
@@ -0,0 +1,71 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include <cassert>
+
+using namespace boost::intrusive;
+
+typedef list_base_hook<> ListBaseHook;
+typedef slist_base_hook<> SListBaseHook;
+typedef set_base_hook<> SetBaseHook;
+typedef unordered_set_base_hook<> USetBaseHook;
+
+class Foo;
+typedef unordered_set<Foo, base_hook<USetBaseHook> > USet;
+
+class Foo : public ListBaseHook, public SListBaseHook, public SetBaseHook, public USetBaseHook
+{
+ USet::bucket_type buckets[1];
+ Foo(const Foo &);
+ Foo & operator=(const Foo &);
+
+ public:
+ Foo() : uset_children(USet::bucket_traits(buckets, 1))
+ {}
+ list <Foo, base_hook<ListBaseHook> > list_children;
+ slist<Foo, base_hook<SListBaseHook> > slist_children;
+ set <Foo, base_hook<SetBaseHook> > set_children;
+ USet uset_children;
+};
+
+void instantiate()
+{
+ list< Foo, base_hook<ListBaseHook> > list_; list_.clear();
+ slist< Foo, base_hook<SListBaseHook> > slist_; slist_.clear();
+ set< Foo, base_hook<SetBaseHook> > set_; set_.clear();
+
+ USet::bucket_type buckets[1];
+ USet unordered_set_(USet::bucket_traits(buckets, 1)); unordered_set_.clear();
+}
+int main()
+{
+ instantiate();
+
+ //A small test with list
+ {
+ Foo f, f2;
+ list< Foo, base_hook<ListBaseHook> > l;
+ l.insert(l.begin(), f);
+ l.begin()->list_children.insert(l.begin()->list_children.begin(), f2);
+ assert(l.size() == l.begin()->list_children.size());
+ l.begin()->list_children.clear();
+ l.clear();
+ }
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/scary_iterators_test.cpp b/src/boost/libs/intrusive/test/scary_iterators_test.cpp
new file mode 100644
index 00000000..6c4b4269
--- /dev/null
+++ b/src/boost/libs/intrusive/test/scary_iterators_test.cpp
@@ -0,0 +1,314 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2013-2013
+//
+// 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/avl_set.hpp>
+#include <boost/intrusive/sg_set.hpp>
+#include <boost/intrusive/bs_set.hpp>
+#include <boost/intrusive/splay_set.hpp>
+#include <boost/intrusive/treap_set.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/static_assert.hpp>
+#include "smart_ptr.hpp"
+#include <functional> //std::greater/std::less
+
+using namespace boost::intrusive;
+struct my_tag;
+
+template<class VoidPtr = void*, link_mode_type mode = normal_link>
+class MyClass
+: public make_list_base_hook
+ < void_pointer<VoidPtr>, link_mode<mode> >::type
+, public make_slist_base_hook
+ < void_pointer<VoidPtr>, link_mode<mode> >::type
+, public make_set_base_hook
+ < void_pointer<VoidPtr>, link_mode<mode> >::type
+, public make_unordered_set_base_hook
+ < void_pointer<VoidPtr>, link_mode<mode> >::type
+, public make_avl_set_base_hook
+ < void_pointer<VoidPtr>, link_mode<mode> >::type
+, public make_bs_set_base_hook
+ < void_pointer<VoidPtr>, link_mode<mode> >::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_); }
+
+ friend bool priority_order(const MyClass &l, const MyClass &r)
+ { return l.int_ < r.int_; }
+};
+
+template<class T>
+struct inverse_priority
+{
+ bool operator()(const T &l, const T &r)
+ { return l.int_ > r.int_; }
+};
+
+template<class T>
+struct inverse_hash
+{
+ bool operator()(const T &l)
+ { return hash_value(l); }
+};
+
+template<class T>
+struct alternative_equal
+{
+ bool operator()(const T &l, const T &r)
+ { return l.int_ == r.int_; }
+};
+
+int main()
+{
+ ////////////
+ // list
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< list<MyClass<> >::iterator
+ , list<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< list<MyClass<>, constant_time_size<true> >::iterator
+ , list<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< list<MyClass<> >::iterator
+ , list<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< list<MyClass<>, size_type<unsigned int > >::iterator
+ , list<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ ////////////
+ // slist
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< slist<MyClass<> >::iterator
+ , slist<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, constant_time_size<true> >::iterator
+ , slist<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< slist<MyClass<> >::iterator
+ , slist<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, size_type<unsigned int > >::iterator
+ , slist<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //cache_last does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, cache_last<false> >::iterator
+ , slist<MyClass<>, cache_last<true> >::iterator
+ >::value));
+ //linear does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< slist<MyClass<>, linear<false> >::iterator
+ , slist<MyClass<>, linear<true> >::iterator
+ >::value));
+ ////////////
+ // set
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< set<MyClass<> >::iterator
+ , set<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< set<MyClass<>, constant_time_size<true> >::iterator
+ , set<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< set<MyClass<> >::iterator
+ , set<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< set<MyClass<>, size_type<unsigned int > >::iterator
+ , set<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //compare does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
+ , set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
+ >::value));
+ ////////////
+ // avl_set
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< avl_set<MyClass<> >::iterator
+ , avl_set<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< avl_set<MyClass<>, constant_time_size<true> >::iterator
+ , avl_set<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< avl_set<MyClass<> >::iterator
+ , avl_set<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< avl_set<MyClass<>, size_type<unsigned int > >::iterator
+ , avl_set<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //compare does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< avl_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
+ , avl_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
+ >::value));
+ ////////////
+ // sg_set
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< sg_set<MyClass<> >::iterator
+ , sg_set<MyClass<> >::const_iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< sg_set<MyClass<> >::iterator
+ , sg_set<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< sg_set<MyClass<>, size_type<unsigned int > >::iterator
+ , sg_set<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //compare does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< sg_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
+ , sg_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
+ >::value));
+ //floating_point does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< sg_set<MyClass<>, floating_point<false> >::iterator
+ , sg_set<MyClass<>, floating_point<true> >::iterator
+ >::value));
+ ////////////
+ // bs_set
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< bs_set<MyClass<> >::iterator
+ , bs_set<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<>, constant_time_size<true> >::iterator
+ , bs_set<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< bs_set<MyClass<> >::iterator
+ , bs_set<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<>, size_type<unsigned int > >::iterator
+ , bs_set<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //compare does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
+ , bs_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
+ >::value));
+ ////////////
+ // splay_set
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< splay_set<MyClass<> >::iterator
+ , splay_set<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< splay_set<MyClass<>, constant_time_size<true> >::iterator
+ , splay_set<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< splay_set<MyClass<> >::iterator
+ , splay_set<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< splay_set<MyClass<>, size_type<unsigned int > >::iterator
+ , splay_set<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //compare does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< splay_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
+ , splay_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
+ >::value));
+ ////////////
+ // treap_set
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< treap_set<MyClass<> >::iterator
+ , treap_set<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<>, constant_time_size<true> >::iterator
+ , treap_set<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< treap_set<MyClass<> >::iterator
+ , treap_set<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<>, size_type<unsigned int > >::iterator
+ , treap_set<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //compare does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<>, compare< std::greater<MyClass<> > > >::iterator
+ , treap_set<MyClass<>, compare< std::less<MyClass<> > > >::iterator
+ >::value));
+ //priority does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< treap_set<MyClass<> >::iterator
+ , treap_set<MyClass<>, priority< inverse_priority<MyClass<> > > >::iterator
+ >::value));
+ //////////////
+ // common tree
+ //////////////
+ BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<> >::iterator
+ , sg_set<MyClass<> >::iterator
+ >::value));
+ BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<> >::iterator
+ , treap_set<MyClass<> >::iterator
+ >::value));
+ BOOST_STATIC_ASSERT((detail::is_same< bs_set<MyClass<> >::iterator
+ , splay_set<MyClass<> >::iterator
+ >::value));
+ ////////////
+ // unordered_set
+ ////////////
+ BOOST_STATIC_ASSERT((!detail::is_same< unordered_set<MyClass<> >::iterator
+ , unordered_set<MyClass<> >::const_iterator
+ >::value));
+ //constant_time_size does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<>, constant_time_size<true> >::iterator
+ , unordered_set<MyClass<>, constant_time_size<false> >::iterator
+ >::value));
+ //void_pointer does change iterator
+ BOOST_STATIC_ASSERT((!detail::is_same< unordered_set<MyClass<> >::iterator
+ , unordered_set<MyClass<smart_ptr<void> > >::iterator
+ >::value));
+ //size_type does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<>, size_type<unsigned int > >::iterator
+ , unordered_set<MyClass<>, size_type<unsigned char> >::iterator
+ >::value));
+ //hash does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
+ , unordered_set<MyClass<>, hash< inverse_hash<MyClass<> > > >::iterator
+ >::value));
+ //equal does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
+ , unordered_set<MyClass<>, equal< alternative_equal<MyClass<> > > >::iterator
+ >::value));
+ //power_2_buckets does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
+ , unordered_set<MyClass<>, power_2_buckets<true> >::iterator
+ >::value));
+ //cache_begin does not change iterator
+ BOOST_STATIC_ASSERT((detail::is_same< unordered_set<MyClass<> >::iterator
+ , unordered_set<MyClass<>, cache_begin<true> >::iterator
+ >::value));
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/set_test.cpp b/src/boost/libs/intrusive/test/set_test.cpp
new file mode 100644
index 00000000..e72575be
--- /dev/null
+++ b/src/boost/libs/intrusive/test/set_test.cpp
@@ -0,0 +1,156 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "rb_test_common.hpp"
+#include "generic_set_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef set
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< rb_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_set
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< rb_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_set
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< rb_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_set
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< RBTree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_set
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/sg_multiset_test.cpp b/src/boost/libs/intrusive/test/sg_multiset_test.cpp
new file mode 100644
index 00000000..2a71cace
--- /dev/null
+++ b/src/boost/libs/intrusive/test/sg_multiset_test.cpp
@@ -0,0 +1,148 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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/sg_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "bs_test_common.hpp"
+#include "generic_multiset_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool FloatingPoint, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef sg_multiset
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , floating_point<FloatingPoint>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, FloatingPoint, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename testval_traits_t::base_value_traits base_hook_t;
+ test::test_generic_multiset
+ < rebinder<base_hook_t, FloatingPoint, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, FloatingPoint, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename testval_traits_t::member_value_traits member_hook_t;
+ test::test_generic_multiset
+ < rebinder<member_hook_t, FloatingPoint, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, FloatingPoint, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_multiset
+ < rebinder<typename testval_traits_t::nonhook_value_traits, FloatingPoint, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+
+template < bool FloatingPoint, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_multiset
+ < rebinder< value_traits, FloatingPoint, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x FloatingPoint x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool FloatingPoint, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/sg_set_test.cpp b/src/boost/libs/intrusive/test/sg_set_test.cpp
new file mode 100644
index 00000000..a115844f
--- /dev/null
+++ b/src/boost/libs/intrusive/test/sg_set_test.cpp
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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/sg_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "bs_test_common.hpp"
+#include "generic_set_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool FloatingPoint, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef sg_set
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , floating_point<FloatingPoint>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, FloatingPoint, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename testval_traits_t::base_value_traits base_hook_t;
+ test::test_generic_set
+ < rebinder<base_hook_t, FloatingPoint, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, FloatingPoint, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename testval_traits_t::member_value_traits member_hook_t;
+ test::test_generic_set
+ < rebinder<member_hook_t, FloatingPoint, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool FloatingPoint, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, FloatingPoint, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_set
+ < rebinder<typename testval_traits_t::nonhook_value_traits, FloatingPoint, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool FloatingPoint, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_set
+ < rebinder< value_traits, FloatingPoint, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x FloatingPoint x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool FloatingPoint, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/slist_test.cpp b/src/boost/libs/intrusive/test/slist_test.cpp
new file mode 100644
index 00000000..8a5362f8
--- /dev/null
+++ b/src/boost/libs/intrusive/test/slist_test.cpp
@@ -0,0 +1,660 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga 2006-2013.
+//
+// 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/slist.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include <typeinfo>
+
+using namespace boost::intrusive;
+
+template<class VoidPointer>
+struct hooks
+{
+ typedef slist_base_hook<void_pointer<VoidPointer> > base_hook_type;
+ typedef slist_base_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer>, tag<void> > auto_base_hook_type;
+ typedef slist_member_hook<void_pointer<VoidPointer>, tag<void> > member_hook_type;
+ typedef slist_member_hook< link_mode<auto_unlink>
+ , void_pointer<VoidPointer> > auto_member_hook_type;
+ typedef nonhook_node_member< slist_node_traits< VoidPointer >,
+ circular_slist_algorithms
+ > nonhook_node_member_type;
+};
+
+template < typename ListType, typename ValueContainer >
+struct test_slist
+{
+ typedef ListType list_type;
+ typedef typename list_type::value_traits value_traits;
+ typedef typename value_traits::value_type value_type;
+ typedef typename list_type::node_algorithms node_algorithms;
+
+ static void test_all(ValueContainer&);
+ static void test_front(ValueContainer&);
+ static void test_back(ValueContainer&, detail::true_type);
+ static void test_back(ValueContainer&, detail::false_type) {}
+ static void test_sort(ValueContainer&);
+ static void test_merge(ValueContainer&);
+ static void test_remove_unique(ValueContainer&);
+ static void test_insert(ValueContainer&);
+ static void test_shift(ValueContainer&);
+ static void test_swap(ValueContainer&);
+ static void test_slow_insert(ValueContainer&);
+ static void test_clone(ValueContainer&);
+ static void test_container_from_end(ValueContainer&, detail::true_type);
+ static void test_container_from_end(ValueContainer&, detail::false_type) {}
+};
+
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_all (ValueContainer& values)
+{
+ {
+ list_type list(values.begin(), values.end());
+ test::test_container(list);
+ list.clear();
+ list.insert(list.end(), values.begin(), values.end());
+ test::test_sequence_container(list, values);
+ }
+ {
+ list_type list(values.begin(), values.end());
+ test::test_iterator_forward(list);
+ }
+ test_front(values);
+ test_back(values, detail::bool_< list_type::cache_last >());
+ test_sort(values);
+ test_merge (values);
+ test_remove_unique(values);
+ test_insert(values);
+ test_shift(values);
+ test_slow_insert (values);
+ test_swap(values);
+ test_clone(values);
+ test_container_from_end(values, detail::bool_< !list_type::linear && list_type::has_container_from_iterator >());
+}
+
+//test: push_front, pop_front, front, size, empty:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_front(ValueContainer& values)
+{
+ list_type testlist;
+ BOOST_TEST (testlist.empty());
+
+ testlist.push_front (values[0]);
+ BOOST_TEST (testlist.size() == 1);
+ BOOST_TEST (&testlist.front() == &values[0]);
+
+ testlist.push_front (values[1]);
+ BOOST_TEST (testlist.size() == 2);
+ BOOST_TEST (&testlist.front() == &values[1]);
+
+ testlist.pop_front();
+ BOOST_TEST (testlist.size() == 1);
+ BOOST_TEST (&testlist.front() == &values[0]);
+
+ testlist.pop_front();
+ BOOST_TEST (testlist.empty());
+}
+
+//test: push_front, pop_front, front, size, empty:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_back(ValueContainer& values, detail::true_type)
+{
+ list_type testlist;
+ BOOST_TEST (testlist.empty());
+
+ testlist.push_back (values[0]);
+ BOOST_TEST (testlist.size() == 1);
+ BOOST_TEST (&testlist.front() == &values[0]);
+ BOOST_TEST (&testlist.back() == &values[0]);
+ testlist.push_back(values[1]);
+ BOOST_TEST(*testlist.previous(testlist.end()) == values[1]);
+ BOOST_TEST (&testlist.front() == &values[0]);
+ BOOST_TEST (&testlist.back() == &values[1]);
+}
+
+//test: merge due to error in merge implementation:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_merge (ValueContainer& values)
+{
+ list_type testlist1, testlist2;
+ testlist1.push_front (values[0]);
+ testlist2.push_front (values[4]);
+ testlist2.push_front (values[3]);
+ testlist2.push_front (values[2]);
+ testlist1.merge (testlist2);
+
+ int init_values [] = { 1, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
+}
+
+//test: merge due to error in merge implementation:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_remove_unique (ValueContainer& values)
+{
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_if(is_even());
+ int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_if(is_odd());
+ int init_values [] = { 2, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_and_dispose_if(is_even(), test::empty_disposer());
+ int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_and_dispose_if(is_odd(), test::empty_disposer());
+ int init_values [] = { 2, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ ValueContainer values2(values);
+ list_type list(values.begin(), values.end());
+ list.insert_after(list.before_begin(), values2.begin(), values2.end());
+ list.sort();
+ int init_values [] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ list.unique();
+ int init_values2 [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values2, list.begin() );
+ }
+}
+
+//test: constructor, iterator, sort, reverse:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_sort(ValueContainer& values)
+{
+ list_type testlist (values.begin(), values.end());
+
+ { int init_values [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
+
+ testlist.sort (even_odd());
+ { int init_values [] = { 2, 4, 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
+
+ testlist.reverse();
+ { int init_values [] = { 5, 3, 1, 4, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
+}
+
+//test: assign, insert_after, const_iterator, erase_after, s_iterator_to, previous:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_insert(ValueContainer& values)
+{
+ list_type testlist;
+ testlist.assign (values.begin() + 2, values.begin() + 5);
+
+ const list_type& const_testlist = testlist;
+ { int init_values [] = { 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+
+ typename list_type::iterator i = ++testlist.begin();
+ BOOST_TEST (i->value_ == 4);
+
+ testlist.insert_after (i, values[0]);
+ { int init_values [] = { 3, 4, 1, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+
+ i = testlist.iterator_to (values[4]);
+ BOOST_TEST (&*i == &values[4]);
+ i = list_type::s_iterator_to (values[4]);
+ BOOST_TEST (&*i == &values[4]);
+
+ typename list_type::const_iterator ic;
+ ic = testlist.iterator_to (static_cast< typename list_type::const_reference >(values[4]));
+ BOOST_TEST (&*ic == &values[4]);
+ ic = list_type::s_iterator_to (static_cast< typename list_type::const_reference >(values[4]));
+ BOOST_TEST (&*ic == &values[4]);
+
+ i = testlist.previous (i);
+ BOOST_TEST (&*i == &values[0]);
+
+ testlist.erase_after (i);
+ BOOST_TEST (&*i == &values[0]);
+ { int init_values [] = { 3, 4, 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+}
+
+//test: insert, const_iterator, erase, siterator_to:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_slow_insert (ValueContainer& values)
+{
+ list_type testlist;
+ testlist.push_front (values[4]);
+ testlist.insert (testlist.begin(), values.begin() + 2, values.begin() + 4);
+
+ const list_type& const_testlist = testlist;
+ { int init_values [] = { 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+
+ typename list_type::iterator i = ++testlist.begin();
+ BOOST_TEST (i->value_ == 4);
+
+ testlist.insert (i, values[0]);
+ { int init_values [] = { 3, 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+
+ 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());
+
+ { int init_values [] = { 3, 1, 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() ); }
+
+ testlist.erase (++testlist.begin(), testlist.end());
+ BOOST_TEST (testlist.size() == 1);
+ BOOST_TEST (testlist.begin()->value_ == 3);
+}
+
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_shift(ValueContainer& values)
+{
+ list_type testlist;
+ const int num_values = (int)values.size();
+ std::vector<int> expected_values(num_values);
+
+ //Shift forward all possible positions 3 times
+ for(int s = 1; s <= num_values; ++s){
+ expected_values.resize(s);
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert_after(testlist.before_begin(), values.begin(), values.begin() + s);
+ testlist.shift_forward(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + s - i%s) % s] = (j + 1);
+ }
+
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
+ testlist.clear();
+ }
+
+ //Shift backwards all possible positions
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert_after(testlist.before_begin(), values.begin(), values.begin() + s);
+ testlist.shift_backwards(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + i) % s] = (j + 1);
+ }
+
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
+ testlist.clear();
+ }
+ }
+}
+
+//test: insert_after (seq-version), swap, splice_after:
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_swap(ValueContainer& values)
+{
+ {
+ list_type testlist1 (values.begin(), values.begin() + 2);
+ list_type testlist2;
+ testlist2.insert_after (testlist2.before_begin(), values.begin() + 2, values.begin() + 5);
+ testlist1.swap(testlist2);
+ { int init_values [] = { 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ { int init_values [] = { 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+ testlist2.splice_after (testlist2.begin(), testlist1);
+ { int init_values [] = { 1, 3, 4, 5, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+ BOOST_TEST (testlist1.empty());
+
+ testlist1.splice_after (testlist1.before_begin(), testlist2, ++testlist2.begin());
+ { int init_values [] = { 4 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ { int init_values [] = { 1, 3, 5, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+
+ testlist1.splice_after (testlist1.begin(), testlist2,
+ testlist2.before_begin(), ++++testlist2.begin());
+ { int init_values [] = { 4, 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ { int init_values [] = { 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+ }
+ { //Now test swap when testlist2 is empty
+ list_type testlist1 (values.begin(), values.begin() + 2);
+ list_type testlist2;
+ testlist1.swap(testlist2);
+ BOOST_TEST (testlist1.empty());
+ { int init_values [] = { 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+ }
+ { //Now test swap when testlist1 is empty
+ list_type testlist2 (values.begin(), values.begin() + 2);
+ list_type testlist1;
+ testlist1.swap(testlist2);
+ BOOST_TEST (testlist2.empty());
+ { int init_values [] = { 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ }
+ { //Now test when both are empty
+ list_type testlist1, testlist2;
+ testlist2.swap(testlist1);
+ BOOST_TEST (testlist1.empty() && testlist2.empty());
+ }
+
+ if(!list_type::linear)
+ {
+ list_type testlist1 (values.begin(), values.begin() + 2);
+ list_type testlist2 (values.begin() + 3, values.begin() + 5);
+
+ swap_nodes< node_algorithms >(values[0], values[2]);
+ { int init_values [] = { 3, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[2], values[4]);
+ { int init_values [] = { 5, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ { int init_values [] = { 4, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+ }
+ if(!list_type::linear)
+ {
+ list_type testlist1 (values.begin(), values.begin()+1);
+ if(testlist1.size() != 1){
+ abort();
+ }
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[1], values[2]);
+
+ BOOST_TEST(testlist1.size() == 1);
+ BOOST_TEST(!(&values[1])->is_linked());
+ BOOST_TEST(!(&values[2])->is_linked());
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[0], values[2]);
+ BOOST_TEST(testlist1.size() == 1);
+ BOOST_TEST((&values[2])->is_linked());
+ BOOST_TEST(!(&values[0])->is_linked());
+ { int init_values [] = { 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ swap_nodes< node_algorithms >(values[0], values[2]);
+ BOOST_TEST(testlist1.size() == 1);
+ BOOST_TEST(!(&values[2])->is_linked());
+ BOOST_TEST((&values[0])->is_linked());
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ }
+}
+
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_clone(ValueContainer& values)
+{
+ list_type testlist1 (values.begin(), values.begin() + values.size());
+ list_type testlist2;
+
+ 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<value_type>());
+ BOOST_TEST (testlist2.empty());
+}
+
+template < typename ListType, typename ValueContainer >
+void test_slist< ListType, ValueContainer >
+ ::test_container_from_end(ValueContainer& values, detail::true_type)
+{
+ list_type testlist1 (values.begin(), values.begin() + 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 < typename ValueTraits, bool ConstantTimeSize, bool Linear, bool CacheLast, bool Default_Holder, typename ValueContainer >
+struct make_and_test_slist
+ : test_slist< slist< typename ValueTraits::value_type,
+ value_traits< ValueTraits >,
+ size_type< std::size_t >,
+ constant_time_size< ConstantTimeSize >,
+ linear<Linear>,
+ cache_last<CacheLast>
+ >,
+ ValueContainer
+ >
+{};
+
+template < typename ValueTraits, bool ConstantTimeSize, bool Linear, bool CacheLast, typename ValueContainer >
+struct make_and_test_slist< ValueTraits, ConstantTimeSize, Linear, CacheLast, false, ValueContainer >
+ : test_slist< slist< typename ValueTraits::value_type,
+ value_traits< ValueTraits >,
+ size_type< std::size_t >,
+ constant_time_size< ConstantTimeSize >,
+ linear<Linear>,
+ cache_last<CacheLast>,
+ header_holder_type< heap_node_holder< typename ValueTraits::pointer > >
+ >,
+ ValueContainer
+ >
+{};
+
+template<class VoidPointer, bool constant_time_size, bool Default_Holder>
+class test_main_template
+{
+ public:
+ int operator()()
+ {
+ typedef testvalue< hooks<VoidPointer> > value_type;
+ std::vector< value_type > data (5);
+ for (int i = 0; i < 5; ++i)
+ data[i].value_ = i + 1;
+
+ make_and_test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename hooks<VoidPointer>::base_hook_type
+ >::type
+ , constant_time_size
+ , false
+ , false
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+ make_and_test_slist < nonhook_node_member_value_traits< value_type,
+ typename hooks<VoidPointer>::nonhook_node_member_type,
+ &value_type::nhn_member_,
+ safe_link
+ >
+ , constant_time_size
+ , false
+ , false
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+
+ //Now linear slists
+ make_and_test_slist < typename detail::get_member_value_traits
+ < member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+ , &value_type::node_
+ >
+ >::type
+ , constant_time_size
+ , true
+ , false
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+
+ //Now the same but caching the last node
+ make_and_test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename hooks<VoidPointer>::base_hook_type
+ >::type
+ , constant_time_size
+ , false
+ , true
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+
+ //Now linear slists
+ make_and_test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename hooks<VoidPointer>::base_hook_type
+ >::type
+ , constant_time_size
+ , true
+ , true
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+ return 0;
+ }
+};
+
+template<class VoidPointer, bool Default_Holder>
+class test_main_template<VoidPointer, false, Default_Holder>
+{
+ public:
+ int operator()()
+ {
+ typedef testvalue< hooks<VoidPointer> > value_type;
+ std::vector< value_type > data (5);
+ for (int i = 0; i < 5; ++i)
+ data[i].value_ = i + 1;
+
+ make_and_test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename hooks<VoidPointer>::auto_base_hook_type
+ >::type
+ , false
+ , false
+ , false
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+
+ make_and_test_slist < nonhook_node_member_value_traits< value_type,
+ typename hooks<VoidPointer>::nonhook_node_member_type,
+ &value_type::nhn_member_,
+ safe_link
+ >
+ , false
+ , false
+ , true
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+
+ make_and_test_slist < typename detail::get_member_value_traits
+ < member_hook< value_type
+ , typename hooks<VoidPointer>::member_hook_type
+ , &value_type::node_
+ >
+ >::type
+ , false
+ , true
+ , false
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+
+ make_and_test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename hooks<VoidPointer>::base_hook_type
+ >::type
+ , false
+ , true
+ , true
+ , Default_Holder
+ , std::vector< value_type >
+ >::test_all(data);
+
+ return 0;
+ }
+};
+
+template < bool ConstantTimeSize >
+struct test_main_template_bptr
+{
+ int operator()()
+ {
+ typedef BPtr_Value value_type;
+ typedef BPtr_Value_Traits< List_BPtr_Node_Traits > list_value_traits;
+ typedef typename list_value_traits::node_ptr node_ptr;
+ typedef bounded_allocator< value_type > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ allocator_type allocator;
+
+ {
+ bounded_reference_cont< value_type > ref_cont;
+ for (int i = 0; i < 5; ++i)
+ {
+ node_ptr tmp = allocator.allocate(1);
+ new (tmp.raw()) value_type(i + 1);
+ ref_cont.push_back(*tmp);
+ }
+
+ test_slist < slist < value_type,
+ value_traits< list_value_traits >,
+ size_type< std::size_t >,
+ constant_time_size< ConstantTimeSize >,
+ header_holder_type< bounded_pointer_holder< value_type > >
+ >,
+ bounded_reference_cont< value_type >
+ >::test_all(ref_cont);
+ }
+ return 0;
+ }
+};
+
+int main(int, char* [])
+{
+ // test (plain/smart pointers) x (nonconst/const size) x (void node allocator)
+ test_main_template<void*, false, true>()();
+ test_main_template<boost::intrusive::smart_ptr<void>, false, true>()();
+ test_main_template<void*, true, true>()();
+ test_main_template<boost::intrusive::smart_ptr<void>, true, true>()();
+ // test (bounded pointers) x ((nonconst/const size) x (special node allocator)
+ test_main_template_bptr< true >()();
+ test_main_template_bptr< false >()();
+
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/smart_ptr.hpp b/src/boost/libs/intrusive/test/smart_ptr.hpp
new file mode 100644
index 00000000..10e54853
--- /dev/null
+++ b/src/boost/libs/intrusive/test/smart_ptr.hpp
@@ -0,0 +1,311 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP
+#define BOOST_INTRUSIVE_SMART_PTR_HPP
+
+#include <boost/intrusive/pointer_plus_bits.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
+#include <boost/move/adl_move_swap.hpp>
+
+#if (defined _MSC_VER)
+# pragma once
+#endif
+
+namespace boost{
+namespace intrusive{
+
+namespace detail {
+
+struct static_cast_tag {};
+struct const_cast_tag {};
+struct dynamic_cast_tag {};
+struct reinterpret_cast_tag {};
+
+} //namespace detail {
+
+//Empty class
+struct empty_type{};
+
+template<class T>
+struct random_it
+: public iterator<std::random_access_iterator_tag, T, std::ptrdiff_t, T*, T&>
+{
+ typedef const T* const_pointer;
+ typedef const T& const_reference;
+};
+
+template<> struct random_it<void>
+{
+ typedef const void * const_pointer;
+ typedef empty_type& reference;
+ typedef const empty_type& const_reference;
+ typedef empty_type difference_type;
+ typedef empty_type iterator_category;
+};
+
+template<> struct random_it<const void>
+{
+ typedef const void * const_pointer;
+ typedef const empty_type & reference;
+ typedef const empty_type & const_reference;
+ typedef empty_type difference_type;
+ typedef empty_type iterator_category;
+};
+
+template<> struct random_it<volatile void>
+{
+ typedef const volatile void * const_pointer;
+ typedef empty_type& reference;
+ typedef const empty_type& const_reference;
+ typedef empty_type difference_type;
+ typedef empty_type iterator_category;
+};
+
+template<> struct random_it<const volatile void>
+{
+ typedef const volatile void * const_pointer;
+ typedef const empty_type & reference;
+ typedef const empty_type & const_reference;
+ typedef empty_type difference_type;
+ typedef empty_type iterator_category;
+};
+
+} //namespace intrusive {
+} //namespace boost {
+
+
+namespace boost {
+namespace intrusive {
+
+template <class PointedType>
+class smart_ptr
+{
+ typedef random_it<PointedType> random_it_t;
+ typedef smart_ptr<PointedType> self_t;
+ typedef typename random_it_t::const_pointer const_pointer_t;
+ typedef typename random_it_t::const_reference const_reference_t;
+
+ void unspecified_bool_type_func() const {}
+ typedef void (self_t::*unspecified_bool_type)() const;
+
+ public:
+ typedef PointedType * pointer;
+ typedef typename random_it_t::reference reference;
+ typedef PointedType value_type;
+ typedef typename random_it_t::difference_type difference_type;
+ typedef typename random_it_t::iterator_category iterator_category;
+
+ PointedType *m_ptr;
+
+ public: //Public Functions
+
+ smart_ptr()
+ : m_ptr(0)
+ {}
+
+ //!Constructor from other smart_ptr
+ smart_ptr(const smart_ptr& ptr)
+ : m_ptr(ptr.m_ptr)
+ {}
+
+ static smart_ptr pointer_to(reference r)
+ { smart_ptr p; p.m_ptr = &r; return p; }
+
+ //!Constructor from other smart_ptr. If pointers of pointee types are
+ //!convertible, offset_ptrs will be convertibles. Never throws.
+ template<class T2>
+ smart_ptr(const smart_ptr<T2> &ptr)
+ : m_ptr(ptr.m_ptr)
+ {}
+
+ pointer get() const
+ { return m_ptr; }
+
+ void set(pointer p)
+ { m_ptr = p; }
+
+ //!Pointer-like -> operator. It can return 0 pointer. Never throws.
+ pointer operator->() const
+ { return m_ptr; }
+
+ //!Dereferencing operator, if it is a null smart_ptr behavior
+ //! is undefined. Never throws.
+ reference operator* () const
+ { return *m_ptr; }
+
+ //!Indexing operator. Never throws.
+ reference operator[](std::ptrdiff_t idx) const
+ { return m_ptr[idx]; }
+
+ //!Assignment from other smart_ptr. Never throws.
+ smart_ptr& operator= (const smart_ptr & pt)
+ { m_ptr = pt.m_ptr; return *this; }
+
+ //!Assignment from related smart_ptr. If pointers of pointee types
+ //! are assignable, offset_ptrs will be assignable. Never throws.
+ template <class T2>
+ smart_ptr& operator= (const smart_ptr<T2> & pt)
+ { m_ptr = pt.m_ptr; return *this; }
+
+ //!smart_ptr + std::ptrdiff_t. Never throws.
+ smart_ptr operator+ (std::ptrdiff_t offset) const
+ { smart_ptr s; s.m_ptr = m_ptr + offset; return s; }
+
+ //!smart_ptr - std::ptrdiff_t. Never throws.
+ smart_ptr operator- (std::ptrdiff_t offset) const
+ { smart_ptr s; s.m_ptr = m_ptr - offset; return s; }
+
+ //!smart_ptr += std::ptrdiff_t. Never throws.
+ smart_ptr &operator+= (std::ptrdiff_t offset)
+ { m_ptr += offset; return *this; }
+
+ //!smart_ptr -= std::ptrdiff_t. Never throws.
+ smart_ptr &operator-= (std::ptrdiff_t offset)
+ { m_ptr -= offset; return *this; }
+
+ //!++smart_ptr. Never throws.
+ smart_ptr& operator++ (void)
+ { ++m_ptr; return *this; }
+
+ //!smart_ptr++. Never throws.
+ smart_ptr operator++ (int)
+ { smart_ptr temp(*this); ++*this; return temp; }
+
+ //!--smart_ptr. Never throws.
+ smart_ptr& operator-- (void)
+ { --m_ptr; return *this; }
+
+ //!smart_ptr--. Never throws.
+ smart_ptr operator-- (int)
+ { smart_ptr temp(*this); --*this; return temp; }
+
+ //!safe bool conversion operator. Never throws.
+ operator unspecified_bool_type() const
+ { return m_ptr? &self_t::unspecified_bool_type_func : 0; }
+
+ //!Not operator. Not needed in theory, but improves portability.
+ //!Never throws.
+ bool operator! () const
+ { return m_ptr == 0; }
+
+ //!swap
+ friend void swap(smart_ptr& x, smart_ptr& y)
+ { boost::adl_move_swap(x.m_ptr, y.m_ptr); }
+};
+
+//!smart_ptr<T1> == smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator== (const smart_ptr<T1> &pt1,
+ const smart_ptr<T2> &pt2)
+{ return pt1.operator->() == pt2.operator->(); }
+
+//!smart_ptr<T1> != smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator!= (const smart_ptr<T1> &pt1,
+ const smart_ptr<T2> &pt2)
+{ return pt1.operator->() != pt2.operator->(); }
+
+//!smart_ptr<T1> < smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator< (const smart_ptr<T1> &pt1,
+ const smart_ptr<T2> &pt2)
+{ return pt1.operator->() < pt2.operator->(); }
+
+//!smart_ptr<T1> <= smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator<= (const smart_ptr<T1> &pt1,
+ const smart_ptr<T2> &pt2)
+{ return pt1.operator->() <= pt2.operator->(); }
+
+//!smart_ptr<T1> > smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator> (const smart_ptr<T1> &pt1,
+ const smart_ptr<T2> &pt2)
+{ return pt1.operator->() > pt2.operator->(); }
+
+//!smart_ptr<T1> >= smart_ptr<T2>. Never throws.
+template<class T1, class T2>
+inline bool operator>= (const smart_ptr<T1> &pt1,
+ const smart_ptr<T2> &pt2)
+{ return pt1.operator->() >= pt2.operator->(); }
+
+//!operator<<
+template<class E, class T, class Y>
+inline std::basic_ostream<E, T> & operator<<
+ (std::basic_ostream<E, T> & os, smart_ptr<Y> const & p)
+{ return os << p.operator->(); }
+
+//!operator>>
+template<class E, class T, class Y>
+inline std::basic_istream<E, T> & operator>>
+ (std::basic_istream<E, T> & os, smart_ptr<Y> & p)
+{ Y * tmp; return os >> tmp; p = tmp; }
+
+//!std::ptrdiff_t + smart_ptr
+template<class T>
+inline smart_ptr<T> operator+(std::ptrdiff_t diff, const smart_ptr<T>& right)
+{ return right + diff; }
+
+//!smart_ptr - smart_ptr
+template<class T, class T2>
+inline std::ptrdiff_t operator- (const smart_ptr<T> &pt, const smart_ptr<T2> &pt2)
+{ return pt.operator->()- pt2.operator->(); }
+
+} //namespace intrusive {
+} //namespace boost {
+
+namespace boost{
+
+//This is to support embedding a bit in the pointer
+//for intrusive containers, saving space
+namespace intrusive {
+
+template<std::size_t Alignment>
+struct max_pointer_plus_bits<smart_ptr<void>, Alignment>
+{
+ static const std::size_t value = max_pointer_plus_bits<void*, Alignment>::value;
+};
+
+template<class T, std::size_t NumBits>
+struct pointer_plus_bits<smart_ptr<T>, NumBits>
+{
+ typedef smart_ptr<T> pointer;
+
+ static pointer get_pointer(const pointer &n)
+ {
+ pointer p;
+ p.set(pointer_plus_bits<T*, NumBits>::get_pointer(n.get()));
+ return p;
+ }
+
+ static void set_pointer(pointer &n, pointer p)
+ {
+ T *raw_n = n.get();
+ pointer_plus_bits<T*, NumBits>::set_pointer(raw_n, p.operator->());
+ n.set(raw_n);
+ }
+
+ static std::size_t get_bits(const pointer &n)
+ { return pointer_plus_bits<T*, NumBits>::get_bits(n.get()); }
+
+ static void set_bits(pointer &n, std::size_t c)
+ {
+ T *raw_n = n.operator->();
+ pointer_plus_bits<T*, NumBits>::set_bits(raw_n, c);
+ n.set(raw_n);
+ }
+};
+
+} //namespace intrusive
+} //namespace boost{
+
+#endif //#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP
diff --git a/src/boost/libs/intrusive/test/splay_multiset_test.cpp b/src/boost/libs/intrusive/test/splay_multiset_test.cpp
new file mode 100644
index 00000000..70fb8912
--- /dev/null
+++ b/src/boost/libs/intrusive/test/splay_multiset_test.cpp
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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/splay_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "bs_test_common.hpp"
+#include "generic_multiset_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef splay_multiset
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_multiset
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_multiset
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_multiset
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_multiset
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/splay_set_test.cpp b/src/boost/libs/intrusive/test/splay_set_test.cpp
new file mode 100644
index 00000000..7aa73b28
--- /dev/null
+++ b/src/boost/libs/intrusive/test/splay_set_test.cpp
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2015
+//
+// 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/splay_set.hpp>
+#include "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "bs_test_common.hpp"
+#include "generic_set_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef splay_set
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_set
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_set
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_set
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_set
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/stateful_value_traits_test.cpp b/src/boost/libs/intrusive/test/stateful_value_traits_test.cpp
new file mode 100644
index 00000000..c24c8fb6
--- /dev/null
+++ b/src/boost/libs/intrusive/test/stateful_value_traits_test.cpp
@@ -0,0 +1,157 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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/intrusive/pointer_traits.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 pointer_traits<node_ptr>::
+ template rebind_pointer<T>::type pointer;
+ typedef typename pointer_traits<node_ptr>::
+ template rebind_pointer<const T>::type const_pointer;
+
+ static const link_mode_type link_mode = normal_link;
+
+ stateful_value_traits(pointer vals, node_ptr node_array)
+ : values_(vals), node_array_(node_array)
+ {}
+
+ node_ptr to_node_ptr (value_type &value) const
+ { 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(const node_ptr &n) const
+ { return values_ + (n - node_array_); }
+
+ const_pointer to_value_ptr(const 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 containers
+ for(MyClass * it(&values[0]), *itend(&values[NumElements])
+ ; it != itend
+ ; ++it){
+ my_list.push_front(*it);
+ if(&*my_list.iterator_to(*it) != &my_list.front())
+ return 1;
+ my_slist.push_front(*it);
+ if(&*my_slist.iterator_to(*it) != &my_slist.front())
+ return 1;
+ Set::iterator sit = my_set.insert(*it).first;
+ if(&*my_set.iterator_to(*it) != &*sit)
+ return 1;
+ Uset::iterator uit = my_uset.insert(*it).first;
+ my_uset.insert(*it);
+ if(&*my_uset.iterator_to(*it) != &*uit)
+ return 1;
+ }
+
+ //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]), *it_rbeg_val(&values[0]);
+
+ //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[-1]) return 1;
+ if(&*slist_it != &it_val[-1]) return 1;
+ if(&*set_rit != &it_val[-1]) return 1;
+ if(my_uset.find(it_val[-1]) == my_uset.cend()) return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/test_common.hpp b/src/boost/libs/intrusive/test/test_common.hpp
new file mode 100644
index 00000000..8c7ae489
--- /dev/null
+++ b/src/boost/libs/intrusive/test/test_common.hpp
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_TEST_TEST_COMMON_HPP
+#define BOOST_INTRUSIVE_TEST_TEST_COMMON_HPP
+
+#include <boost/intrusive/bs_set_hook.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "bptr_value.hpp"
+
+namespace boost {
+namespace intrusive {
+
+template <class KeyOfValueOption, class Map>
+struct key_type_tester
+{
+ struct empty_default{};
+ typedef typename pack_options< empty_default, KeyOfValueOption >::type::key_of_value key_of_value_t;
+
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same< KeyOfValueOption
+ , key_of_value<int_holder_key_of_value<typename Map::value_type> >
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same< key_of_value_t
+ , int_holder_key_of_value<typename Map::value_type>
+ >::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same< typename Map::key_type
+ , typename key_of_value_t::type >::value ));
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same< typename Map::key_of_value
+ , key_of_value_t >::value ));
+ static const bool value = true;
+};
+
+template <class Map>
+struct key_type_tester<void, Map>
+{
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same< typename Map::key_type
+ , typename Map::value_type
+ >::value ));
+
+ BOOST_STATIC_ASSERT(( boost::intrusive::detail::is_same< typename Map::key_of_value
+ , boost::intrusive::detail::identity< typename Map::value_type>
+ >::value ));
+ static const bool value = true;
+};
+
+} //namespace intrusive {
+} //namespace boost {
+
+#endif //BOOST_INTRUSIVE_TEST_TEST_COMMON_HPP
diff --git a/src/boost/libs/intrusive/test/test_container.hpp b/src/boost/libs/intrusive/test/test_container.hpp
new file mode 100644
index 00000000..6e98071f
--- /dev/null
+++ b/src/boost/libs/intrusive/test/test_container.hpp
@@ -0,0 +1,572 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_TEST_CONTAINER_HPP
+#define BOOST_INTRUSIVE_TEST_CONTAINER_HPP
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/simple_disposers.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/static_assert.hpp>
+#include "iterator_test.hpp"
+#include <cstdlib>
+
+namespace boost {
+namespace intrusive {
+namespace test {
+
+BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(is_unordered, hasher)
+
+template<class Container>
+struct test_container_typedefs
+{
+ typedef typename Container::value_type value_type;
+ typedef typename Container::iterator iterator;
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::reference reference;
+ typedef typename Container::const_reference const_reference;
+ typedef typename Container::pointer pointer;
+ typedef typename Container::const_pointer const_pointer;
+ typedef typename Container::difference_type difference_type;
+ typedef typename Container::size_type size_type;
+ typedef typename Container::value_traits value_traits;
+};
+
+template< class Container >
+void test_container( Container & c )
+{
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::iterator iterator;
+ typedef typename Container::size_type size_type;
+
+ {test_container_typedefs<Container> dummy; (void)dummy;}
+ const size_type num_elem = c.size();
+ BOOST_TEST( c.empty() == (num_elem == 0) );
+ {
+ iterator it(c.begin()), itend(c.end());
+ size_type i;
+ for(i = 0; i < num_elem; ++i){
+ ++it;
+ }
+ BOOST_TEST( it == itend );
+ BOOST_TEST( c.size() == i );
+ }
+
+ //Check iterator conversion
+ BOOST_TEST(const_iterator(c.begin()) == c.cbegin() );
+ {
+ const_iterator it(c.cbegin()), itend(c.cend());
+ size_type i;
+ for(i = 0; i < num_elem; ++i){
+ ++it;
+ }
+ BOOST_TEST( it == itend );
+ BOOST_TEST( c.size() == i );
+ }
+ static_cast<const Container&>(c).check();
+ //Very basic test for comparisons
+ {
+ BOOST_TEST(c == c);
+ BOOST_TEST(!(c != c));
+ BOOST_TEST(!(c < c));
+ BOOST_TEST(c <= c);
+ BOOST_TEST(!(c > c));
+ BOOST_TEST(c >= c);
+ }
+}
+
+
+template< class Container, class Data >
+void test_sequence_container(Container & c, Data & d)
+{
+ assert( d.size() > 2 );
+ {
+ c.clear();
+
+ BOOST_TEST( c.size() == 0 );
+ BOOST_TEST( c.empty() );
+
+
+ {
+ typename Data::iterator i = d.begin();
+ c.insert( c.begin(), *i );
+ BOOST_TEST( &*c.iterator_to(*c.begin()) == &*i );
+ BOOST_TEST( &*c.iterator_to(*c.cbegin()) == &*i );
+ BOOST_TEST( &*Container::s_iterator_to(*c.begin()) == &*i );
+ BOOST_TEST( &*Container::s_iterator_to(*c.cbegin()) == &*i );
+ c.insert( c.end(), *(++i) );
+ }
+ BOOST_TEST( c.size() == 2 );
+ BOOST_TEST( !c.empty() );
+
+ typename Container::iterator i;
+ i = c.erase( c.begin() );
+
+ BOOST_TEST( c.size() == 1 );
+ BOOST_TEST( !c.empty() );
+
+ i = c.erase( c.begin() );
+
+ BOOST_TEST( c.size() == 0 );
+ BOOST_TEST( c.empty() );
+
+ c.insert( c.begin(), *d.begin() );
+
+ BOOST_TEST( c.size() == 1 );
+ BOOST_TEST( !c.empty() );
+
+ {
+ typename Data::iterator di = d.begin();
+ ++++di;
+ c.insert( c.begin(), *(di) );
+ }
+
+ i = c.erase( c.begin(), c.end() );
+ BOOST_TEST( i == c.end() );
+
+ BOOST_TEST( c.empty() );
+
+ c.insert( c.begin(), *d.begin() );
+
+ BOOST_TEST( c.size() == 1 );
+
+ BOOST_TEST( c.begin() != c.end() );
+
+ i = c.erase_and_dispose( c.begin(), detail::null_disposer() );
+ BOOST_TEST( i == c.begin() );
+
+ c.assign(d.begin(), d.end());
+
+ BOOST_TEST( c.size() == d.size() );
+
+ c.clear();
+
+ BOOST_TEST( c.size() == 0 );
+ BOOST_TEST( c.empty() );
+ }
+ {
+ c.clear();
+ c.insert( c.begin(), d.begin(), d.end() );
+ Container move_c(::boost::move(c));
+ BOOST_TEST( move_c.size() == d.size() );
+ BOOST_TEST( c.empty());
+
+ c = ::boost::move(move_c);
+ BOOST_TEST( c.size() == d.size() );
+ BOOST_TEST( move_c.empty());
+ }
+}
+
+template< class Container, class Data >
+void test_common_unordered_and_associative_container(Container & c, Data & d, boost::intrusive::detail::true_ unordered)
+{
+ (void)unordered;
+ typedef typename Container::size_type size_type;
+ typedef typename Container::key_of_value key_of_value;
+ typedef typename Container::iterator iterator;
+ typedef typename Container::const_iterator const_iterator;
+
+ assert( d.size() > 2 );
+
+ c.clear();
+ c.insert(d.begin(), d.end());
+
+ {
+ Container const &cc = c;
+ for( typename Data::const_iterator di = d.begin(), de = d.end();
+ di != de; ++di )
+ {
+ BOOST_TEST( cc.find(key_of_value()(*di), c.hash_function(), c.key_eq()) != cc.end() );
+ std::pair<const_iterator, const_iterator> rdi = cc.equal_range(key_of_value()(*di), c.hash_function(), c.key_eq());
+ BOOST_TEST(rdi.first != rdi.second);
+ BOOST_TEST(size_type(boost::intrusive::iterator_distance(rdi.first, rdi.second)) == cc.count(key_of_value()(*di), c.hash_function(), c.key_eq()));
+ }
+
+ for( iterator ci = c.begin(), ce = c.end(); ci != ce; )
+ {
+ BOOST_TEST( c.find(key_of_value()(*ci)) != c.end() );
+ std::pair<iterator, iterator> rci = c.equal_range(key_of_value()(*ci), c.hash_function(), c.key_eq());
+ BOOST_TEST(rci.first != rci.second);
+ size_type const sc = c.count(key_of_value()(*ci), c.hash_function(), c.key_eq());
+ BOOST_TEST(size_type(boost::intrusive::iterator_distance(rci.first, rci.second)) == sc);
+ BOOST_TEST(sc == c.erase(key_of_value()(*ci), c.hash_function(), c.key_eq()));
+ ci = rci.second;
+ }
+ BOOST_TEST(c.empty());
+ }
+
+ c.clear();
+ c.insert(d.begin(), d.end());
+
+ typename Data::const_iterator db = d.begin();
+ typename Data::const_iterator da = db++;
+
+ size_type old_size = c.size();
+
+ c.erase(key_of_value()(*da), c.hash_function(), c.key_eq());
+ BOOST_TEST( c.size() == old_size-1 );
+ //This should not eras anyone
+ size_type second_erase = c.erase_and_dispose
+ ( key_of_value()(*da), c.hash_function(), c.key_eq(), detail::null_disposer() );
+ BOOST_TEST( second_erase == 0 );
+
+ BOOST_TEST( c.count(key_of_value()(*da), c.hash_function(), c.key_eq()) == 0 );
+ BOOST_TEST( c.count(key_of_value()(*db), c.hash_function(), c.key_eq()) != 0 );
+
+ BOOST_TEST( c.find(key_of_value()(*da), c.hash_function(), c.key_eq()) == c.end() );
+ BOOST_TEST( c.find(key_of_value()(*db), c.hash_function(), c.key_eq()) != c.end() );
+
+ BOOST_TEST( c.equal_range(key_of_value()(*db), c.hash_function(), c.key_eq()).first != c.end() );
+
+ c.clear();
+
+ BOOST_TEST( c.equal_range(key_of_value()(*da), c.hash_function(), c.key_eq()).first == c.end() );
+
+ //
+ //suggested_upper_bucket_count
+ //
+ //Maximum fallbacks to the highest possible value
+ typename Container::size_type sz = Container::suggested_upper_bucket_count(size_type(-1));
+ BOOST_TEST( sz > size_type(-1)/2 );
+ //In the rest of cases the upper bound is returned
+ sz = Container::suggested_upper_bucket_count(size_type(-1)/2);
+ BOOST_TEST( sz >= size_type(-1)/2 );
+ sz = Container::suggested_upper_bucket_count(size_type(-1)/4);
+ BOOST_TEST( sz >= size_type(-1)/4 );
+ sz = Container::suggested_upper_bucket_count(0);
+ BOOST_TEST( sz > 0 );
+ //
+ //suggested_lower_bucket_count
+ //
+ sz = Container::suggested_lower_bucket_count(size_type(-1));
+ BOOST_TEST( sz <= size_type(-1) );
+ //In the rest of cases the lower bound is returned
+ sz = Container::suggested_lower_bucket_count(size_type(-1)/2);
+ BOOST_TEST( sz <= size_type(-1)/2 );
+ sz = Container::suggested_lower_bucket_count(size_type(-1)/4);
+ BOOST_TEST( sz <= size_type(-1)/4 );
+ //Minimum fallbacks to the lowest possible value
+ sz = Container::suggested_upper_bucket_count(0);
+ BOOST_TEST( sz > 0 );
+}
+
+template< class Container, class Data >
+void test_common_unordered_and_associative_container(Container & c, Data & d, boost::intrusive::detail::false_ unordered)
+{
+ (void)unordered;
+ typedef typename Container::size_type size_type;
+ typedef typename Container::key_of_value key_of_value;
+ typedef typename Container::iterator iterator;
+ typedef typename Container::const_iterator const_iterator;
+
+ assert( d.size() > 2 );
+
+ c.clear();
+ typename Container::reference r = *d.begin();
+ c.insert(d.begin(), ++d.begin());
+ BOOST_TEST( &*Container::s_iterator_to(*c.begin()) == &r );
+ BOOST_TEST( &*Container::s_iterator_to(*c.cbegin()) == &r );
+
+ c.clear();
+ c.insert(d.begin(), d.end());
+ {
+ Container const &cc = c;
+ for( typename Data::const_iterator di = d.begin(), de = d.end();
+ di != de; ++di )
+ {
+ BOOST_TEST( cc.find(key_of_value()(*di), c.key_comp()) != cc.end() );
+ std::pair<const_iterator, const_iterator> rdi = cc.equal_range(key_of_value()(*di), c.key_comp());
+ BOOST_TEST(rdi.first != rdi.second);
+ BOOST_TEST(size_type(boost::intrusive::iterator_distance(rdi.first, rdi.second)) == cc.count(key_of_value()(*di), c.key_comp()));
+ }
+
+ for( iterator ci = c.begin(), ce = c.end(); ci != ce; )
+ {
+ BOOST_TEST( c.find(key_of_value()(*ci)) != c.end() );
+ std::pair<iterator, iterator> rci = c.equal_range(key_of_value()(*ci), c.key_comp());
+ BOOST_TEST(rci.first != rci.second);
+ size_type const sc = c.count(key_of_value()(*ci), c.key_comp());
+ BOOST_TEST(size_type(boost::intrusive::iterator_distance(rci.first, rci.second)) == sc);
+ BOOST_TEST(sc == c.erase(key_of_value()(*ci), c.key_comp()));
+ ci = rci.second;
+ }
+ BOOST_TEST(c.empty());
+ }
+
+ c.clear();
+ c.insert(d.begin(), d.end());
+
+ typename Data::const_iterator db = d.begin();
+ typename Data::const_iterator da = db++;
+
+ size_type old_size = c.size();
+
+ c.erase(key_of_value()(*da), c.key_comp());
+ BOOST_TEST( c.size() == old_size-1 );
+ //This should not erase any
+ size_type second_erase = c.erase_and_dispose( key_of_value()(*da), c.key_comp(), detail::null_disposer() );
+ BOOST_TEST( second_erase == 0 );
+
+ BOOST_TEST( c.count(key_of_value()(*da), c.key_comp()) == 0 );
+ BOOST_TEST( c.count(key_of_value()(*db), c.key_comp()) != 0 );
+ BOOST_TEST( c.find(key_of_value()(*da), c.key_comp()) == c.end() );
+ BOOST_TEST( c.find(key_of_value()(*db), c.key_comp()) != c.end() );
+ BOOST_TEST( c.equal_range(key_of_value()(*db), c.key_comp()).first != c.end() );
+ c.clear();
+ BOOST_TEST( c.equal_range(key_of_value()(*da), c.key_comp()).first == c.end() );
+}
+
+template< class Container, class Data >
+void test_common_unordered_and_associative_container(Container & c, Data & d)
+{
+ typedef typename Container::size_type size_type;
+ typedef typename Container::key_of_value key_of_value;
+ typedef typename Container::iterator iterator;
+ typedef typename Container::const_iterator const_iterator;
+
+ {
+ assert( d.size() > 2 );
+
+ c.clear();
+ typename Container::reference r = *d.begin();
+ c.insert(d.begin(), ++d.begin());
+ BOOST_TEST( &*c.iterator_to(*c.begin()) == &r );
+ BOOST_TEST( &*c.iterator_to(*c.cbegin()) == &r );
+
+ c.clear();
+ c.insert(d.begin(), d.end());
+
+ Container const &cc = c;
+ for( typename Data::const_iterator di = d.begin(), de = d.end();
+ di != de; ++di )
+ {
+ BOOST_TEST( cc.find(key_of_value()(*di)) != cc.end() );
+ std::pair<const_iterator, const_iterator> rdi = cc.equal_range(key_of_value()(*di));
+ BOOST_TEST(rdi.first != rdi.second);
+ BOOST_TEST(size_type(boost::intrusive::iterator_distance(rdi.first, rdi.second)) == cc.count(key_of_value()(*di)));
+ }
+
+ for( iterator ci = c.begin(), ce = c.end(); ci != ce; )
+ {
+ BOOST_TEST( c.find(key_of_value()(*ci)) != c.end() );
+ std::pair<iterator, iterator> rci = c.equal_range(key_of_value()(*ci));
+ BOOST_TEST(rci.first != rci.second);
+ size_type const sc = c.count(key_of_value()(*ci));
+ BOOST_TEST(size_type(boost::intrusive::iterator_distance(rci.first, rci.second)) == sc);
+ BOOST_TEST(sc == c.erase(key_of_value()(*ci)));
+ ci = rci.second;
+ }
+ BOOST_TEST(c.empty());
+ }
+ {
+ c.clear();
+ c.insert(d.begin(), d.end());
+
+ typename Data::const_iterator db = d.begin();
+ typename Data::const_iterator da = db++;
+
+ size_type old_size = c.size();
+
+ c.erase(key_of_value()(*da));
+ BOOST_TEST( c.size() == old_size-1 );
+ //This should erase nothing
+ size_type second_erase = c.erase_and_dispose( key_of_value()(*da), detail::null_disposer() );
+ BOOST_TEST( second_erase == 0 );
+
+ BOOST_TEST( c.count(key_of_value()(*da)) == 0 );
+ BOOST_TEST( c.count(key_of_value()(*db)) != 0 );
+
+ BOOST_TEST( c.find(key_of_value()(*da)) == c.end() );
+ BOOST_TEST( c.find(key_of_value()(*db)) != c.end() );
+
+ BOOST_TEST( c.equal_range(key_of_value()(*db)).first != c.end() );
+ BOOST_TEST( c.equal_range(key_of_value()(*da)).first == c.equal_range(key_of_value()(*da)).second );
+ }
+ {
+ c.clear();
+ c.insert( d.begin(), d.end() );
+ size_type orig_size = c.size();
+ Container move_c(::boost::move(c));
+ BOOST_TEST(orig_size == move_c.size());
+ BOOST_TEST( c.empty());
+ for( typename Data::const_iterator di = d.begin(), de = d.end();
+ di != de; ++di )
+ { BOOST_TEST( move_c.find(key_of_value()(*di)) != move_c.end() ); }
+
+ c = ::boost::move(move_c);
+ for( typename Data::const_iterator di = d.begin(), de = d.end();
+ di != de; ++di )
+ { BOOST_TEST( c.find(key_of_value()(*di)) != c.end() ); }
+ BOOST_TEST( move_c.empty());
+ }
+ typedef detail::bool_<is_unordered<Container>::value> enabler;
+ test_common_unordered_and_associative_container(c, d, enabler());
+}
+
+template< class Container, class Data >
+void test_associative_container_invariants(Container & c, Data & d)
+{
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::key_of_value key_of_value;
+ for( typename Data::const_iterator di = d.begin(), de = d.end();
+ di != de; ++di)
+ {
+ const_iterator ci = c.find(key_of_value()(*di));
+ BOOST_TEST( ci != c.end() );
+ BOOST_TEST( ! c.value_comp()(*ci, *di) );
+ BOOST_TEST( ! c.key_comp()(key_of_value()(*ci), key_of_value()(*di)) );
+ const_iterator cil = c.lower_bound(key_of_value()(*di));
+ const_iterator ciu = c.upper_bound(key_of_value()(*di));
+ std::pair<const_iterator, const_iterator> er = c.equal_range(key_of_value()(*di));
+ BOOST_TEST( cil == er.first );
+ BOOST_TEST( ciu == er.second );
+ if(ciu != c.end()){
+ BOOST_TEST( c.value_comp()(*cil, *ciu) );
+ BOOST_TEST( c.key_comp()(key_of_value()(*cil), key_of_value()(*ciu)) );
+ }
+ if(c.count(key_of_value()(*di)) > 1){
+ const_iterator ci_next = cil; ++ci_next;
+ for( ; ci_next != ciu; ++cil, ++ci_next){
+ BOOST_TEST( !c.value_comp()(*ci_next, *cil) );
+ BOOST_TEST( !c.key_comp()(key_of_value()(*ci_next), key_of_value()(*cil)) );
+ }
+ }
+ }
+}
+
+template< class Container, class Data >
+void test_associative_container(Container & c, Data & d)
+{
+ assert( d.size() > 2 );
+
+ c.clear();
+ c.insert(d.begin(),d.end());
+
+ test_associative_container_invariants(c, d);
+
+ const Container & cr = c;
+
+ test_associative_container_invariants(cr, d);
+}
+
+template< class Container, class Data >
+void test_unordered_associative_container_invariants(Container & c, Data & d)
+{
+ typedef typename Container::size_type size_type;
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::key_of_value key_of_value;
+
+ for( typename Data::const_iterator di = d.begin(), de = d.end() ;
+ di != de ; ++di ){
+ const_iterator i = c.find(key_of_value()(*di));
+ size_type nb = c.bucket(key_of_value()(*i));
+ size_type bucket_elem = boost::intrusive::iterator_distance(c.begin(nb), c.end(nb));
+ BOOST_TEST( bucket_elem == c.bucket_size(nb) );
+ BOOST_TEST( &*c.local_iterator_to(*c.find(key_of_value()(*di))) == &*i );
+ BOOST_TEST( &*c.local_iterator_to(*const_cast<const Container &>(c).find(key_of_value()(*di))) == &*i );
+ BOOST_TEST( &*Container::s_local_iterator_to(*c.find(key_of_value()(*di))) == &*i );
+ BOOST_TEST( &*Container::s_local_iterator_to(*const_cast<const Container &>(c).find(key_of_value()(*di))) == &*i );
+ std::pair<const_iterator, const_iterator> er = c.equal_range(key_of_value()(*di));
+ size_type cnt = boost::intrusive::iterator_distance(er.first, er.second);
+ BOOST_TEST( cnt == c.count(key_of_value()(*di)));
+ if(cnt > 1){
+ const_iterator n = er.first;
+ i = n++;
+ const_iterator e = er.second;
+ for(; n != e; ++i, ++n){
+ BOOST_TEST( c.key_eq()(key_of_value()(*i), key_of_value()(*n)) );
+ BOOST_TEST( (c.hash_function()(key_of_value()(*i))) == (c.hash_function()(key_of_value()(*n))) );
+ }
+ }
+ }
+
+ size_type blen = c.bucket_count();
+ size_type total_objects = 0;
+ for(size_type i = 0; i < blen; ++i){
+ total_objects += c.bucket_size(i);
+ }
+ BOOST_TEST( total_objects == c.size() );
+}
+
+template< class Container, class Data >
+void test_unordered_associative_container(Container & c, Data & d)
+{
+ c.clear();
+ c.insert( d.begin(), d.end() );
+
+ test_unordered_associative_container_invariants(c, d);
+
+ const Container & cr = c;
+
+ test_unordered_associative_container_invariants(cr, d);
+}
+
+template< class Container, class Data >
+void test_unique_container(Container & c, Data & d)
+{
+ //typedef typename Container::value_type value_type;
+ c.clear();
+ c.insert(d.begin(),d.end());
+ typename Container::size_type old_size = c.size();
+ //value_type v(*d.begin());
+ //c.insert(v);
+ Data d2(1);
+ (&d2.front())->value_ = (&d.front())->value_;
+ c.insert(d2.front());
+ BOOST_TEST( c.size() == old_size );
+ c.clear();
+}
+
+template< class Container, class Data >
+void test_non_unique_container(Container & c, Data & d)
+{
+ //typedef typename Container::value_type value_type;
+ c.clear();
+ c.insert(d.begin(),d.end());
+ typename Container::size_type old_size = c.size();
+ //value_type v(*d.begin());
+ //c.insert(v);
+ Data d2(1);
+ (&d2.front())->value_ = (&d.front())->value_;
+ c.insert(d2.front());
+ BOOST_TEST( c.size() == (old_size+1) );
+ c.clear();
+}
+
+template< class Container, class Data >
+void test_maybe_unique_container(Container & c, Data & d, detail::false_)//is_unique
+{ test_unique_container(c, d); }
+
+template< class Container, class Data >
+void test_maybe_unique_container(Container & c, Data & d, detail::true_)//!is_unique
+{ test_non_unique_container(c, d); }
+
+template< class RandomIt >
+void random_shuffle( RandomIt first, RandomIt last )
+{
+ typedef typename boost::intrusive::iterator_traits<RandomIt>::difference_type difference_type;
+ difference_type n = last - first;
+ for (difference_type i = n-1; i > 0; --i) {
+ difference_type j = std::rand() % (i+1);
+ if(j != i) {
+ boost::adl_move_swap(first[i], first[j]);
+ }
+ }
+}
+
+}}}
+
+#endif //#ifndef BOOST_INTRUSIVE_TEST_CONTAINER_HPP
diff --git a/src/boost/libs/intrusive/test/test_macros.hpp b/src/boost/libs/intrusive/test/test_macros.hpp
new file mode 100644
index 00000000..1f72d978
--- /dev/null
+++ b/src/boost/libs/intrusive/test/test_macros.hpp
@@ -0,0 +1,81 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2013
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_TEST_TEST_MACROS_HPP
+#define BOOST_INTRUSIVE_TEST_TEST_MACROS_HPP
+
+#include <boost/intrusive/intrusive_fwd.hpp>
+#include <algorithm> //std::unique
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+template <class T>
+struct is_multikey_true
+{
+ typedef char yes_type;
+ template<bool IsMultikey>
+ struct two { yes_type _[1+IsMultikey]; };
+ template <class U> static yes_type test(...);
+ template <class U> static two<U::is_multikey>test(int);
+ static const bool value = sizeof(test<T>(0)) != sizeof(yes_type);
+};
+
+} //namespace test{
+
+template<class It1, class It2>
+bool test_equal(It1 f1, It1 l1, It2 f2)
+{
+ while(f1 != l1){
+ if(*f1 != *f2){
+ return false;
+ }
+ ++f1;
+ ++f2;
+ }
+ return true;
+}
+
+#define TEST_INTRUSIVE_SEQUENCE( INTVALUES, ITERATOR )\
+{ \
+ BOOST_TEST (boost::intrusive::test_equal(&INTVALUES[0], &INTVALUES[0] + sizeof(INTVALUES)/sizeof(INTVALUES[0]), ITERATOR) ); \
+}
+
+#define TEST_INTRUSIVE_SEQUENCE_EXPECTED( EXPECTEDVECTOR, ITERATOR )\
+{ \
+ BOOST_TEST (boost::intrusive::test_equal(EXPECTEDVECTOR.begin(), EXPECTEDVECTOR.end(), ITERATOR) ); \
+}
+
+namespace test{
+
+template<class Container, class Vector>
+void test_intrusive_maybe_unique(const Container &c, Vector &v)
+{
+ if(!is_multikey_true<Container>::value)
+ v.erase(std::unique(v.begin(), v.end()), v.end());
+ BOOST_TEST (boost::intrusive::test_equal(v.begin(), v.end(), c.begin()) );
+}
+
+} //namespace test{
+
+#define TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE(INTVALUES, CONTAINER)\
+{\
+ boost::container::vector<int>v(&INTVALUES[0], &INTVALUES[0] + sizeof(INTVALUES)/sizeof(INTVALUES[0]));\
+ boost::intrusive::test::test_intrusive_maybe_unique(CONTAINER, v);\
+}\
+//
+
+} //namespace boost{
+} //namespace intrusive{
+
+#endif
diff --git a/src/boost/libs/intrusive/test/treap_multiset_test.cpp b/src/boost/libs/intrusive/test/treap_multiset_test.cpp
new file mode 100644
index 00000000..79d6e49b
--- /dev/null
+++ b/src/boost/libs/intrusive/test/treap_multiset_test.cpp
@@ -0,0 +1,157 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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 "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "bs_test_common.hpp"
+#include "generic_multiset_test.hpp"
+#include <boost/intrusive/treap_set.hpp>
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef treap_multiset
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , typename common_t::prio_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_multiset
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_multiset
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_multiset
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_multiset
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/treap_set_test.cpp b/src/boost/libs/intrusive/test/treap_set_test.cpp
new file mode 100644
index 00000000..f7987777
--- /dev/null
+++ b/src/boost/libs/intrusive/test/treap_set_test.cpp
@@ -0,0 +1,156 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2015
+//
+// 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 "itestvalue.hpp"
+#include "bptr_value.hpp"
+#include "smart_ptr.hpp"
+#include "bs_test_common.hpp"
+#include "generic_set_test.hpp"
+#include <boost/intrusive/treap_set.hpp>
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool DefaultHolder, bool Map >
+struct rebinder
+{
+ typedef tree_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef treap_set
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , typename common_t::prio_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits
+ >::type base_hook_t;
+ test::test_generic_set
+ < rebinder<base_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits
+ , typename testval_traits_t::auto_member_value_traits
+ >::type member_hook_t;
+ test::test_generic_set
+ < rebinder<member_hook_t, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue_traits< bs_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_generic_set
+ < rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, DefaultHolder, Map>
+ >::test_all();
+ }
+};
+
+template < bool ConstantTimeSize, bool Map >
+struct test_main_template_bptr
+{
+ static void execute()
+ {
+ typedef BPtr_Value_Traits< Tree_BPtr_Node_Traits > value_traits;
+ typedef bounded_allocator< BPtr_Value > allocator_type;
+
+ bounded_allocator_scope<allocator_type> bounded_scope; (void)bounded_scope;
+ test::test_generic_set
+ < rebinder< value_traits, ConstantTimeSize, true, Map>
+ >::test_all();
+ }
+};
+
+int main()
+{
+ //Combinations: VoidPointer x ConstantTimeSize x DefaultHolder x Map
+ //Minimize them selecting different combinations for raw and smart pointers
+ //Start with ('false', 'false', 'false') in sets and 'false', 'false', 'true' in multisets
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ //test_main_template<void*, false, false, true>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ //test_main_template<void*, false, true, true>::execute();
+ test_main_template<void*, true, false, false, Base>::execute();
+ //test_main_template<void*, true, false, true>::execute();
+ test_main_template<void*, true, true, false, Member>::execute();
+ test_main_template<void*, true, true, true, NonMember>::execute();
+
+ //smart_ptr
+ //test_main_template<smart_ptr<void>, false, false, false>::execute();
+ test_main_template<smart_ptr<void>, false, false, true, Base>::execute();
+ //test_main_template<smart_ptr<void>, false, true, false>::execute();
+ test_main_template<smart_ptr<void>, false, true, true, Member>::execute();
+ //test_main_template<smart_ptr<void>, true, false, false>::execute();
+ test_main_template<smart_ptr<void>, true, false, true, NonMember>::execute();
+ //test_main_template<smart_ptr<void>, true, true, false>::execute();
+ //test_main_template<smart_ptr<void>, true, true, true>::execute();
+
+ //bounded_ptr (bool ConstantTimeSize, bool Map)
+ test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/unordered_multiset_test.cpp b/src/boost/libs/intrusive/test/unordered_multiset_test.cpp
new file mode 100644
index 00000000..af872b3c
--- /dev/null
+++ b/src/boost/libs/intrusive/test/unordered_multiset_test.cpp
@@ -0,0 +1,167 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/pointer_traits.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <algorithm> //std::sort
+#include <set>
+#include <boost/detail/lightweight_test.hpp>
+
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include "unordered_test_common.hpp"
+#include "unordered_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool CacheBegin, bool CompareHash, bool Incremental, bool Map, bool DefaultHolder >
+struct rebinder
+{
+ typedef unordered_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef unordered_multiset
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , cache_begin<CacheBegin>
+ , compare_hash<CompareHash>
+ , incremental<Incremental>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ BOOST_STATIC_ASSERT((boost::intrusive::test::is_multikey_true<type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue<unordered_hooks<VoidPointer> > value_type;
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ typedef typename ValueContainer< value_type >::type value_cont_type;
+ value_cont_type data (6);
+ for (int i = 0; i < 6; ++i)
+ data[i].value_ = random_init[i];
+
+ typedef testvalue_traits< unordered_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits //store_hash<true>
+ >::type base_hook_t;
+ test::test_unordered
+ < //cache_begin, compare_hash, incremental
+ rebinder<base_hook_t, ConstantTimeSize, ConstantTimeSize, !ConstantTimeSize, !!ConstantTimeSize, Map, DefaultHolder>
+ >::test_all(data);
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue<unordered_hooks<VoidPointer> > value_type;
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ typedef typename ValueContainer< value_type >::type value_cont_type;
+ value_cont_type data (6);
+ for (int i = 0; i < 6; ++i)
+ data[i].value_ = random_init[i];
+
+ typedef testvalue_traits< unordered_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits //optimize_multikey<true>
+ , typename testval_traits_t::auto_member_value_traits //store_hash<true>, optimize_multikey<true>
+ >::type member_hook_t;
+ test::test_unordered
+ < //cache_begin, compare_hash, incremental
+ rebinder<member_hook_t, ConstantTimeSize, false, !ConstantTimeSize, false, !ConstantTimeSize, DefaultHolder>
+ >::test_all(data);
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue<unordered_hooks<VoidPointer> > value_type;
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ typedef typename ValueContainer< value_type >::type value_cont_type;
+ value_cont_type data (6);
+ for (int i = 0; i < 6; ++i)
+ data[i].value_ = random_init[i];
+
+ typedef testvalue_traits< unordered_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_unordered
+ < //cache_begin, compare_hash, incremental
+ rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, false, false, false, Map, DefaultHolder>
+ >::test_all(data);
+ }
+};
+
+int main()
+{
+ //VoidPointer x ConstantTimeSize x Map x DefaultHolder
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ test_main_template<void*, true, false, false, NonMember>::execute();
+ test_main_template<void*, true, true, false, Base>::execute();
+
+ //smart_ptr
+ test_main_template<smart_ptr<void>, false, false, false, Member>::execute();
+ test_main_template<smart_ptr<void>, false, true, false, NonMember>::execute();
+ test_main_template<smart_ptr<void>, true, false, false, Base>::execute();
+ test_main_template<smart_ptr<void>, true, true, false, Member>::execute();
+
+ ////bounded_ptr (bool ConstantTimeSize, bool Map)
+ //test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ //test_main_template_bptr< true, true >::execute();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/unordered_set_test.cpp b/src/boost/libs/intrusive/test/unordered_set_test.cpp
new file mode 100644
index 00000000..60e8d368
--- /dev/null
+++ b/src/boost/libs/intrusive/test/unordered_set_test.cpp
@@ -0,0 +1,167 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2015.
+//
+// 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/pointer_traits.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
+#include "itestvalue.hpp"
+#include "smart_ptr.hpp"
+#include "common_functors.hpp"
+#include <vector>
+#include <set>
+#include <boost/detail/lightweight_test.hpp>
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include "unordered_test_common.hpp"
+#include "unordered_test.hpp"
+
+using namespace boost::intrusive;
+
+template < class ValueTraits, bool ConstantTimeSize, bool CacheBegin, bool CompareHash, bool Incremental, bool Map, bool DefaultHolder >
+struct rebinder
+{
+ typedef unordered_rebinder_common<ValueTraits, DefaultHolder, Map> common_t;
+ typedef typename ValueContainer< typename ValueTraits::value_type >::type value_cont_type;
+
+ template < class Option1 =void
+ , class Option2 =void
+ >
+ struct container
+ {
+ typedef unordered_set
+ < typename common_t::value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<ConstantTimeSize>
+ , cache_begin<CacheBegin>
+ , compare_hash<CompareHash>
+ , incremental<Incremental>
+ , typename common_t::holder_opt
+ , typename common_t::key_of_value_opt
+ , size_type<unsigned short>
+ , Option1
+ , Option2
+ > type;
+ BOOST_STATIC_ASSERT((key_type_tester<typename common_t::key_of_value_opt, type>::value));
+ BOOST_STATIC_ASSERT((!boost::intrusive::test::is_multikey_true<type>::value));
+ };
+};
+
+enum HookType
+{
+ Base,
+ Member,
+ NonMember
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map, HookType Type>
+class test_main_template;
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Base>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue<unordered_hooks<VoidPointer> > value_type;
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ typedef typename ValueContainer< value_type >::type value_cont_type;
+ value_cont_type data (6);
+ for (int i = 0; i < 6; ++i)
+ data[i].value_ = random_init[i];
+
+ typedef testvalue_traits< unordered_hooks<VoidPointer> > testval_traits_t;
+ //base
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::base_value_traits
+ , typename testval_traits_t::auto_base_value_traits //store_hash<true>
+ >::type base_hook_t;
+ test::test_unordered
+ < //cache_begin, compare_hash, incremental
+ rebinder<base_hook_t, ConstantTimeSize, ConstantTimeSize, !ConstantTimeSize, !!ConstantTimeSize, Map, DefaultHolder>
+ >::test_all(data);
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, Member>
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue<unordered_hooks<VoidPointer> > value_type;
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ typedef typename ValueContainer< value_type >::type value_cont_type;
+ value_cont_type data (6);
+ for (int i = 0; i < 6; ++i)
+ data[i].value_ = random_init[i];
+
+ typedef testvalue_traits< unordered_hooks<VoidPointer> > testval_traits_t;
+ //member
+ typedef typename detail::if_c
+ < ConstantTimeSize
+ , typename testval_traits_t::member_value_traits //optimize_multikey<true>
+ , typename testval_traits_t::auto_member_value_traits //store_hash<true>, optimize_multikey<true>
+ >::type member_hook_t;
+ test::test_unordered
+ < //cache_begin, compare_hash, incremental
+ rebinder<member_hook_t, ConstantTimeSize, false, !ConstantTimeSize, false, !ConstantTimeSize, DefaultHolder>
+ >::test_all(data);
+ }
+};
+
+template<class VoidPointer, bool ConstantTimeSize, bool DefaultHolder, bool Map>
+class test_main_template<VoidPointer, ConstantTimeSize, DefaultHolder, Map, NonMember>
+
+{
+ public:
+ static void execute()
+ {
+ typedef testvalue<unordered_hooks<VoidPointer> > value_type;
+ static const int random_init[6] = { 3, 2, 4, 1, 5, 2 };
+ typedef typename ValueContainer< value_type >::type value_cont_type;
+ value_cont_type data (6);
+ for (int i = 0; i < 6; ++i)
+ data[i].value_ = random_init[i];
+
+ typedef testvalue_traits< unordered_hooks<VoidPointer> > testval_traits_t;
+ //nonmember
+ test::test_unordered
+ < //cache_begin, compare_hash, incremental
+ rebinder<typename testval_traits_t::nonhook_value_traits, ConstantTimeSize, false, false, false, Map, DefaultHolder>
+ >::test_all(data);
+ }
+};
+
+int main()
+{
+ //VoidPointer x ConstantTimeSize x Map x DefaultHolder
+
+ //void pointer
+ test_main_template<void*, false, false, false, Base>::execute();
+ test_main_template<void*, false, true, false, Member>::execute();
+ test_main_template<void*, true, false, false, NonMember>::execute();
+ test_main_template<void*, true, true, false, Base>::execute();
+
+ //smart_ptr
+ test_main_template<smart_ptr<void>, false, false, false, Member>::execute();
+ test_main_template<smart_ptr<void>, false, true, false, NonMember>::execute();
+ test_main_template<smart_ptr<void>, true, false, false, Base>::execute();
+ test_main_template<smart_ptr<void>, true, true, false, Member>::execute();
+
+ ////bounded_ptr (bool ConstantTimeSize, bool Map)
+ //test_main_template_bptr< false, false >::execute();
+ //test_main_template_bptr< false, true >::execute();
+ //test_main_template_bptr< true, false >::execute();
+ //test_main_template_bptr< true, true >::execute();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/intrusive/test/unordered_test.hpp b/src/boost/libs/intrusive/test/unordered_test.hpp
new file mode 100644
index 00000000..29bd7056
--- /dev/null
+++ b/src/boost/libs/intrusive/test/unordered_test.hpp
@@ -0,0 +1,751 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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/pointer_traits.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
+#include "common_functors.hpp"
+#include <vector>
+#include <algorithm> //std::sort
+#include <set>
+#include <boost/detail/lightweight_test.hpp>
+
+#include "test_macros.hpp"
+#include "test_container.hpp"
+#include "unordered_test_common.hpp"
+
+namespace boost{
+namespace intrusive{
+namespace test{
+
+static const std::size_t BucketSize = 8;
+
+template<class ContainerDefiner>
+struct test_unordered
+{
+ typedef typename ContainerDefiner::value_cont_type value_cont_type;
+
+ static void test_all(value_cont_type& values);
+ private:
+ static void test_sort(value_cont_type& values);
+ static void test_insert(value_cont_type& values, detail::true_);
+ static void test_insert(value_cont_type& values, detail::false_);
+ static void test_swap(value_cont_type& values);
+ static void test_rehash(value_cont_type& values, detail::true_);
+ static void test_rehash(value_cont_type& values, detail::false_);
+ static void test_find(value_cont_type& values);
+ static void test_impl();
+ static void test_clone(value_cont_type& values);
+};
+
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_all (value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+ {
+ typename unordered_type::bucket_type buckets [BucketSize];
+ unordered_type testset
+ (bucket_traits(pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize));
+ testset.insert(values.begin(), values.end());
+ test::test_container(testset);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_common_unordered_and_associative_container(testset, values);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ test::test_unordered_associative_container(testset, values);
+ testset.clear();
+ testset.insert(values.begin(), values.end());
+ typedef detail::bool_<boost::intrusive::test::is_multikey_true
+ <unordered_type>::value> select_t;
+ test::test_maybe_unique_container(testset, values, select_t());
+ }
+ {
+ value_cont_type vals(BucketSize);
+ for (int i = 0; i < (int)BucketSize; ++i)
+ (&vals[i])->value_ = i;
+ typename unordered_type::bucket_type buckets [BucketSize];
+ unordered_type testset(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize));
+ testset.insert(vals.begin(), vals.end());
+ test::test_iterator_forward(testset);
+ }
+ test_sort(values);
+ test_insert(values, detail::bool_<boost::intrusive::test::is_multikey_true<unordered_type>::value>());
+ test_swap(values);
+ test_rehash(values, detail::bool_<unordered_type::incremental>());
+ test_find(values);
+ test_impl();
+ test_clone(values);
+}
+
+//test case due to an error in tree implementation:
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_impl()
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+
+ value_cont_type values (5);
+ for (int i = 0; i < 5; ++i)
+ values[i].value_ = i;
+
+ typename unordered_type::bucket_type buckets [BucketSize];
+ unordered_type testset(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize));
+
+ for (int i = 0; i < 5; ++i)
+ testset.insert (values[i]);
+
+ testset.erase (testset.iterator_to (values[0]));
+ testset.erase (testset.iterator_to (values[1]));
+ testset.insert (values[1]);
+
+ testset.erase (testset.iterator_to (values[2]));
+ testset.erase (testset.iterator_to (values[3]));
+}
+
+//test: constructor, iterator, clear, reverse_iterator, front, back, size:
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_sort(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+
+ typename unordered_type::bucket_type buckets [BucketSize];
+ unordered_type testset1
+ (values.begin(), values.end(), bucket_traits
+ (pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize));
+
+ if(unordered_type::incremental){
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+ }
+ else{
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+ }
+ testset1.clear();
+ BOOST_TEST (testset1.empty());
+}
+
+//test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_insert(value_cont_type& values, detail::false_) //not multikey
+{
+
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_set_type;
+ typedef typename unordered_set_type::bucket_traits bucket_traits;
+ typedef typename unordered_set_type::key_of_value key_of_value;
+
+ typename unordered_set_type::bucket_type buckets [BucketSize];
+ unordered_set_type testset(bucket_traits(
+ pointer_traits<typename unordered_set_type::bucket_ptr>::
+ pointer_to(buckets[0]), BucketSize));
+ testset.insert(&values[0] + 2, &values[0] + 5);
+
+ typename unordered_set_type::insert_commit_data commit_data;
+ BOOST_TEST ((!testset.insert_check(key_of_value()(values[2]), commit_data).second));
+ BOOST_TEST (( testset.insert_check(key_of_value()(values[0]), commit_data).second));
+
+ const unordered_set_type& const_testset = testset;
+ if(unordered_set_type::incremental)
+ {
+ { int init_values [] = { 4, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+ typename unordered_set_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 4);
+
+ i = testset.insert(values[0]).first;
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+
+ testset.erase (i);
+
+ { int init_values [] = { 5, 1, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+ }
+ else{
+ { int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+ typename unordered_set_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 1);
+
+ i = testset.insert(values[0]).first;
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+
+ testset.erase (i);
+
+ { int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+ }
+}
+
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_insert(value_cont_type& values, detail::true_) //is multikey
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+ typedef typename unordered_type::iterator iterator;
+ typedef typename unordered_type::key_type key_type;
+ {
+ typename unordered_type::bucket_type buckets [BucketSize];
+ unordered_type testset(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize));
+
+ testset.insert(&values[0] + 2, &values[0] + 5);
+
+ const unordered_type& const_testset = testset;
+
+ if(unordered_type::incremental){
+ {
+ { int init_values [] = { 4, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+
+ typename unordered_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 4);
+
+ i = testset.insert (values[0]);
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+ testset.erase(i);
+
+ { int init_values [] = { 5, 1, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+ testset.clear();
+ testset.insert(&values[0], &values[0] + values.size());
+
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+
+ BOOST_TEST (testset.erase(key_type(1)) == 1);
+ BOOST_TEST (testset.erase(key_type(2)) == 2);
+ BOOST_TEST (testset.erase(key_type(3)) == 1);
+ BOOST_TEST (testset.erase(key_type(4)) == 1);
+ BOOST_TEST (testset.erase(key_type(5)) == 1);
+ BOOST_TEST (testset.empty() == true);
+
+ //Now with a single bucket
+ typename unordered_type::bucket_type single_bucket[1];
+ unordered_type testset2(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(single_bucket[0]), 1));
+ testset2.insert(&values[0], &values[0] + values.size());
+ BOOST_TEST (testset2.erase(key_type(5)) == 1);
+ BOOST_TEST (testset2.erase(key_type(2)) == 2);
+ BOOST_TEST (testset2.erase(key_type(1)) == 1);
+ BOOST_TEST (testset2.erase(key_type(4)) == 1);
+ BOOST_TEST (testset2.erase(key_type(3)) == 1);
+ BOOST_TEST (testset2.empty() == true);
+ }
+ }
+ else{
+ {
+ { int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+
+ typename unordered_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 1);
+
+ i = testset.insert (values[0]);
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+ testset.erase(i);
+
+ { int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+ testset.clear();
+ testset.insert(&values[0], &values[0] + values.size());
+
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, const_testset ); }
+
+ BOOST_TEST (testset.erase(key_type(1)) == 1);
+ BOOST_TEST (testset.erase(key_type(2)) == 2);
+ BOOST_TEST (testset.erase(key_type(3)) == 1);
+ BOOST_TEST (testset.erase(key_type(4)) == 1);
+ BOOST_TEST (testset.erase(key_type(5)) == 1);
+ BOOST_TEST (testset.empty() == true);
+
+ //Now with a single bucket
+ typename unordered_type::bucket_type single_bucket[1];
+ unordered_type testset2(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(single_bucket[0]), 1));
+ testset2.insert(&values[0], &values[0] + values.size());
+ BOOST_TEST (testset2.erase(key_type(5)) == 1);
+ BOOST_TEST (testset2.erase(key_type(2)) == 2);
+ BOOST_TEST (testset2.erase(key_type(1)) == 1);
+ BOOST_TEST (testset2.erase(key_type(4)) == 1);
+ BOOST_TEST (testset2.erase(key_type(3)) == 1);
+ BOOST_TEST (testset2.empty() == true);
+ }
+ }
+ {
+ //Now erase just one per loop
+ const int random_init[] = { 3, 2, 4, 1, 5, 2, 2 };
+ const unsigned int random_size = sizeof(random_init)/sizeof(random_init[0]);
+ typename unordered_type::bucket_type single_bucket[1];
+ for(unsigned int i = 0, max = random_size; i != max; ++i){
+ value_cont_type data (random_size);
+ for (unsigned int j = 0; j < random_size; ++j)
+ data[j].value_ = random_init[j];
+ unordered_type testset_new(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(single_bucket[0]), 1));
+ testset_new.insert(&data[0], &data[0]+max);
+ testset_new.erase(testset_new.iterator_to(data[i]));
+ BOOST_TEST (testset_new.size() == (max -1));
+ }
+ }
+ }
+ {
+ const unsigned int LoadFactor = 3;
+ const unsigned int NumIterations = BucketSize*LoadFactor;
+ value_cont_type random_init(NumIterations);//Preserve memory
+ value_cont_type set_tester;
+ set_tester.reserve(NumIterations);
+
+ //Initialize values
+ for (unsigned int i = 0; i < NumIterations; ++i){
+ random_init[i].value_ = i*2;//(i/LoadFactor)*LoadFactor;
+ }
+
+ typename unordered_type::bucket_type buckets [BucketSize];
+ bucket_traits btraits(pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize);
+
+ for(unsigned int initial_pos = 0; initial_pos != (NumIterations+1); ++initial_pos){
+ for(unsigned int final_pos = initial_pos; final_pos != (NumIterations+1); ++final_pos){
+
+ //Create intrusive container inserting values
+ unordered_type testset
+ ( random_init.data()
+ , random_init.data() + random_init.size()
+ , btraits);
+
+ BOOST_TEST (testset.size() == random_init.size());
+
+ //Obtain the iterator range to erase
+ iterator it_beg_pos = testset.begin();
+ for(unsigned int it_beg_pos_num = 0; it_beg_pos_num != initial_pos; ++it_beg_pos_num){
+ ++it_beg_pos;
+ }
+ iterator it_end_pos(it_beg_pos);
+ for(unsigned int it_end_pos_num = 0; it_end_pos_num != (final_pos - initial_pos); ++it_end_pos_num){
+ ++it_end_pos;
+ }
+
+ //Erase the same values in both the intrusive and original vector
+ std::size_t erased_cnt = boost::intrusive::iterator_distance(it_beg_pos, it_end_pos);
+
+ //Erase values from the intrusive container
+ testset.erase(it_beg_pos, it_end_pos);
+
+ BOOST_TEST (testset.size() == (random_init.size()-(final_pos - initial_pos)));
+
+ //Now test...
+ BOOST_TEST ((random_init.size() - erased_cnt) == testset.size());
+
+ //Create an ordered copy of the intrusive container
+ set_tester.insert(set_tester.end(), testset.begin(), testset.end());
+ std::sort(set_tester.begin(), set_tester.end());
+ {
+ typename value_cont_type::iterator it = set_tester.begin(), itend = set_tester.end();
+ typename value_cont_type::iterator random_init_it(random_init.begin());
+ for( ; it != itend; ++it){
+ while(!random_init_it->is_linked())
+ ++random_init_it;
+ BOOST_TEST(*it == *random_init_it);
+ ++random_init_it;
+ }
+ }
+ set_tester.clear();
+ }
+ }
+ }
+}
+
+//test: insert (seq-version), swap, erase (seq-version), size:
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_swap(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+ typename unordered_type::bucket_type buckets [BucketSize];
+
+ typename unordered_type::bucket_type buckets2 [BucketSize];
+ unordered_type testset1(&values[0], &values[0] + 2,
+ bucket_traits(pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize));
+ unordered_type testset2(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets2[0]), BucketSize));
+
+ testset2.insert (&values[0] + 2, &values[0] + 6);
+ testset1.swap (testset2);
+
+ if(unordered_type::incremental){
+ { int init_values [] = { 4, 5, 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ { int init_values [] = { 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset2 ); }
+ testset1.erase (testset1.iterator_to(values[4]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ // BOOST_TEST (&testset1.front() == &values[3]);
+ BOOST_TEST (&*testset1.begin() == &values[2]);
+ }
+ else{
+ { int init_values [] = { 1, 2, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ { int init_values [] = { 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset2 ); }
+ testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ // BOOST_TEST (&testset1.front() == &values[3]);
+ BOOST_TEST (&*testset1.begin() == &values[3]);
+ }
+}
+
+
+
+//test: rehash:
+
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_rehash(value_cont_type& values, detail::true_)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+ //Build a uset
+ typename unordered_type::bucket_type buckets1 [BucketSize];
+ typename unordered_type::bucket_type buckets2 [BucketSize*2];
+ unordered_type testset1(&values[0], &values[0] + values.size(),
+ bucket_traits(pointer_traits<bucket_ptr>::
+ pointer_to(buckets1[0]), BucketSize));
+ //Test current state
+ BOOST_TEST(testset1.split_count() == BucketSize/2);
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+ //Incremental rehash step
+ BOOST_TEST (testset1.incremental_rehash() == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+ { int init_values [] = { 5, 1, 2, 2, 3, 4 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+ //Rest of incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket != BucketSize; ++split_bucket){
+ BOOST_TEST (testset1.incremental_rehash() == true);
+ BOOST_TEST(testset1.split_count() == (split_bucket+1));
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+ }
+ //This incremental rehash should fail because we've reached the end of the bucket array
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+ //
+ //This incremental rehash should fail because the new size is not twice the original
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets1[0]), BucketSize)) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //
+ //Try incremental hashing specifying a new bucket traits pointing to the same array
+ //
+ //This incremental rehash should fail because the new size is not twice the original
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets2[0]), BucketSize)) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //This incremental rehash should success because the new size is twice the original
+ //and split_count is the same as the old bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets2[0]), BucketSize*2)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //This incremental rehash should also success because the new size is half the original
+ //and split_count is the same as the new bucket count
+ BOOST_TEST(testset1.incremental_rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets1[0]), BucketSize)) == true);
+ BOOST_TEST(testset1.split_count() == BucketSize);
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Shrink rehash
+ testset1.rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets1[0]), 4));
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Shrink rehash again
+ testset1.rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets1[0]), 2));
+ BOOST_TEST (testset1.incremental_rehash() == false);
+ { int init_values [] = { 2, 2, 4, 3, 5, 1 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Growing rehash
+ testset1.rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets1[0]), BucketSize));
+
+ //Full rehash (no effects)
+ testset1.full_rehash();
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Incremental rehash shrinking
+ //First incremental rehashes should lead to the same sequence
+ for(std::size_t split_bucket = testset1.split_count(); split_bucket > 6; --split_bucket){
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (split_bucket-1));
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+ }
+
+ //Incremental rehash step
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2+1));
+ { int init_values [] = { 5, 1, 2, 2, 3, 4 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Incremental rehash step 2
+ BOOST_TEST (testset1.incremental_rehash(false) == true);
+ BOOST_TEST(testset1.split_count() == (BucketSize/2));
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //This incremental rehash should fail because we've reached the half of the bucket array
+ BOOST_TEST(testset1.incremental_rehash(false) == false);
+ BOOST_TEST(testset1.split_count() == BucketSize/2);
+ { int init_values [] = { 4, 5, 1, 2, 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+}
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_rehash(value_cont_type& values, detail::false_)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+
+ typename unordered_type::bucket_type buckets1 [BucketSize];
+ typename unordered_type::bucket_type buckets2 [2];
+ typename unordered_type::bucket_type buckets3 [BucketSize*2];
+
+ unordered_type testset1(&values[0], &values[0] + 6, bucket_traits(
+ pointer_traits<bucket_ptr>::
+ pointer_to(buckets1[0]), BucketSize));
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ testset1.rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets2[0]), 2));
+ { int init_values [] = { 4, 2, 2, 5, 3, 1 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ testset1.rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets3[0]), BucketSize*2));
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Now rehash reducing the buckets
+ testset1.rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets3[0]), 2));
+ { int init_values [] = { 4, 2, 2, 5, 3, 1 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Now rehash increasing the buckets
+ testset1.rehash(bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets3[0]), BucketSize*2));
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+
+ //Full rehash (no effects)
+ testset1.full_rehash();
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
+}
+
+//test: find, equal_range (lower_bound, upper_bound):
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_find(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+ typedef typename unordered_type::value_type value_type;
+
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+ typedef typename unordered_type::key_of_value key_of_value;
+ const bool is_multikey = boost::intrusive::test::is_multikey_true<unordered_type>::value;
+
+ typename unordered_type::bucket_type buckets[BucketSize];
+ unordered_type testset(values.begin(), values.end(), bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets[0]), BucketSize));
+
+ typedef typename unordered_type::iterator iterator;
+
+ value_type cmp_val;
+ cmp_val.value_ = 2;
+ BOOST_TEST (testset.count(key_of_value()(cmp_val)) == (is_multikey ? 2 : 1));
+ iterator i = testset.find (key_of_value()(cmp_val));
+ BOOST_TEST (i->value_ == 2);
+ if(is_multikey)
+ BOOST_TEST ((++i)->value_ == 2);
+ else
+ BOOST_TEST ((++i)->value_ != 2);
+ std::pair<iterator,iterator> range = testset.equal_range (key_of_value()(cmp_val));
+
+ BOOST_TEST (range.first->value_ == 2);
+ BOOST_TEST (range.second->value_ == 3);
+ BOOST_TEST (boost::intrusive::iterator_distance (range.first, range.second) == (is_multikey ? 2 : 1));
+ cmp_val.value_ = 7;
+ BOOST_TEST (testset.find (key_of_value()(cmp_val)) == testset.end());
+ BOOST_TEST (testset.count(key_of_value()(cmp_val)) == 0);
+}
+
+
+template<class ContainerDefiner>
+void test_unordered<ContainerDefiner>::test_clone(value_cont_type& values)
+{
+ typedef typename ContainerDefiner::template container
+ <>::type unordered_type;
+ typedef typename unordered_type::value_type value_type;
+ typedef std::multiset<value_type> std_multiset_t;
+
+ typedef typename unordered_type::bucket_traits bucket_traits;
+ typedef typename unordered_type::bucket_ptr bucket_ptr;
+
+ {
+ //Test with equal bucket arrays
+ typename unordered_type::bucket_type buckets1 [BucketSize];
+ typename unordered_type::bucket_type buckets2 [BucketSize];
+ unordered_type testset1 (values.begin(), values.end(), bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets1[0]), BucketSize));
+ unordered_type testset2 (bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets2[0]), BucketSize));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST(testset1 == testset2);
+ //Ordering is not guarantee in the cloning so insert data in a set and test
+ std_multiset_t src(testset1.begin(), testset1.end());
+ std_multiset_t dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+
+ testset2.clone_from(boost::move(testset1), test::new_nonconst_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST(testset1 == testset2);
+ //Ordering is not guarantee in the cloning so insert data in a set and test
+ std_multiset_t(testset1.begin(), testset1.end()).swap(src);
+ std_multiset_t(testset2.begin(), testset2.end()).swap(dst);
+ BOOST_TEST(src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+ }
+ {
+ //Test with bigger source bucket arrays
+ typename unordered_type::bucket_type buckets1 [BucketSize*2];
+ typename unordered_type::bucket_type buckets2 [BucketSize];
+ unordered_type testset1 (values.begin(), values.end(), bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets1[0]), BucketSize*2));
+ unordered_type testset2 (bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets2[0]), BucketSize));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST(testset1 == testset2);
+ //Ordering is not guarantee in the cloning so insert data in a set and test
+ std_multiset_t src(testset1.begin(), testset1.end());
+ std_multiset_t dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+
+ testset2.clone_from(boost::move(testset1), test::new_nonconst_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST(testset1 == testset2);
+ //Ordering is not guarantee in the cloning so insert data in a set and test
+ std_multiset_t(testset1.begin(), testset1.end()).swap(src);
+ std_multiset_t(testset2.begin(), testset2.end()).swap(dst);
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+ }
+ {
+ //Test with smaller source bucket arrays
+ typename unordered_type::bucket_type buckets1 [BucketSize];
+ typename unordered_type::bucket_type buckets2 [BucketSize*2];
+ unordered_type testset1 (values.begin(), values.end(), bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets1[0]), BucketSize));
+ unordered_type testset2 (bucket_traits(
+ pointer_traits<bucket_ptr>::pointer_to(buckets2[0]), BucketSize*2));
+
+ testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST(testset1 == testset2);
+ //Ordering is not guaranteed in the cloning so insert data in a set and test
+ std_multiset_t src(testset1.begin(), testset1.end());
+ std_multiset_t dst(testset2.begin(), testset2.end());
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+
+ testset2.clone_from(boost::move(testset1), test::new_nonconst_cloner<value_type>(), test::delete_disposer<value_type>());
+ BOOST_TEST(testset1 == testset2);
+ //Ordering is not guaranteed in the cloning so insert data in a set and test
+ std_multiset_t(testset1.begin(), testset1.end()).swap(src);
+ std_multiset_t(testset2.begin(), testset2.end()).swap(dst);
+ BOOST_TEST (src.size() == dst.size() && std::equal(src.begin(), src.end(), dst.begin()));
+ testset2.clear_and_dispose(test::delete_disposer<value_type>());
+ BOOST_TEST (testset2.empty());
+ }
+}
+
+} //namespace test{
+} //namespace intrusive{
+} //namespace boost{
diff --git a/src/boost/libs/intrusive/test/unordered_test_common.hpp b/src/boost/libs/intrusive/test/unordered_test_common.hpp
new file mode 100644
index 00000000..385b39df
--- /dev/null
+++ b/src/boost/libs/intrusive/test/unordered_test_common.hpp
@@ -0,0 +1,69 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_TEST_UNORDERED_TEST_COMMON_HPP
+#define BOOST_INTRUSIVE_TEST_UNORDERED_TEST_COMMON_HPP
+
+#include <boost/intrusive/unordered_set_hook.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+#include "bptr_value.hpp"
+#include "test_common.hpp"
+
+namespace boost {
+namespace intrusive {
+
+template<class VoidPointer>
+struct unordered_hooks
+{
+ typedef unordered_set_base_hook<void_pointer<VoidPointer> > base_hook_type;
+ typedef unordered_set_base_hook
+ < link_mode<auto_unlink>
+ , void_pointer<VoidPointer>
+ , tag<void>
+ , store_hash<true>
+ > auto_base_hook_type;
+
+ typedef unordered_set_member_hook
+ < void_pointer<VoidPointer>
+ , optimize_multikey<true>
+ > member_hook_type;
+ typedef unordered_set_member_hook
+ < link_mode<auto_unlink>, void_pointer<VoidPointer>
+ , store_hash<true>
+ , optimize_multikey<true>
+ > auto_member_hook_type;
+ typedef nonhook_node_member< unordered_node_traits< VoidPointer, true, true >,
+ unordered_algorithms
+ > nonhook_node_member_type;
+};
+
+template < class ValueTraits, bool DefaultHolder, bool Map >
+struct unordered_rebinder_common
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef typename detail::if_c
+ < DefaultHolder
+ , typename detail::if_c
+ < detail::is_same<value_type, BPtr_Value>::value
+ , header_holder_type< bounded_pointer_holder< BPtr_Value > >
+ , void
+ >::type
+ , header_holder_type< heap_node_holder< typename ValueTraits::node_ptr > >
+ >::type holder_opt;
+ typedef typename detail::if_c
+ < Map, key_of_value<int_holder_key_of_value<value_type> >, void
+ >::type key_of_value_opt;
+};
+
+} //namespace intrusive {
+} //namespace boost {
+
+#endif //BOOST_INTRUSIVE_TEST_UNORDERED_TEST_COMMON_HPP
diff --git a/src/boost/libs/intrusive/test/virtual_base_test.cpp b/src/boost/libs/intrusive/test/virtual_base_test.cpp
new file mode 100644
index 00000000..b1b25925
--- /dev/null
+++ b/src/boost/libs/intrusive/test/virtual_base_test.cpp
@@ -0,0 +1,100 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013
+//
+// 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
+{
+ protected:
+ NonVirtualBase()
+ : dummy()
+ {}
+
+ //<-
+ const int *get_dummy() const { return dummy; }
+ //->
+
+ private:
+ int dummy[10];
+};
+
+class MyClass
+ : public NonVirtualBase
+ , public virtual VirtualBase3
+{
+ int int_;
+
+ public:
+ list_member_hook<> list_hook_;
+ MyClass(int i = 0)
+ : int_(i)
+ {}
+ //<-
+ int get_int() const { return int_; }
+ //->
+};
+
+//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()
+{
+ #ifndef _MSC_VER
+ 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;
+ }
+ #endif
+ return 0;
+}
diff --git a/src/boost/libs/intrusive/test/voidptr_key_test.cpp b/src/boost/libs/intrusive/test/voidptr_key_test.cpp
new file mode 100644
index 00000000..c6055999
--- /dev/null
+++ b/src/boost/libs/intrusive/test/voidptr_key_test.cpp
@@ -0,0 +1,94 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Andrey Semashev 2018.
+//
+// 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/options.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/set_hook.hpp>
+#include <boost/config.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <functional> // std::less
+
+// The test verifies that the set implementation does not use void* as auxiliary arguments for SFINAE
+// in internal functions, which would make overload resolution ambiguous if user's key type is also void*.
+
+typedef boost::intrusive::set_base_hook<
+ boost::intrusive::link_mode< boost::intrusive::safe_link >,
+ boost::intrusive::tag< struct for_set_element_lookup_by_key >,
+ boost::intrusive::optimize_size< true >
+> set_element_hook_t;
+
+struct set_element :
+ public set_element_hook_t
+{
+ struct order_by_key
+ {
+ typedef bool result_type;
+
+ result_type operator() (set_element const& left, set_element const& right) const
+ {
+ return std::less< void* >()(left.m_key, right.m_key);
+ }
+ result_type operator() (void* left, set_element const& right) const
+ {
+ return std::less< void* >()(left, right.m_key);
+ }
+ result_type operator() (set_element const& left, void* right) const
+ {
+ return std::less< void* >()(left.m_key, right);
+ }
+ };
+
+ void* m_key;
+
+ explicit set_element(void* key) : m_key(key) {}
+
+ BOOST_DELETED_FUNCTION(set_element(set_element const&))
+ BOOST_DELETED_FUNCTION(set_element& operator=(set_element const&))
+};
+
+typedef boost::intrusive::set<
+ set_element,
+ boost::intrusive::base_hook< set_element_hook_t >,
+ boost::intrusive::compare< set_element::order_by_key >,
+ boost::intrusive::constant_time_size< true >
+> set_t;
+
+void test_set()
+{
+ int v1 = 0, v2 = 1, v3 = 2;
+ set_element e1(&v1), e2(&v2), e3(&v3);
+
+ set_t s;
+ s.insert(e1);
+ s.insert(e2);
+
+ set_t::iterator it = s.find(e1);
+ BOOST_TEST(it != s.end() && &*it == &e1);
+
+ it = s.find((void*)&v2, set_element::order_by_key());
+ BOOST_TEST(it != s.end() && &*it == &e2);
+
+ it = s.find(e3);
+ BOOST_TEST(it == s.end());
+
+ it = s.find((void*)&v3, set_element::order_by_key());
+ BOOST_TEST(it == s.end());
+
+ s.clear();
+}
+
+int main()
+{
+ test_set();
+
+ return boost::report_errors();
+}