diff --git a/include/kwk/utility/container/shape.hpp b/include/kwk/utility/container/shape.hpp index 32e555bf..2a0bdaef 100644 --- a/include/kwk/utility/container/shape.hpp +++ b/include/kwk/utility/container/shape.hpp @@ -26,6 +26,36 @@ namespace kwk template constexpr auto compress(shape const& s) noexcept; + //================================================================================================ + //! @brief Generates a kwk::shape from a list of sizes + //! @tparam SizeType Integral type used to store sizes. If unspecified, `std::ptrdiff_t` is used. + //! @param ds Variadic pack of sizes + //================================================================================================ + template... Ds> + constexpr auto of_size(Ds... ds) noexcept + { + return detail::make_extent(ds...); + } + + template... Ds> + constexpr auto of_size( Ds... ds) noexcept + { + using type_t = typename detail::largest_type...>::type; + return of_size(ds...); + } + + template + constexpr auto of_size( Ds ds) noexcept + { + return kumi::apply([](auto... s) { return of_size(s...); }, ds); + } + + template + constexpr auto of_size( Ds ds) noexcept + { + return kumi::apply([](auto... s) { return of_size(s...); }, ds); + } + //================================================================================================ //! @ingroup containers //! @brief Fixed order shape with mixed size capability @@ -376,9 +406,21 @@ namespace kwk //! @return An instance of @ref kwk::shape corresponding to the shape of the selected //! sub-volume //============================================================================================== + // has to be defined inline due to (Apple) Clang deficiencies + // https://github.com/llvm/llvm-project/issues/58952 + // but also after of_size + //============================================================================================== template - inline constexpr auto operator()(Slicers const&... s) const noexcept - requires( sizeof...(Slicers) <= static_order); + constexpr auto operator()(Slicers const&... s ) const noexcept + requires( sizeof...(Slicers) <= static_order ) + { + auto shd = compress(*this); + auto sliced = kumi::map_index ( [&](auto i, auto m) { return reshape(shd,m,i); } + , kumi::tie(s...) + ); + + return kumi::apply( [](auto... v) { return of_size(v...); }, sliced ); + } protected: template @@ -445,50 +487,6 @@ namespace kwk static_cast(that) = compress(static_cast(s)); return that; } - - //================================================================================================ - //! @brief Generates a kwk::shape from a list of sizes - //! @tparam SizeType Integral type used to store sizes. If unspecified, `std::ptrdiff_t` is used. - //! @param ds Variadic pack of sizes - //================================================================================================ - template... Ds> - constexpr auto of_size(Ds... ds) noexcept - { - return detail::make_extent(ds...); - } - - template... Ds> - constexpr auto of_size( Ds... ds) noexcept - { - using type_t = typename detail::largest_type...>::type; - return of_size(ds...); - } - - template - constexpr auto of_size( Ds ds) noexcept - { - return kumi::apply([](auto... s) { return of_size(s...); }, ds); - } - - template - constexpr auto of_size( Ds ds) noexcept - { - return kumi::apply([](auto... s) { return of_size(s...); }, ds); - } - - // Implementation of slicing interface - template - template - inline constexpr auto shape::operator()(Slicers const&... s) const noexcept - requires( sizeof...(Slicers) <= static_order) - { - auto shd = compress(*this); - auto sliced = kumi::map_index ( [&](auto i, auto m) { return reshape(shd,m,i); } - , kumi::tie(s...) - ); - - return kumi::apply( [](auto... v) { return of_size(v...); }, sliced ); - } } // Tuple interface adaptation