1 // Copyright (C) 2019-2020 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library.  This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3.  If not see
16 // <http://www.gnu.org/licenses/>.
17 
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do run { target c++2a } }
20 
21 #include <iterator>
22 #include <testsuite_hooks.h>
23 #include <testsuite_iterators.h>
24 
25 using __gnu_test::test_range;
26 using __gnu_test::test_sized_range;
27 using __gnu_test::random_access_iterator_wrapper;
28 using __gnu_test::bidirectional_iterator_wrapper;
29 using __gnu_test::forward_iterator_wrapper;
30 using __gnu_test::input_iterator_wrapper;
31 using __gnu_test::output_iterator_wrapper;
32 
33 void
test01()34 test01()
35 {
36   int a[10] = { };
37   VERIFY( std::ranges::distance(a) == 10 );
38 
39   test_range<int, random_access_iterator_wrapper> c(a);
40   VERIFY( std::ranges::distance(c) == 10 );
41 
42   auto b = c.begin();
43   auto e = c.end();
44   auto ei = std::ranges::next(b, e);
45   VERIFY( std::ranges::distance(b, e) == 10 );
46   VERIFY( std::ranges::distance(ei, b) == -10 );
47 
48   const auto cb = b;
49   const auto ce = e;
50   const auto cei = ei;
51   VERIFY( std::ranges::distance(cb, ce) == 10 );
52   VERIFY( std::ranges::distance(cei, cb) == -10 );
53 
54   test_sized_range<int, random_access_iterator_wrapper> c2(a);
55   VERIFY( std::ranges::distance(c2) == 10 );
56 }
57 
58 void
test02()59 test02()
60 {
61   int a[2] = { };
62   VERIFY( std::ranges::distance(a) == 2 );
63 
64   test_range<int, bidirectional_iterator_wrapper> c(a);
65   VERIFY( std::ranges::distance(c) == 2 );
66 
67   auto b = c.begin();
68   auto e = c.end();
69   VERIFY( std::ranges::distance(b, e) == 2 );
70 
71   const auto cb = b;
72   const auto ce = e;
73   VERIFY( std::ranges::distance(cb, ce) == 2 );
74 
75   test_sized_range<int, bidirectional_iterator_wrapper> c2(a);
76   VERIFY( std::ranges::distance(c2) == 2 );
77 }
78 
79 void
test03()80 test03()
81 {
82   int a[3] = { };
83   test_range<int, forward_iterator_wrapper> c(a);
84   VERIFY( std::ranges::distance(c) == 3 );
85 
86   auto b = c.begin();
87   auto e = c.end();
88   VERIFY( std::ranges::distance(b, e) == 3 );
89 
90   const auto cb = b;
91   const auto ce = e;
92   VERIFY( std::ranges::distance(cb, ce) == 3 );
93 
94   test_sized_range<int, forward_iterator_wrapper> c2(a);
95   VERIFY( std::ranges::distance(c2) == 3 );
96 }
97 
98 void
test04()99 test04()
100 {
101   int a[4] = { };
102   test_range<int, input_iterator_wrapper> c(a);
103   static_assert( std::ranges::range<decltype(c)> );
104 
105   VERIFY( std::ranges::distance(c) == 4 );
106   // first call to distance has traversed the range:
107   VERIFY( std::ranges::distance(c) == 0 );
108 
109   c = test_range<int, input_iterator_wrapper>(a);
110   auto b = c.begin();
111   auto e = c.end();
112   VERIFY( std::ranges::distance(b, e) == 4 );
113 
114   test_range<int, input_iterator_wrapper> c2(a);
115   const auto cb = c2.begin();
116   const auto ce = c2.end();
117   VERIFY( std::ranges::distance(cb, ce) == 4 );
118 
119   test_sized_range<int, input_iterator_wrapper> c3(a);
120   VERIFY( std::ranges::distance(c3) == 4 );
121   // first call to distance just called size() without affecting the range:
122   VERIFY( std::ranges::distance(c3) == 4 );
123 }
124 
125 void
test05()126 test05()
127 {
128   int a[5] = { };
129   test_range<int, output_iterator_wrapper> c(a);
130   VERIFY( std::ranges::distance(c) == 5 );
131 
132   test_range<int, output_iterator_wrapper> c2(a);
133   auto b = c2.begin();
134   auto e = c2.end();
135   VERIFY( std::ranges::distance(b, e) == 5 );
136 
137   test_range<int, output_iterator_wrapper> c3(a);
138   const auto cb = c3.begin();
139   const auto ce = c3.end();
140   VERIFY( std::ranges::distance(cb, ce) == 5 );
141 
142   test_sized_range<int, output_iterator_wrapper> c4(a);
143   VERIFY( std::ranges::distance(c4) == 5 );
144   // first call to distance just called size() without affecting the range:
145   VERIFY( std::ranges::distance(c4) == 5 );
146 }
147 
148 int
main()149 main()
150 {
151   test01();
152   test02();
153   test03();
154   test04();
155   test05();
156 }
157