From 557acf4cacaad50059c1fccb01f06b7b7f95351e Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Thu, 23 Nov 2023 00:46:16 -0500 Subject: [PATCH] cpp-common/bt2c: add bt2c::call() 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 void f(MethT&& meth, ObjT&& obj, const int val) { bt2c::call(std::forward(meth), std::forward(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 Change-Id: Ib7db0315ee6f68f168793488a7da67c1bc410fb8 Reviewed-on: https://review.lttng.org/c/babeltrace/+/11425 Reviewed-by: Simon Marchi CI-Build: Simon Marchi Tested-by: jenkins --- src/Makefile.am | 1 + src/cpp-common/bt2c/call.hpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/cpp-common/bt2c/call.hpp diff --git a/src/Makefile.am b/src/Makefile.am index 2166e36d..4c6126b2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,7 @@ noinst_HEADERS = \ 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 \ diff --git a/src/cpp-common/bt2c/call.hpp b/src/cpp-common/bt2c/call.hpp new file mode 100644 index 00000000..3241f736 --- /dev/null +++ b/src/cpp-common/bt2c/call.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Philippe Proulx + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BABELTRACE_CPP_COMMON_BT2C_CALL_HPP +#define BABELTRACE_CPP_COMMON_BT2C_CALL_HPP + +#include +#include + +namespace bt2c { + +/* + * Partial implementation of INVOKE. + * + * As found in + * . + */ +template +auto call(FuncT func, ArgTs&&...args) -> decltype(std::ref(func)(std::forward(args)...)) +{ + return std::ref(func)(std::forward(args)...); +} + +} /* namespace bt2c */ + +#endif /* BABELTRACE_CPP_COMMON_BT2C_CALL_HPP */ -- 2.34.1