This new function partially implements INVOKE.
It's bt2c::call() instead of bt2s::invoke() because it's not a perfect
drop-in replacement (not forwarding `func` because
`std::reference_wrapper` requires that the parameter isn't an rvalue).
The std::ref() trick is taken from [1].
My main use case for this is IIFE (initializing some `const` variable
from a parameter-less lambda call) without risking to forget the
trailing `()` to actually call it:
const auto meow = [&aqua, &fina] {
// some steps
return mix;
}; // oops, forgot `()` here
Instead:
const auto meow = bt2c::call([&aqua, &fina] {
// some steps
return mix;
});
When you see bt2c::call(), you know there's a call.
You can also use bt2c::call() for most use cases [2] of std::invoke()
(C++17), for example:
template <typename MethT, typename ObjT>
void f(MethT&& meth, ObjT&& obj, const int val)
{
bt2c::call(std::forward<MethT>(meth), std::forward<ObjT>(obj), val, 42);
}
struct Meow
{
void mix(const int a, const int b)
{
std::cout << a << ":" << b << std::endl;
}
};
int main()
{
Meow meow;
f(&Meow::mix, meow, 17);
}
[1]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0312r1.html
[2]: https://devblogs.microsoft.com/oldnewthing/
20220401-00/?p=106426
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ib7db0315ee6f68f168793488a7da67c1bc410fb8
Reviewed-on: https://review.lttng.org/c/babeltrace/+/11425
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
CI-Build: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
cpp-common/bt2/value.hpp \
cpp-common/bt2/wrap.hpp \
cpp-common/bt2c/align.hpp \
+ cpp-common/bt2c/call.hpp \
cpp-common/bt2c/endian.hpp \
cpp-common/bt2c/exc.hpp \
cpp-common/bt2c/glib-up.hpp \
--- /dev/null
+/*
+ * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BABELTRACE_CPP_COMMON_BT2C_CALL_HPP
+#define BABELTRACE_CPP_COMMON_BT2C_CALL_HPP
+
+#include <functional>
+#include <utility>
+
+namespace bt2c {
+
+/*
+ * Partial implementation of INVOKE.
+ *
+ * As found in
+ * <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0312r1.html>.
+ */
+template <typename FuncT, typename... ArgTs>
+auto call(FuncT func, ArgTs&&...args) -> decltype(std::ref(func)(std::forward<ArgTs>(args)...))
+{
+ return std::ref(func)(std::forward<ArgTs>(args)...);
+}
+
+} /* namespace bt2c */
+
+#endif /* BABELTRACE_CPP_COMMON_BT2C_CALL_HPP */