diff --git a/include/boost/unordered/unordered_flat_map.hpp b/include/boost/unordered/unordered_flat_map.hpp index ccc7568e..7ba2ba28 100644 --- a/include/boost/unordered/unordered_flat_map.hpp +++ b/include/boost/unordered/unordered_flat_map.hpp @@ -106,6 +106,13 @@ namespace boost { { } + template + unordered_flat_map( + InputIterator f, InputIterator l, allocator_type const& a) + : unordered_flat_map(f, l, size_type(0), hasher(), key_equal(), a) + { + } + explicit unordered_flat_map(allocator_type const& a) : unordered_flat_map(0, a) { @@ -165,6 +172,12 @@ namespace boost { { } + unordered_flat_map( + std::initializer_list il, allocator_type const& a) + : unordered_flat_map(il, size_type(0), hasher(), key_equal(), a) + { + } + unordered_flat_map(std::initializer_list init, size_type n, allocator_type const& a) : unordered_flat_map(init, n, hasher(), key_equal(), a) diff --git a/include/boost/unordered/unordered_flat_set.hpp b/include/boost/unordered/unordered_flat_set.hpp index 55d79b02..ef96d4e1 100644 --- a/include/boost/unordered/unordered_flat_set.hpp +++ b/include/boost/unordered/unordered_flat_set.hpp @@ -88,6 +88,13 @@ namespace boost { { } + template + unordered_flat_set( + InputIterator f, InputIterator l, allocator_type const& a) + : unordered_flat_set(f, l, size_type(0), hasher(), key_equal(), a) + { + } + explicit unordered_flat_set(allocator_type const& a) : unordered_flat_set(0, a) { @@ -147,6 +154,12 @@ namespace boost { { } + unordered_flat_set( + std::initializer_list il, allocator_type const& a) + : unordered_flat_set(il, size_type(0), hasher(), key_equal(), a) + { + } + unordered_flat_set(std::initializer_list init, size_type n, allocator_type const& a) : unordered_flat_set(init, n, hasher(), key_equal(), a) diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index d66c5394..4a060358 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -123,6 +123,9 @@ namespace boost { explicit unordered_map(size_type, const hasher&, const allocator_type&); + template + unordered_map(InputIterator, InputIterator, const allocator_type&); + template unordered_map(InputIt, InputIt, size_type, const allocator_type&); @@ -131,6 +134,8 @@ namespace boost { InputIt, InputIt, size_type, const hasher&, const allocator_type&); #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + unordered_map(std::initializer_list, const allocator_type&); + unordered_map( std::initializer_list, size_type, const allocator_type&); @@ -1076,6 +1081,9 @@ namespace boost { explicit unordered_multimap( size_type, const hasher&, const allocator_type&); + template + unordered_multimap(InputIterator, InputIterator, const allocator_type&); + template unordered_multimap(InputIt, InputIt, size_type, const allocator_type&); @@ -1084,6 +1092,9 @@ namespace boost { InputIt, InputIt, size_type, const hasher&, const allocator_type&); #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + unordered_multimap( + std::initializer_list, const allocator_type&); + unordered_multimap( std::initializer_list, size_type, const allocator_type&); @@ -1751,6 +1762,17 @@ namespace boost { { } + template + template + unordered_map::unordered_map( + InputIterator f, InputIterator l, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + f, l, detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(f, l); + } + template template unordered_map::unordered_map( @@ -1773,6 +1795,16 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + unordered_map::unordered_map( + std::initializer_list list, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + list.begin(), list.end(), detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(list.begin(), list.end()); + } + template unordered_map::unordered_map( std::initializer_list list, size_type n, @@ -2234,6 +2266,17 @@ namespace boost { { } + template + template + unordered_multimap::unordered_multimap( + InputIterator f, InputIterator l, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + f, l, detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(f, l); + } + template template unordered_multimap::unordered_multimap( @@ -2256,6 +2299,16 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + unordered_multimap::unordered_multimap( + std::initializer_list list, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + list.begin(), list.end(), detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(list.begin(), list.end()); + } + template unordered_multimap::unordered_multimap( std::initializer_list list, size_type n, diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index ed736c21..b3e75134 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -121,6 +121,9 @@ namespace boost { explicit unordered_set(size_type, const hasher&, const allocator_type&); + template + unordered_set(InputIterator, InputIterator, const allocator_type&); + template unordered_set(InputIt, InputIt, size_type, const allocator_type&); @@ -129,6 +132,8 @@ namespace boost { InputIt, InputIt, size_type, const hasher&, const allocator_type&); #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + unordered_set(std::initializer_list, const allocator_type&); + unordered_set( std::initializer_list, size_type, const allocator_type&); @@ -739,6 +744,9 @@ namespace boost { explicit unordered_multiset( size_type, const hasher&, const allocator_type&); + template + unordered_multiset(InputIterator, InputIterator, const allocator_type&); + template unordered_multiset(InputIt, InputIt, size_type, const allocator_type&); @@ -747,6 +755,9 @@ namespace boost { InputIt, InputIt, size_type, const hasher&, const allocator_type&); #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + unordered_multiset( + std::initializer_list, const allocator_type&); + unordered_multiset( std::initializer_list, size_type, const allocator_type&); @@ -1352,6 +1363,17 @@ namespace boost { { } + template + template + unordered_set::unordered_set( + InputIterator f, InputIterator l, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + f, l, detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(f, l); + } + template template unordered_set::unordered_set( @@ -1374,6 +1396,16 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + unordered_set::unordered_set( + std::initializer_list list, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + list.begin(), list.end(), detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(list.begin(), list.end()); + } + template unordered_set::unordered_set( std::initializer_list list, size_type n, @@ -1750,6 +1782,17 @@ namespace boost { { } + template + template + unordered_multiset::unordered_multiset( + InputIterator f, InputIterator l, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + f, l, detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(f, l); + } + template template unordered_multiset::unordered_multiset( @@ -1772,6 +1815,16 @@ namespace boost { #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + template + unordered_multiset::unordered_multiset( + std::initializer_list list, const allocator_type& a) + : table_(boost::unordered::detail::initial_size( + list.begin(), list.end(), detail::default_bucket_count), + hasher(), key_equal(), a) + { + this->insert(list.begin(), list.end()); + } + template unordered_multiset::unordered_multiset( std::initializer_list list, size_type n, diff --git a/test/unordered/constructor_tests.cpp b/test/unordered/constructor_tests.cpp index b68a7eb5..b610b5b1 100644 --- a/test/unordered/constructor_tests.cpp +++ b/test/unordered/constructor_tests.cpp @@ -14,6 +14,8 @@ #include "../helpers/input_iterator.hpp" #include "../helpers/invariants.hpp" +#include + namespace constructor_tests { test::seed_t initialize_seed(356730); @@ -171,6 +173,16 @@ namespace constructor_tests { BOOST_TEST(test::equivalent(x.get_allocator(), al)); test::check_equivalent_keys(x); } + + UNORDERED_SUB_TEST("Construct 12") + { + test::check_instances check_; + + test::random_values v(1000, generator); + T x(v.begin(), v.end(), al); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + test::check_container(x, v); + } } template @@ -317,66 +329,206 @@ namespace constructor_tests { } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - std::initializer_list list; + typedef typename T::value_type value_type; + + std::initializer_list list; + + test::random_values v(3, generator); + std::vector vec(v.begin(), v.end()); + BOOST_ASSERT(vec.size() >= 3); + + // create a new vector here because erase() requires assignability which is + // deleted for some of the test types + // + std::vector expected(vec.begin(), vec.begin() + 3); UNORDERED_SUB_TEST("Initializer list construct 1") { test::check_instances check_; - T x(list); - BOOST_TEST(x.empty()); - BOOST_TEST_EQ(x.bucket_count(), 0u); - BOOST_TEST(test::equivalent(x.hash_function(), hf)); - BOOST_TEST(test::equivalent(x.key_eq(), eq)); - BOOST_TEST(test::equivalent(x.get_allocator(), al)); + { + T x(list); + BOOST_TEST(x.empty()); + BOOST_TEST_EQ(x.bucket_count(), 0u); + BOOST_TEST(test::equivalent(x.hash_function(), hf)); + BOOST_TEST(test::equivalent(x.key_eq(), eq)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + } + + { + T x{vec[0], vec[1], vec[2]}; + BOOST_TEST_NOT(x.empty()); + BOOST_TEST_GT(x.bucket_count(), 0u); + BOOST_TEST(test::equivalent(x.hash_function(), hf)); + BOOST_TEST(test::equivalent(x.key_eq(), eq)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + test::check_container(x, expected); + } } UNORDERED_SUB_TEST("Initializer list construct 2") { test::check_instances check_; - T x(list, 1000); - BOOST_TEST(x.empty()); - BOOST_TEST(x.bucket_count() >= 1000); - BOOST_TEST(test::equivalent(x.hash_function(), hf)); - BOOST_TEST(test::equivalent(x.key_eq(), eq)); - BOOST_TEST(test::equivalent(x.get_allocator(), al)); + { + T x(list, 1000); + BOOST_TEST(x.empty()); + BOOST_TEST(x.bucket_count() >= 1000); + BOOST_TEST(test::equivalent(x.hash_function(), hf)); + BOOST_TEST(test::equivalent(x.key_eq(), eq)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + } + + { + T x({vec[0], vec[1], vec[2]}, 1000); + BOOST_TEST_NOT(x.empty()); + BOOST_TEST(x.bucket_count() >= 1000); + BOOST_TEST(test::equivalent(x.hash_function(), hf)); + BOOST_TEST(test::equivalent(x.key_eq(), eq)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + test::check_container(x, expected); + } } UNORDERED_SUB_TEST("Initializer list construct 3") { - test::check_instances check_; + { + test::check_instances check_; - T x(list, 10, hf1); - BOOST_TEST(x.empty()); - BOOST_TEST(x.bucket_count() >= 10); - BOOST_TEST(test::equivalent(x.hash_function(), hf1)); - BOOST_TEST(test::equivalent(x.key_eq(), eq)); - BOOST_TEST(test::equivalent(x.get_allocator(), al)); + T x(list, 10, hf1); + BOOST_TEST(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.key_eq(), eq)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + } + + { + test::check_instances check_; + + T x({vec[0], vec[1], vec[2]}, 10, hf1); + BOOST_TEST_NOT(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.key_eq(), eq)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + test::check_container(x, expected); + } } UNORDERED_SUB_TEST("Initializer list construct 4") { - test::check_instances check_; + { + test::check_instances check_; - T x(list, 10, hf1, eq1); - BOOST_TEST(x.empty()); - BOOST_TEST(x.bucket_count() >= 10); - BOOST_TEST(test::equivalent(x.hash_function(), hf1)); - BOOST_TEST(test::equivalent(x.key_eq(), eq1)); - BOOST_TEST(test::equivalent(x.get_allocator(), al)); + T x(list, 10, hf1, eq1); + BOOST_TEST(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.key_eq(), eq1)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + } + + { + test::check_instances check_; + + T x({vec[0], vec[1], vec[2]}, 10, hf1, eq1); + BOOST_TEST_NOT(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.key_eq(), eq1)); + BOOST_TEST(test::equivalent(x.get_allocator(), al)); + test::check_container(x, expected); + } } UNORDERED_SUB_TEST("Initializer list construct 5") + { + { + test::check_instances check_; + + T x(list, 10, hf1, eq1, al1); + BOOST_TEST(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.key_eq(), eq1)); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + } + + { + test::check_instances check_; + + T x({vec[0], vec[1], vec[2]}, 10, hf1, eq1, al1); + BOOST_TEST_NOT(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.key_eq(), eq1)); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + test::check_container(x, expected); + } + } + + UNORDERED_SUB_TEST("Initializer list construct 6") + { + { + test::check_instances check_; + + T x(list, 10, al1); + BOOST_TEST(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + } + + { + test::check_instances check_; + + T x({vec[0], vec[1], vec[2]}, 10, al1); + BOOST_TEST_NOT(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + test::check_container(x, expected); + } + } + + UNORDERED_SUB_TEST("Initializer list construct 7") + { + { + test::check_instances check_; + + T x(list, 10, hf1, al1); + BOOST_TEST(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + } + + { + test::check_instances check_; + + T x({vec[0], vec[1], vec[2]}, 10, hf1, al1); + BOOST_TEST_NOT(x.empty()); + BOOST_TEST(x.bucket_count() >= 10); + BOOST_TEST(test::equivalent(x.hash_function(), hf1)); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + test::check_container(x, expected); + } + } + + UNORDERED_SUB_TEST("Initializer list construct 8") { test::check_instances check_; - T x(list, 10, hf1, eq1, al1); - BOOST_TEST(x.empty()); - BOOST_TEST(x.bucket_count() >= 10); - BOOST_TEST(test::equivalent(x.hash_function(), hf1)); - BOOST_TEST(test::equivalent(x.key_eq(), eq1)); - BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + { + T x(list, al1); + BOOST_TEST(x.empty()); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + } + + { + T x({vec[0], vec[1], vec[2]}, al1); + BOOST_TEST(test::equivalent(x.get_allocator(), al1)); + test::check_container(x, expected); + } } #endif }