#include "d_range.h" #include #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE Rebirth xrange #include /* Test that an xrange is empty when the ending bound is 0. */ BOOST_AUTO_TEST_CASE(xrange_empty_0) { bool empty = true; for (auto &&v : xrange(0u)) { (void)v; empty = false; } BOOST_TEST(empty); } /* Test that an xrange is empty when the start is higher than the end. */ BOOST_AUTO_TEST_CASE(xrange_empty_transposed) { bool empty = true; for (auto &&v : xrange(2u, 1u)) { (void)v; empty = false; } BOOST_TEST(empty); } /* Test that an xrange produces the correct number of entries. */ BOOST_AUTO_TEST_CASE(xrange_length) { unsigned count = 0; constexpr unsigned length = 4u; for (auto &&v : xrange(length)) { (void)v; ++ count; } BOOST_TEST(count == length); } /* Test that an xrange produces the correct values when using an implied * start of 0. */ BOOST_AUTO_TEST_CASE(xrange_contents) { std::vector out; for (auto &&v : xrange(4u)) out.emplace_back(v); std::vector expected{0, 1, 2, 3}; BOOST_TEST(out == expected); } /* Test that an xrange produces the correct values when using an * explicit start. */ BOOST_AUTO_TEST_CASE(xrange_contents_start) { std::vector out; for (auto &&v : xrange(2u, 4u)) out.emplace_back(v); std::vector expected{2, 3}; BOOST_TEST(out == expected); } /* Test that an xrange produces the correct values when stepping up * with skipped values. */ BOOST_AUTO_TEST_CASE(xrange_contents_start_up_2) { std::vector out; for (auto &&v : xrange(std::integral_constant(), std::integral_constant(), std::integral_constant())) out.emplace_back(v); std::vector expected{2, 4}; BOOST_TEST(out == expected); } BOOST_AUTO_TEST_CASE(xrange_contents_descending) { std::vector out; for (auto &&v : xrange(std::integral_constant(), std::integral_constant(), xrange_descending())) out.emplace_back(v); std::vector expected{4, 3}; BOOST_TEST(out == expected); } /* Test that an xrange produces the correct values when stepping down * with skipped values. */ BOOST_AUTO_TEST_CASE(xrange_contents_start_down_2_constant) { std::vector out; for (auto &&v : xrange(std::integral_constant(), std::integral_constant(), std::integral_constant())) out.emplace_back(v); std::vector expected{5, 3}; BOOST_TEST(out == expected); } BOOST_AUTO_TEST_CASE(xrange_contents_start_down_variable) { std::vector out; for (auto &&v : xrange(5u, std::integral_constant(), xrange_descending())) out.emplace_back(v); std::vector expected{5, 4, 3}; BOOST_TEST(out == expected); } /* Test that pairs of iterators pulled from a shared xrange are * independent. If traversing an xrange modified the state of the * xrange object, this test would either hang due to the inner loop * resetting state, or produce incorrect output. */ BOOST_AUTO_TEST_CASE(xrange_self_nest) { std::vector out; auto &&r = xrange(2u); for (auto &&ov : r) for (auto &&iv : r) out.emplace_back((ov << 8) | iv); std::vector expected{0, 1, (1 << 8), (1 << 8) + 1}; BOOST_TEST(out == expected); } BOOST_AUTO_TEST_CASE(xrange_iter_values) { auto &&r = xrange(2u); BOOST_TEST(*r.begin() == 0); BOOST_TEST(*std::next(r.begin()) == 1); BOOST_TEST(*std::next(r.begin(), 2) == 2); }