From dc2e2cd76f387ea6e80787fb94adcbc269cd1f25 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 18 Jun 2022 11:53:57 -0400 Subject: DRTVWR-564: Add LL::apply(): call function, passing args from tuple. This anticipates C++17's std::apply(), and in fact once we detect C++17, we'll just use that. But in C++14 we must still provide our own implementation. --- indra/llcommon/apply.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 indra/llcommon/apply.h (limited to 'indra') diff --git a/indra/llcommon/apply.h b/indra/llcommon/apply.h new file mode 100644 index 0000000000..ef4a8fd68b --- /dev/null +++ b/indra/llcommon/apply.h @@ -0,0 +1,51 @@ +/** + * @file apply.h + * @author Nat Goodspeed + * @date 2022-06-18 + * @brief C++14 version of std::apply() + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_APPLY_H) +#define LL_APPLY_H + +#include + +namespace LL +{ + +#if __cplusplus >= 201703L + +// C++17 implementation +using std::apply; + +#else // C++14 + +// Derived from https://stackoverflow.com/a/20441189 +// and https://en.cppreference.com/w/cpp/utility/apply +template +auto apply_impl(CALLABLE&& func, TUPLE&& args, std::index_sequence) +{ + // call func(unpacked args) + return std::forward(func)(std::move(std::get(args))...); +} + +template +auto apply(CALLABLE&& func, std::tuple&& args) +{ + // std::index_sequence_for is the magic sauce here, generating an argument + // pack of indexes for each entry in args. apply_impl() can then pass + // those to std::get() to unpack args into individual arguments. + return apply_impl(std::forward(func), + std::forward>(args), + std::index_sequence_for{}); +} + +#endif // C++14 + +} // namespace LL + +#endif /* ! defined(LL_APPLY_H) */ -- cgit v1.2.3