diff --git a/include/boost/unordered/unordered_flat_map.hpp b/include/boost/unordered/unordered_flat_map.hpp index 46784ac4..e39c194d 100644 --- a/include/boost/unordered/unordered_flat_map.hpp +++ b/include/boost/unordered/unordered_flat_map.hpp @@ -35,9 +35,12 @@ namespace boost { using init_type = std::pair; using moved_type = std::pair; using value_type = std::pair; - static Key const& extract(init_type const& kv) { return kv.first; } - static Key const& extract(value_type const& kv) { return kv.first; } - static Key const& extract(moved_type const& kv) { return kv.first; } + + template + static K const& extract(std::pair const& kv) + { + return kv.first; + } static moved_type move(value_type& x) { @@ -57,6 +60,7 @@ namespace boost { using mapped_type = T; using value_type = typename map_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; @@ -79,6 +83,11 @@ namespace boost { { } + unordered_flat_map(size_type n, hasher const& h, allocator_type const& a) + : unordered_flat_map(n, h, key_equal(), a) + { + } + explicit unordered_flat_map(allocator_type const& a) : unordered_flat_map(0, a) { @@ -93,6 +102,20 @@ namespace boost { this->insert(first, last); } + template + unordered_flat_map( + Iterator first, Iterator last, size_type n, allocator_type const& a) + : unordered_flat_map(first, last, n, hasher(), key_equal(), a) + { + } + + template + unordered_flat_map(Iterator first, Iterator last, size_type n, + hasher const& h, allocator_type const& a) + : unordered_flat_map(first, last, n, h, key_equal(), a) + { + } + unordered_flat_map(unordered_flat_map const& other) : table_(other.table_) { } @@ -124,6 +147,18 @@ namespace boost { { } + unordered_flat_map(std::initializer_list init, size_type n, + allocator_type const& a) + : unordered_flat_map(init, n, hasher(), key_equal(), a) + { + } + + unordered_flat_map(std::initializer_list init, size_type n, + hasher const& h, allocator_type const& a) + : unordered_flat_map(init, n, h, key_equal(), a) + { + } + ~unordered_flat_map() = default; unordered_flat_map& operator=(unordered_flat_map const& other) @@ -165,6 +200,8 @@ namespace boost { size_type size() const noexcept { return table_.size(); } + size_type max_size() const noexcept { return table_.max_size(); } + /// Modifiers /// @@ -302,6 +339,22 @@ namespace boost { table_.swap(rhs.table_); } + template + void merge( + unordered_flat_map& + source) + { + (void)source; + } + + template + void merge( + unordered_flat_map&& + source) + { + (void)source; + } + /// Lookup /// diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fa9d474c..5c15aa0d 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -105,6 +105,7 @@ rule build_foa ( name ) build_foa fwd_set_test ; build_foa fwd_map_test ; build_foa compile_set ; +build_foa compile_map ; build_foa constructor_tests ; build_foa copy_tests ; build_foa move_tests ; diff --git a/test/unordered/compile_map.cpp b/test/unordered/compile_map.cpp index 6a84d595..272f7de5 100644 --- a/test/unordered/compile_map.cpp +++ b/test/unordered/compile_map.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 @@ -17,7 +22,28 @@ #include "./compile_tests.hpp" // 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_map +{ + typedef boost::unordered_flat_map container; + container x; +}; + +template class instantiate_flat_map, + std::equal_to, test::minimal::allocator >; + +template class instantiate_flat_map, + test::minimal::equal_to, + test::minimal::allocator >; + +#else #define INSTANTIATE(type) \ template class boost::unordered::detail::instantiate_##type @@ -35,6 +61,7 @@ INSTANTIATE(multimap), test::minimal::equal_to, test::minimal::allocator >; +#endif UNORDERED_AUTO_TEST (test0) { test::minimal::constructor_param x; @@ -45,6 +72,19 @@ UNORDERED_AUTO_TEST (test0) { BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n"; +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_map int_map; + + boost::unordered_flat_map, std::equal_to, + test::minimal::cxx11_allocator > > + int_map2; + + boost::unordered_flat_map, + test::minimal::equal_to, + test::minimal::allocator > + map; +#else boost::unordered_map int_map; boost::unordered_map, std::equal_to, @@ -56,11 +96,13 @@ UNORDERED_AUTO_TEST (test0) { test::minimal::equal_to, test::minimal::allocator > map; +#endif container_test(int_map, std::pair(0, 0)); container_test(int_map2, std::pair(0, 0)); container_test(map, value); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n"; boost::unordered_multimap int_multimap; @@ -78,6 +120,7 @@ UNORDERED_AUTO_TEST (test0) { container_test(int_multimap, std::pair(0, 0)); container_test(int_multimap2, std::pair(0, 0)); container_test(multimap, value); +#endif } UNORDERED_AUTO_TEST (equality_tests) { @@ -85,6 +128,22 @@ UNORDERED_AUTO_TEST (equality_tests) { test::minimal::copy_constructible_equality_comparable> value_type; +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_map int_map; + + boost::unordered_flat_map, std::equal_to, + test::minimal::cxx11_allocator > > + int_map2; + + boost::unordered_flat_map< + test::minimal::copy_constructible_equality_comparable, + test::minimal::copy_constructible_equality_comparable, + test::minimal::hash, + test::minimal::equal_to< + test::minimal::copy_constructible_equality_comparable>, + test::minimal::allocator > + map; +#else boost::unordered_map int_map; boost::unordered_map, std::equal_to, @@ -98,11 +157,13 @@ UNORDERED_AUTO_TEST (equality_tests) { test::minimal::copy_constructible_equality_comparable>, test::minimal::allocator > map; +#endif equality_test(int_map); equality_test(int_map2); equality_test(map); +#ifndef BOOST_UNORDERED_FOA_TESTS boost::unordered_multimap int_multimap; boost::unordered_multimap, std::equal_to, @@ -121,6 +182,7 @@ UNORDERED_AUTO_TEST (equality_tests) { equality_test(int_multimap); equality_test(int_multimap2); equality_test(multimap); +#endif } UNORDERED_AUTO_TEST (test1) { @@ -131,11 +193,19 @@ UNORDERED_AUTO_TEST (test1) { BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n"; +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_map map; + + boost::unordered_flat_map, std::equal_to, + test::minimal::cxx11_allocator > > + map2; +#else boost::unordered_map map; boost::unordered_map, std::equal_to, test::minimal::cxx11_allocator > > map2; +#endif unordered_unique_test(map, map_value); unordered_map_test(map, value, value); @@ -147,6 +217,7 @@ UNORDERED_AUTO_TEST (test1) { unordered_copyable_test(map2, value, map_value, hash, equal_to); unordered_map_functions(map2, value, value); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n"; boost::unordered_multimap multimap; @@ -162,6 +233,7 @@ UNORDERED_AUTO_TEST (test1) { unordered_equivalent_test(multimap2, map_value); unordered_map_test(multimap2, value, value); unordered_copyable_test(multimap2, value, map_value, hash, equal_to); +#endif } UNORDERED_AUTO_TEST (test2) { @@ -178,28 +250,46 @@ UNORDERED_AUTO_TEST (test2) { BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n"; +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_map, + test::minimal::equal_to, + test::minimal::allocator > + map; +#else boost::unordered_map, test::minimal::equal_to, test::minimal::allocator > map; +#endif unordered_unique_test(map, map_value); unordered_map_test(map, assignable, assignable); unordered_copyable_test(map, assignable, map_value, hash, equal_to); unordered_map_member_test(map, map_value); +#ifdef BOOST_UNORDERED_FOA_TESTS + boost::unordered_flat_map, + test::minimal::equal_to, + test::minimal::allocator > + map2; +#else boost::unordered_map, test::minimal::equal_to, test::minimal::allocator > map2; +#endif test::minimal::default_assignable default_assignable; unordered_map_functions(map2, assignable, default_assignable); +#ifndef BOOST_UNORDERED_FOA_TESTS BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n"; boost::unordered_multimap x; + x.emplace(lwg2059_key(10), 5); + x.erase(x.begin()); +#else { boost::unordered_map x; x.emplace(lwg2059_key(10), 5); @@ -243,6 +339,7 @@ UNORDERED_AUTO_TEST (lwg2059) { x.emplace(lwg2059_key(10), 5); x.erase(x.begin()); } +#endif } RUN_TESTS() diff --git a/test/unordered/compile_tests.hpp b/test/unordered/compile_tests.hpp index 3975cd07..65509e79 100644 --- a/test/unordered/compile_tests.hpp +++ b/test/unordered/compile_tests.hpp @@ -360,23 +360,29 @@ void unordered_map_test(X& r, Key const& k, T const& v) 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 @@ -396,6 +402,7 @@ void unordered_map_test(X& r, Key const& k, T const& v) BOOST_STATIC_ASSERT((boost::is_same::difference_type>::value)); +#ifndef BOOST_UNORDERED_FOA_TESTS // pointer_traits BOOST_STATIC_ASSERT((boost::is_same::value)); // Superfluous,but just to make sure. BOOST_STATIC_ASSERT((!boost::is_const::value)); +#endif // Calling functions @@ -442,8 +450,12 @@ void unordered_map_test(X& r, Key const& k, T const& v) r.emplace(k_lvalue, v_lvalue); r.emplace(rvalue(k), rvalue(v)); +#ifdef BOOST_UNORDERED_FOA_TESTS + r.emplace(std::piecewise_construct, std::make_tuple(k), std::make_tuple(v)); +#else r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k), boost::make_tuple(v)); +#endif // Emplace with hint @@ -451,9 +463,15 @@ void unordered_map_test(X& r, Key const& k, T const& v) r.emplace_hint(r.begin(), k_lvalue, v_lvalue); r.emplace_hint(r.begin(), rvalue(k), rvalue(v)); +#ifdef BOOST_UNORDERED_FOA_TESTS + r.emplace_hint(r.begin(), std::piecewise_construct, std::make_tuple(k), + std::make_tuple(v)); +#else r.emplace_hint(r.begin(), boost::unordered::piecewise_construct, boost::make_tuple(k), boost::make_tuple(v)); +#endif +#ifndef BOOST_UNORDERED_FOA_TESTS // Extract test::check_return_type::equals(r.extract(r.begin())); @@ -476,6 +494,7 @@ void unordered_map_test(X& r, Key const& k, T const& v) node_type n = r.extract(r.begin()); test::check_return_type::equals_ref(n.key()); test::check_return_type::equals_ref(n.mapped()); +#endif } template void equality_test(X& r)