#include "tap.hpp" #include "point.hpp" #include "vector.hpp" #include "coord/iostream.hpp" #include "coord/comparator.hpp" #include int main (void) { static_assert (std::is_trivially_copyable_v); static_assert (cruft::has_result_v); static_assert (sizeof (cruft::point1u) == 1 * sizeof (cruft::point1u::value_type), "point1u is not packed"); static_assert (sizeof (cruft::point2u) == 2 * sizeof (cruft::point2u::value_type), "point2u is not packed"); static_assert (sizeof (cruft::point3u) == 3 * sizeof (cruft::point3u::value_type), "point3u is not packed"); static_assert (sizeof (cruft::point4u) == 4 * sizeof (cruft::point4u::value_type), "point4u is not packed"); static_assert (sizeof (cruft::point1f) == 1 * sizeof (cruft::point1f::value_type), "point1f is not packed"); static_assert (sizeof (cruft::point2f) == 2 * sizeof (cruft::point2f::value_type), "point2f is not packed"); static_assert (sizeof (cruft::point3f) == 3 * sizeof (cruft::point3f::value_type), "point3f is not packed"); static_assert (sizeof (cruft::point4f) == 4 * sizeof (cruft::point4f::value_type), "point4f is not packed"); cruft::TAP::logger tap; constexpr cruft::point2i p { -1, 2 }; tap.expect_eq (-p, cruft::point2i { 1, -2 }, "unary point negation"); tap.expect_eq ( p, p, "unary point addition"); auto vec = cruft::vector4f (0.5f); tap.expect (cruft::almost_equal (vec, cruft::normalised (vec)), "normalisation of normalised vector"); tap.expect_eq (sum (cruft::vector4f::ones ()), 4.f, "elementwise summation"); // check that structured bindings work { const auto &[x,y] = p; tap.expect (x == p.x && y == p.y, "structured bindings extract correct data"); } // check that we can assign to arrays from coord types { std::array q = p; tap.expect ( std::equal (std::begin (q), std::end (q), std::begin (p)), "assignment to array preserves values" ); } // ensure the distance function behaves correctly with non-normal numbers. { cruft::point3f a { 103, 0, 14 }; cruft::point3f b { 104, INFINITY, 15 }; tap.expect_eq ( std::numeric_limits::infinity (), ::cruft::distance (a, b), "distance with an infinity is infinite" ); } // test expected outputs for various vector-logical operations { constexpr cruft::point3i a { 0, -1, 2 }; constexpr cruft::point3i b { 0, 1, -2 }; constexpr cruft::point3i c { -9, -9, -9 }; tap.expect (!all (a <= b), "all, expected failure"); tap.expect ( all (a <= a), "all, expected success"); tap.expect (!any (a <= c), "any, expected failure"); tap.expect ( any (a <= b), "any, expected success"); }; // ensure the cruft::select function behaves as expected { const cruft::point3f a { -1, 2, 0 }; const cruft::point3f b { 1, 0, 2 }; const cruft::point3f lo { -1, 0, 0 }; const cruft::point3f hi { 1, 2, 2 }; tap.expect_eq (select (a < b, a, b), lo, "select with points and min"); tap.expect_eq (select (a > b, a, b), hi, "select with points and max"); }; // ensure that cruft::clamp resolves to the coord overload. the exact // values are less useful than exercising the compiler/linker. { const cruft::vector3f val { 0, -1, 2 }; const cruft::vector3f lo { -1, 1, -2 }; const cruft::vector3f hi { 1, 2, 0 }; tap.expect_eq (clamp (val, lo, hi), cruft::vector3f { 0, 1, 0 }, "clamp with vec/vec/vec"); tap.expect_eq (clamp (val, 0.f, hi), cruft::vector3f { 0, 0, 0 }, "clamp with vec/num/vec"); tap.expect_eq (clamp (val, lo, 2.f), cruft::vector3f { 0, 1, 2 }, "clamp with vec/vec/num"); tap.expect_eq (clamp (val, 0.f, 2.f), cruft::vector3f { 0, 0, 2 }, "clamp with vec/num/num"); } // ensure that klass::indices appears to link correctly { const cruft::vector3i seq { 0, 1, 2 }; { const cruft::vector4i res { 2, 0, 0, 1 }; tap.expect_eq (seq.indices<2,0,0,1> (), res, "coord::indices expansion"); } { const cruft::vector4i res { 2, 3, 4, 0 }; tap.expect_eq (seq.indices<2,3,4,0> (3, 4), res, "coord::indices supplemental expansion"); } }; // ensure that cruft::shift operations appear to operate correctly { const cruft::vector3i seq { 0, 1, 2 }; tap.expect_eq (rshift (seq, 1, 0), cruft::make_vector (0, 0, 1), "rshift, scalar fill"); tap.expect_eq ( rshift (seq, 2, cruft::make_vector (3, 4, 5 )), cruft::make_vector (3, 4, 0), "rshift, coord fill" ); } { struct { cruft::point2i a; cruft::point2i b; std::weak_ordering expected; char const *message; } const TESTS[] { { { 0, 0 }, { 0, 0 }, std::weak_ordering::equivalent, "equal zeroes" }, { { 1, 0 }, { 0, 0 }, std::weak_ordering::greater, "a, leading high" }, { { 0, 1 }, { 0, 0 }, std::weak_ordering::greater, "a, trailing high" }, { { 0, 0 }, { 1, 0 }, std::weak_ordering::less, "b, leading high" }, { { 0, 0 }, { 0, 1 }, std::weak_ordering::less, "b, trailing high" }, }; for (auto const &t: TESTS) tap.expect (cruft::coord::element_ordering (t.a, t.b) == t.expected, "ordering; {}", t.message); } return tap.status (); }