File: generate.cpp

package info (click to toggle)
range-v3 0.12.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,652 kB
  • sloc: cpp: 76,839; xml: 226; sh: 89; python: 34; makefile: 19; perl: 15
file content (102 lines) | stat: -rw-r--r-- 3,559 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Range v3 library
//
//  Copyright Eric Niebler 2014-present
//
//  Use, modification and distribution is subject to the
//  Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3

#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()
{
    // Test for constant generator functions
    {
        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});
    }

    // Test for mutable-only generator functions
    {
        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});
        // The generator cannot be called when it's const-qualified, so "fib const"
        // does not model View.
        CPP_assert(!ranges::view_<decltype(fib) const>);
    }

    // Test for generator functions that return move-only types
    // https://github.com/ericniebler/range-v3/issues/905
    {
        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, "");
    }

    // Test for generator functions that return internal references
    // https://github.com/ericniebler/range-v3/issues/807
    {
        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);
    }

    // Test that we only call the function once for each dereferenceable position
    // https://github.com/ericniebler/range-v3/issues/819
    {
        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);
    }

    // Test that skipping past positions works correctly
    // https://github.com/ericniebler/range-v3/issues/1258
    {
        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();
}