diff --git a/support/indexed/fcarouge/indexed_linalg.hpp b/support/indexed/fcarouge/indexed_linalg.hpp index 86aeed272..fa157a37a 100644 --- a/support/indexed/fcarouge/indexed_linalg.hpp +++ b/support/indexed/fcarouge/indexed_linalg.hpp @@ -57,8 +57,25 @@ namespace fcarouge::indexed { //! @todo Move to utility. template -using element_t = product, - std::tuple_element_t>; +using element = product, + std::tuple_element_t>; + +//! @brief The given row and column indexes form a colum-vector/matrix. +template +concept column = size == 1; + +//! @brief The given row and column indexes form a row-vector/matrix. +template +concept row = size == 1; + +//! @brief The given row and column indexes form a singleton matrix. +template +concept singleton = + column && row; + +//! @brief The packs have the same count of types. +template +concept equal_size = size == size; //! @name Types //! @{ @@ -94,8 +111,8 @@ struct matrix { inline constexpr explicit matrix( std::initializer_list> rows) { for (std::size_t i{0}; const auto &row : rows) { - for (std::size_t j{0}; const auto &element : row) { - data(i, j) = element; + for (std::size_t j{0}; const auto &value : row) { + data(i, j) = value; ++j; } ++i; @@ -103,54 +120,56 @@ struct matrix { } template - requires(size == 1 && size != 1 && - sizeof...(Types) == size) - inline constexpr matrix(const Types &...elements) { - std::tuple element_pack{elements...}; - for_constexpr<0, size, 1>([this, &element_pack](auto position) { - data[position] = std::get(element_pack); + requires column && + equal_size> + inline constexpr matrix(const Types &...values) { + std::tuple value_pack{values...}; + for_constexpr<0, size, 1>([this, &value_pack](auto position) { + data[position] = std::get(value_pack); }); } template requires(size == 1 && size != 1 && sizeof...(Types) == size) - explicit inline constexpr matrix(const Types &...elements) { - std::tuple element_pack{elements...}; + explicit inline constexpr matrix(const Types &...values) { + std::tuple value_pack{values...}; for_constexpr<0, size, 1>( - [this, &element_pack](auto position) { - data[position] = std::get(element_pack); + [this, &value_pack](auto position) { + data[position] = std::get(value_pack); }); } [[nodiscard]] inline constexpr explicit(false) - operator element_t<0, RowIndexes, 0, ColumnIndexes>() const - requires(size == 1 && size == 1) + operator element<0, RowIndexes, 0, ColumnIndexes>() const + requires singleton { - return element_t<0, RowIndexes, 0, ColumnIndexes>{data(0, 0)}; + return element<0, RowIndexes, 0, ColumnIndexes>{data(0, 0)}; } //! @todo Shorten with self deduced this? [[nodiscard]] inline constexpr auto &operator[](std::size_t index) - requires(size != 1 && size == 1) + requires column && + (not row) { return data(index, 0); } [[nodiscard]] inline constexpr const auto &operator[](std::size_t index) const - requires(size != 1 && size == 1) + requires column && + (not row) { return data(index, 0); } [[nodiscard]] inline constexpr auto &operator[](std::size_t index) - requires(size == 1) + requires row { return data(0, index); } [[nodiscard]] inline constexpr const auto &operator[](std::size_t index) const - requires(size == 1) + requires row { return data(0, index); } @@ -166,25 +185,27 @@ struct matrix { } [[nodiscard]] inline constexpr auto &operator()(std::size_t index) - requires(size != 1 && size == 1) + requires column && + (not row) { return data(index, 0); } [[nodiscard]] inline constexpr const auto &operator()(std::size_t index) const - requires(size != 1 && size == 1) + requires column && + (not row) { return data(index, 0); } [[nodiscard]] inline constexpr auto &operator()(std::size_t index) - requires(size == 1) + requires row { return data(0, index); } [[nodiscard]] inline constexpr const auto &operator()(std::size_t index) const - requires(size == 1) + requires row { return data(0, index); } @@ -245,12 +266,11 @@ operator+(const matrix &lhs, template - requires(size == 1 && size == 1) + requires singleton [[nodiscard]] inline constexpr auto operator+(const matrix &lhs, Scalar rhs) { - //! @todo Return element. //! @todo Scalar will become Index with constraints. - return element_t<0, RowIndexes, 0, ColumnIndexes>{lhs.data(0) + rhs}; + return element<0, RowIndexes, 0, ColumnIndexes>{lhs.data(0) + rhs}; } template &lhs, template - requires(size == 1 && size == 1) + requires singleton [[nodiscard]] inline constexpr auto operator-(Scalar lhs, const matrix &rhs) { //! @todo Don't evaluate? Return the expression? - return element_t<0, RowIndexes, 0, ColumnIndexes>{lhs - rhs.data(0)}; + return element<0, RowIndexes, 0, ColumnIndexes>{lhs - rhs.data(0)}; } template - requires(size == 1 && size == 1) + requires singleton [[nodiscard]] inline constexpr auto operator*(Scalar lhs, const matrix &rhs) { - return element_t<0, RowIndexes, 0, ColumnIndexes>{lhs * rhs.data(0)}; + return element<0, RowIndexes, 0, ColumnIndexes>{lhs * rhs.data(0)}; } template &rhs) { template - requires(size == 1 && size == 1) + requires singleton [[nodiscard]] inline constexpr auto operator*(const matrix &lhs, Scalar rhs) { - return element_t<0, RowIndexes, 0, ColumnIndexes>{lhs.data(0) * rhs}; + return element<0, RowIndexes, 0, ColumnIndexes>{lhs.data(0) * rhs}; } template &lhs, Scalar rhs) { template - requires(size == 1 && size == 1) + requires singleton [[nodiscard]] inline constexpr auto operator/(const matrix &lhs, Scalar rhs) { - return element_t<0, RowIndexes, 0, ColumnIndexes>{lhs.data(0) / rhs}; + return element<0, RowIndexes, 0, ColumnIndexes>{lhs.data(0) / rhs}; } } // namespace fcarouge::indexed @@ -372,8 +392,7 @@ struct std::formatter< const fcarouge::indexed::matrix &value, std::basic_format_context &format_context) const -> OutputIterator - requires(fcarouge::size == 1 && - fcarouge::size != 1) + requires fcarouge::indexed::row { format_context.advance_to(std::format_to(format_context.out(), "[")); @@ -396,8 +415,7 @@ struct std::formatter< const fcarouge::indexed::matrix &value, std::basic_format_context &format_context) const -> OutputIterator - requires(fcarouge::size == 1 && - fcarouge::size == 1) + requires fcarouge::indexed::singleton { format_context.advance_to( std::format_to(format_context.out(), "{}", value.data(0, 0)));