summaryrefslogtreecommitdiff
path: root/indra/llcommon/apply.h
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2022-12-19 16:29:06 -0500
committerNat Goodspeed <nat@lindenlab.com>2023-07-13 12:34:12 -0400
commitc682603417e1ef8290aacf274ff49821bd204c0b (patch)
tree54d245703df0cd6ef1f59b8607b70b2bcd3ebeea /indra/llcommon/apply.h
parent324f0d9b8abad3a74a7c19a6e28f8c77c76b3b83 (diff)
DRTVWR-558: Extend LL::apply() to LLSD array arguments.
Make apply(function, std::array) and apply(function, std::vector) available even when we borrow the C++17 implementation of apply(function, std::tuple). Add apply(function, LLSD) with interpretations: * isUndefined() is treated as an empty array, for calling a nullary function * scalar LLSD is treated as a single-entry array, for calling a unary function * isArray() converts function parameters using LLSDParam * isMap() is an error. Add unit tests for all flavors of LL::apply(). (cherry picked from commit 3006c24251c6259d00df9e0f4f66b8a617e6026d)
Diffstat (limited to 'indra/llcommon/apply.h')
-rw-r--r--indra/llcommon/apply.h23
1 files changed, 16 insertions, 7 deletions
diff --git a/indra/llcommon/apply.h b/indra/llcommon/apply.h
index 7c58d63bc0..26753f5017 100644
--- a/indra/llcommon/apply.h
+++ b/indra/llcommon/apply.h
@@ -13,6 +13,7 @@
#define LL_APPLY_H
#include <boost/type_traits/function_traits.hpp>
+#include <cassert>
#include <tuple>
namespace LL
@@ -54,6 +55,9 @@ namespace LL
}, \
(ARGS))
+/*****************************************************************************
+* apply(function, tuple)
+*****************************************************************************/
#if __cplusplus >= 201703L
// C++17 implementation
@@ -63,8 +67,8 @@ using std::apply;
// 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...>)
+template <typename CALLABLE, typename... ARGS, std::size_t... I>
+auto apply_impl(CALLABLE&& func, const std::tuple<ARGS...>& args, std::index_sequence<I...>)
{
// call func(unpacked args)
return std::forward<CALLABLE>(func)(std::move(std::get<I>(args))...);
@@ -81,6 +85,11 @@ auto apply(CALLABLE&& func, const std::tuple<ARGS...>& args)
std::index_sequence_for<ARGS...>{});
}
+#endif // C++14
+
+/*****************************************************************************
+* apply(function, std::array)
+*****************************************************************************/
// per https://stackoverflow.com/a/57510428/5533635
template <typename CALLABLE, typename T, size_t SIZE>
auto apply(CALLABLE&& func, const std::array<T, SIZE>& args)
@@ -88,13 +97,15 @@ auto apply(CALLABLE&& func, const std::array<T, SIZE>& args)
return apply(std::forward<CALLABLE>(func), std::tuple_cat(args));
}
+/*****************************************************************************
+* apply(function, std::vector)
+*****************************************************************************/
// per https://stackoverflow.com/a/28411055/5533635
template <typename CALLABLE, typename T, std::size_t... I>
auto apply_impl(CALLABLE&& func, const std::vector<T>& args, std::index_sequence<I...>)
{
- return apply_impl(std::forward<CALLABLE>(func),
- std::make_tuple(std::forward<T>(args[I])...),
- I...);
+ return apply(std::forward<CALLABLE>(func),
+ std::make_tuple(args[I]...));
}
// this goes beyond C++17 std::apply()
@@ -108,8 +119,6 @@ auto apply(CALLABLE&& func, const std::vector<T>& args)
std::make_index_sequence<arity>());
}
-#endif // C++14
-
} // namespace LL
#endif /* ! defined(LL_APPLY_H) */