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

View file

@ -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<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC> const& m)
requires(requires { parent(m.base()); } && is_immutable)
: parent(m.base())
ref(matrix<S, R, C, O, MR, MC>&& m)
requires(requires {
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>
ref(block<Ref, R, C, I>&& b)
requires(requires { parent(b.base()); })
: parent(b.base())
template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC> const& m)
requires(requires { parent(m.base()); })
: parent(m.base())
{
}
@ -204,7 +205,7 @@ namespace rotgen
template<typename Ref, int R, int C, bool I>
ref(block<Ref, R, C, I> const& b)
requires(requires { parent(b.base()); } && is_immutable)
requires(requires { parent(b.base()); })
: parent(b.base())
{
}
@ -218,7 +219,7 @@ namespace rotgen
template<typename Ref, int O, typename S>
ref(map<Ref, O, S> const& m)
requires(requires { parent(m.base()); } && is_immutable)
requires(requires { 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>
ref(ref<TT, OO, SS> const& r)
requires(requires { parent(r.base()); } && is_immutable)
requires(requires { parent(r.base()); })
: parent(r.base())
{
}

View file

@ -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<float> mat_dyn(1, 3);
rotgen::matrix<float, -1, 3, rotgen::ColMajor> mat_col(1, 3);
rotgen::matrix<float, -1, 3, rotgen::RowMajor> mat_row(1, 3);
using col3 = rotgen::matrix<float, -1, 3, rotgen::ColMajor>;
using row3 = rotgen::matrix<float, -1, 3, rotgen::RowMajor>;
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<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);
};