You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mp...@apache.org on 2017/12/05 08:25:14 UTC
mesos git commit: Added `CallableOnce` class template,
similar to `std::function`.
Repository: mesos
Updated Branches:
refs/heads/master 0e3509444 -> 7beea9cbe
Added `CallableOnce` class template, similar to `std::function`.
`CallableOnce` class is similar to `std::function`, but allows it to
be called only once. Together with `lambda::partial` this provides
foundation for copy-less `defer`, `dispatch` and `Future`.
Review: https://reviews.apache.org/r/63630/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/7beea9cb
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/7beea9cb
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/7beea9cb
Branch: refs/heads/master
Commit: 7beea9cbe083caf738fb02b9d58dadf3da900f4b
Parents: 0e35094
Author: Dmitry Zhuk <dz...@twopensource.com>
Authored: Mon Dec 4 08:12:01 2017 -0800
Committer: Michael Park <mp...@apache.org>
Committed: Tue Dec 5 00:19:13 2017 -0800
----------------------------------------------------------------------
3rdparty/stout/include/stout/lambda.hpp | 99 ++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/7beea9cb/3rdparty/stout/include/stout/lambda.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/lambda.hpp b/3rdparty/stout/include/stout/lambda.hpp
index c14241a..96586bd 100644
--- a/3rdparty/stout/include/stout/lambda.hpp
+++ b/3rdparty/stout/include/stout/lambda.hpp
@@ -15,10 +15,13 @@
#include <algorithm>
#include <functional>
+#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
+#include <glog/logging.h>
+
#include <stout/cpp14.hpp>
#include <stout/cpp17.hpp>
#include <stout/result_of.hpp>
@@ -296,6 +299,102 @@ partial(F&& f, Args&&... args)
#undef RETURN
+
+namespace internal {
+
+// Helper for invoking functional objects.
+// It needs specialization for `void` return type to ignore potentialy
+// non-`void` return value from `cpp17::invoke(f, args...)`.
+template <typename R>
+struct Invoke
+{
+ template <typename F, typename... Args>
+ R operator()(F&& f, Args&&... args)
+ {
+ return cpp17::invoke(std::forward<F>(f), std::forward<Args>(args)...);
+ }
+};
+
+
+template <>
+struct Invoke<void>
+{
+ template <typename F, typename... Args>
+ void operator()(F&& f, Args&&... args)
+ {
+ cpp17::invoke(std::forward<F>(f), std::forward<Args>(args)...);
+ }
+};
+
+} // namespace internal {
+
+
+// This is similar to `std::function`, but it can only be called once.
+// The "called once" semantics is enforced by having rvalue-ref qualifier
+// on `operator()`, so instances of `CallableOnce` must be `std::move`'d
+// in order to be invoked. Similar to `std::function`, this has heap
+// allocation overhead due to type erasure.
+//
+// Note: Heap allocation can be avoided in some cases by implementing
+// small buffer optimization. This is currently not implemented.
+template <typename F>
+class CallableOnce;
+
+
+template <typename R, typename... Args>
+class CallableOnce<R(Args...)>
+{
+public:
+ template <
+ typename F,
+ typename std::enable_if<
+ !std::is_same<F, CallableOnce>::value &&
+ (std::is_same<R, void>::value ||
+ std::is_convertible<
+ decltype(
+ cpp17::invoke(std::declval<F>(), std::declval<Args>()...)),
+ R>::value),
+ int>::type = 0>
+ CallableOnce(F&& f)
+ : f(new CallableFn<typename std::decay<F>::type>(std::forward<F>(f))) {}
+
+ CallableOnce(CallableOnce&&) = default;
+ CallableOnce(const CallableOnce&) = delete;
+
+ CallableOnce& operator=(CallableOnce&&) = default;
+ CallableOnce& operator=(const CallableOnce&) = delete;
+
+ template <typename... Args_>
+ R operator()(Args_&&... args) &&
+ {
+ CHECK(f != nullptr);
+ return std::move(*f)(std::forward<Args_>(args)...);
+ }
+
+private:
+ struct Callable
+ {
+ virtual ~Callable() = default;
+ virtual R operator()(Args...) && = 0;
+ };
+
+ template <typename F>
+ struct CallableFn : Callable
+ {
+ F f;
+
+ CallableFn(const F& f) : f(f) {}
+ CallableFn(F&& f) : f(std::move(f)) {}
+
+ virtual R operator()(Args... args) &&
+ {
+ return internal::Invoke<R>{}(std::move(f), std::forward<Args>(args)...);
+ }
+ };
+
+ std::unique_ptr<Callable> f;
+};
+
} // namespace lambda {