This is an automated email from the ASF dual-hosted git repository. amc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 46de4252f38b7df32943a702dc93dce79c3eb08e Author: Alan M. Carroll <[email protected]> AuthorDate: Fri Jul 20 08:36:45 2018 -0500 IntrusiveHashMap: Add overloads to apply method to support functor taking reference or pointer. --- lib/ts/IntrusiveHashMap.h | 37 +++++++++++++++++++++++++----- lib/ts/unit-tests/test_IntrusiveHashMap.cc | 2 +- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/lib/ts/IntrusiveHashMap.h b/lib/ts/IntrusiveHashMap.h index 003326b..3f1848a 100644 --- a/lib/ts/IntrusiveHashMap.h +++ b/lib/ts/IntrusiveHashMap.h @@ -617,17 +617,42 @@ IntrusiveHashMap<H>::erase(range const &r) -> iterator return this->erase(r.first, r.second); } +namespace detail +{ +// Make @c apply more convenient by allowing the function to take a reference type or pointer type to the container +// elements. The pointer type is the base, plus a shim to convert from a reference type functor to a pointer pointer +// type. The complex return type definition forces only one, but not both, to be valid for a particular functor. This +// also must be done via free functions and not method overloads because the compiler forces a match up of method +// definitions and declarations before any template instantiation. + +template <typename H, typename F> +auto +IntrusiveHashMapApply(IntrusiveHashMap<H> &map, F &&f) + -> decltype(f(*static_cast<typename IntrusiveHashMap<H>::value_type *>(nullptr)), map) +{ + return map.apply([&f](typename IntrusiveHashMap<H>::value_type *v) { return f(*v); }); +} + +template <typename H, typename F> +auto +IntrusiveHashMapApply(IntrusiveHashMap<H> &map, F &&f) + -> decltype(f(static_cast<typename IntrusiveHashMap<H>::value_type *>(nullptr)), map) +{ + auto spot{map.begin()}; + auto limit{map.end()}; + while (spot != limit) { + f(spot++); // post increment means @a spot is updated before @a f is applied. + } + return map; +} +} // namespace detail + template <typename H> template <typename F> auto IntrusiveHashMap<H>::apply(F &&f) -> self_type & { - iterator spot{this->begin()}; - iterator limit{this->end()}; - while (spot != limit) { - f(*spot++); // post increment means @a spot is updated before @a f is applied. - } - return *this; + return detail::IntrusiveHashMapApply(*this, f); }; template <typename H> diff --git a/lib/ts/unit-tests/test_IntrusiveHashMap.cc b/lib/ts/unit-tests/test_IntrusiveHashMap.cc index 6828e3a..abcbd35 100644 --- a/lib/ts/unit-tests/test_IntrusiveHashMap.cc +++ b/lib/ts/unit-tests/test_IntrusiveHashMap.cc @@ -144,5 +144,5 @@ TEST_CASE("IntrusiveHashMap", "[libts][IntrusiveHashMap]") REQUIRE(elt._payload == "dup"sv); } // clean up the last bits. - map.apply([](Thing &thing) { delete &thing; }); + map.apply([](Thing *thing) { delete thing; }); };
