bkietz commented on a change in pull request #8680:
URL: https://github.com/apache/arrow/pull/8680#discussion_r534350582
##########
File path: cpp/src/arrow/util/functional.h
##########
@@ -79,5 +84,47 @@ struct call_traits {
typename std::enable_if<std::is_same<return_type<F>, T>::value, RT>;
};
+/// A type erased callable object which may only be invoked once.
+/// It can be constructed from any lambda which matches the provided call
signature.
+/// Invoking it results in destruction of the lambda, freeing any
state/references
+/// immediately. Invoking a default constructed FnOnce or one which has
already been
+/// invoked will segfault.
+template <typename Signature>
+class FnOnce;
+
+template <typename R, typename... A>
+class FnOnce<R(A...)> {
+ public:
+ FnOnce() = default;
+
+ template <typename Fn,
+ typename = typename std::enable_if<std::is_convertible<
+ typename std::result_of<Fn && (A...)>::type, R>::value>::type>
+ FnOnce(Fn fn) : impl_(new FnImpl<Fn>(std::move(fn))) { // NOLINT
runtime/explicit
+ }
+
+ explicit operator bool() const { return impl_ != NULLPTR; }
+
+ R operator()(A... a) && {
+ auto bye = std::move(impl_);
+ return bye->invoke(static_cast<A&&>(a)...);
Review comment:
Since the types of the arguments are already fixed at class scope (so
this is not a function template), perfect forwarding is not *really* available
here.
`A` might be:
- `std::string`, in which case `static_cast<A&&>` becomes
`static_cast<std::string&&>` (appropriate move)
- `const std::string&`, in which case `static_cast<A&&>` reference-decays to
`static_cast<const std::string&>` (no inappropriate move)
- `std::string&&`, in which case `static_cast<A&&>` becomes
`static_cast<std::string&&>` (appropriate move)
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]