summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2022-06-18 11:53:57 -0400
committerNat Goodspeed <nat@lindenlab.com>2022-08-22 20:39:37 -0400
commitc0f709b637d800fe07fb265c8ab6f28080994224 (patch)
treef367fea3f47f0555a3e60ea7f294bb2a3f68dc94 /indra/llcommon
parent9dba9f80f4d40ec12a735ddbb66a9d103a959ece (diff)
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. (cherry picked from commit dc2e2cd76f387ea6e80787fb94adcbc269cd1f25)
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/apply.h51
1 files changed, 51 insertions, 0 deletions
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 <tuple>
+
+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 <typename CALLABLE, typename TUPLE, std::size_t... I>
+auto apply_impl(CALLABLE&& func, TUPLE&& args, std::index_sequence<I...>)
+{
+ // call func(unpacked args)
+ return std::forward<CALLABLE>(func)(std::move(std::get<I>(args))...);
+}
+
+template <typename CALLABLE, typename... ARGS>
+auto apply(CALLABLE&& func, std::tuple<ARGS...>&& 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<CALLABLE>(func),
+ std::forward<std::tuple<ARGS...>>(args),
+ std::index_sequence_for<ARGS...>{});
+}
+
+#endif // C++14
+
+} // namespace LL
+
+#endif /* ! defined(LL_APPLY_H) */