From 4a8d6877789684b55cc3860c3ffc724f91ad87ea Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Tue, 11 Oct 2022 15:20:37 -0700 Subject: [PATCH] Add compile_set tests with stub for merge() --- include/boost/unordered/detail/foa.hpp | 15 ++- .../boost/unordered/unordered_flat_set.hpp | 46 +++++++ test/Jamfile.v2 | 1 + test/unordered/compile_set.cpp | 121 +++++++++++++++++- test/unordered/compile_tests.hpp | 35 +++++ 5 files changed, 209 insertions(+), 9 deletions(-) diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index 049dfada..63d5e827 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -618,10 +618,13 @@ class table_iterator { public: using difference_type=std::ptrdiff_t; - using value_type=typename std::conditional::type; - using pointer=value_type*; + using value_type=Value; + using pointer= + typename std::conditional::type; using reference=value_type&; using iterator_category=std::forward_iterator_tag; + using element_type= + typename std::conditional::type; table_iterator()=default; template::type* =nullptr> @@ -746,10 +749,12 @@ struct table_arrays static void delete_(Allocator& al,table_arrays& arrays)noexcept { using alloc_traits=boost::allocator_traits; + using pointer=typename alloc_traits::pointer; + using pointer_traits=boost::pointer_traits; if(arrays.elements){ alloc_traits::deallocate( - al,arrays.elements,buffer_size(arrays.groups_size_mask+1)); + al,pointer_traits::pointer_to(*arrays.elements),buffer_size(arrays.groups_size_mask+1)); } } @@ -981,7 +986,7 @@ public: static constexpr auto pocca= alloc_traits::propagate_on_container_copy_assignment::value; - if(this!=&x){ + if(this!=std::addressof(x)){ clear(); h()=x.h(); pred()=x.pred(); @@ -1025,7 +1030,7 @@ public: unchecked_insert(type_policy::move(*p)); }; - if(this!=&x){ + if(this!=std::addressof(x)){ clear(); h()=std::move(x.h()); pred()=std::move(x.pred()); diff --git a/include/boost/unordered/unordered_flat_set.hpp b/include/boost/unordered/unordered_flat_set.hpp index 98f2534c..9a740448 100644 --- a/include/boost/unordered/unordered_flat_set.hpp +++ b/include/boost/unordered/unordered_flat_set.hpp @@ -46,6 +46,7 @@ namespace boost { using key_type = Key; using value_type = typename set_types::value_type; using size_type = std::size_t; + using difference_type = std::ptrdiff_t; using hasher = Hash; using key_equal = KeyEqual; using allocator_type = Allocator; @@ -68,6 +69,11 @@ namespace boost { { } + unordered_flat_set(size_type n, hasher const& h, allocator_type const& a) + : unordered_flat_set(n, h, key_equal(), a) + { + } + explicit unordered_flat_set(allocator_type const& a) : unordered_flat_set(0, a) { @@ -82,6 +88,20 @@ namespace boost { this->insert(first, last); } + template + unordered_flat_set( + InputIt first, InputIt last, size_type n, allocator_type const& a) + : unordered_flat_set(first, last, n, hasher(), key_equal(), a) + { + } + + template + unordered_flat_set(Iterator first, Iterator last, size_type n, + hasher const& h, allocator_type const& a) + : unordered_flat_set(first, last, n, h, key_equal(), a) + { + } + unordered_flat_set(unordered_flat_set const& other) : table_(other.table_) { } @@ -113,6 +133,18 @@ namespace boost { { } + unordered_flat_set(std::initializer_list init, size_type n, + allocator_type const& a) + : unordered_flat_set(init, n, hasher(), key_equal(), a) + { + } + + unordered_flat_set(std::initializer_list init, size_type n, + hasher const& h, allocator_type const& a) + : unordered_flat_set(init, n, h, key_equal(), a) + { + } + ~unordered_flat_set() = default; unordered_flat_set& operator=(unordered_flat_set const& other) @@ -154,6 +186,8 @@ namespace boost { size_type size() const noexcept { return table_.size(); } + size_type max_size() const noexcept { return table_.max_size(); } + /// Modifiers /// @@ -229,6 +263,18 @@ namespace boost { table_.swap(rhs.table_); } + template + void merge(unordered_flat_set& source) + { + (void) source; + } + + template + void merge(unordered_flat_set&& source) + { + (void) source; + } + /// Lookup /// diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2a3e4f84..fa9d474c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -104,6 +104,7 @@ rule build_foa ( name ) build_foa fwd_set_test ; build_foa fwd_map_test ; +build_foa compile_set ; build_foa constructor_tests ; build_foa copy_tests ; build_foa move_tests ; diff --git a/test/unordered/compile_set.cpp b/test/unordered/compile_set.cpp index 727294f3..32e4a170 100644 --- a/test/unordered/compile_set.cpp +++ b/test/unordered/compile_set.cpp @@ -8,7 +8,12 @@ // clang-format off #include "../helpers/prefix.hpp" +#ifdef BOOST_UNORDERED_FOA_TESTS +#include +#include +#else #include +#endif #include "../helpers/postfix.hpp" // clang-format on @@ -18,6 +23,28 @@ // Explicit instantiation to catch compile-time errors +#ifdef BOOST_UNORDERED_FOA_TESTS + +// emulates what was already done for previous tests but without leaking to +// the detail namespace +// +template +class instantiate_flat_set +{ + typedef boost::unordered_flat_set container; + container x; +}; + +template class instantiate_flat_set, std::equal_to, + test::minimal::allocator >; + +template class instantiate_flat_set, + test::minimal::equal_to, + test::minimal::allocator >; + +#else + #define INSTANTIATE(type) \ template class boost::unordered::detail::instantiate_##type @@ -35,6 +62,8 @@ INSTANTIATE(multiset), test::minimal::allocator >; +#endif + UNORDERED_AUTO_TEST (test0) { test::minimal::constructor_param x; @@ -42,6 +71,19 @@ UNORDERED_AUTO_TEST (test0) { BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n"; +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_set int_set; + + boost::unordered_flat_set, std::equal_to, + test::minimal::cxx11_allocator > + int_set2; + + boost::unordered_flat_set, + test::minimal::equal_to, + test::minimal::allocator > + set; +#else boost::unordered_set int_set; boost::unordered_set, std::equal_to, @@ -53,11 +95,13 @@ UNORDERED_AUTO_TEST (test0) { test::minimal::equal_to, test::minimal::allocator > set; +#endif container_test(int_set, 0); container_test(int_set2, 0); container_test(set, assignable); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n"; boost::unordered_multiset int_multiset; @@ -75,11 +119,27 @@ UNORDERED_AUTO_TEST (test0) { container_test(int_multiset, 0); container_test(int_multiset2, 0); container_test(multiset, assignable); +#endif } UNORDERED_AUTO_TEST (equality_tests) { typedef test::minimal::copy_constructible_equality_comparable value_type; +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_set int_set; + + boost::unordered_flat_set, std::equal_to, + test::minimal::cxx11_allocator > + int_set2; + + boost::unordered_flat_set< + test::minimal::copy_constructible_equality_comparable, + test::minimal::hash, + test::minimal::equal_to< + test::minimal::copy_constructible_equality_comparable>, + test::minimal::allocator > + set; +#else boost::unordered_set int_set; boost::unordered_set, std::equal_to, @@ -92,11 +152,13 @@ UNORDERED_AUTO_TEST (equality_tests) { test::minimal::copy_constructible_equality_comparable>, test::minimal::allocator > set; +#endif equality_test(int_set); equality_test(int_set2); equality_test(set); +#ifndef BOOST_UNORDERED_FOA_TESTS boost::unordered_multiset int_multiset; boost::unordered_multiset, std::equal_to, @@ -114,6 +176,7 @@ UNORDERED_AUTO_TEST (equality_tests) { equality_test(int_multiset); equality_test(int_multiset2); equality_test(multiset); +#endif } UNORDERED_AUTO_TEST (test1) { @@ -122,12 +185,19 @@ UNORDERED_AUTO_TEST (test1) { int value = 0; BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set." << std::endl; +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_set set; + boost::unordered_flat_set, std::equal_to, + test::minimal::cxx11_allocator > + set2; +#else boost::unordered_set set; boost::unordered_set, std::equal_to, test::minimal::cxx11_allocator > set2; +#endif unordered_unique_test(set, value); unordered_set_test(set, value); @@ -137,6 +207,7 @@ UNORDERED_AUTO_TEST (test1) { unordered_set_test(set2, value); unordered_copyable_test(set2, value, value, hash, equal_to); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset." << std::endl; boost::unordered_multiset multiset; @@ -152,6 +223,7 @@ UNORDERED_AUTO_TEST (test1) { unordered_equivalent_test(multiset2, value); unordered_set_test(multiset2, value); unordered_copyable_test(multiset2, value, value, hash, equal_to); +#endif } UNORDERED_AUTO_TEST (test2) { @@ -163,18 +235,26 @@ UNORDERED_AUTO_TEST (test2) { test::minimal::equal_to equal_to(x); BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n"; - +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_set, + test::minimal::equal_to, + test::minimal::allocator > + set; +#else boost::unordered_set, test::minimal::equal_to, test::minimal::allocator > set; +#endif unordered_unique_test(set, assignable); unordered_set_test(set, assignable); unordered_copyable_test(set, assignable, assignable, hash, equal_to); unordered_set_member_test(set, assignable); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n"; boost::unordered_multiset equal_to(x); BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n"; - +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_set, + test::minimal::equal_to, + test::minimal::allocator > + set; +#else boost::unordered_set, test::minimal::equal_to, test::minimal::allocator > set; +#endif // unordered_unique_test(set, movable1); unordered_set_test(set, movable1); unordered_movable_test(set, movable1, movable1, hash, equal_to); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n"; boost::unordered_multiset equal_to(x); BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n"; - +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_set, + test::minimal::equal_to, + test::minimal::allocator > + set; +#else boost::unordered_set, test::minimal::equal_to, test::minimal::allocator > set; +#endif // unordered_unique_test(set, movable2); unordered_set_test(set, movable2); unordered_movable_test(set, movable2, movable2, hash, equal_to); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n"; boost::unordered_multiset equal_to(x); BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n"; - +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_set, + test::minimal::equal_to > + set; +#else boost::unordered_set, test::minimal::equal_to > set; +#endif unordered_destructible_test(set); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n"; boost::unordered_multiset x; + x.emplace(lwg2059_key(10)); + x.erase(x.begin()); +#else { boost::unordered_set x; x.emplace(lwg2059_key(10)); @@ -308,6 +420,7 @@ UNORDERED_AUTO_TEST (lwg2059) { x.emplace(lwg2059_key(10)); x.erase(x.begin()); } +#endif } RUN_TESTS() diff --git a/test/unordered/compile_tests.hpp b/test/unordered/compile_tests.hpp index bb5256f8..3975cd07 100644 --- a/test/unordered/compile_tests.hpp +++ b/test/unordered/compile_tests.hpp @@ -70,7 +70,9 @@ template void container_test(X& r, T const&) typedef typename X::reference reference; typedef typename X::const_reference const_reference; +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename X::node_type node_type; +#endif typedef typename X::allocator_type allocator_type; @@ -97,8 +99,10 @@ template void container_test(X& r, T const&) // node_type +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_STATIC_ASSERT(( boost::is_same::value)); +#endif // difference_type @@ -167,6 +171,7 @@ template void container_test(X& r, T const&) sink(X(rvalue(a_const), m)); X c3(rvalue(a_const), m); +#ifndef BOOST_UNORDERED_FOA_TESTS // node_type implicit_construct(); @@ -193,6 +198,7 @@ template void container_test(X& r, T const&) test::check_return_type::equals(n_const.empty()); TEST_NOEXCEPT_EXPR(!n_const); TEST_NOEXCEPT_EXPR(n_const.empty()); +#endif // Avoid unused variable warnings: @@ -262,24 +268,30 @@ template void unordered_set_test(X& r, Key const&) typedef typename X::iterator iterator; typedef typename X::const_iterator const_iterator; +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename X::local_iterator local_iterator; typedef typename X::const_local_iterator const_local_iterator; +#endif typedef typename std::iterator_traits::pointer iterator_pointer; typedef typename std::iterator_traits::pointer const_iterator_pointer; +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename std::iterator_traits::pointer local_iterator_pointer; typedef typename std::iterator_traits::pointer const_local_iterator_pointer; +#endif BOOST_STATIC_ASSERT( (boost::is_same::value)); BOOST_STATIC_ASSERT( (boost::is_same::value)); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_STATIC_ASSERT( (boost::is_same::value)); BOOST_STATIC_ASSERT( (boost::is_same::value)); +#endif // pointer_traits @@ -299,6 +311,8 @@ template void unordered_set_test(X& r, Key const&) BOOST_STATIC_ASSERT((boost::is_same::difference_type>::value)); + (void) r; +#ifndef BOOST_UNORDERED_FOA_TESTS // pointer_traits BOOST_STATIC_ASSERT((boost::is_same void unordered_set_test(X& r, Key const&) r.emplace(boost::move(k_lvalue)); node_type n1 = r.extract(r.begin()); test::check_return_type::equals_ref(n1.value()); +#endif } template @@ -475,6 +490,9 @@ template void equality_test(X& r) template void unordered_unique_test(X& r, T const& t) { + (void) r; + (void) t; +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename X::iterator iterator; test::check_return_type >::equals(r.insert(t)); test::check_return_type >::equals(r.emplace(t)); @@ -503,6 +521,7 @@ template void unordered_unique_test(X& r, T const& t) test::check_return_type::equals(insert_return.position); test::check_return_type::equals_ref(insert_return.node); boost::swap(insert_return, insert_return2); +#endif } template void unordered_equivalent_test(X& r, T const& t) @@ -554,6 +573,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq) typedef typename X::iterator iterator; typedef typename X::const_iterator const_iterator; +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename X::local_iterator local_iterator; typedef typename X::const_local_iterator const_local_iterator; @@ -590,6 +610,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq) const_local_iterator_pointer; typedef typename std::iterator_traits::reference const_local_iterator_reference; +#endif typedef typename X::allocator_type allocator_type; BOOST_STATIC_ASSERT((boost::is_same::value)); @@ -602,6 +623,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq) BOOST_STATIC_ASSERT((boost::is_same::value)); test::check_return_type::convertible(eq(k, k)); +#ifndef BOOST_UNORDERED_FOA_TESTS boost::function_requires >(); BOOST_STATIC_ASSERT( (boost::is_same::value)); @@ -622,6 +644,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq) const_iterator_pointer>::value)); BOOST_STATIC_ASSERT((boost::is_same::value)); +#endif X a; allocator_type m = a.get_allocator(); @@ -667,6 +690,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq) test::check_return_type >::equals( b.equal_range(k)); test::check_return_type::equals(b.bucket_count()); +#ifndef BOOST_UNORDERED_FOA_TESTS test::check_return_type::equals(b.max_bucket_count()); test::check_return_type::equals(b.bucket(k)); test::check_return_type::equals(b.bucket_size(0)); @@ -680,6 +704,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq) test::check_return_type::equals(b.cbegin(0)); test::check_return_type::equals(a.cend(0)); test::check_return_type::equals(b.cend(0)); +#endif test::check_return_type::equals(b.load_factor()); test::check_return_type::equals(b.max_load_factor()); @@ -792,7 +817,11 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq) X a10; a10.insert(t); q = a10.cbegin(); +#ifdef BOOST_UNORDERED_FOA_TESTS + BOOST_STATIC_ASSERT(std::is_same::value); +#else test::check_return_type::equals(a10.erase(q)); +#endif // Avoid unused variable warnings: @@ -807,10 +836,12 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq) sink(a7a); sink(a9a); +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename X::node_type node_type; typedef typename X::allocator_type allocator_type; node_type const n_const = a.extract(a.begin()); test::check_return_type::equals(n_const.get_allocator()); +#endif } template @@ -879,7 +910,11 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq) T v5(v); a10.insert(boost::move(v5)); q = a10.cbegin(); +#ifdef BOOST_UNORDERED_FOA_TESTS + BOOST_STATIC_ASSERT(std::is_same::value); +#else test::check_return_type::equals(a10.erase(q)); +#endif // Avoid unused variable warnings: