Fix handling of temporary data passed as ref

See merge request oss/rotgen!44
This commit is contained in:
Joel Falcou 2025-10-29 18:08:15 +01:00
commit f8cb289529
3 changed files with 75 additions and 26 deletions

View file

@ -135,11 +135,20 @@ namespace rotgen
assert(correct_ref_setup); assert(correct_ref_setup);
} }
template<typename S, int R, int C, int O, int MR, int MC>
requires(detail::same_scalar<ref, matrix<S, R, C, O, MR, MC>>)
ref(matrix<S, R, C, O, MR, MC>&& m) : parent(detail::postpone{})
{
if (!detail::validate_ref(*this, m))
{
potential_local_copy = std::move(m);
detail::validate_ref(*this, potential_local_copy);
}
}
template<typename S, int R, int C, int O, int MR, int MC> template<typename S, int R, int C, int O, int MR, int MC>
requires(is_immutable && requires(is_immutable &&
detail::same_scalar<ref, matrix<S, R, C, O, MR, MC>> && detail::same_scalar<ref, matrix<S, R, C, O, MR, MC>>)
(detail::accept_as_ref<ref, matrix<S, R, C, O, MR, MC>> ||
may_map_object))
ref(matrix<S, R, C, O, MR, MC> const& m) : parent(detail::postpone{}) ref(matrix<S, R, C, O, MR, MC> const& m) : parent(detail::postpone{})
{ {
if (!detail::validate_ref(*this, m)) if (!detail::validate_ref(*this, m))
@ -166,9 +175,7 @@ namespace rotgen
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
requires(is_immutable && detail::same_scalar<ref, block<Ref, R, C, I>> && requires(is_immutable && detail::same_scalar<ref, block<Ref, R, C, I>>)
(detail::accept_as_ref<ref, block<Ref, R, C, I>> ||
may_map_object))
ref(block<Ref, R, C, I> const& b) : parent(detail::postpone{}) ref(block<Ref, R, C, I> const& b) : parent(detail::postpone{})
{ {
if (!detail::validate_ref(*this, b)) if (!detail::validate_ref(*this, b))
@ -187,8 +194,18 @@ namespace rotgen
} }
template<typename Ref, int O, typename S> template<typename Ref, int O, typename S>
requires(is_immutable && detail::same_scalar<ref, map<Ref, O, S>> && requires(detail::accept_as_ref<ref, map<Ref, O, S>>)
(detail::accept_as_ref<ref, map<Ref, O, S>> || may_map_object)) ref(map<Ref, O, S>&& b) : parent(detail::postpone{})
{
if (!detail::validate_ref(*this, b))
{
potential_local_copy = std::move(b);
detail::validate_ref(*this, potential_local_copy);
}
}
template<typename Ref, int O, typename S>
requires(is_immutable && detail::accept_as_ref<ref, map<Ref, O, S>>)
ref(map<Ref, O, S> const& b) : parent(detail::postpone{}) ref(map<Ref, O, S> const& b) : parent(detail::postpone{})
{ {
if (!detail::validate_ref(*this, b)) if (!detail::validate_ref(*this, b))
@ -207,8 +224,7 @@ namespace rotgen
} }
template<typename TT, int OO, typename SS> template<typename TT, int OO, typename SS>
requires(is_immutable && detail::same_scalar<ref, ref<TT, OO, SS>> && requires(detail::same_scalar<ref, ref<TT, OO, SS>>)
(detail::accept_as_ref<ref, ref<TT, OO, SS>> || may_map_object))
ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{}) ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{})
{ {
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b); [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);

View file

@ -163,7 +163,6 @@ namespace rotgen
base().colPivHouseholderQr().solve(rhs.base())); base().colPivHouseholderQr().solve(rhs.base()));
}; };
// using parent::operator=;
ref& operator=(concepts::entity auto const& e) ref& operator=(concepts::entity auto const& e)
{ {
base() = e.base(); base() = e.base();
@ -182,16 +181,18 @@ namespace rotgen
} }
template<typename S, int R, int C, int O, int MR, int MC> template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC> const& m) ref(matrix<S, R, C, O, MR, MC>&& m)
requires(requires { parent(m.base()); } && is_immutable) requires(requires {
: parent(m.base()) parent(std::forward<matrix<S, R, C, O, MR, MC>>(m.base()));
} && is_immutable)
: parent(std::forward<matrix<S, R, C, O, MR, MC>>(m.base()))
{ {
} }
template<typename Ref, int R, int C, bool I> template<typename S, int R, int C, int O, int MR, int MC>
ref(block<Ref, R, C, I>&& b) ref(matrix<S, R, C, O, MR, MC> const& m)
requires(requires { parent(b.base()); }) requires(requires { parent(m.base()); })
: parent(b.base()) : parent(m.base())
{ {
} }
@ -204,7 +205,7 @@ namespace rotgen
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
ref(block<Ref, R, C, I> const& b) ref(block<Ref, R, C, I> const& b)
requires(requires { parent(b.base()); } && is_immutable) requires(requires { parent(b.base()); })
: parent(b.base()) : parent(b.base())
{ {
} }
@ -218,7 +219,7 @@ namespace rotgen
template<typename Ref, int O, typename S> template<typename Ref, int O, typename S>
ref(map<Ref, O, S> const& m) ref(map<Ref, O, S> const& m)
requires(requires { parent(m.base()); } && is_immutable) requires(requires { parent(m.base()); })
: parent(m.base()) : parent(m.base())
{ {
} }
@ -230,9 +231,16 @@ namespace rotgen
{ {
} }
template<typename TT, int OO, typename SS>
ref(ref<TT, OO, SS>&& r)
requires(requires { parent(r.base()); })
: parent(r.base())
{
}
template<typename TT, int OO, typename SS> template<typename TT, int OO, typename SS>
ref(ref<TT, OO, SS> const& r) ref(ref<TT, OO, SS> const& r)
requires(requires { parent(r.base()); } && is_immutable) requires(requires { parent(r.base()); })
: parent(r.base()) : parent(r.base())
{ {
} }

View file

@ -83,15 +83,40 @@ requires(N > 1)
return -1; return -1;
} }
TTS_CASE("Reference overload on stroage order check") TTS_CASE("Reference overload on storage order check")
{ {
rotgen::matrix<float> mat_dyn(1, 3); using col3 = rotgen::matrix<float, -1, 3, rotgen::ColMajor>;
rotgen::matrix<float, -1, 3, rotgen::ColMajor> mat_col(1, 3); using row3 = rotgen::matrix<float, -1, 3, rotgen::RowMajor>;
rotgen::matrix<float, -1, 3, rotgen::RowMajor> mat_row(1, 3);
rotgen::matrixXf mat_dyn(1, 3);
col3 mat_col(1, 3);
row3 mat_row(1, 3);
TTS_EQUAL(f(mat_dyn), +2); TTS_EQUAL(f(mat_dyn), +2);
TTS_EQUAL(g<3>(mat_dyn), +1); TTS_EQUAL(g<3>(mat_dyn), +1);
TTS_EQUAL(g<3>(mat_col), +1); TTS_EQUAL(g<3>(mat_col), +1);
TTS_EQUAL(g<3>(mat_row), -1); TTS_EQUAL(g<3>(mat_row), -1);
TTS_EQUAL(f(rotgen::map<rotgen::matrixXf, 1>(mat_dyn.data(), 1, 3)), +2);
TTS_EQUAL(g<3>(rotgen::map<rotgen::matrixXf, 1>(mat_dyn.data(), 1, 3)), +1);
TTS_EQUAL(g<3>(rotgen::map<col3, 1>(mat_dyn.data(), 1, 3)), +1);
TTS_EQUAL(g<3>(rotgen::map<row3, 1>(mat_dyn.data(), 1, 3)), -1);
TTS_EQUAL(f(rotgen::map<rotgen::matrixXf, 1, rotgen::outer_stride<>>(
mat_dyn.data(), 1, 3, rotgen::outer_stride<>{1})),
+2);
TTS_EQUAL(g<3>(rotgen::map<rotgen::matrixXf, 1, rotgen::outer_stride<>>(
mat_dyn.data(), 1, 3, rotgen::outer_stride<>{1})),
+1);
TTS_EQUAL(g<3>(rotgen::map<col3, 1, rotgen::outer_stride<>>(
mat_dyn.data(), 1, 3, rotgen::outer_stride<>{1})),
+1);
TTS_EQUAL(g<3>(rotgen::map<row3, 1, rotgen::outer_stride<>>(
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);
}; };