trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject [trafficserver] 06/08: IntrusiveHashMap: Add overloads to apply method to support functor taking reference or pointer.
Date Wed, 22 Aug 2018 14:55:31 GMT
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 <amc@apache.org>
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; });
 };


Mime
View raw message