From 249ca33aabc57d3326057988ff845fc0ef40ca67 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 30 Oct 2021 22:04:50 +0300 Subject: [PATCH] Support indexing util::array with arbitrary array-like types --- libs/util/include/psemek/util/array.hpp | 85 ++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/libs/util/include/psemek/util/array.hpp b/libs/util/include/psemek/util/array.hpp index b711802a..ac9e0370 100644 --- a/libs/util/include/psemek/util/array.hpp +++ b/libs/util/include/psemek/util/array.hpp @@ -9,6 +9,38 @@ namespace psemek::util { + namespace detail + { + + template + struct is_array : std::false_type {}; + + template + struct is_array()[0])>> + : std::true_type + {}; + + template + constexpr bool is_array_v = is_array::value; + + template + struct is_index; + + template <> + struct is_index<> + : std::false_type + {}; + + template + struct is_index + : std::bool_constant> + {}; + + template + constexpr bool is_index_v = is_index::value; + + } + template struct array { @@ -62,14 +94,27 @@ namespace psemek::util return dims_[2]; } - T & operator()(dims_type const & index); - T const & operator()(dims_type const & index) const; + template + std::enable_if_t, T &> + operator()(Index const & index); + + template + std::enable_if_t, T const &> + operator()(Index const & index) const; template - T & operator()(Ixs ... ixs); + std::enable_if_t, T &> + operator()(Ixs ... ixs); template - T const & operator()(Ixs ... ixs) const; + std::enable_if_t, T const &> + operator()(Ixs ... ixs) const; + + template + T & operator()(std::initializer_list const & index); + + template + T const & operator()(std::initializer_list const & index) const; array copy() const; @@ -127,8 +172,8 @@ namespace psemek::util return false; } - template - std::size_t index(std::array const & i, std::array const & dims) + template + std::size_t index(Index const & i, std::array const & dims) { std::size_t r = 0; for (std::size_t d = N; d --> 0;) @@ -278,20 +323,25 @@ namespace psemek::util } template - T & array::operator()(dims_type const & index) + template + std::enable_if_t, T &> + array::operator()(Index const & index) { return data_[detail::index(index, dims_)]; } template - T const & array::operator()(dims_type const & index) const + template + std::enable_if_t, T const &> + array::operator()(Index const & index) const { return data_[detail::index(index, dims_)]; } template template - T & array::operator()(Ixs ... ixs) + std::enable_if_t, T &> + array::operator()(Ixs ... ixs) { dims_type dims{static_cast(ixs)...}; return (*this)(dims); @@ -299,12 +349,27 @@ namespace psemek::util template template - T const & array::operator()(Ixs ... ixs) const + std::enable_if_t, T const &> + array::operator()(Ixs ... ixs) const { dims_type dims{static_cast(ixs)...}; return (*this)(dims); } + template + template + T & array::operator()(std::initializer_list const & index) + { + return data_[detail::index(std::data(index), dims_)]; + } + + template + template + T const & array::operator()(std::initializer_list const & index) const + { + return data_[detail::index(std::data(index), dims_)]; + } + template array array::copy() const {