////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2004-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/container for documentation. // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include "print_container.hpp" #include "movable_int.hpp" #include "dummy_test_allocator.hpp" #include "set_test.hpp" #include "propagate_allocator_test.hpp" #include "emplace_test.hpp" using namespace boost::container; namespace boost { namespace container { //Explicit instantiation to detect compilation errors //set template class set < test::movable_and_copyable_int , std::less , test::dummy_test_allocator >; template class set < test::movable_and_copyable_int , std::less , test::simple_allocator >; template class set < test::movable_and_copyable_int , std::less , std::allocator >; template class set < test::movable_and_copyable_int , std::less , allocator >; template class set < test::movable_and_copyable_int , std::less , adaptive_pool >; template class set < test::movable_and_copyable_int , std::less , node_allocator >; //multiset template class multiset < test::movable_and_copyable_int , std::less , test::dummy_test_allocator >; template class multiset < test::movable_and_copyable_int , std::less , test::simple_allocator >; template class multiset < test::movable_and_copyable_int , std::less , std::allocator >; template class multiset < test::movable_and_copyable_int , std::less , allocator >; template class multiset < test::movable_and_copyable_int , std::less , adaptive_pool >; template class multiset < test::movable_and_copyable_int , std::less , node_allocator >; namespace container_detail { //Instantiate base class as previous instantiations don't instantiate inherited members template class tree < test::movable_and_copyable_int , test::movable_and_copyable_int , identity , std::less , test::dummy_test_allocator , tree_assoc_defaults >; template class tree < test::movable_and_copyable_int , test::movable_and_copyable_int , identity , std::less , test::simple_allocator , tree_assoc_defaults >; template class tree < test::movable_and_copyable_int , test::movable_and_copyable_int , identity , std::less , std::allocator , tree_assoc_defaults >; template class tree < test::movable_and_copyable_int , test::movable_and_copyable_int , identity , std::less , allocator , tree_assoc_defaults >; template class tree < test::movable_and_copyable_int , test::movable_and_copyable_int , identity , std::less , adaptive_pool , tree_assoc_defaults >; template class tree < test::movable_and_copyable_int , test::movable_and_copyable_int , identity , std::less , node_allocator , tree_assoc_defaults >; } //container_detail { }} //boost::container //Test recursive structures class recursive_set { public: recursive_set & operator=(const recursive_set &x) { id_ = x.id_; set_ = x.set_; return *this; } int id_; set set_; set::iterator it_; set::const_iterator cit_; set::reverse_iterator rit_; set::const_reverse_iterator crit_; friend bool operator< (const recursive_set &a, const recursive_set &b) { return a.id_ < b.id_; } }; //Test recursive structures class recursive_multiset { public: recursive_multiset & operator=(const recursive_multiset &x) { id_ = x.id_; multiset_ = x.multiset_; return *this; } int id_; multiset multiset_; multiset::iterator it_; multiset::const_iterator cit_; multiset::reverse_iterator rit_; multiset::const_reverse_iterator crit_; friend bool operator< (const recursive_multiset &a, const recursive_multiset &b) { return a.id_ < b.id_; } }; template void test_move() { //Now test move semantics C original; original.emplace(); C move_ctor(boost::move(original)); C move_assign; move_assign.emplace(); move_assign = boost::move(move_ctor); move_assign.swap(original); } template class set_propagate_test_wrapper : public boost::container::set, Allocator //tree_assoc_defaults > { BOOST_COPYABLE_AND_MOVABLE(set_propagate_test_wrapper) typedef boost::container::set, Allocator > Base; public: set_propagate_test_wrapper() : Base() {} set_propagate_test_wrapper(const set_propagate_test_wrapper &x) : Base(x) {} set_propagate_test_wrapper(BOOST_RV_REF(set_propagate_test_wrapper) x) : Base(boost::move(static_cast(x))) {} set_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(set_propagate_test_wrapper) x) { this->Base::operator=(x); return *this; } set_propagate_test_wrapper &operator=(BOOST_RV_REF(set_propagate_test_wrapper) x) { this->Base::operator=(boost::move(static_cast(x))); return *this; } void swap(set_propagate_test_wrapper &x) { this->Base::swap(x); } }; template struct GetAllocatorSet { template struct apply { typedef set < ValueType , std::less , typename allocator_traits ::template portable_rebind_alloc::type , typename boost::container::tree_assoc_options < boost::container::tree_type >::type > set_type; typedef multiset < ValueType , std::less , typename allocator_traits ::template portable_rebind_alloc::type , typename boost::container::tree_assoc_options < boost::container::tree_type >::type > multiset_type; }; }; template int test_set_variants() { typedef typename GetAllocatorSet::template apply::set_type MySet; typedef typename GetAllocatorSet::template apply::set_type MyMoveSet; typedef typename GetAllocatorSet::template apply::set_type MyCopyMoveSet; typedef typename GetAllocatorSet::template apply::set_type MyCopySet; typedef typename GetAllocatorSet::template apply::multiset_type MyMultiSet; typedef typename GetAllocatorSet::template apply::multiset_type MyMoveMultiSet; typedef typename GetAllocatorSet::template apply::multiset_type MyCopyMoveMultiSet; typedef typename GetAllocatorSet::template apply::multiset_type MyCopyMultiSet; typedef std::set MyStdSet; typedef std::multiset MyStdMultiSet; if (0 != test::set_test< MySet ,MyStdSet ,MyMultiSet ,MyStdMultiSet>()){ std::cout << "Error in set_test" << std::endl; return 1; } if (0 != test::set_test< MyMoveSet ,MyStdSet ,MyMoveMultiSet ,MyStdMultiSet>()){ std::cout << "Error in set_test" << std::endl; return 1; } if (0 != test::set_test< MyCopyMoveSet ,MyStdSet ,MyCopyMoveMultiSet ,MyStdMultiSet>()){ std::cout << "Error in set_test" << std::endl; return 1; } if (0 != test::set_test< MyCopySet ,MyStdSet ,MyCopyMultiSet ,MyStdMultiSet>()){ std::cout << "Error in set_test" << std::endl; return 1; } return 0; } template bool test_support_for_initialization_list_for() { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) std::initializer_list il = {1, 2, 3, 4, 5}; SetType expected(il.begin(), il.end()); { SetType sil = il; if (sil != expected) return false; SetType sil_ordered(ordered_unique_range, il); if(sil_ordered != expected) return false; SetType sil_assign = {99, 100, 101, 102, 103, 104, 105}; sil_assign = il; if(sil_assign != expected) return false; } { SetType sil; sil.insert(il); if(sil != expected) return false; } return true; #endif return true; } int main () { //Recursive container instantiation { set set_; multiset multiset_; } //Allocator argument container { set set_((set::allocator_type())); multiset multiset_((multiset::allocator_type())); } //Now test move semantics { test_move >(); test_move >(); } //////////////////////////////////// // Testing allocator implementations //////////////////////////////////// // std:allocator if(test_set_variants< std::allocator, red_black_tree >()){ std::cerr << "test_set_variants< std::allocator > failed" << std::endl; return 1; } // boost::container::allocator if(test_set_variants< allocator, red_black_tree>()){ std::cerr << "test_set_variants< allocator > failed" << std::endl; return 1; } // boost::container::node_allocator if(test_set_variants< node_allocator, red_black_tree>()){ std::cerr << "test_set_variants< node_allocator > failed" << std::endl; return 1; } // boost::container::adaptive_pool if(test_set_variants< adaptive_pool, red_black_tree>()){ std::cerr << "test_set_variants< adaptive_pool > failed" << std::endl; return 1; } //////////////////////////////////// // Tree implementations //////////////////////////////////// // AVL if(test_set_variants< std::allocator, avl_tree >()){ std::cerr << "test_set_variants< std::allocator, avl_tree > failed" << std::endl; return 1; } // SCAPEGOAT TREE if(test_set_variants< std::allocator, scapegoat_tree >()){ std::cerr << "test_set_variants< std::allocator, scapegoat_tree > failed" << std::endl; return 1; } // SPLAY TREE if(test_set_variants< std::allocator, splay_tree >()){ std::cerr << "test_set_variants< std::allocator, splay_tree > failed" << std::endl; return 1; } //////////////////////////////////// // Emplace testing //////////////////////////////////// const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC); if(!boost::container::test::test_emplace, SetOptions>()) return 1; if(!boost::container::test::test_emplace, SetOptions>()) return 1; //////////////////////////////////// // Allocator propagation testing //////////////////////////////////// if(!boost::container::test::test_propagate_allocator()) return 1; if(!test_support_for_initialization_list_for >()) return 1; if(!test_support_for_initialization_list_for >()) return 1; //////////////////////////////////// // Test optimize_size option //////////////////////////////////// // // set // typedef set< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > rbset_size_optimized_no; typedef set< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > rbset_size_optimized_yes; BOOST_STATIC_ASSERT(sizeof(rbset_size_optimized_yes) < sizeof(rbset_size_optimized_no)); typedef set< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > avlset_size_optimized_no; typedef set< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > avlset_size_optimized_yes; BOOST_STATIC_ASSERT(sizeof(avlset_size_optimized_yes) < sizeof(avlset_size_optimized_no)); // // multiset // typedef multiset< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > rbmset_size_optimized_no; typedef multiset< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > rbmset_size_optimized_yes; BOOST_STATIC_ASSERT(sizeof(rbmset_size_optimized_yes) < sizeof(rbmset_size_optimized_no)); typedef multiset< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > avlmset_size_optimized_no; typedef multiset< int*, std::less, std::allocator , tree_assoc_options< optimize_size, tree_type >::type > avlmset_size_optimized_yes; BOOST_STATIC_ASSERT(sizeof(avlmset_size_optimized_yes) < sizeof(avlmset_size_optimized_no)); return 0; } #include