westonpace commented on a change in pull request #8680:
URL: https://github.com/apache/arrow/pull/8680#discussion_r544781160
##########
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:
This is mostly true. It can't be perfect forwarding because we need to
capture the values when the FnOnce is constructed (similar to the capture done
by a lambda or std::function). We also then need to move the values once more
to make the actual call to the callback.
However, the static_cast was causing one extra move to happen inside the
FnOnce (from FnOnce to FnOnce::Impl) and that could be avoided with
std::forward. I modified FnOnceTest::MoveOnlyDataType to verify this change
moved us from 3 moves to 2 moves.
----------------------------------------------------------------
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]