unordered_set_test.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 635 行 · 第 1/2 页

CPP
635
字号
///////////////////////////////////////////////////////////////////////////////// (C) Copyright Olaf Krzikalla 2004-2006.// (C) Copyright Ion Gaztanaga  2006-2007.//// Distributed under the Boost Software License, Version 1.0.//    (See accompanying file LICENSE_1_0.txt or copy at//          http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/intrusive for documentation.///////////////////////////////////////////////////////////////////////////////#include <boost/intrusive/detail/config_begin.hpp>#include <boost/intrusive/unordered_set.hpp>#include <boost/intrusive/detail/pointer_to_other.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"using namespace boost::intrusive;static const std::size_t BucketSize = 8;template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>struct test_unordered_set {   typedef typename ValueTraits::value_type value_type;   static void test_all(std::vector<value_type>& values);   static void test_sort(std::vector<value_type>& values);   static void test_insert(std::vector<value_type>& values);   static void test_swap(std::vector<value_type>& values);   static void test_rehash(std::vector<value_type>& values, detail::true_);   static void test_rehash(std::vector<value_type>& values, detail::false_);   static void test_find(std::vector<value_type>& values);   static void test_impl();   static void test_clone(std::vector<value_type>& values);};template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::   test_all(std::vector<typename ValueTraits::value_type>& values){   typedef typename ValueTraits::value_type value_type;   typedef unordered_set      <value_type      , value_traits<ValueTraits>      , constant_time_size<value_type::constant_time_size>      , cache_begin<CacheBegin>      , compare_hash<CompareHash>      , incremental<Incremental>      > unordered_set_type;   typedef typename unordered_set_type::bucket_traits bucket_traits;   {      typename unordered_set_type::bucket_type buckets [BucketSize];      unordered_set_type testset(bucket_traits(buckets, 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());      test::test_unique_container(testset, values);   }   test_sort(values);   test_insert(values);   test_swap(values);   test_rehash(values, detail::bool_<Incremental>());   test_find(values);   test_impl();   test_clone(values);}//test case due to an error in tree implementation:template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::test_impl(){   typedef typename ValueTraits::value_type value_type;   typedef unordered_set      <value_type      , value_traits<ValueTraits>      , constant_time_size<value_type::constant_time_size>      , cache_begin<CacheBegin>      , compare_hash<CompareHash>      , incremental<Incremental>      > unordered_set_type;   typedef typename unordered_set_type::bucket_traits bucket_traits;   std::vector<value_type> values (5);   for (int i = 0; i < 5; ++i)      values[i].value_ = i;    typename unordered_set_type::bucket_type buckets [BucketSize];   unordered_set_type testset(bucket_traits(buckets, 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 ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::   test_sort(std::vector<typename ValueTraits::value_type>& values){   typedef typename ValueTraits::value_type value_type;   typedef unordered_set      <value_type      , value_traits<ValueTraits>      , constant_time_size<value_type::constant_time_size>      , cache_begin<CacheBegin>      , compare_hash<CompareHash>      , incremental<Incremental>      > unordered_set_type;   typedef typename unordered_set_type::bucket_traits bucket_traits;   typename unordered_set_type::bucket_type buckets [BucketSize];   unordered_set_type testset1(values.begin(), values.end(), bucket_traits(buckets, BucketSize));   BOOST_TEST (5 == std::distance(testset1.begin(), testset1.end()));   if(Incremental){      {  int init_values [] = { 4, 5, 1, 2, 3 };         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   }   else{      {  int init_values [] = { 1, 2, 3, 4, 5 };         TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   }       testset1.clear();   BOOST_TEST (testset1.empty());}    //test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::   test_insert(std::vector<typename ValueTraits::value_type>& values){   typedef typename ValueTraits::value_type value_type;   typedef unordered_set      <value_type      , value_traits<ValueTraits>      , constant_time_size<value_type::constant_time_size>      , cache_begin<CacheBegin>      , compare_hash<CompareHash>      , incremental<Incremental>      > unordered_set_type;   typedef typename unordered_set_type::bucket_traits bucket_traits;   typename unordered_set_type::bucket_type buckets [BucketSize];   unordered_set_type testset(bucket_traits(buckets, BucketSize));   testset.insert(&values[0] + 2, &values[0] + 5);   const unordered_set_type& const_testset = testset;   if(Incremental)   {      {  int init_values [] = { 4, 5, 1 };         TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() );  }      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( init_values, const_testset.begin() );  }   }   else{      {  int init_values [] = { 1, 4, 5 };         TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() );  }      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( init_values, const_testset.begin() );  }   }}  //test: insert (seq-version), swap, erase (seq-version), size:template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::   test_swap(std::vector<typename ValueTraits::value_type>& values){   typedef typename ValueTraits::value_type value_type;   typedef unordered_set      <value_type      , value_traits<ValueTraits>      , constant_time_size<value_type::constant_time_size>      , cache_begin<CacheBegin>      , compare_hash<CompareHash>      , incremental<Incremental>      > unordered_set_type;   typedef typename unordered_set_type::bucket_traits bucket_traits;   typename unordered_set_type::bucket_type buckets1 [BucketSize];   typename unordered_set_type::bucket_type buckets2 [BucketSize];   unordered_set_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets1, BucketSize));   unordered_set_type testset2(bucket_traits(buckets2, BucketSize));   testset2.insert (&values[0] + 2, &values[0] + 6);   testset1.swap (testset2);   if(Incremental){      {  int init_values [] = { 4, 5, 1, 2 };         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[4]), testset1.end());      BOOST_TEST (testset1.size() == 1);      BOOST_TEST (&*testset1.begin() == &values[2]);   }   else{      {  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]);   }}  //test: rehash:template<class ValueTraits, bool CacheBegin, bool CompareHash, bool Incremental>void test_unordered_set<ValueTraits, CacheBegin, CompareHash, Incremental>::   test_rehash(std::vector<typename ValueTraits::value_type>& values, detail::true_){   typedef typename ValueTraits::value_type value_type;   typedef unordered_set      <value_type      , value_traits<ValueTraits>      , constant_time_size<value_type::constant_time_size>      , cache_begin<CacheBegin>      , compare_hash<CompareHash>      , incremental<Incremental>      > unordered_set_type;   typedef typename unordered_set_type::bucket_traits bucket_traits;   //Build a uset   typename unordered_set_type::bucket_type buckets1 [BucketSize];   typename unordered_set_type::bucket_type buckets2 [BucketSize*2];   unordered_set_type testset1(&values[0], &values[0] + 6, bucket_traits(buckets1, BucketSize));   //Test current state   BOOST_TEST(testset1.split_count() == BucketSize/2);   {  int init_values [] = { 4, 5, 1, 2, 3 };      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   //Incremental rehash step   BOOST_TEST (testset1.incremental_rehash() == true);   BOOST_TEST(testset1.split_count() == (BucketSize/2+1));   {  int init_values [] = { 5, 1, 2, 3, 4 };      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   //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, 3, 4, 5 };      TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   }   //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, 3, 4, 5 };   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   //   //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(buckets1, BucketSize)) == false);   BOOST_TEST(testset1.split_count() == BucketSize);   {  int init_values [] = { 1, 2, 3, 4, 5 };   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   //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(buckets1, BucketSize*2)) == true);   BOOST_TEST(testset1.split_count() == BucketSize);   {  int init_values [] = { 1, 2, 3, 4, 5 };   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   //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(buckets1, BucketSize)) == true);   BOOST_TEST(testset1.split_count() == BucketSize);   {  int init_values [] = { 1, 2, 3, 4, 5 };   TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() );  }   //   //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(buckets2, BucketSize)) == false);   BOOST_TEST(testset1.split_count() == BucketSize);   {  int init_values [] = { 1, 2, 3, 4, 5 };

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?