diff --git a/include/boost/unordered/unordered_flat_map.hpp b/include/boost/unordered/unordered_flat_map.hpp index 426391fb..3c687124 100644 --- a/include/boost/unordered/unordered_flat_map.hpp +++ b/include/boost/unordered/unordered_flat_map.hpp @@ -286,6 +286,15 @@ namespace boost { size_type erase(key_type const& key) { return table_.erase(key); } + template + typename std::enable_if< + detail::transparent_non_iterable::value, + size_type>::type + erase(K const& key) + { + return table_.erase(key); + } + /// Lookup /// @@ -326,6 +335,15 @@ namespace boost { return pos != table_.end() ? 1 : 0; } + template + typename std::enable_if< + detail::are_transparent::value, size_type>::type + count(K const& key) const + { + auto pos = table_.find(key); + return pos != table_.end() ? 1 : 0; + } + iterator find(key_type const& key) { return table_.find(key); } const_iterator find(key_type const& key) const @@ -390,6 +408,38 @@ namespace boost { return {pos, next}; } + template + typename std::enable_if< + detail::are_transparent::value, + std::pair >::type + equal_range(K const& key) + { + auto pos = table_.find(key); + if (pos == table_.end()) { + return {pos, pos}; + } + + auto next = pos; + ++next; + return {pos, next}; + } + + template + typename std::enable_if< + detail::are_transparent::value, + std::pair >::type + equal_range(K const& key) const + { + auto pos = table_.find(key); + if (pos == table_.end()) { + return {pos, pos}; + } + + auto next = pos; + ++next; + return {pos, next}; + } + /// Hash Policy /// diff --git a/include/boost/unordered/unordered_flat_set.hpp b/include/boost/unordered/unordered_flat_set.hpp index 1b48a1a1..297e4554 100644 --- a/include/boost/unordered/unordered_flat_set.hpp +++ b/include/boost/unordered/unordered_flat_set.hpp @@ -214,6 +214,15 @@ namespace boost { size_type erase(key_type const& key) { return table_.erase(key); } + template + typename std::enable_if< + detail::transparent_non_iterable::value, + size_type>::type + erase(K const& key) + { + return table_.erase(key); + } + /// Lookup /// @@ -223,6 +232,15 @@ namespace boost { return pos != table_.end() ? 1 : 0; } + template + typename std::enable_if< + detail::are_transparent::value, size_type>::type + count(K const& key) const + { + auto pos = table_.find(key); + return pos != table_.end() ? 1 : 0; + } + iterator find(key_type const& key) { return table_.find(key); } const_iterator find(key_type const& key) const @@ -287,6 +305,38 @@ namespace boost { return {pos, next}; } + template + typename std::enable_if< + detail::are_transparent::value, + std::pair >::type + equal_range(K const& key) + { + auto pos = table_.find(key); + if (pos == table_.end()) { + return {pos, pos}; + } + + auto next = pos; + ++next; + return {pos, next}; + } + + template + typename std::enable_if< + detail::are_transparent::value, + std::pair >::type + equal_range(K const& key) const + { + auto pos = table_.find(key); + if (pos == table_.end()) { + return {pos, pos}; + } + + auto next = pos; + ++next; + return {pos, next}; + } + /// Hash Policy /// diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f1425155..628553a6 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -114,5 +114,6 @@ build_foa find_tests ; build_foa at_tests ; build_foa load_factor_tests ; build_foa rehash_tests ; +build_foa transparent_tests ; build_foa contains_tests ; build_foa equality_tests ; diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 50f6bfdc..d1e67870 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -4,8 +4,14 @@ // clang-format off #include "../helpers/prefix.hpp" +#ifdef BOOST_UNORDERED_FOA_TESTS +#include +#include +#include +#else #include #include +#endif #include "../helpers/postfix.hpp" // clang-format on @@ -1053,14 +1059,25 @@ template struct convertible_to_const_iterator } }; +#ifdef BOOST_UNORDERED_FOA_TESTS +typedef boost::unordered_flat_map + transparent_unordered_map; +#else typedef boost::unordered_map transparent_unordered_map; +#endif // test that in the presence of the member function template `erase()`, we still // invoke the correct iterator overloads when the type is implicitly convertible // -transparent_unordered_map::iterator map_erase_overload_compile_test() +#ifdef BOOST_UNORDERED_FOA_TESTS +void +#else +transparent_unordered_map::iterator +#endif +map_erase_overload_compile_test() { convertible_to_iterator c; transparent_unordered_map map; @@ -1069,7 +1086,11 @@ transparent_unordered_map::iterator map_erase_overload_compile_test() return map.erase(c); } +#ifdef BOOST_UNORDERED_FOA_TESTS +void +#else transparent_unordered_map::const_iterator +#endif map_erase_const_overload_compile_test() { convertible_to_const_iterator c; @@ -1079,6 +1100,7 @@ map_erase_const_overload_compile_test() return map.erase(c); } +#ifndef BOOST_UNORDERED_FOA_TESTS typedef boost::unordered_multimap transparent_unordered_multimap; @@ -1101,6 +1123,7 @@ multimap_erase_const_overload_compile_test() pos = c; return map.erase(c); } +#endif template void test_map_transparent_erase() { @@ -1197,14 +1220,25 @@ template void test_map_non_transparent_erase() BOOST_TEST_EQ(key::count_, key_count); } +#if BOOST_UNORDERED_FOA_TESTS +typedef boost::unordered_flat_set + transparent_unordered_set; +#else typedef boost::unordered_set transparent_unordered_set; typedef boost::unordered_multiset transparent_unordered_multiset; +#endif -transparent_unordered_set::iterator set_erase_overload_compile_test() +#ifdef BOOST_UNORDERED_FOA_TESTS +void +#else +transparent_unordered_set::iterator +#endif +set_erase_overload_compile_test() { convertible_to_iterator c; transparent_unordered_set set; @@ -1213,7 +1247,11 @@ transparent_unordered_set::iterator set_erase_overload_compile_test() return set.erase(c); } +#ifdef BOOST_UNORDERED_FOA_TESTS +void +#else transparent_unordered_set::const_iterator +#endif set_erase_const_overload_compile_test() { convertible_to_const_iterator c; @@ -1223,6 +1261,7 @@ set_erase_const_overload_compile_test() return set.erase(c); } +#ifndef BOOST_UNORDERED_FOA_TESTS transparent_unordered_multiset::iterator multiset_erase_overload_compile_test() { convertible_to_iterator c; @@ -1241,6 +1280,7 @@ multiset_erase_const_overload_compile_test() pos = c; return set.erase(c); } +#endif template void test_set_transparent_erase() { @@ -1337,6 +1377,7 @@ template void test_set_non_transparent_erase() BOOST_TEST_EQ(key::count_, key_count); } +#ifndef BOOST_UNORDERED_FOA_TESTS // test that in the presence of the member function template `extract()`, we // still invoke the correct iterator overloads when the type is implicitly // convertible @@ -1359,9 +1400,11 @@ multimap_extract_const_overload_compile_test() pos = c; return map.extract(c); } +#endif template void test_map_transparent_extract() { +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename UnorderedMap::node_type node_type; typedef typename UnorderedMap::const_iterator const_iterator; typedef std::pair const_iterator_pair; @@ -1397,10 +1440,12 @@ template void test_map_transparent_extract() BOOST_TEST(nh.empty()); BOOST_TEST_EQ(key::count_, expected_key_count); +#endif } template void test_map_non_transparent_extract() { +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename UnorderedMap::node_type node_type; typedef typename UnorderedMap::const_iterator const_iterator; typedef std::pair const_iterator_pair; @@ -1441,8 +1486,10 @@ template void test_map_non_transparent_extract() ++key_count; BOOST_TEST(nh.empty()); BOOST_TEST_EQ(key::count_, key_count); +#endif } +#ifndef BOOST_UNORDERED_FOA_TESTS transparent_unordered_set::node_type set_extract_overload_compile_test() { convertible_to_iterator c; @@ -1480,9 +1527,11 @@ multiset_extract_const_overload_compile_test() pos = c; return set.extract(c); } +#endif template void test_set_transparent_extract() { +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename UnorderedSet::node_type node_type; count_reset(); @@ -1526,10 +1575,12 @@ template void test_set_transparent_extract() BOOST_TEST_EQ(set.size(), set_size); BOOST_TEST_EQ(key::count_, expected_key_count); +#endif } template void test_set_non_transparent_extract() { +#ifndef BOOST_UNORDERED_FOA_TESTS typedef typename UnorderedSet::node_type node_type; count_reset(); @@ -1583,14 +1634,23 @@ template void test_set_non_transparent_extract() BOOST_TEST_EQ(set.size(), set_size); BOOST_TEST_EQ(key::count_, key_count); +#endif } +template struct map_type +{ +#ifdef BOOST_UNORDERED_FOA_TESTS + typedef boost::unordered_flat_map type; +#else + typedef boost::unordered_map type; +#endif +}; + void test_unordered_map() { { - typedef boost::unordered_map - unordered_map; + typedef typename map_type::type unordered_map; test_map_transparent_count(); test_map_transparent_find(); @@ -1602,7 +1662,7 @@ void test_unordered_map() { // non-transparent Hash, non-transparent KeyEqual // - typedef boost::unordered_map unordered_map; + typedef typename map_type::type unordered_map; test_map_non_transparent_count(); test_map_non_transparent_find(); @@ -1614,7 +1674,7 @@ void test_unordered_map() { // transparent Hash, non-transparent KeyEqual // - typedef boost::unordered_map + typedef typename map_type::type unordered_map; test_map_non_transparent_count(); @@ -1627,7 +1687,7 @@ void test_unordered_map() { // non-transparent Hash, transparent KeyEqual // - typedef boost::unordered_map + typedef typename map_type::type unordered_map; test_map_non_transparent_count(); @@ -1638,6 +1698,7 @@ void test_unordered_map() } } +#ifndef BOOST_UNORDERED_FOA_TESTS void test_unordered_multimap() { { @@ -1691,12 +1752,23 @@ void test_unordered_multimap() test_map_non_transparent_extract(); } } +#endif + +template struct set_type +{ +#ifdef BOOST_UNORDERED_FOA_TESTS + typedef boost::unordered_flat_set type; +#else + typedef boost::unordered_set type; +#endif +}; void test_unordered_set() { { - typedef boost::unordered_set - unordered_set; + typedef + typename set_type::type + unordered_set; test_set_transparent_count(); test_set_transparent_find(); @@ -1708,7 +1780,7 @@ void test_unordered_set() { // non-transparent Hash, non-transparent KeyEqual // - typedef boost::unordered_set unordered_set; + typedef typename set_type::type unordered_set; test_set_non_transparent_count(); test_set_non_transparent_find(); @@ -1720,8 +1792,8 @@ void test_unordered_set() { // transparent Hash, non-transparent KeyEqual // - typedef boost::unordered_set - unordered_set; + typedef + typename set_type::type unordered_set; test_set_non_transparent_count(); test_set_non_transparent_find(); @@ -1733,8 +1805,8 @@ void test_unordered_set() { // non-transparent Hash, transparent KeyEqual // - typedef boost::unordered_set - unordered_set; + typedef + typename set_type::type unordered_set; test_set_non_transparent_count(); test_set_non_transparent_find(); @@ -1744,6 +1816,7 @@ void test_unordered_set() } } +#ifndef BOOST_UNORDERED_FOA_TESTS void test_unordered_multiset() { { @@ -1796,12 +1869,16 @@ void test_unordered_multiset() test_set_non_transparent_extract(); } } +#endif UNORDERED_AUTO_TEST (transparent_ops) { test_unordered_map(); - test_unordered_multimap(); test_unordered_set(); + +#ifndef BOOST_UNORDERED_FOA_TESTS + test_unordered_multimap(); test_unordered_multiset(); +#endif } RUN_TESTS()