diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2022-08-22 21:00:42 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2022-08-22 21:00:42 -0400 |
commit | 15d37713b9113a6f70dde48c764df02c76e18cbc (patch) | |
tree | 022e150c503fa4f63d47374b89cd13d8446cb566 /indra/llcommon/apply.h | |
parent | c0f709b637d800fe07fb265c8ab6f28080994224 (diff) |
DRTVWR-558: Fix builds on macOS 12.5 Monterey.
Always search for python3[.exe] instead of plain 'python'. macOS Monterey no
longer bundles Python 2 at all.
Explicitly make PYTHON_EXECUTABLE a cached value so if the user edits it in
CMakeCache.txt, it won't be overwritten by indra/cmake/Python.cmake.
Do NOT set DYLD_LIBRARY_PATH for test executables! That has Bad Effects, as
discussed in https://stackoverflow.com/q/73418423/5533635. Instead, create
symlinks from build-mumble/sharedlibs/Resources -> Release/Resources and from
build-mumble/test/Resources -> ../sharedlibs/Release/Resources. For test
executables in sharedlibs/RelWithDebInfo and test/RelWithDebInfo, this
supports our dylibs' baked-in load path @executable_path/../Resources. That
load path assumes running in a standard app bundle (which the viewer in fact
does), but we've been avoiding creating an app bundle for every test program.
These symlinks allow us to continue doing that while avoiding
DYLD_LIBRARY_PATH.
Add indra/llcommon/apply.h. The LL::apply() function and its wrapper macro
VAPPLY were very useful in diagnosing the problem.
Tweak llleap_test.cpp. This source was modified extensively for diagnostic
purposes; these are the small improvements that remain.
Diffstat (limited to 'indra/llcommon/apply.h')
-rw-r--r-- | indra/llcommon/apply.h | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/indra/llcommon/apply.h b/indra/llcommon/apply.h index ef4a8fd68b..7c58d63bc0 100644 --- a/indra/llcommon/apply.h +++ b/indra/llcommon/apply.h @@ -12,11 +12,48 @@ #if ! defined(LL_APPLY_H) #define LL_APPLY_H +#include <boost/type_traits/function_traits.hpp> #include <tuple> namespace LL { +/** + * USAGE NOTE: + * https://stackoverflow.com/a/40523474/5533635 + * + * If you're trying to pass apply() a variadic function, the compiler + * complains that it can't deduce the callable type, presumably because it + * doesn't know which arity to reify to pass. + * + * But it works to wrap the variadic function in a generic lambda, e.g.: + * + * @CODE + * LL::apply( + * [](auto&&... args) + * { + * return variadic(std::forward<decltype(args)>(args)...); + * }, + * args); + * @ENDCODE + * + * Presumably this is because there's only one instance of the generic lambda + * @em type, with a variadic <tt>operator()()</tt>. + * + * It's pointless to provide a wrapper @em function that implicitly supplies + * the generic lambda. You couldn't pass your variadic function to our wrapper + * function, for the same original reason! + * + * Instead we provide a wrapper @em macro. Sorry, Dr. Stroustrup. + */ +#define VAPPLY(FUNC, ARGS) \ + LL::apply( \ + [](auto&&... args) \ + { \ + return (FUNC)(std::forward<decltype(args)>(args)...); \ + }, \ + (ARGS)) + #if __cplusplus >= 201703L // C++17 implementation @@ -34,16 +71,43 @@ auto apply_impl(CALLABLE&& func, TUPLE&& args, std::index_sequence<I...>) } template <typename CALLABLE, typename... ARGS> -auto apply(CALLABLE&& func, std::tuple<ARGS...>&& args) +auto apply(CALLABLE&& func, const 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), + args, std::index_sequence_for<ARGS...>{}); } +// 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) +{ + return apply(std::forward<CALLABLE>(func), std::tuple_cat(args)); +} + +// 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...); +} + +// this goes beyond C++17 std::apply() +template <typename CALLABLE, typename T> +auto apply(CALLABLE&& func, const std::vector<T>& args) +{ + constexpr auto arity = boost::function_traits<CALLABLE>::arity; + assert(args.size() == arity); + return apply_impl(std::forward<CALLABLE>(func), + args, + std::make_index_sequence<arity>()); +} + #endif // C++14 } // namespace LL |