4071cd0cbf
The standard type imposes some additional requirements that are not necessary here, but using this concept allows standard containers to be classified correctly without specific overrides.
146 lines
3.7 KiB
C++
146 lines
3.7 KiB
C++
#include "d_range.h"
|
|
#include <ranges>
|
|
#include <vector>
|
|
|
|
#define BOOST_TEST_DYN_LINK
|
|
#define BOOST_TEST_MODULE Rebirth xrange
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
/* 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<unsigned> out;
|
|
for (auto &&v : xrange(4u))
|
|
out.emplace_back(v);
|
|
std::vector<unsigned> 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<unsigned> out;
|
|
for (auto &&v : xrange(2u, 4u))
|
|
out.emplace_back(v);
|
|
std::vector<unsigned> 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<unsigned> out;
|
|
for (auto &&v : xrange(std::integral_constant<unsigned, 2u>(), std::integral_constant<unsigned, 6u>(), std::integral_constant<int, 2>()))
|
|
out.emplace_back(v);
|
|
std::vector<unsigned> expected{2, 4};
|
|
BOOST_TEST(out == expected);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(xrange_contents_descending)
|
|
{
|
|
std::vector<unsigned> out;
|
|
for (auto &&v : xrange(std::integral_constant<unsigned, 4u>(), std::integral_constant<unsigned, 2u>(), xrange_descending()))
|
|
out.emplace_back(v);
|
|
std::vector<unsigned> 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<unsigned> out;
|
|
for (auto &&v : xrange(std::integral_constant<unsigned, 5u>(), std::integral_constant<unsigned, 1u>(), std::integral_constant<int, -2>()))
|
|
out.emplace_back(v);
|
|
std::vector<unsigned> expected{5, 3};
|
|
BOOST_TEST(out == expected);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(xrange_contents_start_down_variable)
|
|
{
|
|
std::vector<unsigned> out;
|
|
for (auto &&v : xrange(5u, std::integral_constant<unsigned, 2u>(), xrange_descending()))
|
|
out.emplace_back(v);
|
|
std::vector<unsigned> 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<unsigned> out;
|
|
auto &&r = xrange(2u);
|
|
for (auto &&ov : r)
|
|
for (auto &&iv : r)
|
|
out.emplace_back((ov << 8) | iv);
|
|
std::vector<unsigned> 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);
|
|
}
|
|
|
|
template <typename T>
|
|
requires(std::ranges::borrowed_range<T>)
|
|
struct check_is_borrowed_range : std::true_type
|
|
{
|
|
};
|
|
|
|
static_assert(check_is_borrowed_range<decltype(xrange(2u))>::value);
|