From 64a9db2e82ea589030389e9ea45580bfc891521c Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 31 Aug 2022 13:39:16 +0100 Subject: [PATCH] Introduce `MergeInto` helper for simplified construction of arrays of structs In the upcoming GPU code each state member will hold a reference to its corresponding Maxwell 3D regs, this helper is needed to allow easy transformation from the the main 3D register struct into them. Example: ```c++ struct Regs { std::array viewRegs; u32 enable; } regs; struct ViewState { const View &view; const u32 &enable; size_t index; }; std::array viewStates{MergeInto(regs.viewRegs, regs.enable, IncrementingT{}) ``` --- app/src/main/cpp/skyline/common/utils.h | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/app/src/main/cpp/skyline/common/utils.h b/app/src/main/cpp/skyline/common/utils.h index 3fe316f4..d82a1925 100644 --- a/app/src/main/cpp/skyline/common/utils.h +++ b/app/src/main/cpp/skyline/common/utils.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "base.h" #include "exception.h" @@ -309,4 +310,43 @@ namespace skyline::util { std::array MakeFilledArray(TArgs &&... args) { return MakeFilledArray(std::make_index_sequence(), std::forward(args)...); } + + template + struct IncrementingT { + using Type = T; + }; + + + template + struct IsIncrementingT : std::false_type {}; + + template + struct IsIncrementingT> : std::true_type {}; + + template + T MakeMergeElem(TSrcs &&... srcs) { + auto readElem{[index = Index](auto &&src) -> decltype(auto) { + using SrcType = std::decay_t; + if constexpr (requires { src[Index]; }) + return src[Index]; + else if constexpr (IsIncrementingT{}) + return static_cast(index); + else + return src; + }}; + return T{readElem(std::forward(srcs))...}; + } + + template + std::array MergeInto(std::index_sequence seq, TSrcs &&... srcs) { + return {MakeMergeElem(std::forward(srcs)...)...}; + } + + /** + * @brief Constructs {{scalar0, array0[0], array1[0], ... arrayN[0], scalar1}, {scalar0, array0[1], array1[1]. ... arrayN[1], scalar0}, ...} + */ + template + std::array MergeInto(TSrcs &&... srcs) { + return MergeInto(std::make_index_sequence(), std::forward(srcs)...); + } }