Fix some operations API mismatch

* Compound operators were not usable properly.
* std::size_t was used in the API in places where Index should have been used.
This commit is contained in:
Joel Falcou 2025-10-29 20:33:59 +01:00
parent f8cb289529
commit c7aa4a0afa
12 changed files with 152 additions and 120 deletions

View file

@ -87,62 +87,52 @@ namespace rotgen
return *this; return *this;
} }
block(Ref const& r, block(Ref const& r, Index i0, Index j0, Index ni, Index nj)
std::size_t i0,
std::size_t j0,
std::size_t ni,
std::size_t nj)
requires(!requires { typename Ref::rotgen_block_tag; } && is_immutable) requires(!requires { typename Ref::rotgen_block_tag; } && is_immutable)
: parent(r.base(), i0, j0, ni, nj) : parent(r.base(), i0, j0, ni, nj)
{ {
} }
block(Ref const& r, block(Ref const& r, Index i0, Index j0, Index ni, Index nj)
std::size_t i0,
std::size_t j0,
std::size_t ni,
std::size_t nj)
requires(requires { typename Ref::rotgen_block_tag; } && is_immutable) requires(requires { typename Ref::rotgen_block_tag; } && is_immutable)
: parent(r.base(), i0, j0, ni, nj) : parent(r.base(), i0, j0, ni, nj)
{ {
} }
block(Ref const& r, std::size_t i0, std::size_t j0) block(Ref const& r, Index i0, Index j0)
requires(!requires { typename Ref::rotgen_block_tag; } && Rows != -1 && requires(!requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
Cols != -1 && is_immutable) Cols != -1 && is_immutable)
: parent(r.base(), i0, j0, Rows, Cols) : parent(r.base(), i0, j0, Rows, Cols)
{ {
} }
block(Ref const& r, std::size_t i0, std::size_t j0) block(Ref const& r, Index i0, Index j0)
requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 && requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
Cols != -1 && is_immutable) Cols != -1 && is_immutable)
: parent(r.base(), i0, j0, Rows, Cols) : parent(r.base(), i0, j0, Rows, Cols)
{ {
} }
block( block(Ref& r, Index i0, Index j0, Index ni, Index nj)
Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
requires(!requires { typename Ref::rotgen_block_tag; } && !is_immutable) requires(!requires { typename Ref::rotgen_block_tag; } && !is_immutable)
: parent(r.base(), i0, j0, ni, nj) : parent(r.base(), i0, j0, ni, nj)
{ {
} }
block( block(Ref& r, Index i0, Index j0, Index ni, Index nj)
Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
requires(requires { typename Ref::rotgen_block_tag; } && !is_immutable) requires(requires { typename Ref::rotgen_block_tag; } && !is_immutable)
: parent(r.base(), i0, j0, ni, nj) : parent(r.base(), i0, j0, ni, nj)
{ {
} }
block(Ref& r, std::size_t i0, std::size_t j0) block(Ref& r, Index i0, Index j0)
requires(!requires { typename Ref::rotgen_block_tag; } && Rows != -1 && requires(!requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
Cols != -1 && !is_immutable) Cols != -1 && !is_immutable)
: parent(r.base(), i0, j0, Rows, Cols) : parent(r.base(), i0, j0, Rows, Cols)
{ {
} }
block(Ref& r, std::size_t i0, std::size_t j0) block(Ref& r, Index i0, Index j0)
requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 && requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
Cols != -1 && !is_immutable) Cols != -1 && !is_immutable)
: parent(r.base(), i0, j0, Rows, Cols) : parent(r.base(), i0, j0, Rows, Cols)

View file

@ -109,30 +109,25 @@ namespace rotgen
block& operator=(block const&) = default; block& operator=(block const&) = default;
block& operator=(block&&) = default; block& operator=(block&&) = default;
block(Ref const& r, block(Ref const& r, Index i0, Index j0, Index ni, Index nj)
std::size_t i0,
std::size_t j0,
std::size_t ni,
std::size_t nj)
requires(is_immutable) requires(is_immutable)
: parent(r.base(), i0, j0, ni, nj) : parent(r.base(), i0, j0, ni, nj)
{ {
} }
block(Ref const& r, std::size_t i0, std::size_t j0) block(Ref const& r, Index i0, Index j0)
requires(Rows != -1 && Cols != -1 && is_immutable) requires(Rows != -1 && Cols != -1 && is_immutable)
: parent(r.base(), i0, j0, Rows, Cols) : parent(r.base(), i0, j0, Rows, Cols)
{ {
} }
block( block(Ref& r, Index i0, Index j0, Index ni, Index nj)
Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
requires(!is_immutable) requires(!is_immutable)
: parent(r.base(), i0, j0, ni, nj) : parent(r.base(), i0, j0, ni, nj)
{ {
} }
block(Ref& r, std::size_t i0, std::size_t j0) block(Ref& r, Index i0, Index j0)
requires(Rows != -1 && Cols != -1 && !is_immutable) requires(Rows != -1 && Cols != -1 && !is_immutable)
: parent(r.base(), i0, j0, Rows, Cols) : parent(r.base(), i0, j0, Rows, Cols)
{ {

View file

@ -94,7 +94,7 @@ namespace rotgen
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
{ {
[[maybe_unused]] std::size_t c = 0; [[maybe_unused]] Index c = 0;
if (init.size()) c = init.begin()->size(); if (init.size()) c = init.begin()->size();
assert(c == Cols && assert(c == Cols &&
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");

View file

@ -15,10 +15,8 @@ class ROTGEN_EXPORT CLASSNAME
{ {
public: public:
CLASSNAME(); CLASSNAME();
CLASSNAME(std::size_t rows, std::size_t cols); CLASSNAME(Index rows, Index cols);
CLASSNAME(std::size_t rows, CLASSNAME(Index rows, Index cols, std::initializer_list<TYPE> init);
std::size_t cols,
std::initializer_list<TYPE> init);
CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init); CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init);
@ -34,8 +32,8 @@ public:
Index cols() const; Index cols() const;
Index size() const; Index size() const;
void resize(std::size_t new_rows, std::size_t new_cols); void resize(Index new_rows, Index new_cols);
void conservativeResize(std::size_t new_rows, std::size_t new_cols); void conservativeResize(Index new_rows, Index new_cols);
CLASSNAME normalized() const; CLASSNAME normalized() const;
CLASSNAME transpose() const; CLASSNAME transpose() const;
@ -64,11 +62,11 @@ public:
TYPE norm() const; TYPE norm() const;
TYPE lp_norm(int p) const; TYPE lp_norm(int p) const;
TYPE& operator()(std::size_t i, std::size_t j); TYPE& operator()(Index i, Index j);
TYPE const& operator()(std::size_t i, std::size_t j) const; TYPE const& operator()(Index i, Index j) const;
TYPE& operator()(std::size_t index); TYPE& operator()(Index index);
TYPE const& operator()(std::size_t index) const; TYPE const& operator()(Index index) const;
CLASSNAME& operator+=(CLASSNAME const& rhs); CLASSNAME& operator+=(CLASSNAME const& rhs);
CLASSNAME& operator-=(CLASSNAME const& rhs); CLASSNAME& operator-=(CLASSNAME const& rhs);
@ -89,17 +87,17 @@ public:
const TYPE* data() const; const TYPE* data() const;
TYPE* data(); TYPE* data();
static CLASSNAME Zero(std::size_t rows, std::size_t cols); static CLASSNAME Zero(Index rows, Index cols);
static CLASSNAME Ones(std::size_t rows, std::size_t cols); static CLASSNAME Ones(Index rows, Index cols);
static CLASSNAME Constant(std::size_t rows, std::size_t cols, TYPE value); static CLASSNAME Constant(Index rows, Index cols, TYPE value);
static CLASSNAME Random(std::size_t rows, std::size_t cols); static CLASSNAME Random(Index rows, Index cols);
static CLASSNAME Identity(std::size_t rows, std::size_t cols); static CLASSNAME Identity(Index rows, Index cols);
void setOnes(std::size_t rows, std::size_t cols); void setOnes(Index rows, Index cols);
void setZero(std::size_t rows, std::size_t cols); void setZero(Index rows, Index cols);
void setConstant(std::size_t rows, std::size_t cols, TYPE value); void setConstant(Index rows, Index cols, TYPE value);
void setRandom(std::size_t rows, std::size_t cols); void setRandom(Index rows, Index cols);
void setIdentity(std::size_t rows, std::size_t cols); void setIdentity(Index rows, Index cols);
private: private:
struct payload; struct payload;

View file

@ -86,6 +86,45 @@ namespace rotgen
using parent::cwiseInverse; using parent::cwiseInverse;
using parent::cwiseSqrt; using parent::cwiseSqrt;
// Compound Operators
template<typename A, int O, typename S>
ref& operator+=(ref<A, O, S> rhs)
requires(!is_immutable)
{
base() += rhs.base();
return *this;
}
template<typename A, int O, typename S>
ref& operator-=(ref<A, O, S> rhs)
requires(!is_immutable)
{
base() -= rhs.base();
return *this;
}
template<typename A, int O, typename S>
ref& operator*=(ref<A, O, S> rhs)
requires(!is_immutable)
{
base() *= rhs.base();
return *this;
}
ref& operator*=(std::convertible_to<value_type> auto s)
requires(!is_immutable)
{
base() *= s;
return *this;
}
ref& operator/=(std::convertible_to<value_type> auto s)
requires(!is_immutable)
{
base() /= s;
return *this;
}
// Shape modifications // Shape modifications
using parent::adjoint; using parent::adjoint;
using parent::conjugate; using parent::conjugate;

View file

@ -132,6 +132,45 @@ namespace rotgen
using parent::sum; using parent::sum;
using parent::trace; using parent::trace;
// Compound Operators
template<typename A, int O, typename S>
ref& operator+=(ref<A, O, S> rhs)
requires(!is_immutable)
{
base() += rhs.base();
return *this;
}
template<typename A, int O, typename S>
ref& operator-=(ref<A, O, S> rhs)
requires(!is_immutable)
{
base() -= rhs.base();
return *this;
}
template<typename A, int O, typename S>
ref& operator*=(ref<A, O, S> rhs)
requires(!is_immutable)
{
base() *= rhs.base();
return *this;
}
ref& operator*=(std::convertible_to<value_type> auto s)
requires(!is_immutable)
{
base() *= s;
return *this;
}
ref& operator/=(std::convertible_to<value_type> auto s)
requires(!is_immutable)
{
base() /= s;
return *this;
}
// Shape modifications // Shape modifications
using parent::adjoint; using parent::adjoint;
using parent::conjugate; using parent::conjugate;

View file

@ -23,35 +23,6 @@ namespace rotgen
return lhs.base() != rhs.base(); return lhs.base() != rhs.base();
} }
template<typename A, int O, typename S, typename B, int P, typename T>
auto operator+=(ref<A, O, S> lhs, ref<B, P, T> rhs)
{
lhs.base() += rhs.base();
return lhs;
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto operator-=(ref<A, O, S> lhs, ref<B, P, T> rhs)
{
lhs.base() -= rhs.base();
return lhs;
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto operator*=(ref<A, O, S> lhs, ref<B, P, T> rhs)
{
lhs.base() *= rhs.base();
return lhs;
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto operator/=(ref<A, O, S> lhs,
std::convertible_to<typename A::value_type> auto s)
{
lhs.base() /= s;
return lhs;
}
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto operator*(std::convertible_to<typename A::value_type> auto s, auto operator*(std::convertible_to<typename A::value_type> auto s,
ref<A, O, S> rhs) ref<A, O, S> rhs)

View file

@ -26,7 +26,7 @@ namespace rotgen
data_type data; data_type data;
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {} payload(Index r = 0, Index c = 0) : data(r, c) {}
payload(std::initializer_list<std::initializer_list<double>> init) payload(std::initializer_list<std::initializer_list<double>> init)
: data(init) : data(init)
@ -49,7 +49,7 @@ namespace rotgen
data_type data; data_type data;
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {} payload(Index r = 0, Index c = 0) : data(r, c) {}
payload(std::initializer_list<std::initializer_list<double>> init) payload(std::initializer_list<std::initializer_list<double>> init)
: data(init) : data(init)
@ -72,7 +72,7 @@ namespace rotgen
data_type data; data_type data;
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {} payload(Index r = 0, Index c = 0) : data(r, c) {}
payload(std::initializer_list<std::initializer_list<float>> init) payload(std::initializer_list<std::initializer_list<float>> init)
: data(init) : data(init)
@ -95,7 +95,7 @@ namespace rotgen
data_type data; data_type data;
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {} payload(Index r = 0, Index c = 0) : data(r, c) {}
payload(std::initializer_list<std::initializer_list<float>> init) payload(std::initializer_list<std::initializer_list<float>> init)
: data(init) : data(init)

View file

@ -14,19 +14,19 @@ namespace rotgen
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
// Infos & Shape // Infos & Shape
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
std::size_t rows(auto const& m) Index rows(auto const& m)
requires(requires { m.rows(); }) requires(requires { m.rows(); })
{ {
return m.rows(); return m.rows();
} }
std::size_t cols(auto const& m) Index cols(auto const& m)
requires(requires { m.cols(); }) requires(requires { m.cols(); })
{ {
return m.cols(); return m.cols();
} }
std::size_t size(auto const& m) Index size(auto const& m)
requires(requires { m.size(); }) requires(requires { m.size(); })
{ {
return m.size(); return m.size();

View file

@ -8,6 +8,7 @@
#pragma once #pragma once
#include <rotgen/concepts.hpp> #include <rotgen/concepts.hpp>
#include <cassert> #include <cassert>
#include <iosfwd> #include <iosfwd>
@ -81,7 +82,7 @@ namespace rotgen
// Compounds operators across types // Compounds operators across types
template<typename A, typename B> template<typename A, typename B>
auto operator+=(A& a, B const& b) auto operator+=(A& a, B const& b)
requires(concepts::entity<A> || concepts::entity<B>) requires(concepts::entity<A> && concepts::entity<B>)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return generalize_t<A>(a) += generalize_t<B const>(b); return generalize_t<A>(a) += generalize_t<B const>(b);
@ -90,7 +91,7 @@ namespace rotgen
template<typename A, typename B> template<typename A, typename B>
auto operator-=(A& a, B const& b) auto operator-=(A& a, B const& b)
requires(concepts::entity<A> || concepts::entity<B>) requires(concepts::entity<A> && concepts::entity<B>)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return generalize_t<A>(a) -= generalize_t<B const>(b); return generalize_t<A>(a) -= generalize_t<B const>(b);
@ -99,7 +100,7 @@ namespace rotgen
template<typename A, typename B> template<typename A, typename B>
auto operator*=(A& a, B const& b) auto operator*=(A& a, B const& b)
requires(concepts::entity<A> || concepts::entity<B>) requires(concepts::entity<A> && concepts::entity<B>)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return generalize_t<A>(a) *= generalize_t<B const>(b); return generalize_t<A>(a) *= generalize_t<B const>(b);

View file

@ -17,7 +17,7 @@
//================================================================================================== //==================================================================================================
CLASSNAME::CLASSNAME() : storage_(std::make_unique<payload>(0, 0)) {} CLASSNAME::CLASSNAME() : storage_(std::make_unique<payload>(0, 0)) {}
CLASSNAME::CLASSNAME(std::size_t r, std::size_t c) CLASSNAME::CLASSNAME(Index r, Index c)
: storage_(std::make_unique<payload>(r, c)) : storage_(std::make_unique<payload>(r, c))
{ {
} }
@ -27,9 +27,7 @@ CLASSNAME::CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init)
{ {
} }
CLASSNAME::CLASSNAME(std::size_t r, CLASSNAME::CLASSNAME(Index r, Index c, std::initializer_list<TYPE> init)
std::size_t c,
std::initializer_list<TYPE> init)
: CLASSNAME(r, c) : CLASSNAME(r, c)
{ {
auto first = init.begin(); auto first = init.begin();
@ -71,32 +69,32 @@ rotgen::Index CLASSNAME::size() const
return storage_->data.size(); return storage_->data.size();
} }
void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols) void CLASSNAME::resize(Index new_rows, Index new_cols)
{ {
storage_->data.resize(new_rows, new_cols); storage_->data.resize(new_rows, new_cols);
} }
void CLASSNAME::conservativeResize(std::size_t new_rows, std::size_t new_cols) void CLASSNAME::conservativeResize(Index new_rows, Index new_cols)
{ {
storage_->data.conservativeResize(new_rows, new_cols); storage_->data.conservativeResize(new_rows, new_cols);
} }
TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) TYPE& CLASSNAME::operator()(Index i, Index j)
{ {
return storage_->data(i, j); return storage_->data(i, j);
} }
TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const TYPE const& CLASSNAME::operator()(Index i, Index j) const
{ {
return storage_->data(i, j); return storage_->data(i, j);
} }
TYPE& CLASSNAME::operator()(std::size_t index) TYPE& CLASSNAME::operator()(Index index)
{ {
return storage_->data(index); return storage_->data(index);
} }
TYPE const& CLASSNAME::operator()(std::size_t index) const TYPE const& CLASSNAME::operator()(Index index) const
{ {
return storage_->data(index); return storage_->data(index);
} }
@ -303,27 +301,27 @@ CLASSNAME& CLASSNAME::operator/=(TYPE s)
//============================================================================== //==============================================================================
// Generators functions // Generators functions
//============================================================================== //==============================================================================
void CLASSNAME::setOnes(std::size_t rows, std::size_t cols) void CLASSNAME::setOnes(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Ones(rows, cols).eval()); storage_->assign(payload::data_type::Ones(rows, cols).eval());
} }
void CLASSNAME::setZero(std::size_t rows, std::size_t cols) void CLASSNAME::setZero(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Zero(rows, cols).eval()); storage_->assign(payload::data_type::Zero(rows, cols).eval());
} }
void CLASSNAME::setConstant(std::size_t rows, std::size_t cols, TYPE value) void CLASSNAME::setConstant(Index rows, Index cols, TYPE value)
{ {
storage_->assign(payload::data_type::Constant(rows, cols, value).eval()); storage_->assign(payload::data_type::Constant(rows, cols, value).eval());
} }
void CLASSNAME::setRandom(std::size_t rows, std::size_t cols) void CLASSNAME::setRandom(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Random(rows, cols).eval()); storage_->assign(payload::data_type::Random(rows, cols).eval());
} }
void CLASSNAME::setIdentity(std::size_t rows, std::size_t cols) void CLASSNAME::setIdentity(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Identity(rows, cols).eval()); storage_->assign(payload::data_type::Identity(rows, cols).eval());
} }
@ -331,21 +329,21 @@ void CLASSNAME::setIdentity(std::size_t rows, std::size_t cols)
//============================================================================== //==============================================================================
// Static functions // Static functions
//============================================================================== //==============================================================================
CLASSNAME CLASSNAME::Ones(std::size_t rows, std::size_t cols) CLASSNAME CLASSNAME::Ones(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = std::make_unique<payload>(payload::data_type::Ones(rows, cols)); m.storage_ = std::make_unique<payload>(payload::data_type::Ones(rows, cols));
return m; return m;
} }
CLASSNAME CLASSNAME::Zero(std::size_t rows, std::size_t cols) CLASSNAME CLASSNAME::Zero(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = std::make_unique<payload>(payload::data_type::Zero(rows, cols)); m.storage_ = std::make_unique<payload>(payload::data_type::Zero(rows, cols));
return m; return m;
} }
CLASSNAME CLASSNAME::Constant(std::size_t rows, std::size_t cols, TYPE value) CLASSNAME CLASSNAME::Constant(Index rows, Index cols, TYPE value)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = m.storage_ =
@ -353,7 +351,7 @@ CLASSNAME CLASSNAME::Constant(std::size_t rows, std::size_t cols, TYPE value)
return m; return m;
} }
CLASSNAME CLASSNAME::Random(std::size_t rows, std::size_t cols) CLASSNAME CLASSNAME::Random(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = m.storage_ =
@ -361,7 +359,7 @@ CLASSNAME CLASSNAME::Random(std::size_t rows, std::size_t cols)
return m; return m;
} }
CLASSNAME CLASSNAME::Identity(std::size_t rows, std::size_t cols) CLASSNAME CLASSNAME::Identity(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = m.storage_ =

View file

@ -5,10 +5,11 @@
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp"
#include <rotgen/rotgen.hpp> #include <rotgen/rotgen.hpp>
#include <functional>
#include "unit/tests.hpp"
#include <array> #include <array>
#include <functional>
template<typename MatrixType> struct MatrixDescriptor template<typename MatrixType> struct MatrixDescriptor
{ {
@ -18,15 +19,15 @@ template<typename MatrixType> struct MatrixDescriptor
template<typename MatrixType, std::size_t N> template<typename MatrixType, std::size_t N>
void test_matrix_sizes( void test_matrix_sizes(
std::size_t rows, rotgen::Index rows,
std::size_t cols, rotgen::Index cols,
std::function<void(MatrixType&, std::size_t, std::size_t)> const& init_fn, std::function<void(MatrixType&, std::size_t, std::size_t)> const& init_fn,
std::array<std::pair<int, int>, N> const& resize_dimensions) std::array<std::pair<int, int>, N> const& resize_dimensions)
{ {
MatrixType matrix(rows, cols); MatrixType matrix(rows, cols);
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c) init_fn(matrix, r, c); for (rotgen::Index c = 0; c < cols; ++c) init_fn(matrix, r, c);
TTS_EQUAL(rotgen::size(matrix), rows * cols); TTS_EQUAL(rotgen::size(matrix), rows * cols);
@ -37,24 +38,24 @@ void test_matrix_sizes(
rotgen::resize(matrix, r, c); rotgen::resize(matrix, r, c);
TTS_EQUAL(rotgen::rows(matrix), static_cast<size_t>(r)); TTS_EQUAL(rotgen::rows(matrix), r);
TTS_EQUAL(rotgen::cols(matrix), static_cast<size_t>(c)); TTS_EQUAL(rotgen::cols(matrix), c);
TTS_EQUAL(rotgen::size(matrix), static_cast<size_t>(r * c)); TTS_EQUAL(rotgen::size(matrix), r * c);
} }
rotgen::conservativeResize(matrix, rows, cols); rotgen::conservativeResize(matrix, rows, cols);
TTS_EQUAL(rotgen::size(matrix), rows * cols); TTS_EQUAL(rotgen::size(matrix), rows * cols);
int i = 1; int i = 1;
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c) matrix(r, c) = i++; for (rotgen::Index c = 0; c < cols; ++c) matrix(r, c) = i++;
rotgen::conservativeResize(matrix, rows + 3, cols + 2); rotgen::conservativeResize(matrix, rows + 3, cols + 2);
TTS_EQUAL(rotgen::size(matrix), (rows + 3) * (cols + 2)); TTS_EQUAL(rotgen::size(matrix), (rows + 3) * (cols + 2));
i = 1; i = 1;
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c) TTS_EQUAL(matrix(r, c), i++); for (rotgen::Index c = 0; c < cols; ++c) TTS_EQUAL(matrix(r, c), i++);
} }
TTS_CASE("Matrix size-related operations") TTS_CASE("Matrix size-related operations")