diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2022-12-19 16:29:06 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2023-07-13 12:34:12 -0400 |
commit | c682603417e1ef8290aacf274ff49821bd204c0b (patch) | |
tree | 54d245703df0cd6ef1f59b8607b70b2bcd3ebeea /indra/llcommon/apply.h | |
parent | 324f0d9b8abad3a74a7c19a6e28f8c77c76b3b83 (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.h | 23 |
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) */ |