diff --git a/src/include/ranges/index_utils.cc.h b/src/include/ranges/index_utils.cc.h index 8d1f9c7..66f0569 100644 --- a/src/include/ranges/index_utils.cc.h +++ b/src/include/ranges/index_utils.cc.h @@ -71,6 +71,112 @@ namespace CNORZX } } + template + constexpr decltype(auto) getIndexDepth(const Index& ind) + { + static_assert(is_index::value, "got non-index type"); + if constexpr(has_sub::value){ + if constexpr(has_static_sub::value){ + constexpr SizeT D = index_dim::value; + return iter<0,D> + ( [&](auto i) { return getIndexDepth(*std::get(ind.pack())); }, + [](auto... e) { + if constexpr( is_integral_constant::value and ... ){ + return std::integral_constant {}; + } + else { + return std::max({e...}); + } + } ); + } + else { + SizeT o = 0; + if(ind.dim() == 1){ + auto p = ind.pack(); + if(p.size() == 0){ + o = 1; + } + else { + o = getIndexDepth(*p[0]); + } + } + else { + for(SizeT i = 0; i != ind.dim(); ++i){ + const SizeT e = getIndexDepth(*ind.pack()[i]); + if(e > o){ + o = e; + } + } + } + return o; + } + } + else { + return std::integral_constant {}; + } + } + + template + constexpr decltype(auto) getDimension(const Index& ind, IntT depth) + { + static_assert(is_index::value, "got non-index type"); + if constexpr(std::is_same,IntT>::value) { + return std::integral_constant {} + } + else { + auto iminus = [](auto i) { + if constexpr( is_integral_constant::value ) { + return std::integral_constant {} + } + else { + return i-1; + } + }; + if constexpr(has_sub::value){ + if constexpr(has_static_sub::value and is_integral_constant::value){ + constexpr SizeT D = index_dim::value; + return iter<0,D> + ( [&](auto i) { return getDimension(*std::get(ind.pack()), + iminus(depth)); }, + [](auto... e) { + if constexpr( is_integral_constant::value and ... ){ + return std::integral_constant {}; + } + else { + return (e + ...); + } + } ); + } + else { + SizeT o = 0; + if(depth == 0u){ + o = 1; + } + else if(ind.dim() == 1){ + auto p = ind.pack(); + if(p.size() == 0){ + o = 1; + } + else { + o = getDimension(*p[0], iminus(depth)); + } + } + else { + for(SizeT i = 0; i != ind.dim(); ++i){ + const SizeT e = getDimension(*ind.pack()[i], iminus(depth)); + if(e > o){ + o = e; + } + } + } + return o; + } + } + else { + return std::integral_constant {}; + } + } + } } #endif diff --git a/src/include/ranges/index_utils.h b/src/include/ranges/index_utils.h index 73ec4e2..cafaa2f 100644 --- a/src/include/ranges/index_utils.h +++ b/src/include/ranges/index_utils.h @@ -13,6 +13,12 @@ namespace CNORZX template inline decltype(auto) indexPackZip(const Vector& a, const Vector& b, F&& f); + + template + constexpr decltype(auto) getIndexDepth(const Index& ind); + + template + constexpr decltype(auto) getDimension(const Index& ind, IntT depth); } #endif