diff --git a/include/rotgen/container/ref/dynamic.hpp b/include/rotgen/container/ref/dynamic.hpp index 75010d3..fcd3d17 100644 --- a/include/rotgen/container/ref/dynamic.hpp +++ b/include/rotgen/container/ref/dynamic.hpp @@ -135,11 +135,20 @@ namespace rotgen assert(correct_ref_setup); } + template + requires(detail::same_scalar>) + ref(matrix&& m) : parent(detail::postpone{}) + { + if (!detail::validate_ref(*this, m)) + { + potential_local_copy = std::move(m); + detail::validate_ref(*this, potential_local_copy); + } + } + template requires(is_immutable && - detail::same_scalar> && - (detail::accept_as_ref> || - may_map_object)) + detail::same_scalar>) ref(matrix const& m) : parent(detail::postpone{}) { if (!detail::validate_ref(*this, m)) @@ -166,9 +175,7 @@ namespace rotgen } template - requires(is_immutable && detail::same_scalar> && - (detail::accept_as_ref> || - may_map_object)) + requires(is_immutable && detail::same_scalar>) ref(block const& b) : parent(detail::postpone{}) { if (!detail::validate_ref(*this, b)) @@ -187,8 +194,18 @@ namespace rotgen } template - requires(is_immutable && detail::same_scalar> && - (detail::accept_as_ref> || may_map_object)) + requires(detail::accept_as_ref>) + ref(map&& b) : parent(detail::postpone{}) + { + if (!detail::validate_ref(*this, b)) + { + potential_local_copy = std::move(b); + detail::validate_ref(*this, potential_local_copy); + } + } + + template + requires(is_immutable && detail::accept_as_ref>) ref(map const& b) : parent(detail::postpone{}) { if (!detail::validate_ref(*this, b)) @@ -207,8 +224,7 @@ namespace rotgen } template - requires(is_immutable && detail::same_scalar> && - (detail::accept_as_ref> || may_map_object)) + requires(detail::same_scalar>) ref(ref const& b) : parent(detail::postpone{}) { [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b); diff --git a/include/rotgen/container/ref/fixed.hpp b/include/rotgen/container/ref/fixed.hpp index 51e96f3..039e700 100644 --- a/include/rotgen/container/ref/fixed.hpp +++ b/include/rotgen/container/ref/fixed.hpp @@ -163,7 +163,6 @@ namespace rotgen base().colPivHouseholderQr().solve(rhs.base())); }; - // using parent::operator=; ref& operator=(concepts::entity auto const& e) { base() = e.base(); @@ -182,16 +181,18 @@ namespace rotgen } template - ref(matrix const& m) - requires(requires { parent(m.base()); } && is_immutable) - : parent(m.base()) + ref(matrix&& m) + requires(requires { + parent(std::forward>(m.base())); + } && is_immutable) + : parent(std::forward>(m.base())) { } - template - ref(block&& b) - requires(requires { parent(b.base()); }) - : parent(b.base()) + template + ref(matrix const& m) + requires(requires { parent(m.base()); }) + : parent(m.base()) { } @@ -204,7 +205,7 @@ namespace rotgen template ref(block const& b) - requires(requires { parent(b.base()); } && is_immutable) + requires(requires { parent(b.base()); }) : parent(b.base()) { } @@ -218,7 +219,7 @@ namespace rotgen template ref(map const& m) - requires(requires { parent(m.base()); } && is_immutable) + requires(requires { parent(m.base()); }) : parent(m.base()) { } @@ -230,9 +231,16 @@ namespace rotgen { } + template + ref(ref&& r) + requires(requires { parent(r.base()); }) + : parent(r.base()) + { + } + template ref(ref const& r) - requires(requires { parent(r.base()); } && is_immutable) + requires(requires { parent(r.base()); }) : parent(r.base()) { } diff --git a/test/integration/ref_magic.cpp b/test/integration/ref_magic.cpp index bb7809b..ca463d1 100644 --- a/test/integration/ref_magic.cpp +++ b/test/integration/ref_magic.cpp @@ -83,15 +83,40 @@ requires(N > 1) return -1; } -TTS_CASE("Reference overload on stroage order check") +TTS_CASE("Reference overload on storage order check") { - rotgen::matrix mat_dyn(1, 3); - rotgen::matrix mat_col(1, 3); - rotgen::matrix mat_row(1, 3); + using col3 = rotgen::matrix; + using row3 = rotgen::matrix; + + rotgen::matrixXf mat_dyn(1, 3); + col3 mat_col(1, 3); + row3 mat_row(1, 3); TTS_EQUAL(f(mat_dyn), +2); - TTS_EQUAL(g<3>(mat_dyn), +1); TTS_EQUAL(g<3>(mat_col), +1); TTS_EQUAL(g<3>(mat_row), -1); + + TTS_EQUAL(f(rotgen::map(mat_dyn.data(), 1, 3)), +2); + TTS_EQUAL(g<3>(rotgen::map(mat_dyn.data(), 1, 3)), +1); + TTS_EQUAL(g<3>(rotgen::map(mat_dyn.data(), 1, 3)), +1); + TTS_EQUAL(g<3>(rotgen::map(mat_dyn.data(), 1, 3)), -1); + + TTS_EQUAL(f(rotgen::map>( + mat_dyn.data(), 1, 3, rotgen::outer_stride<>{1})), + +2); + TTS_EQUAL(g<3>(rotgen::map>( + mat_dyn.data(), 1, 3, rotgen::outer_stride<>{1})), + +1); + TTS_EQUAL(g<3>(rotgen::map>( + mat_dyn.data(), 1, 3, rotgen::outer_stride<>{1})), + +1); + TTS_EQUAL(g<3>(rotgen::map>( + mat_dyn.data(), 1, 3, rotgen::outer_stride<>{1})), + -1); + + TTS_EQUAL(f(rotgen::extract(mat_dyn, 0, 0, 1, 3)), +2); + TTS_EQUAL(g<3>(rotgen::extract(mat_dyn, 0, 0, 1, 3)), +1); + TTS_EQUAL(g<3>(rotgen::extract(mat_col, 0, 0, 1, 3)), +1); + TTS_EQUAL(g<3>(rotgen::extract(mat_row, 0, 0, 1, 3)), -1); };