#include <range/v3/core.hpp>
#include <range/v3/view/generate.hpp>
#include <range/v3/view/drop_exactly.hpp>
#include <range/v3/view/take_exactly.hpp>
#include "../simple_test.hpp"
#include "../test_utils.hpp"
namespace
views = ranges::views;
int
main()
{
{
int
i = 0, j = 1;
auto
fib = views::generate([&]()->
int
{
int
tmp = i; i += j; std::swap(i, j);
return
tmp;});
CPP_assert(ranges::input_range<
decltype
(fib)> && ranges::view_<
decltype
(fib)>);
check_equal(fib | views::take_exactly(10), {0,1,1,2,3,5,8,13,21,34});
}
{
int
i = 0, j = 1;
auto
fib = views::generate([=]()
mutable
->
int
{
int
tmp = i; i += j; std::swap(i, j);
return
tmp;});
CPP_assert(ranges::input_range<
decltype
(fib)> && ranges::view_<
decltype
(fib)>);
check_equal(fib | views::take_exactly(10), {0,1,1,2,3,5,8,13,21,34});
CPP_assert(!ranges::view_<
decltype
(fib)
const
>);
}
{
char
str[] =
"gi"
;
auto
rng = views::generate([&]{str[0]++;
return
MoveOnlyString{str};}) | views::take_exactly(2);
auto
i = rng.begin();
CHECK(
bool
(*i == MoveOnlyString{
"hi"
}));
CHECK(
bool
(*i == MoveOnlyString{
"hi"
}));
CHECK(
bool
(*rng.begin() == MoveOnlyString{
"hi"
}));
CHECK(
bool
(*rng.begin() == MoveOnlyString{
"hi"
}));
CPP_assert(ranges::input_range<
decltype
(rng)> && ranges::view_<
decltype
(rng)>);
check_equal(rng, {MoveOnlyString{
"hi"
}, MoveOnlyString{
"ii"
}});
static_assert
(std::is_same<ranges::range_reference_t<
decltype
(rng)>, MoveOnlyString &&>::value,
""
);
}
{
int
i = 42;
auto
rng = views::generate([i]{
return
&i;});
auto
rng2 = std::move(rng);
auto
it = rng2.begin();
auto
p = *it;
auto
p2 = *++it;
CHECK(p == p2);
}
{
int
i = 0;
auto
rng = views::generate([&i]{
return
++i;});
auto
rng2 = std::move(rng);
auto
it = rng2.begin();
CHECK(i == 0);
CHECK(*it == 1);
CHECK(i == 1);
++it;
CHECK(i == 1);
CHECK(*it == 2);
CHECK(i == 2);
}
{
auto
fib = [p = std::make_pair(0, 1)]()
mutable
->
int
{
auto
a = p.first;
p = {p.second, p.first + p.second};
return
a;
};
auto
rng = ranges::views::generate(fib)
| ranges::views::drop_exactly(3)
| ranges::views::take_exactly(5);
check_equal(rng, {2,3,5,8,13});
}
return
test_result();
}