From f41b3e8295a8c831808a9b188be802149b92c8a4 Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Fri, 19 Nov 2021 15:29:57 -0800 Subject: [PATCH 1/9] Get initial prototype of transparent `count()` working --- include/boost/unordered/unordered_map.hpp | 17 ++++++ test/Jamfile.v2 | 1 + test/unordered/transparent_tests.cpp | 64 +++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 test/unordered/transparent_tests.cpp diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index a9387ef3..aed6619b 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -757,6 +757,8 @@ namespace boost { size_type count(const key_type&) const; + template size_type count(const TransparentKey&) const; + std::pair equal_range(const key_type&); std::pair equal_range( const key_type&) const; @@ -1837,6 +1839,21 @@ namespace boost { return table_.find_node(k) ? 1 : 0; } + template + template + typename unordered_map::size_type + unordered_map::count(const TransparentKey& k) const + { + std::size_t const key_hash = + table::policy::apply_hash(this->hash_function(), k); + + P const& eq = this->key_eq(); + + node_pointer p = table_.find_node_impl(key_hash, k, eq); + + return (p ? 1 : 0); + } + template std::pair::iterator, typename unordered_map::iterator> diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e87886aa..e91cfc98 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -65,6 +65,7 @@ test-suite unordered [ run unordered/detail_tests.cpp ] [ run unordered/deduction_tests.cpp ] [ run unordered/scoped_allocator.cpp /boost/filesystem//boost_filesystem ] + [ run unordered/transparent_tests.cpp ] [ run unordered/compile_set.cpp : : : BOOST_UNORDERED_USE_MOVE diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp new file mode 100644 index 00000000..22c20905 --- /dev/null +++ b/test/unordered/transparent_tests.cpp @@ -0,0 +1,64 @@ +// Copyright 2021 Christian Mazakas. +// 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) + +// clang-format off +#include "../helpers/prefix.hpp" +#include +#include +#include "../helpers/postfix.hpp" +// clang-format on + +#include "../helpers/test.hpp" + +#include + +struct key { + int x_; + static int count_; + + explicit key(int x) : x_(x) { + ++count_; + } +}; + +int key::count_; + +UNORDERED_AUTO_TEST(transparent_count) { + key::count_ = 0; + + struct hasher { + std::size_t operator()(key const& k) const { + return boost::hash()(k.x_); + } + + std::size_t operator()(int const k) const { + return boost::hash()(k); + } + }; + + struct key_equal { + bool operator()(key const& k1, key const& k2) const { + return k1.x_ == k2.x_; + } + + bool operator()(key const& k1, int const x) const { + return k1.x_ == x; + } + + bool operator()(int const x, key const& k1 ) const { + return k1.x_ == x; + } + }; + + boost::unordered_map map; + map.insert({key(0), 1337}); + BOOST_TEST(key::count_ == 1); + + std::size_t const count = map.count(0); + + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 1); +} + +RUN_TESTS() From 59db6cf7882f992a18adce8f0765660fbbc1fe88 Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Mon, 22 Nov 2021 11:16:04 -0800 Subject: [PATCH 2/9] Add SFINAE to transparent `count()` overload in `unordered_map` --- .../boost/unordered/detail/implementation.hpp | 17 +++++++++++++++++ include/boost/unordered/unordered_map.hpp | 16 ++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 4d411b31..7c9150ba 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -722,6 +723,22 @@ namespace boost { #endif +//////////////////////////////////////////////////////////////////////////// +// Type checkers used for the transparent member functions added by C++20 and up + + template + struct make_dependent : public true_type {}; + + template struct is_transparent : public false_type + { + }; + + template + struct is_transparent::type> : public true_type + { + }; + //////////////////////////////////////////////////////////////////////////// // Explicitly call a destructor diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index aed6619b..7e6dd467 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -757,7 +757,12 @@ namespace boost { size_type count(const key_type&) const; - template size_type count(const TransparentKey&) const; + template + typename boost::enable_if_c::value && + detail::is_transparent::value && + detail::is_transparent

::value, + size_type>::type + count(const Key&) const; std::pair equal_range(const key_type&); std::pair equal_range( @@ -1840,9 +1845,12 @@ namespace boost { } template - template - typename unordered_map::size_type - unordered_map::count(const TransparentKey& k) const + template + typename boost::enable_if_c::value && + detail::is_transparent::value && + detail::is_transparent

::value, + typename unordered_map::size_type>::type + unordered_map::count(const Key& k) const { std::size_t const key_hash = table::policy::apply_hash(this->hash_function(), k); From 937c3484cf32704f7c7fd69cbff45165b9d65aa0 Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Mon, 22 Nov 2021 12:27:29 -0800 Subject: [PATCH 3/9] Flesh out test case --- test/unordered/transparent_tests.cpp | 97 ++++++++++++++++++---------- 1 file changed, 64 insertions(+), 33 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 22c20905..b5cc5bfc 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -13,52 +13,83 @@ #include -struct key { - int x_; - static int count_; +struct key +{ + int x_; + static int count_; - explicit key(int x) : x_(x) { - ++count_; - } + key(int x) : x_(x) { ++count_; } + key(key const& k) : x_(k.x_) { ++count_; } + + key& operator=(key const& k) + { + x_ = k.x_; + ++count_; + return *this; + } }; int key::count_; -UNORDERED_AUTO_TEST(transparent_count) { - key::count_ = 0; +struct transparent_hasher +{ + typedef void is_transparent; - struct hasher { - std::size_t operator()(key const& k) const { - return boost::hash()(k.x_); - } + std::size_t operator()(key const& k) const + { + return boost::hash()(k.x_); + } - std::size_t operator()(int const k) const { - return boost::hash()(k); - } - }; + std::size_t operator()(int const k) const { return boost::hash()(k); } +}; - struct key_equal { - bool operator()(key const& k1, key const& k2) const { - return k1.x_ == k2.x_; - } +struct transparent_key_equal +{ + typedef void is_transparent; - bool operator()(key const& k1, int const x) const { - return k1.x_ == x; - } + static bool was_called_; - bool operator()(int const x, key const& k1 ) const { - return k1.x_ == x; - } - }; + bool operator()(key const& k1, key const& k2) const { return k1.x_ == k2.x_; } + bool operator()(int const x, key const& k1) const + { + was_called_ = true; + return k1.x_ == x; + } +}; - boost::unordered_map map; - map.insert({key(0), 1337}); - BOOST_TEST(key::count_ == 1); +bool transparent_key_equal::was_called_; - std::size_t const count = map.count(0); +UNORDERED_AUTO_TEST (unordered_map_transparent_count) { + key::count_ = 0; + transparent_key_equal::was_called_ = false; - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 1); + boost::unordered_map map; + + // initial `key(0)` expression increases the count + // then copying into the `unordered_map` increments the count again thus we + // have 2 + // + map[key(0)] = 1337; + BOOST_TEST(key::count_ == 2); + + // now the number of `key` objects created should be a constant and never + // touched again + // + std::size_t count = 0; + count = map.count(0); + + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 2); + BOOST_TEST(map.key_eq().was_called_); + + count = map.count(1); + + BOOST_TEST(count == 0); + BOOST_TEST(key::count_ == 2); + + count = map.count(key(0)); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ > 2); } RUN_TESTS() From 8ba710637a2f83046c40d742c9c430d9827604cd Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Mon, 22 Nov 2021 13:29:41 -0800 Subject: [PATCH 4/9] Remove `detail::make_dependent` in favor of an extra template parameter in `is_transparetn` --- include/boost/unordered/detail/implementation.hpp | 13 ++++++------- include/boost/unordered/unordered_map.hpp | 10 ++++------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 7c9150ba..b084bbc0 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -726,16 +726,15 @@ namespace boost { //////////////////////////////////////////////////////////////////////////// // Type checkers used for the transparent member functions added by C++20 and up - template - struct make_dependent : public true_type {}; - - template struct is_transparent : public false_type + template + struct is_transparent : public false_type { }; - template - struct is_transparent::type> : public true_type + template + struct is_transparent::type> + : public true_type { }; diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 7e6dd467..261fc943 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -758,9 +758,8 @@ namespace boost { size_type count(const key_type&) const; template - typename boost::enable_if_c::value && - detail::is_transparent::value && - detail::is_transparent

::value, + typename boost::enable_if_c::value && + detail::is_transparent::value, size_type>::type count(const Key&) const; @@ -1846,9 +1845,8 @@ namespace boost { template template - typename boost::enable_if_c::value && - detail::is_transparent::value && - detail::is_transparent

::value, + typename boost::enable_if_c::value && + detail::is_transparent::value, typename unordered_map::size_type>::type unordered_map::count(const Key& k) const { From 93216374efbabbf040eb2b52958acb8774c1110c Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Mon, 22 Nov 2021 13:30:10 -0800 Subject: [PATCH 5/9] Flesh out test suite to cover all permutations of transparent/non-transparent Hash & KeyEqual pairs --- test/unordered/transparent_tests.cpp | 186 +++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 23 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index b5cc5bfc..13779bd7 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -59,37 +59,177 @@ struct transparent_key_equal bool transparent_key_equal::was_called_; +struct hasher +{ + std::size_t operator()(key const& k) const + { + return boost::hash()(k.x_); + } +}; + +struct key_equal +{ + static bool was_called_; + + bool operator()(key const& k1, key const& k2) const { return k1.x_ == k2.x_; } + bool operator()(int const x, key const& k1) const + { + was_called_ = true; + return k1.x_ == x; + } +}; + +bool key_equal::was_called_; + UNORDERED_AUTO_TEST (unordered_map_transparent_count) { - key::count_ = 0; - transparent_key_equal::was_called_ = false; + { + // transparent Hash, transparent KeyEqual + // - boost::unordered_map map; + key::count_ = 0; + transparent_key_equal::was_called_ = false; + key_equal::was_called_ = false; - // initial `key(0)` expression increases the count - // then copying into the `unordered_map` increments the count again thus we - // have 2 - // - map[key(0)] = 1337; - BOOST_TEST(key::count_ == 2); + boost::unordered_map + map; - // now the number of `key` objects created should be a constant and never - // touched again - // - std::size_t count = 0; - count = map.count(0); + // initial `key(0)` expression increases the count + // then copying into the `unordered_map` increments the count again thus we + // have 2 + // + map[key(0)] = 1337; + BOOST_TEST(key::count_ == 2); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 2); - BOOST_TEST(map.key_eq().was_called_); + // now the number of `key` objects created should be a constant and never + // touched again + // + std::size_t count = 0; + count = map.count(0); - count = map.count(1); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 2); + BOOST_TEST(map.key_eq().was_called_); - BOOST_TEST(count == 0); - BOOST_TEST(key::count_ == 2); + count = map.count(1); - count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ > 2); + BOOST_TEST(count == 0); + BOOST_TEST(key::count_ == 2); + + count = map.count(key(0)); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ > 2); + } + + { + // non-transparent Hash, non-transparent KeyEqual + // + + key::count_ = 0; + transparent_key_equal::was_called_ = false; + key_equal::was_called_ = false; + + boost::unordered_map map; + + // initial `key(0)` expression increases the count + // then copying into the `unordered_map` increments the count again thus we + // have 2 + // + map[key(0)] = 1337; + BOOST_TEST(key::count_ == 2); + + // rely on the implicit constructor here to spawn a new object which + // increases the count + // + std::size_t count = 0; + count = map.count(0); + + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 3); + BOOST_TEST(!map.key_eq().was_called_); + + count = map.count(1); + + BOOST_TEST(count == 0); + BOOST_TEST(key::count_ == 4); + + count = map.count(key(0)); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 5); + } + + { + // transparent Hash, non-transparent KeyEqual + // + + key::count_ = 0; + transparent_key_equal::was_called_ = false; + key_equal::was_called_ = false; + + boost::unordered_map map; + + // initial `key(0)` expression increases the count + // then copying into the `unordered_map` increments the count again thus we + // have 2 + // + map[key(0)] = 1337; + BOOST_TEST(key::count_ == 2); + + // rely on the implicit constructor here to spawn a new object which + // increases the count + // + std::size_t count = 0; + count = map.count(0); + + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 3); + BOOST_TEST(!map.key_eq().was_called_); + + count = map.count(1); + + BOOST_TEST(count == 0); + BOOST_TEST(key::count_ == 4); + + count = map.count(key(0)); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 5); + } + + { + // non-transparent Hash, transparent KeyEqual + // + + key::count_ = 0; + transparent_key_equal::was_called_ = false; + key_equal::was_called_ = false; + + boost::unordered_map map; + + // initial `key(0)` expression increases the count + // then copying into the `unordered_map` increments the count again thus we + // have 2 + // + map[key(0)] = 1337; + BOOST_TEST(key::count_ == 2); + + // rely on the implicit constructor here to spawn a new object which + // increases the count + // + std::size_t count = 0; + count = map.count(0); + + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 3); + BOOST_TEST(!map.key_eq().was_called_); + + count = map.count(1); + + BOOST_TEST(count == 0); + BOOST_TEST(key::count_ == 4); + + count = map.count(key(0)); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 5); + } } RUN_TESTS() From fd0cab2ab809631cdbfbbf33faa8e4426311e0ef Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Mon, 22 Nov 2021 15:43:28 -0800 Subject: [PATCH 6/9] Remove out-of-line defintion for transparent `count()` to hopefully appease msvc-9.0 --- include/boost/unordered/unordered_map.hpp | 29 +++++++++-------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 261fc943..3535fc7e 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -761,7 +761,17 @@ namespace boost { typename boost::enable_if_c::value && detail::is_transparent::value, size_type>::type - count(const Key&) const; + count(const Key& k) const + { + std::size_t const key_hash = + table::policy::apply_hash(this->hash_function(), k); + + P const& eq = this->key_eq(); + + node_pointer p = table_.find_node_impl(key_hash, k, eq); + + return (p ? 1 : 0); + } std::pair equal_range(const key_type&); std::pair equal_range( @@ -1843,23 +1853,6 @@ namespace boost { return table_.find_node(k) ? 1 : 0; } - template - template - typename boost::enable_if_c::value && - detail::is_transparent::value, - typename unordered_map::size_type>::type - unordered_map::count(const Key& k) const - { - std::size_t const key_hash = - table::policy::apply_hash(this->hash_function(), k); - - P const& eq = this->key_eq(); - - node_pointer p = table_.find_node_impl(key_hash, k, eq); - - return (p ? 1 : 0); - } - template std::pair::iterator, typename unordered_map::iterator> From bc9eca70d02b552bb4b7b58947f4909c1803efb9 Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Tue, 23 Nov 2021 12:04:00 -0800 Subject: [PATCH 7/9] Remove unnecessary assignment operator for test `key` --- test/unordered/transparent_tests.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 13779bd7..58367791 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -20,13 +20,6 @@ struct key key(int x) : x_(x) { ++count_; } key(key const& k) : x_(k.x_) { ++count_; } - - key& operator=(key const& k) - { - x_ = k.x_; - ++count_; - return *this; - } }; int key::count_; From 3f1e4a703a9b066340d322fc706710a1e0fe6fe4 Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Tue, 23 Nov 2021 12:15:53 -0800 Subject: [PATCH 8/9] Clean up tests to be a bit more readable --- test/unordered/transparent_tests.cpp | 165 +++++++++------------------ 1 file changed, 53 insertions(+), 112 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index 58367791..f70a9e30 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -74,14 +74,51 @@ struct key_equal bool key_equal::was_called_; +void count_reset() +{ + key::count_ = 0; + transparent_key_equal::was_called_ = false; + key_equal::was_called_ = false; +} + +template void test_non_transparent_count() +{ + count_reset(); + + UnorderedMap map; + + // initial `key(0)` expression increases the count + // then copying into the `unordered_map` increments the count again thus we + // have 2 + // + map[key(0)] = 1337; + BOOST_TEST(key::count_ == 2); + + // rely on the implicit constructor here to spawn a new object which + // increases the count + // + std::size_t count = 0; + count = map.count(0); + + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 3); + BOOST_TEST(!map.key_eq().was_called_); + + count = map.count(1); + + BOOST_TEST(count == 0); + BOOST_TEST(key::count_ == 4); + + count = map.count(key(0)); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 5); +} + UNORDERED_AUTO_TEST (unordered_map_transparent_count) { { // transparent Hash, transparent KeyEqual // - - key::count_ = 0; - transparent_key_equal::was_called_ = false; - key_equal::was_called_ = false; + count_reset(); boost::unordered_map map; @@ -109,120 +146,24 @@ UNORDERED_AUTO_TEST (unordered_map_transparent_count) { BOOST_TEST(key::count_ == 2); count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ > 2); - } - - { - // non-transparent Hash, non-transparent KeyEqual - // - - key::count_ = 0; - transparent_key_equal::was_called_ = false; - key_equal::was_called_ = false; - - boost::unordered_map map; - - // initial `key(0)` expression increases the count - // then copying into the `unordered_map` increments the count again thus we - // have 2 - // - map[key(0)] = 1337; - BOOST_TEST(key::count_ == 2); - - // rely on the implicit constructor here to spawn a new object which - // increases the count - // - std::size_t count = 0; - count = map.count(0); - BOOST_TEST(count == 1); BOOST_TEST(key::count_ == 3); - BOOST_TEST(!map.key_eq().was_called_); - - count = map.count(1); - - BOOST_TEST(count == 0); - BOOST_TEST(key::count_ == 4); - - count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 5); } - { - // transparent Hash, non-transparent KeyEqual - // + // non-transparent Hash, non-transparent KeyEqual + // + test_non_transparent_count< + boost::unordered_map >(); - key::count_ = 0; - transparent_key_equal::was_called_ = false; - key_equal::was_called_ = false; + // transparent Hash, non-transparent KeyEqual + // + test_non_transparent_count< + boost::unordered_map >(); - boost::unordered_map map; - - // initial `key(0)` expression increases the count - // then copying into the `unordered_map` increments the count again thus we - // have 2 - // - map[key(0)] = 1337; - BOOST_TEST(key::count_ == 2); - - // rely on the implicit constructor here to spawn a new object which - // increases the count - // - std::size_t count = 0; - count = map.count(0); - - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 3); - BOOST_TEST(!map.key_eq().was_called_); - - count = map.count(1); - - BOOST_TEST(count == 0); - BOOST_TEST(key::count_ == 4); - - count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 5); - } - - { - // non-transparent Hash, transparent KeyEqual - // - - key::count_ = 0; - transparent_key_equal::was_called_ = false; - key_equal::was_called_ = false; - - boost::unordered_map map; - - // initial `key(0)` expression increases the count - // then copying into the `unordered_map` increments the count again thus we - // have 2 - // - map[key(0)] = 1337; - BOOST_TEST(key::count_ == 2); - - // rely on the implicit constructor here to spawn a new object which - // increases the count - // - std::size_t count = 0; - count = map.count(0); - - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 3); - BOOST_TEST(!map.key_eq().was_called_); - - count = map.count(1); - - BOOST_TEST(count == 0); - BOOST_TEST(key::count_ == 4); - - count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 5); - } + // non-transparent Hash, transparent KeyEqual + // + test_non_transparent_count< + boost::unordered_map >(); } RUN_TESTS() From 6f5727cbdb737709c4d51098bda41ed48a078571 Mon Sep 17 00:00:00 2001 From: LeonineKing1199 Date: Tue, 23 Nov 2021 14:14:26 -0800 Subject: [PATCH 9/9] Clean up tests by pulling transparent tests into a named function --- test/unordered/transparent_tests.cpp | 69 ++++++++++++++-------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/test/unordered/transparent_tests.cpp b/test/unordered/transparent_tests.cpp index f70a9e30..a0289c94 100644 --- a/test/unordered/transparent_tests.cpp +++ b/test/unordered/transparent_tests.cpp @@ -81,6 +81,39 @@ void count_reset() key_equal::was_called_ = false; } +template void test_transparent_count() +{ + count_reset(); + + UnorderedMap map; + + // initial `key(0)` expression increases the count + // then copying into the `unordered_map` increments the count again thus we + // have 2 + // + map[key(0)] = 1337; + BOOST_TEST(key::count_ == 2); + + // now the number of `key` objects created should be a constant and never + // touched again + // + std::size_t count = 0; + count = map.count(0); + + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 2); + BOOST_TEST(map.key_eq().was_called_); + + count = map.count(1); + + BOOST_TEST(count == 0); + BOOST_TEST(key::count_ == 2); + + count = map.count(key(0)); + BOOST_TEST(count == 1); + BOOST_TEST(key::count_ == 3); +} + template void test_non_transparent_count() { count_reset(); @@ -115,40 +148,8 @@ template void test_non_transparent_count() } UNORDERED_AUTO_TEST (unordered_map_transparent_count) { - { - // transparent Hash, transparent KeyEqual - // - count_reset(); - - boost::unordered_map - map; - - // initial `key(0)` expression increases the count - // then copying into the `unordered_map` increments the count again thus we - // have 2 - // - map[key(0)] = 1337; - BOOST_TEST(key::count_ == 2); - - // now the number of `key` objects created should be a constant and never - // touched again - // - std::size_t count = 0; - count = map.count(0); - - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 2); - BOOST_TEST(map.key_eq().was_called_); - - count = map.count(1); - - BOOST_TEST(count == 0); - BOOST_TEST(key::count_ == 2); - - count = map.count(key(0)); - BOOST_TEST(count == 1); - BOOST_TEST(key::count_ == 3); - } + test_transparent_count >(); // non-transparent Hash, non-transparent KeyEqual //