1 // Range v3 library
2 //
3 //  Copyright Eric Niebler 2014-present
4 //
5 //  Use, modification and distribution is subject to the
6 //  Boost Software License, Version 1.0. (See accompanying
7 //  file LICENSE_1_0.txt or copy at
8 //  http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // Project home: https://github.com/ericniebler/range-v3
11 
12 #include <list>
13 #include <vector>
14 #include <range/v3/core.hpp>
15 #include <range/v3/view/chunk.hpp>
16 #include <range/v3/view/drop.hpp>
17 #include <range/v3/view/iota.hpp>
18 #include <range/v3/view/join.hpp>
19 #include <range/v3/view/reverse.hpp>
20 #include <range/v3/view/take.hpp>
21 #include <range/v3/view/transform.hpp>
22 #include <range/v3/utility/copy.hpp>
23 #include "../simple_test.hpp"
24 #include "../test_utils.hpp"
25 
main()26 int main()
27 {
28     using namespace ranges;
29 
30     int rgi[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
31 
32     {
33         auto rng0 = rgi | views::drop(6);
34         has_type<int &>(*begin(rng0));
35         CPP_assert(view_<decltype(rng0)>);
36         CPP_assert(common_range<decltype(rng0)>);
37         CPP_assert(sized_range<decltype(rng0)>);
38         CPP_assert(random_access_iterator<decltype(begin(rng0))>);
39         ::check_equal(rng0, {6, 7, 8, 9, 10});
40         CHECK(size(rng0) == 5u);
41 
42         auto rng1 = rng0 | views::reverse;
43         has_type<int &>(*begin(rng1));
44         CPP_assert(view_<decltype(rng1)>);
45         CPP_assert(common_range<decltype(rng1)>);
46         CPP_assert(sized_range<decltype(rng1)>);
47         CPP_assert(random_access_iterator<decltype(begin(rng1))>);
48         ::check_equal(rng1, {10, 9, 8, 7, 6});
49     }
50 
51     {
52         std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
53         auto rng2 = v | views::drop(6) | views::reverse;
54         has_type<int &>(*begin(rng2));
55         CPP_assert(view_<decltype(rng2)>);
56         CPP_assert(common_range<decltype(rng2)>);
57         CPP_assert(sized_range<decltype(rng2)>);
58         CPP_assert(random_access_iterator<decltype(begin(rng2))>);
59         ::check_equal(rng2, {10, 9, 8, 7, 6});
60     }
61 
62     {
63         std::list<int> l{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
64         auto rng3 = l | views::drop(6);
65         has_type<int &>(*begin(rng3));
66         CPP_assert(view_<decltype(rng3)>);
67         CPP_assert(common_range<decltype(rng3)>);
68         CPP_assert(sized_range<decltype(rng3)>);
69         CPP_assert(bidirectional_iterator<decltype(begin(rng3))>);
70         CPP_assert(!random_access_iterator<decltype(begin(rng3))>);
71         ::check_equal(rng3, {6, 7, 8, 9, 10});
72     }
73 
74     {
75         auto rng4 = views::iota(10) | views::drop(10);
76         CPP_assert(view_<decltype(rng4)>);
77         CPP_assert(!common_range<decltype(rng4)>);
78         CPP_assert(!sized_range<decltype(rng4)>);
79         static_assert(ranges::is_infinite<decltype(rng4)>::value, "");
80         auto b = ranges::begin(rng4);
81         CHECK(*b == 20);
82         CHECK(*(b+1) == 21);
83     }
84 
85     {
86         auto rng5 = views::iota(10) | views::drop(10) | views::take(10) | views::reverse;
87         CPP_assert(view_<decltype(rng5)>);
88         CPP_assert(common_range<decltype(rng5)>);
89         CPP_assert(sized_range<decltype(rng5)>);
90         static_assert(!ranges::is_infinite<decltype(rng5)>::value, "");
91         ::check_equal(rng5, {29, 28, 27, 26, 25, 24, 23, 22, 21, 20});
92         CHECK(size(rng5) == 10u);
93     }
94 
95     {
96         int some_ints[] = {0,1,2};
97         auto rng = make_subrange(some_ints + 0, some_ints + 1);
98         auto rng2 = views::drop(rng, 2);
99         CHECK(begin(rng2) == some_ints + 1);
100         CHECK(size(rng2) == 0u);
101     }
102 
103     {
104         // Regression test for https://github.com/ericniebler/range-v3/issues/413
105         auto skips = [](std::vector<int> xs) {
106             return views::ints(0, (int)xs.size())
107                 | views::transform([&](int n) {
108                     return xs | views::chunk(n + 1)
109                               | views::transform(views::drop(n))
110                               | views::join;
111                 })
112                 | to<std::vector<std::vector<int>>>();
113         };
114         auto skipped = skips({1,2,3,4,5,6,7,8});
115         CHECK(skipped.size() == 8u);
116         if(skipped.size() >= 8u)
117         {
118             ::check_equal(skipped[0], {1,2,3,4,5,6,7,8});
119             ::check_equal(skipped[1], {2,4,6,8});
120             ::check_equal(skipped[2], {3,6});
121             ::check_equal(skipped[3], {4,8});
122             ::check_equal(skipped[4], {5});
123             ::check_equal(skipped[5], {6});
124             ::check_equal(skipped[6], {7});
125             ::check_equal(skipped[7], {8});
126         }
127     }
128 
129     {
130         static int const some_ints[] = {0,1,2,3};
131         auto rng = debug_input_view<int const>{some_ints} | views::drop(2);
132         using R = decltype(rng);
133         CPP_assert(input_range<R> && view_<R>);
134         CPP_assert(!forward_range<R>);
135         CPP_assert(same_as<int const&, range_reference_t<R>>);
136         ::check_equal(rng, {2,3});
137     }
138 
139     {
140         // regression test for #728
141         auto rng1 = views::iota(1) | views::chunk(6) | views::take(3);
142         int i = 2;
143         RANGES_FOR(auto o1, rng1)
144         {
145             auto rng2 = o1 | views::drop(1);
146             ::check_equal(rng2, {i, i+1, i+2, i+3, i+4});
147             i += 6;
148         }
149     }
150 
151     {
152         // regression test for #813
153         static int const some_ints[] = {0,1,2,3};
154         auto rng = some_ints | views::drop(10);
155         CHECK(empty(rng));
156     }
157 
158     return test_result();
159 }
160