diff --git a/math/vecops/inc/ROOT/TVec.hxx b/math/vecops/inc/ROOT/TVec.hxx index 3913c5f583d2bf8531ebc6a22383944ff7c43a11..834b613bd80c02f57e21f4139485feb71cdcbaad 100644 --- a/math/vecops/inc/ROOT/TVec.hxx +++ b/math/vecops/inc/ROOT/TVec.hxx @@ -253,6 +253,16 @@ public: fData = ilist; return *this; } + + // conversion + template <typename U, typename = std::enable_if<std::is_convertible<T, U>::value>> + operator TVec<U>() const + { + TVec<U> ret(size()); + std::copy(begin(), end(), ret.begin()); + return ret; + } + // accessors reference at(size_type pos) { return fData.at(pos); } const_reference at(size_type pos) const { return fData.at(pos); } diff --git a/math/vecops/test/vecops_tvec.cxx b/math/vecops/test/vecops_tvec.cxx index 617ea7a77acc18e10e3b78b0579e469fc2d74b2a..e5057566d76f54cf63b17e17638a4b50e5108c2d 100644 --- a/math/vecops/test/vecops_tvec.cxx +++ b/math/vecops/test/vecops_tvec.cxx @@ -78,6 +78,36 @@ TEST(VecOps, MoveCtor) EXPECT_EQ(v2.size(), 3u); } +TEST(VecOps, Conversion) +{ + ROOT::Experimental::VecOps::TVec<float> fvec{1.0f, 2.0f, 3.0f}; + ROOT::Experimental::VecOps::TVec<unsigned> uvec{1u, 2u, 3u}; + + ROOT::Experimental::VecOps::TVec<int> ivec = uvec; + ROOT::Experimental::VecOps::TVec<long> lvec = ivec; + + EXPECT_EQ(1, ivec[0]); + EXPECT_EQ(2, ivec[1]); + EXPECT_EQ(3, ivec[2]); + EXPECT_EQ(3u, ivec.size()); + EXPECT_EQ(1l, lvec[0]); + EXPECT_EQ(2l, lvec[1]); + EXPECT_EQ(3l, lvec[2]); + EXPECT_EQ(3u, lvec.size()); + + auto dvec1 = ROOT::Experimental::VecOps::TVec<double>(fvec); + auto dvec2 = ROOT::Experimental::VecOps::TVec<double>(uvec); + + EXPECT_EQ(1.0, dvec1[0]); + EXPECT_EQ(2.0, dvec1[1]); + EXPECT_EQ(3.0, dvec1[2]); + EXPECT_EQ(3u, dvec1.size()); + EXPECT_EQ(1.0, dvec2[0]); + EXPECT_EQ(2.0, dvec2[1]); + EXPECT_EQ(3.0, dvec2[2]); + EXPECT_EQ(3u, dvec2.size()); +} + TEST(VecOps, MathScalar) { ROOT::Experimental::VecOps::TVec<double> ref{1, 2, 3};