Skip to content

Commit 5dd4754

Browse files
add test for iterator member type
1 parent ff8d7b6 commit 5dd4754

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// REQUIRES: std-at-least-c++26
10+
11+
#include <array>
12+
#include <ranges>
13+
#include <tuple>
14+
15+
#include "test_iterators.h"
16+
17+
#include "../../range_adaptor_types.h"
18+
19+
template <class T>
20+
struct ForwardView : std::ranges::view_base {
21+
forward_iterator<T*> begin() const;
22+
sentinel_wrapper<forward_iterator<T*>> end() const;
23+
};
24+
25+
template <class T>
26+
struct InputView : std::ranges::view_base {
27+
cpp17_input_iterator<T*> begin() const;
28+
sentinel_wrapper<cpp17_input_iterator<T*>> end() const;
29+
};
30+
31+
template <class T>
32+
concept HasIterCategory = requires { typename T::iterator_category; };
33+
34+
template <class T>
35+
struct DiffTypeIter {
36+
using iterator_category = std::input_iterator_tag;
37+
using value_type = int;
38+
using difference_type = T;
39+
40+
int operator*() const;
41+
DiffTypeIter& operator++();
42+
void operator++(int);
43+
friend constexpr bool operator==(DiffTypeIter, DiffTypeIter) = default;
44+
};
45+
46+
template <class T>
47+
struct DiffTypeRange {
48+
DiffTypeIter<T> begin() const;
49+
DiffTypeIter<T> end() const;
50+
};
51+
52+
struct Foo {};
53+
struct Bar {};
54+
55+
struct ConstVeryDifferentRange {
56+
int* begin();
57+
int* end();
58+
59+
forward_iterator<double*> begin() const;
60+
forward_iterator<double*> end() const;
61+
};
62+
63+
void test() {
64+
int buffer[] = {1, 2, 3, 4};
65+
{
66+
// random_access_iterator_tag
67+
std::ranges::concat_view v(buffer, buffer);
68+
using Iter = decltype(v.begin());
69+
70+
static_assert(std::is_same_v<Iter::iterator_concept, std::random_access_iterator_tag>);
71+
static_assert(std::is_same_v<Iter::iterator_category, std::random_access_iterator_tag>);
72+
static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>);
73+
static_assert(std::is_same_v<Iter::value_type, int>);
74+
static_assert(HasIterCategory<Iter>);
75+
}
76+
77+
78+
{
79+
// 3 views
80+
std::ranges::concat_view v(buffer, buffer, buffer);
81+
using Iter = decltype(v.begin());
82+
83+
static_assert(std::is_same_v<Iter::iterator_concept, std::random_access_iterator_tag>);
84+
static_assert(std::is_same_v<Iter::iterator_category, std::random_access_iterator_tag>);
85+
static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>);
86+
static_assert(std::is_same_v<Iter::value_type, int>);
87+
static_assert(HasIterCategory<Iter>);
88+
}
89+
90+
91+
{
92+
// bidirectional_iterator_tag
93+
std::ranges::concat_view v(BidiCommonView{buffer});
94+
using Iter = decltype(v.begin());
95+
96+
static_assert(std::is_same_v<Iter::iterator_concept, std::bidirectional_iterator_tag>);
97+
static_assert(std::is_same_v<Iter::iterator_category, std::bidirectional_iterator_tag>);
98+
static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>);
99+
static_assert(std::is_same_v<Iter::value_type, int>);
100+
}
101+
102+
103+
104+
{
105+
// forward_iterator_tag
106+
using Iter = std::ranges::iterator_t<std::ranges::concat_view<ForwardView<int>>>;
107+
108+
static_assert(std::is_same_v<Iter::iterator_concept, std::forward_iterator_tag>);
109+
static_assert(std::is_same_v<Iter::iterator_category, std::forward_iterator_tag>);
110+
static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>);
111+
static_assert(std::is_same_v<Iter::value_type, int>);
112+
static_assert(HasIterCategory<Iter>);
113+
}
114+
115+
{
116+
// input_iterator_tag
117+
using Iter = std::ranges::iterator_t<std::ranges::concat_view<InputView<int>>>;
118+
119+
static_assert(std::is_same_v<Iter::iterator_concept, std::input_iterator_tag>);
120+
static_assert(!HasIterCategory<Iter>);
121+
static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>);
122+
static_assert(std::is_same_v<Iter::value_type, int>);
123+
}
124+
125+
{
126+
// difference_type of single view
127+
std::ranges::concat_view v{DiffTypeRange<std::intptr_t>{}};
128+
using Iter = decltype(v.begin());
129+
static_assert(std::is_same_v<Iter::difference_type, std::intptr_t>);
130+
}
131+
132+
{
133+
// difference_type of multiple views should be the common type
134+
std::ranges::concat_view v{DiffTypeRange<std::intptr_t>{}, DiffTypeRange<std::ptrdiff_t>{}};
135+
using Iter = decltype(v.begin());
136+
static_assert(std::is_same_v<Iter::difference_type, std::common_type_t<std::intptr_t, std::ptrdiff_t>>);
137+
}
138+
139+
const std::array foos{Foo{}};
140+
{
141+
// value_type of user-defined type
142+
std::ranges::concat_view v{foos};
143+
using Iter = decltype(v.begin());
144+
static_assert(std::is_same_v<Iter::value_type, Foo>);
145+
}
146+
147+
{
148+
// const-iterator different from iterator
149+
std::ranges::concat_view v{ConstVeryDifferentRange{}};
150+
using Iter = decltype(v.begin());
151+
using ConstIter = decltype(std::as_const(v).begin());
152+
153+
static_assert(std::is_same_v<Iter::iterator_concept, std::random_access_iterator_tag>);
154+
static_assert(std::is_same_v<Iter::iterator_category, std::random_access_iterator_tag>);
155+
static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>);
156+
static_assert(std::is_same_v<Iter::value_type, int>);
157+
158+
static_assert(std::is_same_v<ConstIter::iterator_concept, std::forward_iterator_tag>);
159+
static_assert(std::is_same_v<ConstIter::iterator_category, std::forward_iterator_tag>);
160+
static_assert(std::is_same_v<ConstIter::difference_type, std::ptrdiff_t>);
161+
static_assert(std::is_same_v<ConstIter::value_type, double>);
162+
}
163+
164+
}

0 commit comments

Comments
 (0)