Fix a lot of ref issues reagrding extarction, rvalueness and proper use of temporary memory.

This commit is contained in:
Joel Falcou 2025-10-28 20:12:33 +01:00
parent d5c41bf43e
commit 379d77ebef
50 changed files with 2945 additions and 1397 deletions

193
test/unit/meta/ref.cpp Normal file
View file

@ -0,0 +1,193 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include <rotgen/rotgen.hpp>
#include "unit/tests.hpp"
using row_matrixXf = rotgen::matrix<float, -1, -1, rotgen::RowMajor>;
template<typename Ref, typename Generator> void check_acceptance(Generator f)
{
auto in = f();
rotgen::matrixXf data;
bool verbose = ::tts::arguments()[{"--verbose"}];
auto acceptor = [&](rotgen::ref<Ref> v, auto ptr) {
// Check that ref is not a copy
TTS_EQUAL(v.data(), ptr);
// Setup the data correctly
data.resize(v.rows(), v.cols());
rotgen::setRandom(data);
// Assign through the ref
v = data;
if (verbose) std::cout << "V:\n" << v << std::endl << std::endl;
};
auto constant_acceptor = [&](rotgen::ref<Ref const> v) {
return minCoeff(v);
};
acceptor(in, in.data());
data.resize(in.rows(), in.cols());
TTS_EQUAL(in, data);
TTS_EQUAL(constant_acceptor(in), minCoeff(data)) << in << "\n"
<< data << "\n";
}
TTS_CASE_TPL("Assert ref construction rules - Vector cases",
rotgen::vectorXf,
rotgen::vector2f,
rotgen::row_vectorXf,
rotgen::row_vector2f)
<typename T>(::tts::type<T>)
{
TTS_WHEN("Call a function accepting a ref<" << ::tts::typename_<T> << "> ...")
{
rotgen::matrixXf mc(2, 1);
rotgen::vectorXf vc(2);
rotgen::matrixXf mr(1, 2);
row_matrixXf mrr(1, 2);
rotgen::row_vectorXf vr(2);
rotgen::vector2f vcf;
rotgen::row_vector2f vrf;
TTS_AND_THEN("with a vector-like matrix")
{
check_acceptance<T>([&]() { return mc; });
check_acceptance<T>([&]() { return vc; });
check_acceptance<T>([&]() { return mr; });
check_acceptance<T>([&]() { return mrr; });
check_acceptance<T>([&]() { return vr; });
check_acceptance<T>([&]() { return vcf; });
check_acceptance<T>([&]() { return vrf; });
}
TTS_AND_THEN("with a vector-like block")
{
check_acceptance<T>([&]() { return rotgen::head(vc, 2); });
check_acceptance<T>([&]() { return rotgen::head(vr, 2); });
check_acceptance<T>([&]() { return rotgen::head(vcf, 2); });
check_acceptance<T>([&]() { return rotgen::head(vrf, 2); });
check_acceptance<T>([&]() { return rotgen::head<2>(vc); });
check_acceptance<T>([&]() { return rotgen::head<2>(vr); });
check_acceptance<T>([&]() { return rotgen::head<2>(vcf); });
check_acceptance<T>([&]() { return rotgen::head<2>(vrf); });
}
TTS_AND_THEN("with a vector-like map")
{
rotgen::map<rotgen::matrixXf> mmc(vc.data(), 2, 1);
rotgen::map<rotgen::matrixXf> mmr(vc.data(), 1, 2);
rotgen::map<row_matrixXf> mmrr(vc.data(), 1, 2);
rotgen::map<rotgen::vectorXf> mvc(vc.data(), vc.size());
rotgen::map<rotgen::row_vectorXf> mvr(vr.data(), vr.size());
rotgen::map<rotgen::vector2f> mvcf(vc.data());
rotgen::map<rotgen::row_vector2f> mvrf(vr.data());
check_acceptance<T>([&]() { return mmc; });
check_acceptance<T>([&]() { return mvc; });
check_acceptance<T>([&]() { return mvr; });
check_acceptance<T>([&]() { return mmr; });
check_acceptance<T>([&]() { return mmrr; });
check_acceptance<T>([&]() { return mvcf; });
check_acceptance<T>([&]() { return mvrf; });
}
TTS_AND_THEN("with a vector-like ref")
{
rotgen::ref<row_matrixXf> mmrr(mrr);
rotgen::ref<rotgen::vectorXf> mvc(mc);
rotgen::ref<rotgen::row_vectorXf> mvr(mc);
rotgen::ref<rotgen::vector2f> mvcf(mc);
rotgen::ref<rotgen::row_vector2f> mvrf(mc);
check_acceptance<T>([&]() { return mvc; });
check_acceptance<T>([&]() { return mvr; });
check_acceptance<T>([&]() { return mmrr; });
check_acceptance<T>([&]() { return mvcf; });
check_acceptance<T>([&]() { return mvrf; });
}
}
};
TTS_CASE("Assert ref construction rules Matrix cases")
{
using MatC = rotgen::matrix<float, -1, -1, rotgen::ColMajor>;
using MatR = rotgen::matrix<float, -1, -1, rotgen::RowMajor>;
TTS_WHEN("Call a function accepting a ref<"
<< ::tts::typename_<MatC> << "> ...")
{
rotgen::matrixXf mc(2, 1);
rotgen::matrixXf mr(1, 2);
rotgen::matrixXf mn(4, 2);
row_matrixXf mnr(4, 2);
rotgen::matrix<float, 2, 1> mcf(2, 1);
rotgen::matrix<float, 1, 2> mrf(1, 2);
rotgen::matrix<float, 4, 2> mnf(4, 2);
TTS_AND_THEN("with a matrix")
{
check_acceptance<MatC>([&]() { return mc; });
check_acceptance<MatC>([&]() { return mr; });
check_acceptance<MatC>([&]() { return mn; });
check_acceptance<MatC>([&]() { return mcf; });
check_acceptance<MatC>([&]() { return mrf; });
check_acceptance<MatC>([&]() { return mnf; });
TTS_EXPECT_COMPILES(mnr, { rotgen::ref<MatC const>{mnr}; });
}
TTS_AND_THEN("with a map")
{
rotgen::map<rotgen::matrixXf> mmc(mc.data(), 2, 1);
rotgen::map<rotgen::matrixXf> mmr(mc.data(), 1, 2);
rotgen::map<row_matrixXf> mmrr(mc.data(), 1, 2);
rotgen::map<row_matrixXf> mmnr(mnr.data(), 4, 2);
rotgen::map<rotgen::vectorXf> mvc(mc.data(), mc.size());
rotgen::map<rotgen::row_vectorXf> mvr(mr.data(), mr.size());
rotgen::map<rotgen::vector2f> mvcf(mc.data());
rotgen::map<rotgen::row_vector2f> mvrf(mr.data());
check_acceptance<MatC>([&]() { return mmc; });
check_acceptance<MatC>([&]() { return mmr; });
check_acceptance<MatC>([&]() { return mvc; });
check_acceptance<MatC>([&]() { return mvr; });
check_acceptance<MatC>([&]() { return mvcf; });
check_acceptance<MatC>([&]() { return mvrf; });
TTS_EXPECT_COMPILES(mmnr, { rotgen::ref<MatC const>{mmnr}; });
TTS_EXPECT_COMPILES(mmrr, { rotgen::ref<MatC const>{mmrr}; });
}
}
TTS_WHEN("Call a function accepting a ref<"
<< ::tts::typename_<MatR> << "> ...")
{
row_matrixXf mc(2, 1);
row_matrixXf mr(1, 2);
row_matrixXf mn(4, 2);
rotgen::matrix<float, 2, 1> mcf(2, 1);
rotgen::matrix<float, 1, 2> mrf(1, 2);
rotgen::matrix<float, 4, 2, rotgen::RowMajor> mnf(4, 2);
TTS_AND_THEN("with a matrix")
{
check_acceptance<MatR>([&]() { return mc; });
check_acceptance<MatR>([&]() { return mr; });
check_acceptance<MatR>([&]() { return mn; });
check_acceptance<MatR>([&]() { return mcf; });
check_acceptance<MatR>([&]() { return mrf; });
check_acceptance<MatR>([&]() { return mnf; });
}
}
};