]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/container/test/flat_set_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / container / test / flat_set_test.cpp
index e23cf7a74bf5b42e896c165a0cfeb78f91a0715f..7927b99a4a3be3568641dcb77cc9816966ee9151 100644 (file)
 
 #include <boost/container/detail/config_begin.hpp>
 
+#include <iostream>
 #include <set>
+#include <utility>
+#include <vector>
 
 #include <boost/container/flat_set.hpp>
-#include <boost/container/stable_vector.hpp>
-#include <boost/container/small_vector.hpp>
-#include <boost/container/deque.hpp>
-#include <boost/container/static_vector.hpp>
-#include <boost/container/allocator.hpp>
 #include <boost/container/detail/container_or_allocator_rebind.hpp>
 
 #include "print_container.hpp"
 
 using namespace boost::container;
 
-namespace boost {
-namespace container {
-
-//Explicit instantiation to detect compilation errors
-
-//flat_set
-template class flat_set
-   < test::movable_and_copyable_int
-   , std::less<test::movable_and_copyable_int>
-   , test::simple_allocator<test::movable_and_copyable_int>
-   >;
-
-template class flat_set
-   < test::movable_and_copyable_int
-   , std::less<test::movable_and_copyable_int>
-   , small_vector<test::movable_and_copyable_int, 10, allocator<test::movable_and_copyable_int> >
-   >;
-
-//flat_multiset
-template class flat_multiset
-   < test::movable_and_copyable_int
-   , std::less<test::movable_and_copyable_int>
-   , stable_vector<test::movable_and_copyable_int, test::simple_allocator<test::movable_and_copyable_int> >
-   >;
-
-template class flat_multiset
-   < test::movable_and_copyable_int
-   , std::less<test::movable_and_copyable_int>
-   , deque<test::movable_and_copyable_int, test::simple_allocator< test::movable_and_copyable_int > >
-   >;
-
-template class flat_multiset
-   < test::movable_and_copyable_int
-   , std::less<test::movable_and_copyable_int>
-   , static_vector<test::movable_and_copyable_int, 10 >
-   >;
-
-//As flat container iterators are typedefs for vector::[const_]iterator,
-//no need to explicit instantiate them
-
-}} //boost::container
-
-
-#if (__cplusplus > 201103L)
-#include <vector>
-
-namespace boost{
-namespace container{
-
-template class flat_set
-   < test::movable_and_copyable_int
-   , std::less<test::movable_and_copyable_int>
-   , std::vector<test::movable_and_copyable_int>
->;
-
-}} //boost::container
-
-#endif
-
 //Test recursive structures
 class recursive_flat_set
 {
@@ -340,6 +279,106 @@ bool flat_tree_ordered_insertion_test()
    return true;
 }
 
+bool constructor_template_auto_deduction_test()
+{
+
+#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
+   using namespace boost::container;
+   const std::size_t NumElements = 100;
+   {
+      std::set<int> int_set;
+      for (std::size_t i = 0; i != NumElements; ++i) {
+         int_set.insert(static_cast<int>(i));
+      }
+      std::multiset<int> int_mset;
+      for (std::size_t i = 0; i != NumElements; ++i) {
+         int_mset.insert(static_cast<int>(i));
+      }
+
+      typedef std::less<int> comp_int_t;
+      typedef std::allocator<int> alloc_int_t;
+
+      //range
+      {
+         auto fset = flat_set(int_set.begin(), int_set.end());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(int_mset.begin(), int_mset.end());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+      //range+comp
+      {
+         auto fset = flat_set(int_set.begin(), int_set.end(), comp_int_t());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(int_mset.begin(), int_mset.end(), comp_int_t());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+      //range+comp+alloc
+      {
+         auto fset = flat_set(int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+      //range+alloc
+      {
+         auto fset = flat_set(int_set.begin(), int_set.end(), alloc_int_t());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(int_mset.begin(), int_mset.end(), alloc_int_t());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+
+      //ordered_unique_range / ordered_range
+
+      //range
+      {
+         auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+      //range+comp
+      {
+         auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+      //range+comp+alloc
+      {
+         auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+      //range+alloc
+      {
+         auto fset = flat_set(ordered_unique_range, int_set.begin(), int_set.end(), alloc_int_t());
+         if (!CheckEqualContainers(int_set, fset))
+            return false;
+         auto fmset = flat_multiset(ordered_range, int_mset.begin(), int_mset.end(), alloc_int_t());
+         if (!CheckEqualContainers(int_mset, fmset))
+            return false;
+      }
+   }
+#endif
+
+   return true;
+}
+
 template< class RandomIt >
 void random_shuffle( RandomIt first, RandomIt last )
 {
@@ -450,6 +489,129 @@ bool flat_tree_extract_adopt_test()
    return true;
 }
 
+bool test_heterogeneous_lookups()
+{
+   typedef flat_set<int, test::less_transparent> set_t;
+   typedef flat_multiset<int, test::less_transparent> mset_t;
+
+   set_t set1;
+   mset_t mset1;
+
+   const set_t &cset1 = set1;
+   const mset_t &cmset1 = mset1;
+
+   set1.insert(1);
+   set1.insert(1);
+   set1.insert(2);
+   set1.insert(2);
+   set1.insert(3);
+
+   mset1.insert(1);
+   mset1.insert(1);
+   mset1.insert(2);
+   mset1.insert(2);
+   mset1.insert(3);
+
+   const test::non_copymovable_int find_me(2);
+
+   //find
+   if(*set1.find(find_me) != 2)
+      return false;
+   if(*cset1.find(find_me) != 2)
+      return false;
+   if(*mset1.find(find_me) != 2)
+      return false;
+   if(*cmset1.find(find_me) != 2)
+      return false;
+
+   //count
+   if(set1.count(find_me) != 1)
+      return false;
+   if(cset1.count(find_me) != 1)
+      return false;
+   if(mset1.count(find_me) != 2)
+      return false;
+   if(cmset1.count(find_me) != 2)
+      return false;
+
+   //contains
+   if(!set1.contains(find_me))
+      return false;
+   if(!cset1.contains(find_me))
+      return false;
+   if(!mset1.contains(find_me))
+      return false;
+   if(!cmset1.contains(find_me))
+      return false;
+
+   //lower_bound
+   if(*set1.lower_bound(find_me) != 2)
+      return false;
+   if(*cset1.lower_bound(find_me) != 2)
+      return false;
+   if(*mset1.lower_bound(find_me) != 2)
+      return false;
+   if(*cmset1.lower_bound(find_me) != 2)
+      return false;
+
+   //upper_bound
+   if(*set1.upper_bound(find_me) != 3)
+      return false;
+   if(*cset1.upper_bound(find_me) != 3)
+      return false;
+   if(*mset1.upper_bound(find_me) != 3)
+      return false;
+   if(*cmset1.upper_bound(find_me) != 3)
+      return false;
+
+   //equal_range
+   if(*set1.equal_range(find_me).first != 2)
+      return false;
+   if(*cset1.equal_range(find_me).second != 3)
+      return false;
+   if(*mset1.equal_range(find_me).first != 2)
+      return false;
+   if(*cmset1.equal_range(find_me).second != 3)
+      return false;
+
+   return true;
+}
+
+// An ordered sequence of std:pair is also ordered by std::pair::first.
+struct with_lookup_by_first
+{
+   typedef void is_transparent;
+   inline bool operator()(std::pair<int, int> a, std::pair<int, int> b) const
+   {
+      return a < b;
+   }
+   inline bool operator()(std::pair<int, int> a, int first) const
+   {
+      return a.first < first;
+   }
+   inline bool operator()(int first, std::pair<int, int> b) const
+   {
+      return first < b.first;
+   }
+};
+
+bool test_heterogeneous_lookup_by_partial_key()
+{
+   typedef flat_set<std::pair<int, int>, with_lookup_by_first> set_t;
+
+   set_t set1;
+   set1.insert(std::pair<int, int>(0, 1));
+   set1.insert(std::pair<int, int>(0, 2));
+
+   std::pair<set_t::iterator, set_t::iterator> const first_0_range = set1.equal_range(0);
+   if(2 != (first_0_range.second - first_0_range.first))
+      return false;
+
+   if(2 != set1.count(0))
+      return false;
+   return true;
+}
+
 }}}
 
 template<class VoidAllocatorOrContainer>
@@ -470,62 +632,6 @@ struct GetSetContainer
    };
 };
 
-template<class VoidAllocator>
-int test_set_variants()
-{
-   typedef typename GetSetContainer<VoidAllocator>::template apply<int>::set_type MySet;
-   typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_int>::set_type MyMoveSet;
-   typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
-   typedef typename GetSetContainer<VoidAllocator>::template apply<test::copyable_int>::set_type MyCopySet;
-
-   typedef typename GetSetContainer<VoidAllocator>::template apply<int>::multiset_type MyMultiSet;
-   typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
-   typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
-   typedef typename GetSetContainer<VoidAllocator>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
-
-   typedef std::set<int>                                          MyStdSet;
-   typedef std::multiset<int>                                     MyStdMultiSet;
-
-   if (0 != test::set_test<
-                  MySet
-                  ,MyStdSet
-                  ,MyMultiSet
-                  ,MyStdMultiSet>()){
-      std::cout << "Error in set_test<MyBoostSet>" << std::endl;
-      return 1;
-   }
-
-   if (0 != test::set_test<
-                  MyMoveSet
-                  ,MyStdSet
-                  ,MyMoveMultiSet
-                  ,MyStdMultiSet>()){
-      std::cout << "Error in set_test<MyBoostSet>" << std::endl;
-      return 1;
-   }
-
-   if (0 != test::set_test<
-                  MyCopyMoveSet
-                  ,MyStdSet
-                  ,MyCopyMoveMultiSet
-                  ,MyStdMultiSet>()){
-      std::cout << "Error in set_test<MyBoostSet>" << std::endl;
-      return 1;
-   }
-
-   if (0 != test::set_test<
-                  MyCopySet
-                  ,MyStdSet
-                  ,MyCopyMultiSet
-                  ,MyStdMultiSet>()){
-      std::cout << "Error in set_test<MyBoostSet>" << std::endl;
-      return 1;
-   }
-
-   return 0;
-}
-
-
 template<typename FlatSetType>
 bool test_support_for_initialization_list_for()
 {
@@ -626,6 +732,13 @@ int main()
       return 1;
    }
 
+   ////////////////////////////////////
+   //    Constructor Template Auto Deduction test
+   ////////////////////////////////////
+   if (!constructor_template_auto_deduction_test()) {
+      return 1;
+   }
+
    ////////////////////////////////////
    //    Extract/Adopt test
    ////////////////////////////////////
@@ -636,20 +749,67 @@ int main()
    if (!boost::container::test::instantiate_constructors<flat_set<int>, flat_multiset<int> >())
       return 1;
 
-   ////////////////////////////////////
-   //    Testing allocator implementations
-   ////////////////////////////////////
-   //       std::allocator
-   if(test_set_variants< std::allocator<void> >()){
-      std::cerr << "test_set_variants< std::allocator<void> > failed" << std::endl;
+   if(!test_heterogeneous_lookups()){
       return 1;
    }
-   //       boost::container::allocator
-   if(test_set_variants< allocator<void> >()){
-      std::cerr << "test_set_variants< allocator<void> > failed" << std::endl;
+
+   if(!test_heterogeneous_lookup_by_partial_key()){
       return 1;
    }
 
+   ////////////////////////////////////
+   //    Testing allocator implementations
+   ////////////////////////////////////
+   {
+      typedef std::set<int>                                          MyStdSet;
+      typedef std::multiset<int>                                     MyStdMultiSet;
+
+      if (0 != test::set_test
+         < GetSetContainer<std::allocator<void> >::apply<int>::set_type
+         , MyStdSet
+         , GetSetContainer<std::allocator<void> >::apply<int>::multiset_type
+         , MyStdMultiSet>()) {
+         std::cout << "Error in set_test<std::allocator<void> >" << std::endl;
+         return 1;
+      }
+
+      if (0 != test::set_test
+         < GetSetContainer<new_allocator<void> >::apply<int>::set_type
+         , MyStdSet
+         , GetSetContainer<new_allocator<void> >::apply<int>::multiset_type
+         , MyStdMultiSet>()) {
+         std::cout << "Error in set_test<new_allocator<void> >" << std::endl;
+         return 1;
+      }
+
+      if (0 != test::set_test
+         < GetSetContainer<new_allocator<void> >::apply<test::movable_int>::set_type
+         , MyStdSet
+         , GetSetContainer<new_allocator<void> >::apply<test::movable_int>::multiset_type
+         , MyStdMultiSet>()) {
+         std::cout << "Error in set_test<new_allocator<void> >" << std::endl;
+         return 1;
+      }
+
+      if (0 != test::set_test
+         < GetSetContainer<new_allocator<void> >::apply<test::copyable_int>::set_type
+         , MyStdSet
+         , GetSetContainer<new_allocator<void> >::apply<test::copyable_int>::multiset_type
+         , MyStdMultiSet>()) {
+         std::cout << "Error in set_test<new_allocator<void> >" << std::endl;
+         return 1;
+      }
+
+      if (0 != test::set_test
+         < GetSetContainer<new_allocator<void> >::apply<test::movable_and_copyable_int>::set_type
+         , MyStdSet
+         , GetSetContainer<new_allocator<void> >::apply<test::movable_and_copyable_int>::multiset_type
+         , MyStdMultiSet>()) {
+         std::cout << "Error in set_test<new_allocator<void> >" << std::endl;
+         return 1;
+      }
+   }
+
    ////////////////////////////////////
    //    Emplace testing
    ////////////////////////////////////
@@ -695,6 +855,77 @@ int main()
       }
    }
 
+   ////////////////////////////////////
+   //    has_trivial_destructor_after_move testing
+   ////////////////////////////////////
+   {
+      typedef boost::container::dtl::identity<int> key_of_value_t;
+      // flat_set, default
+      {
+         typedef boost::container::flat_set<int> cont;
+         typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, void> tree;
+         if (boost::has_trivial_destructor_after_move<cont>::value !=
+             boost::has_trivial_destructor_after_move<tree>::value) {
+            std::cerr << "has_trivial_destructor_after_move(flat_set, default) test failed" << std::endl;
+            return 1;
+         }
+      }
+      // flat_set, vector
+      {
+         typedef boost::container::vector<int> alloc_or_cont_t;
+         typedef boost::container::flat_set<int, std::less<int>, alloc_or_cont_t> cont;
+         typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
+         if (boost::has_trivial_destructor_after_move<cont>::value !=
+             boost::has_trivial_destructor_after_move<tree>::value) {
+            std::cerr << "has_trivial_destructor_after_move(flat_set, vector) test failed" << std::endl;
+            return 1;
+         }
+      }
+      // flat_set, std::vector
+      {
+         typedef std::vector<int> alloc_or_cont_t;
+         typedef boost::container::flat_set<int, std::less<int>, alloc_or_cont_t> cont;
+         typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
+         if (boost::has_trivial_destructor_after_move<cont>::value !=
+             boost::has_trivial_destructor_after_move<tree>::value) {
+            std::cerr << "has_trivial_destructor_after_move(flat_set, std::vector) test failed" << std::endl;
+            return 1;
+         }
+      }
+      // flat_multiset, default
+      {
+         typedef boost::container::flat_multiset<int> cont;
+         typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, void> tree;
+         if (boost::has_trivial_destructor_after_move<cont>::value !=
+             boost::has_trivial_destructor_after_move<tree>::value) {
+            std::cerr << "has_trivial_destructor_after_move(flat_multiset, default) test failed" << std::endl;
+            return 1;
+         }
+      }
+      // flat_multiset, vector
+      {
+         typedef boost::container::vector<int> alloc_or_cont_t;
+         typedef boost::container::flat_multiset<int, std::less<int>, alloc_or_cont_t> cont;
+         typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
+         if (boost::has_trivial_destructor_after_move<cont>::value !=
+             boost::has_trivial_destructor_after_move<tree>::value) {
+            std::cerr << "has_trivial_destructor_after_move(flat_multiset, vector) test failed" << std::endl;
+            return 1;
+         }
+      }
+      // flat_multiset, std::vector
+      {
+         typedef std::vector<int> alloc_or_cont_t;
+         typedef boost::container::flat_multiset<int, std::less<int>, alloc_or_cont_t> cont;
+         typedef boost::container::dtl::flat_tree<int, key_of_value_t, std::less<int>, alloc_or_cont_t> tree;
+         if (boost::has_trivial_destructor_after_move<cont>::value !=
+             boost::has_trivial_destructor_after_move<tree>::value) {
+            std::cerr << "has_trivial_destructor_after_move(flat_multiset, std::vector) test failed" << std::endl;
+            return 1;
+         }
+      }
+   }
+
    return 0;
 }