From 02f195b8d4014bb44f7da725eae9f2dc36ce1791 Mon Sep 17 00:00:00 2001 From: namark <namark@disroot.org> Date: Wed, 29 Jan 2020 02:55:41 +0400 Subject: [PATCH] first<N>, last<N> and better mutant_clone, also deprecated mutantClone... anyone use it? probably not, but still... deprecated! --- source/simple/geom/vector.hpp | 38 ++++++++++++++++++++++++++++++++--- unit_tests/point.cpp | 7 ++++--- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/source/simple/geom/vector.hpp b/source/simple/geom/vector.hpp index 50306c5..1049d2b 100644 --- a/source/simple/geom/vector.hpp +++ b/source/simple/geom/vector.hpp @@ -174,6 +174,7 @@ namespace simple::geom : raw {std::forward<Coordinates>(coordinates)...} {} + // TODO: constexpr and forwarding template <typename Another, is_convertible_to_me<Another>* = nullptr, std::enable_if_t<std::is_same_v<typename Another::order, Order>> *...> explicit vector(const Another& another) @@ -181,6 +182,7 @@ namespace simple::geom std::copy(another.begin(), another.end(), begin()); } + // TODO: forwarding template <typename Another, is_convertible_to_me<Another>* = nullptr, std::enable_if_t<!std::is_same_v<typename Another::order, Order>> *...> constexpr explicit vector(const Another& another) : raw{} @@ -210,7 +212,7 @@ namespace simple::geom } template <typename Another> - [[nodiscard]] + [[nodiscard]] [[deprecated("use mutant_clone instead")]] constexpr Another mutantClone(typename Another::coordinate_type(*method)(const vector::coordinate_type&)) const& { static_assert(Another::dimensions == Dimensions, " Dimension mismatch. "); @@ -221,13 +223,21 @@ namespace simple::geom template <typename Function, typename AnotherCoord = std::invoke_result_t<Function, Coordinate>> [[nodiscard]] - constexpr vector<AnotherCoord, Dimensions> mutant_clone(const Function& transform) const& + constexpr vector<AnotherCoord, Dimensions, Order> mutant_clone(Function&& transform) const& { vector<AnotherCoord, Dimensions> another{}; - std::transform(begin(), end(), another.begin(), transform); + for(size_t i = 0; i < Dimensions; ++i) + { + // std::invoke is not constexpr -_- + another[i] = std::apply( + std::forward<Function>(transform), + std::forward_as_tuple((*this)[i]) + ); + } return another; } + // TODO: mix should preserve order if mixed size >= original size template<size_t... CoordinateIndices, typename Mixed = vector<Coordinate, sizeof...(CoordinateIndices)> > [[nodiscard]] constexpr Mixed mix() const @@ -276,6 +286,28 @@ namespace simple::geom return result; } + template <size_t N, + std::enable_if_t<N <= Dimensions>* = nullptr> + [[nodiscard]] + constexpr vector<Coordinate,N> last() const + { + vector<Coordinate,N> result{}; + for(size_t i = 0; i < N; ++i) + result[i] = (*this)[Dimensions-N+i]; + return result; + } + + template <size_t N, + std::enable_if_t<N <= Dimensions>* = nullptr> + [[nodiscard]] + constexpr vector<Coordinate,N> first() const + { + vector<Coordinate,N> result{}; + for(size_t i = 0; i < N; ++i) + result[i] = (*this)[i]; + return result; + } + template <typename C = Coordinate, size_t D = Dimensions, std::enable_if_t<std::is_same_v<C,bool> && (D != 1)>* = nullptr> [[nodiscard]] diff --git a/unit_tests/point.cpp b/unit_tests/point.cpp index 130f9c5..7f07e72 100644 --- a/unit_tests/point.cpp +++ b/unit_tests/point.cpp @@ -87,10 +87,8 @@ void Mutation() float4 p {1.3f, 1.5f, 2.1f, 4.6f}; int4 p2 {1, 2, 2, 5}; int4 p3 {1, 1, 2, 4}; - assert( p2 == p.mutantClone<int4>( [](auto x) -> int { return std::round(x); } )); - assert( p3 == p.mutantClone<int4>( [](auto x) -> int { return x; } )); assert( p2 == p.mutant_clone( [](auto x) -> int { return std::round(x); } )); - assert( p3 == p.mutant_clone( [](auto x) -> int { return x; } )); + assert( p3 == p.mutant_clone( [](auto x) { return int(x); } )); } void Mixing() @@ -104,6 +102,9 @@ void Mixing() assert( (geom::vector<int, 6>{3,3,3,2,2,1} == p.mix<6>({2,2,2,1,1,0})) ); assert( (geom::vector<int, 3>{1,2,0} == p.mix<0,1,4>(0)) ); assert( (geom::vector<int, 3>{1,2,0} == p.mix<3>({0,1,4}, 0)) ); + + assert( (vector(1,2) == p.first<2>()) ); + assert( (vector(2,3,4) == p.last<3>()) ); } void MultidimensionalElementAccess() -- GitLab