#include "d_range.h" #include "d_zip.h" #include #include #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE Rebirth zip #include /* Test that a zipped range is empty when the component range is empty. */ BOOST_AUTO_TEST_CASE(zip_empty) { bool empty = true; std::array a; for (auto &&v : zip(a)) { (void)v; empty = false; } BOOST_TEST(empty); } /* Test that a zipped range is the length of the first sequence. * * Note that there is no test for when the first sequence is longer than * the later ones, since such a test would increment some iterators past * their end. */ BOOST_AUTO_TEST_CASE(zip_length) { unsigned count = 0; std::array a{}; short b[4]{}; for (auto &&[va, vb] : zip(a, b)) { asm("" : "+rm" (va), "+rm" (vb)); ++ count; } BOOST_TEST(count == a.size()); } BOOST_AUTO_TEST_CASE(zip_length_selection_01s) { unsigned count = 0; std::array b{}; short a[4]{}; for (auto &&[va, vb] : zip(zip_sequence_selector(), a, b)) { asm("" : "+rm" (va), "+rm" (vb)); ++ count; } BOOST_TEST(count == b.size()); } BOOST_AUTO_TEST_CASE(zip_length_selection_01v) { unsigned count = 0; std::vector b{1, 2}; short a[3]{}; for (auto &&[va, vb] : zip(zip_sequence_selector(), a, b)) { asm("" : "+rm" (va), "+rm" (vb)); ++ count; } BOOST_TEST(count == b.size()); } /* Test that a zipped value references the underlying storage. */ BOOST_AUTO_TEST_CASE(zip_passthrough_modifications) { std::array a{{1}}; short b[1]{2}; for (auto &&v : zip(a, b)) { ++ std::get<0>(v); ++ std::get<1>(v); } BOOST_TEST(a[0] == 2); BOOST_TEST(b[0] == 3); } BOOST_AUTO_TEST_CASE(zip_selection_11_short_first) { unsigned count = 0; std::vector b{1, 2}; short a[3]{4, 5, 6}; for (auto &&[vb, va] : zip(zip_sequence_selector(), b, a)) { ++ count; va += 10 + count; vb += 20 + count; } BOOST_TEST(count == b.size()); BOOST_TEST(a[0] == 15); BOOST_TEST(a[1] == 17); BOOST_TEST(a[2] == 6); BOOST_TEST(b[0] == 22); BOOST_TEST(b[1] == 24); } BOOST_AUTO_TEST_CASE(zip_selection_11_short_second) { unsigned count = 0; std::vector b{1, 2}; short a[3]{4, 5, 6}; for (auto &&[va, vb] : zip(zip_sequence_selector(), a, b)) { ++ count; va += 10 + count; vb += 20 + count; } BOOST_TEST(count == b.size()); BOOST_TEST(a[0] == 15); BOOST_TEST(a[1] == 17); BOOST_TEST(a[2] == 6); BOOST_TEST(b[0] == 22); BOOST_TEST(b[1] == 24); } /* Test that a zipped range can zip an xrange, and produce the correct * underlying value. */ BOOST_AUTO_TEST_CASE(zip_xrange) { for (auto &&v : zip(xrange(1u))) { BOOST_TEST(std::get<0>(v) == 0); } } /* Type system tests can be done at compile-time. Applying them as * static_assert can produce a better error message than letting it fail * at runtime. */ template requires(std::is_same::value) struct assert_index_type : std::true_type { }; static_assert(assert_index_type &>(), std::declval &>()))>::value); template struct custom_index_type : std::array { using index_type = T; void operator[](typename std::remove_reference::type); }; enum class e1 : unsigned char; enum class e2 : unsigned char; static_assert(assert_index_type&>(), std::declval&>()))>::value); static_assert(assert_index_type&>(), std::declval&>()))>::value); template requires(std::is_same::value) using assert_same_type = std::true_type; static_assert(assert_same_type()))>::value); static_assert(assert_same_type::iterator>()))>::value); static_assert(assert_same_type, decltype(d_zip::detail::get_static_size(std::declval()))>::value); static_assert(assert_same_type, decltype(d_zip::detail::get_static_size(std::declval &>()))>::value); template requires(std::ranges::range) struct check_is_range : std::true_type { }; template requires(std::ranges::borrowed_range) struct check_is_borrowed_range : std::true_type { }; static_assert(check_is_borrowed_range()))>::value); struct difference_range { struct iterator { int *operator *() const; iterator &operator++(); iterator operator++(int); constexpr auto operator<=>(const iterator &) const = default; using difference_type = short; using value_type = int; using pointer = value_type *; using reference = value_type &; using iterator_category = std::forward_iterator_tag; difference_type operator-(const iterator &) const; }; struct index_type {}; iterator begin(); iterator end(); }; static_assert(check_is_range())>::value); static_assert(check_is_borrowed_range())>::value); static_assert(assert_same_type()).begin())::difference_type>::value); static_assert(assert_same_type>::type>::value); static_assert(assert_same_type, d_zip::detail::minimum_static_size, std::nullptr_t>>::type>::value); static_assert(assert_same_type, d_zip::detail::minimum_static_size>>::type>::value); static_assert(assert_same_type, d_zip::detail::minimum_static_size, std::integral_constant>>::type>::value); static_assert(assert_same_type, d_zip::detail::minimum_static_size, std::nullptr_t, std::integral_constant>>::type>::value);