From 80b509ee2dcf01354d85ed089d61859be13b0372 Mon Sep 17 00:00:00 2001 From: Matei David Date: Fri, 16 May 2014 10:58:20 -0400 Subject: [PATCH] lib: fix proxy-reference-unfriendly method in node_cloner --- include/boost/intrusive/detail/utilities.hpp | 13 +- test/generic_assoc_test.hpp | 186 ++++++++++++------- test/generic_multiset_test.hpp | 70 +++---- test/generic_set_test.hpp | 92 ++++----- test/multiset_test.cpp | 112 +++++++++-- test/set_test.cpp | 111 +++++++++-- test/test_container.hpp | 18 +- 7 files changed, 430 insertions(+), 172 deletions(-) diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index b11c89c..86e3c7c 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -239,14 +239,25 @@ struct node_cloner typedef typename real_value_traits::pointer pointer; typedef typename node_traits::node node; typedef typename real_value_traits::const_node_ptr const_node_ptr; + typedef typename real_value_traits::reference reference; + typedef typename real_value_traits::const_reference const_reference; node_cloner(F f, const RealValueTraits *traits) : base_t(f), traits_(traits) {} + // tree-based containers use this method, which is proxy-reference friendly node_ptr operator()(const node_ptr & p) - { return this->operator()(*p); } + { + const_reference v = *traits_->to_value_ptr(p); + node_ptr n = traits_->to_node_ptr(*base_t::get()(v)); + //Cloned node must be in default mode if the linking mode requires it + if(safemode_or_autounlink) + BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n)); + return n; + } + // hashtables use this method, which is proxy-reference unfriendly node_ptr operator()(const node &to_clone) { const value_type &v = diff --git a/test/generic_assoc_test.hpp b/test/generic_assoc_test.hpp index 6b01749..6dbae8a 100644 --- a/test/generic_assoc_test.hpp +++ b/test/generic_assoc_test.hpp @@ -75,35 +75,41 @@ template& values); - static void test_clone(std::vector& values); + typedef typename Value_Container< value_type >::type value_cont_type; + typedef typename ValueTraits::reference reference; + typedef typename ValueTraits::const_reference const_reference; + static void test_all(value_cont_type& values); + static void test_clone(value_cont_type& values); static void test_insert_erase_burst(); - static void test_container_from_end(std::vector& values); - static void test_splay_up(std::vector& values); - static void test_splay_up(std::vector& values, boost::intrusive::detail::true_type); - static void test_splay_up(std::vector& values, boost::intrusive::detail::false_type); - static void test_splay_down(std::vector& values); - static void test_splay_down(std::vector& values, boost::intrusive::detail::true_type); - static void test_splay_down(std::vector& values, boost::intrusive::detail::false_type); - static void test_rebalance(std::vector& values); - static void test_rebalance(std::vector& values, boost::intrusive::detail::true_type); - static void test_rebalance(std::vector& values, boost::intrusive::detail::false_type); - static void test_insert_before(std::vector& values); - static void test_insert_before(std::vector& values, boost::intrusive::detail::true_type); - static void test_insert_before(std::vector& values, boost::intrusive::detail::false_type); - static void test_container_from_iterator(std::vector& values); + static void test_container_from_end(value_cont_type& values); + static void test_splay_up(value_cont_type& values); + static void test_splay_up(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_splay_up(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_splay_down(value_cont_type& values); + static void test_splay_down(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_splay_down(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_rebalance(value_cont_type& values); + static void test_rebalance(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_rebalance(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_insert_before(value_cont_type& values); + static void test_insert_before(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_insert_before(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_container_from_iterator(value_cont_type& values); }; -template class ContainerDefiner> -void test_generic_assoc:: - test_container_from_iterator(std::vector& values) +template < bool Has_Container_From_Iterator, typename assoc_type, typename Value_Container > +struct test_container_from_iterator_impl +{ + void operator () (Value_Container&) + { + std::clog << "skipping test_container_from_iterator\n"; + } +}; +template < typename assoc_type, typename Value_Container > +struct test_container_from_iterator_impl< true, assoc_type, Value_Container > +{ + void operator () (Value_Container& values) { - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::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; @@ -121,16 +127,30 @@ void test_generic_assoc:: BOOST_TEST(testset.size() == sz); } } +}; + +template class ContainerDefiner> +void test_generic_assoc:: + test_container_from_iterator(value_cont_type& values) +{ + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + test_container_from_iterator_impl< assoc_type::has_container_from_iterator, assoc_type, value_cont_type >()(values); +} template class ContainerDefiner> void test_generic_assoc::test_insert_erase_burst() { typedef typename ValueTraits::value_type value_type; - std::vector values; + //value_cont_type values; const int MaxValues = 100; + value_cont_type values(MaxValues); for(int i = 0; i != MaxValues; ++i){ - values.push_back(value_type(i)); + (&values[i])->value_ = i; } typedef typename ContainerDefiner @@ -141,7 +161,7 @@ void test_generic_assoc::test_insert_erase_burst( typedef typename assoc_type::iterator iterator; //First ordered insertions - assoc_type testset (&values[0], &values[0] + values.size()); + assoc_type testset (values.begin(), values.begin() + values.size()); TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin()); //Ordered erasure @@ -157,13 +177,11 @@ void test_generic_assoc::test_insert_erase_burst( //Now random insertions std::random_shuffle(values.begin(), values.end()); - testset.insert(&values[0], &values[0] + values.size()); - std::vector values_ordered(values); - std::sort(values_ordered.begin(), values_ordered.end()); + testset.insert(values.begin(), values.begin() + values.size()); TEST_INTRUSIVE_SEQUENCE_EXPECTED(testset, testset.begin()); { - typedef typename std::vector::const_iterator cvec_iterator; + typedef typename value_cont_type::const_iterator cvec_iterator; //Random erasure std::vector it_vector; @@ -182,7 +200,7 @@ void test_generic_assoc::test_insert_erase_burst( } template class ContainerDefiner> -void test_generic_assoc::test_all(std::vector& values) +void test_generic_assoc::test_all(value_cont_type& values) { test_clone(values); test_container_from_end(values); @@ -194,18 +212,28 @@ void test_generic_assoc::test_all(std::vector class ContainerDefiner> -void test_generic_assoc - ::test_clone(std::vector& values) +template < bool Has_Value_Allocator, typename assoc_type, typename value_cont_type > +struct test_clone_impl { - typedef typename ValueTraits::value_type value_type; - typedef typename ContainerDefiner - < value_type - , value_traits - , constant_time_size - >::type assoc_type; +void operator () (value_cont_type& values) +{ + assoc_type testset1 (values.begin(), values.begin() + values.size()); + assoc_type testset2; - assoc_type testset1 (&values[0], &values[0] + values.size()); + testset2.clone_from(testset1); + BOOST_TEST (testset2 == testset1); + testset2.clear_and_dispose(); + BOOST_TEST (testset2.empty()); +} +}; + +template < typename assoc_type, typename value_cont_type > +struct test_clone_impl< false, assoc_type, value_cont_type > +{ +void operator () (value_cont_type& values) +{ + typedef typename assoc_type::value_type value_type; + assoc_type testset1 (values.begin(), values.begin() + values.size()); assoc_type testset2; testset2.clone_from(testset1, test::new_cloner(), test::delete_disposer()); @@ -213,10 +241,11 @@ void test_generic_assoc testset2.clear_and_dispose(test::delete_disposer()); BOOST_TEST (testset2.empty()); } +}; template class ContainerDefiner> void test_generic_assoc - ::test_container_from_end(std::vector& values) + ::test_clone(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -224,14 +253,45 @@ void test_generic_assoc , value_traits , constant_time_size >::type assoc_type; - assoc_type testset (&values[0], &values[0] + values.size()); + + test_clone_impl< assoc_type::has_value_allocator, assoc_type, value_cont_type >()(values); +} + +template < bool Has_Container_From_Iterator, typename assoc_type, typename value_cont_type > +struct test_container_from_end_impl +{ + void operator () (value_cont_type&) + { + std::clog << "skipping test_container_from_end\n"; + } +}; +template < typename assoc_type, typename value_cont_type > +struct test_container_from_end_impl< true, assoc_type, value_cont_type > +{ + void operator () (value_cont_type& values) +{ + 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 + ::test_container_from_end(value_cont_type& values) +{ + typedef typename ValueTraits::value_type value_type; + typedef typename ContainerDefiner + < value_type + , value_traits + , constant_time_size + >::type assoc_type; + test_container_from_end_impl< assoc_type::has_container_from_iterator, assoc_type, value_cont_type >()(values); +} template class ContainerDefiner> void test_generic_assoc::test_splay_up -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -240,7 +300,7 @@ void test_generic_assoc::test_splay_up , constant_time_size >::type assoc_type; typedef typename assoc_type::iterator iterator; - typedef std::vector orig_set_t; + typedef value_cont_type orig_set_t; std::size_t num_values; orig_set_t original_testset; { @@ -269,12 +329,12 @@ void test_generic_assoc::test_splay_up template class ContainerDefiner> void test_generic_assoc::test_splay_up -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_splay_up -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type @@ -288,7 +348,7 @@ void test_generic_assoc::test_splay_up template class ContainerDefiner> void test_generic_assoc::test_splay_down -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -297,7 +357,7 @@ void test_generic_assoc::test_splay_down , constant_time_size >::type assoc_type; typedef typename assoc_type::iterator iterator; - typedef std::vector orig_set_t; + typedef value_cont_type orig_set_t; std::size_t num_values; orig_set_t original_testset; { @@ -327,12 +387,12 @@ void test_generic_assoc::test_splay_down template class ContainerDefiner> void test_generic_assoc::test_splay_down -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_splay_down -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type @@ -346,7 +406,7 @@ void test_generic_assoc::test_splay_down template class ContainerDefiner> void test_generic_assoc::test_rebalance -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -354,7 +414,7 @@ void test_generic_assoc::test_rebalance , value_traits , constant_time_size >::type assoc_type; - typedef std::vector orig_set_t; + typedef value_cont_type orig_set_t; orig_set_t original_testset; { assoc_type testset (values.begin(), values.end()); @@ -385,12 +445,12 @@ void test_generic_assoc::test_rebalance template class ContainerDefiner> void test_generic_assoc::test_rebalance -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_rebalance -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type @@ -404,7 +464,7 @@ void test_generic_assoc::test_rebalance template class ContainerDefiner> void test_generic_assoc::test_insert_before -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -414,7 +474,7 @@ void test_generic_assoc::test_insert_before >::type assoc_type; { assoc_type testset; - typedef typename std::vector::iterator vec_iterator; + typedef typename value_cont_type::iterator vec_iterator; for(vec_iterator it(values.begin()), itend(values.end()) ; it != itend ; ++it){ @@ -425,7 +485,7 @@ void test_generic_assoc::test_insert_before } { assoc_type testset; - typedef typename std::vector::iterator vec_iterator; + typedef typename value_cont_type::iterator vec_iterator; for(vec_iterator it(--values.end()); true; --it){ testset.push_front(*it); @@ -438,7 +498,7 @@ void test_generic_assoc::test_insert_before } { assoc_type testset; - typedef typename std::vector::iterator vec_iterator; + 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()); @@ -454,12 +514,12 @@ void test_generic_assoc::test_insert_before template class ContainerDefiner> void test_generic_assoc::test_insert_before -(std::vector&, boost::intrusive::detail::false_type) +(value_cont_type&, boost::intrusive::detail::false_type) {} template class ContainerDefiner> void test_generic_assoc::test_insert_before -(std::vector& values) +(value_cont_type& values) { typedef typename ContainerDefiner < value_type diff --git a/test/generic_multiset_test.hpp b/test/generic_multiset_test.hpp index 81a0c27..fe3800d 100644 --- a/test/generic_multiset_test.hpp +++ b/test/generic_multiset_test.hpp @@ -27,11 +27,14 @@ template::type value_cont_type; + typedef typename ValueTraits::reference reference; + typedef typename ValueTraits::const_reference const_reference; static void test_all (); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); + static void test_sort(value_cont_type& values); + static void test_insert(value_cont_type& values); + static void test_swap(value_cont_type& values); + static void test_find(value_cont_type& values); static void test_impl(); }; @@ -40,9 +43,9 @@ void test_generic_multiset::test_all () { typedef typename ValueTraits::value_type value_type; static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector values (6); + value_cont_type values (6); for (int i = 0; i < 6; ++i) - values[i].value_ = random_init[i]; + (&values[i])->value_ = random_init[i]; typedef typename ContainerDefiner < value_type @@ -75,9 +78,9 @@ template::test_impl() { typedef typename ValueTraits::value_type value_type; - std::vector values (5); + value_cont_type values (5); for (int i = 0; i < 5; ++i) - values[i].value_ = i; + (&values[i])->value_ = i; typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner < value_type @@ -99,7 +102,7 @@ void test_generic_multiset::test_impl() //test: constructor, iterator, clear, reverse_iterator, front, back, size: template class ContainerDefiner> -void test_generic_multiset::test_sort(std::vector& values) +void test_generic_multiset::test_sort(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -121,7 +124,7 @@ void test_generic_multiset::test_sort(std::vector , value_traits , constant_time_size >::type multiset_type2; - multiset_type2 testset2 (&values[0], &values[0] + 6); + multiset_type2 testset2 (values.begin(), values.begin() + 6); { int init_values [] = { 5, 3, 1, 4, 2, 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testset2.rbegin() ); } @@ -131,7 +134,7 @@ void test_generic_multiset::test_sort(std::vector //test: insert, const_iterator, const_reverse_iterator, erase, iterator_to: template class ContainerDefiner> -void test_generic_multiset::test_insert(std::vector& values) +void test_generic_multiset::test_insert(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -142,7 +145,7 @@ void test_generic_multiset::test_insert(std::vect >::type multiset_type; multiset_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); + testset.insert(values.begin() + 2, values.begin() + 5); { int init_values [] = { 1, 4, 5 }; TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } @@ -169,7 +172,7 @@ void test_generic_multiset::test_insert(std::vect //test: insert (seq-version), swap, erase (seq-version), size: template class ContainerDefiner> -void test_generic_multiset::test_swap(std::vector& values) +void test_generic_multiset::test_swap(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -178,9 +181,9 @@ void test_generic_multiset::test_swap(std::vector , size_type , constant_time_size >::type multiset_type; - multiset_type testset1 (&values[0], &values[0] + 2); + multiset_type testset1 (values.begin(), values.begin() + 2); multiset_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); + testset2.insert (values.begin() + 2, values.begin() + 6); testset1.swap (testset2); { int init_values [] = { 1, 2, 4, 5 }; @@ -195,7 +198,7 @@ void test_generic_multiset::test_swap(std::vector //test: find, equal_range (lower_bound, upper_bound): template class ContainerDefiner> -void test_generic_multiset::test_find(std::vector& values) +void test_generic_multiset::test_find(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -208,8 +211,9 @@ void test_generic_multiset::test_find(std::vector typedef typename multiset_type::iterator iterator; { - value_type cmp_val; - cmp_val.value_ = 2; + value_cont_type cmp_val_cont(1); + reference cmp_val = cmp_val_cont.front(); + (&cmp_val)->value_ = 2; iterator i = testset.find (cmp_val); BOOST_TEST (i->value_ == 2); BOOST_TEST ((++i)->value_ == 2); @@ -219,7 +223,7 @@ void test_generic_multiset::test_find(std::vector BOOST_TEST (range.second->value_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 2); - cmp_val.value_ = 7; + (&cmp_val)->value_ = 7; BOOST_TEST (testset.find (cmp_val) == testset.end()); } { //1, 2, 2, 3, 4, 5 @@ -227,10 +231,12 @@ void test_generic_multiset::test_find(std::vector std::pair range; std::pair::type ,typename search_const_iterator::type> 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; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; //left-closed, right-closed range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, true); BOOST_TEST (range.first->value_ == 1); @@ -238,39 +244,39 @@ void test_generic_multiset::test_find(std::vector BOOST_TEST (std::distance (range.first, range.second) == 3); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 1); BOOST_TEST (const_range.second->value_ == 2); BOOST_TEST (std::distance (const_range.first, const_range.second) == 1); - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 3; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 3; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (range.first->value_ == 1); BOOST_TEST (range.second->value_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 3); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, false, true); BOOST_TEST (const_range.first->value_ == 2); BOOST_TEST (const_range.second->value_ == 3); BOOST_TEST (std::distance (const_range.first, const_range.second) == 2); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, false, false); BOOST_TEST (range.first->value_ == 2); BOOST_TEST (range.second->value_ == 2); BOOST_TEST (std::distance (range.first, range.second) == 0); } { - cmp_val_lower.value_ = 5; - cmp_val_upper.value_ = 6; + (&cmp_val_lower)->value_ = 5; + (&cmp_val_upper)->value_ = 6; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 5); BOOST_TEST (const_range.second == const_testset.end()); diff --git a/test/generic_set_test.hpp b/test/generic_set_test.hpp index 2a46ba9..cf132a2 100644 --- a/test/generic_set_test.hpp +++ b/test/generic_set_test.hpp @@ -33,14 +33,17 @@ template::type value_cont_type; + typedef typename ValueTraits::reference reference; + typedef typename ValueTraits::const_reference const_reference; static void test_all(); - static void test_sort(std::vector& values); - static void test_insert(std::vector& values); - static void test_insert_advanced(std::vector& values, boost::intrusive::detail::true_type); - static void test_insert_advanced(std::vector& values, boost::intrusive::detail::false_type); - static void test_insert_advanced(std::vector& values); - static void test_swap(std::vector& values); - static void test_find(std::vector& values); + static void test_sort(value_cont_type& values); + static void test_insert(value_cont_type& values); + static void test_insert_advanced(value_cont_type& values, boost::intrusive::detail::true_type); + static void test_insert_advanced(value_cont_type& values, boost::intrusive::detail::false_type); + static void test_insert_advanced(value_cont_type& values); + static void test_swap(value_cont_type& values); + static void test_find(value_cont_type& values); static void test_impl(); }; @@ -50,9 +53,9 @@ void test_generic_set::test_all() { typedef typename ValueTraits::value_type value_type; static const int random_init[6] = { 3, 2, 4, 1, 5, 2 }; - std::vector values (6); + value_cont_type values(6); for (int i = 0; i < 6; ++i) - values[i].value_ = random_init[i]; + (&values[i])->value_ = random_init[i]; typedef typename ContainerDefiner < value_type @@ -86,9 +89,9 @@ template::test_impl() { typedef typename ValueTraits::value_type value_type; - std::vector values (5); + value_cont_type values (5); for (int i = 0; i < 5; ++i) - values[i].value_ = i; + (&values[i])->value_ = i; typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -110,7 +113,7 @@ void test_generic_set::test_impl() //test: constructor, iterator, clear, reverse_iterator, front, back, size: template class ContainerDefiner> -void test_generic_set::test_sort(std::vector& values) +void test_generic_set::test_sort(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -132,7 +135,7 @@ void test_generic_set::test_sort(std::vector , constant_time_size >::type set_type2; - set_type2 testset2 (&values[0], &values[0] + 6); + 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); @@ -141,7 +144,7 @@ void test_generic_set::test_sort(std::vector class ContainerDefiner> -void test_generic_set::test_insert(std::vector& values) +void test_generic_set::test_insert(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -151,7 +154,7 @@ void test_generic_set::test_insert(std::vector::type set_type; { set_type testset; - testset.insert(&values[0] + 2, &values[0] + 5); + testset.insert(values.begin() + 2, values.begin() + 5); const set_type& const_testset = testset; { int init_values [] = { 1, 4, 5 }; @@ -173,9 +176,9 @@ void test_generic_set::test_insert(std::vector(values[2])); + ic = testset.iterator_to (static_cast< const_reference >(values[2])); BOOST_TEST (&*ic == &values[2]); - ic = set_type::s_iterator_to (const_cast(values[2])); + ic = set_type::s_iterator_to (static_cast< const_reference >(values[2])); BOOST_TEST (&*ic == &values[2]); testset.erase (i); @@ -186,7 +189,7 @@ void test_generic_set::test_insert(std::vector class ContainerDefiner> void test_generic_set::test_insert_advanced -(std::vector& values, boost::intrusive::detail::true_type) +(value_cont_type& values, boost::intrusive::detail::true_type) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -196,7 +199,7 @@ void test_generic_set::test_insert_advanced >::type set_type; { set_type testset; - testset.insert(&values[0], &values[0] + values.size()); + testset.insert(values.begin(), values.begin() + values.size()); value_type v(1); typename set_type::insert_commit_data data; BOOST_TEST (!testset.insert_check(v, testset.value_comp(), testset.priority_comp(), data).second); @@ -207,7 +210,7 @@ void test_generic_set::test_insert_advanced template class ContainerDefiner> void test_generic_set::test_insert_advanced -(std::vector& values) +(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -224,7 +227,7 @@ void test_generic_set::test_insert_advanced //test: insert, const_iterator, const_reverse_iterator, erase, s_iterator_to: template class ContainerDefiner> void test_generic_set::test_insert_advanced - ( std::vector& values + ( value_cont_type& values , boost::intrusive::detail::false_type) { typedef typename ValueTraits::value_type value_type; @@ -235,7 +238,7 @@ void test_generic_set::test_insert_advanced >::type set_type; { set_type testset; - testset.insert(&values[0], &values[0] + values.size()); + testset.insert(values.begin(), values.begin() + values.size()); value_type v(1); typename set_type::insert_commit_data data; BOOST_TEST (!testset.insert_check(v, testset.value_comp(), data).second); @@ -246,7 +249,7 @@ void test_generic_set::test_insert_advanced //test: insert (seq-version), swap, erase (seq-version), size: template class ContainerDefiner> -void test_generic_set::test_swap(std::vector& values) +void test_generic_set::test_swap(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -254,9 +257,9 @@ void test_generic_set::test_swap(std::vector , constant_time_size >::type set_type; - set_type testset1 (&values[0], &values[0] + 2); + set_type testset1 (values.begin(), values.begin() + 2); set_type testset2; - testset2.insert (&values[0] + 2, &values[0] + 6); + testset2.insert (values.begin() + 2, values.begin() + 6); testset1.swap (testset2); { int init_values [] = { 1, 2, 4, 5 }; @@ -273,7 +276,7 @@ void test_generic_set::test_swap(std::vector class ContainerDefiner> -void test_generic_set::test_find(std::vector& values) +void test_generic_set::test_find(value_cont_type& values) { typedef typename ValueTraits::value_type value_type; typedef typename ContainerDefiner @@ -285,8 +288,10 @@ void test_generic_set::test_find(std::vectorvalue_ = 2; iterator i = testset.find (cmp_val); BOOST_TEST (i->value_ == 2); BOOST_TEST ((++i)->value_ != 2); @@ -296,7 +301,7 @@ void test_generic_set::test_find(std::vectorvalue_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 1); - cmp_val.value_ = 7; + (&cmp_val)->value_ = 7; BOOST_TEST (testset.find (cmp_val) == testset.end()); } @@ -305,10 +310,13 @@ void test_generic_set::test_find(std::vector range; std::pair::type ,typename search_const_iterator::type> const_range; - value_type cmp_val_lower, cmp_val_upper; + //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; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; //left-closed, right-closed range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, true); BOOST_TEST (range.first->value_ == 1); @@ -316,39 +324,39 @@ void test_generic_set::test_find(std::vectorvalue_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 1); BOOST_TEST (const_range.second->value_ == 2); BOOST_TEST (std::distance (const_range.first, const_range.second) == 1); - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 3; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 3; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (range.first->value_ == 1); BOOST_TEST (range.second->value_ == 3); BOOST_TEST (std::distance (range.first, range.second) == 2); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, false, true); BOOST_TEST (const_range.first->value_ == 2); BOOST_TEST (const_range.second->value_ == 3); BOOST_TEST (std::distance (const_range.first, const_range.second) == 1); } { - cmp_val_lower.value_ = 1; - cmp_val_upper.value_ = 2; + (&cmp_val_lower)->value_ = 1; + (&cmp_val_upper)->value_ = 2; range = testset.bounded_range (cmp_val_lower, cmp_val_upper, false, false); BOOST_TEST (range.first->value_ == 2); BOOST_TEST (range.second->value_ == 2); BOOST_TEST (std::distance (range.first, range.second) == 0); } { - cmp_val_lower.value_ = 5; - cmp_val_upper.value_ = 6; + (&cmp_val_lower)->value_ = 5; + (&cmp_val_upper)->value_ = 6; const_range = const_testset.bounded_range (cmp_val_lower, cmp_val_upper, true, false); BOOST_TEST (const_range.first->value_ == 5); BOOST_TEST (const_range.second == const_testset.end()); diff --git a/test/multiset_test.cpp b/test/multiset_test.cpp index dd52cfe..2a38dcd 100644 --- a/test/multiset_test.cpp +++ b/test/multiset_test.cpp @@ -13,6 +13,7 @@ #include #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_multiset_test.hpp" @@ -59,6 +60,10 @@ struct hooks > nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Void_Allocator > +struct GetContainer_With_Allocator +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -73,8 +78,36 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Allocator< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::multiset + < ValueType + , Option1 + , Option2 + , Option3 + , node_allocator_type< std::allocator< node > > + > type; +}; +}; + + +template class test_main_template { public: @@ -87,7 +120,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits < value_type @@ -96,21 +129,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -122,7 +155,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -132,14 +165,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_multiset < typename detail::get_member_value_traits @@ -149,18 +182,69 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Allocator > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::multiset< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + node_allocator_type< Allocator > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< RBTree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_multiset< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, allocator_type >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; + int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // 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/test/set_test.cpp b/test/set_test.cpp index 8d5c490..8a2c3c6 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -14,6 +14,7 @@ #include #include "itestvalue.hpp" +#include "bptr_value.hpp" #include "smart_ptr.hpp" #include "generic_set_test.hpp" @@ -60,6 +61,10 @@ struct hooks > nonhook_node_member_type; }; +// container generator with void node allocator +template < bool Void_Allocator > +struct GetContainer_With_Allocator +{ template< class ValueType , class Option1 =void , class Option2 =void @@ -74,8 +79,36 @@ struct GetContainer , Option3 > type; }; +}; -template +// container generator with standard (non-void) node allocator +template <> +struct GetContainer_With_Allocator< false > +{ +template< class ValueType + , class Option1 =void + , class Option2 =void + , class Option3 =void + > +struct GetContainer +{ + // extract node type through options->value_traits->node_traits->node + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename detail::get_value_traits< ValueType, typename packed_options::proto_value_traits>::type value_traits; + typedef typename value_traits::node_traits::node node; + + typedef boost::intrusive::set + < ValueType + , Option1 + , Option2 + , Option3 + , node_allocator_type< std::allocator< node > > + > type; +}; +}; + + +template class test_main_template { public: @@ -88,7 +121,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits < value_type @@ -97,21 +130,21 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < nonhook_node_member_value_traits< value_type, typename hooks::nonhook_node_member_type, &value_type::nhn_member_, safe_link >, - GetContainer + GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; -template -class test_main_template +template +class test_main_template { public: int operator()() @@ -123,7 +156,7 @@ class test_main_template < value_type , typename hooks::base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -133,14 +166,14 @@ class test_main_template , &value_type::node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_base_value_traits < value_type , typename hooks::auto_base_hook_type >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); test::test_generic_set < typename detail::get_member_value_traits @@ -150,20 +183,70 @@ class test_main_template , &value_type::auto_node_ > >::type - , GetContainer + , GetContainer_With_Allocator< Void_Allocator >::template GetContainer >::test_all(); return 0; } }; +// container generator which ignores further parametrization, except for compare option +template < typename Value_Traits, bool Constant_Time_Size, typename Allocator > +struct Get_Preset_Container +{ + template < class + , class Option1 = void + , class Option2 = void + , class Option3 = void + > + struct GetContainer + { + // ignore further paramatrization except for the compare option + // notably ignore the size option (use preset) + typedef typename pack_options< rbtree_defaults, Option1, Option2, Option3 >::type packed_options; + typedef typename packed_options::compare compare_option; + + typedef boost::intrusive::set< typename Value_Traits::value_type, + value_traits< Value_Traits >, + constant_time_size< Constant_Time_Size >, + compare< compare_option >, + node_allocator_type< Allocator > + > type; + }; +}; + +template < bool Constant_Time_Size > +struct test_main_template_bptr +{ + void operator () () + { + typedef BPtr_Value value_type; + typedef BPtr_Value_Traits< RBTree_BPtr_Node_Traits > value_traits; + typedef Bounded_Allocator< value_type > allocator_type; + + allocator_type::init(); + test::test_generic_set< value_traits, + Get_Preset_Container< value_traits, Constant_Time_Size, allocator_type >::template GetContainer + >::test_all(); + assert(allocator_type::is_clear()); + allocator_type::destroy(); + } +}; int main( int, char* [] ) { - test_main_template()(); - test_main_template, false>()(); - test_main_template()(); - test_main_template, true>()(); + // test (plain/smart pointers) x (nonconst/const size) x (void node allocator) + test_main_template()(); + test_main_template, false, true>()(); + test_main_template()(); + test_main_template, true, true>()(); + // test (plain pointers) x (nonconst/const size) x (standard node allocator) + test_main_template()(); + test_main_template()(); + // 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/test/test_container.hpp b/test/test_container.hpp index 2bacb16..fbddaec 100644 --- a/test/test_container.hpp +++ b/test/test_container.hpp @@ -428,12 +428,15 @@ void test_unordered_associative_container(Container & c, Data & d) template< class Container, class Data > void test_unique_container(Container & c, Data & d) { - typedef typename Container::value_type value_type; + //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); + //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(); } @@ -441,12 +444,15 @@ void test_unique_container(Container & c, Data & d) template< class Container, class Data > void test_non_unique_container(Container & c, Data & d) { - typedef typename Container::value_type value_type; + //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); + //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(); }