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 | // <iterator> |
10 | |
11 | // All of these became constexpr in C++17 |
12 | // |
13 | // template <InputIterator Iter, class Distance> |
14 | // constexpr void advance(Iter& i, Distance n); |
15 | // |
16 | // template <BidirectionalIterator Iter, class Distance> |
17 | // constexpr void advance(Iter& i, Distance n); |
18 | // |
19 | // template <RandomAccessIterator Iter, class Distance> |
20 | // constexpr void advance(Iter& i, Distance n); |
21 | |
22 | |
23 | // TODO: test_iterators.h includes <ranges>, and <ranges> includes <chrono> and <atomic>. |
24 | // Lots of implementation headers under <__chrono/> and <atomic> has signed to unsigned conversion, |
25 | // which will trigger the -Wsign-conversion warning. |
26 | // Once those headers are fixed, enable the -Wsign-conversion for this test by removing |
27 | // <TODO:Remove brackets> below |
28 | |
29 | // Make sure we catch forced conversions to the difference_type if they happen. |
30 | // ADDITIONAL_COMPILE_FLAGS<TODO:Remove brackets>(gcc-style-warnings): -Wsign-conversion |
31 | |
32 | #include <iterator> |
33 | #include <cassert> |
34 | #include <cstddef> |
35 | #include <type_traits> |
36 | |
37 | #include "test_macros.h" |
38 | #include "test_iterators.h" |
39 | |
40 | template <class Distance, class It> |
41 | TEST_CONSTEXPR_CXX17 |
42 | void check_advance(It it, Distance n, It result) |
43 | { |
44 | static_assert(std::is_same<decltype(std::advance(it, n)), void>::value, "" ); |
45 | std::advance(it, n); |
46 | assert(it == result); |
47 | } |
48 | |
49 | TEST_CONSTEXPR_CXX17 bool tests() |
50 | { |
51 | const char* s = "1234567890" ; |
52 | |
53 | // Check with iterator_traits::difference_type |
54 | { |
55 | typedef std::iterator_traits<const char*>::difference_type Distance; |
56 | check_advance<Distance>(cpp17_input_iterator<const char*>(s), 10, cpp17_input_iterator<const char*>(s+10)); |
57 | check_advance<Distance>(forward_iterator<const char*>(s), 10, forward_iterator<const char*>(s+10)); |
58 | check_advance<Distance>(bidirectional_iterator<const char*>(s+5), 5, bidirectional_iterator<const char*>(s+10)); |
59 | check_advance<Distance>(bidirectional_iterator<const char*>(s+5), -5, bidirectional_iterator<const char*>(s)); |
60 | check_advance<Distance>(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s+10)); |
61 | check_advance<Distance>(random_access_iterator<const char*>(s+5), -5, random_access_iterator<const char*>(s)); |
62 | check_advance<Distance>(s+5, 5, s+10); |
63 | check_advance<Distance>(s+5, -5, s); |
64 | } |
65 | |
66 | // Also check with other distance types |
67 | { |
68 | typedef int Distance; |
69 | check_advance<Distance>(cpp17_input_iterator<const char*>(s), 10, cpp17_input_iterator<const char*>(s+10)); |
70 | check_advance<Distance>(forward_iterator<const char*>(s), 10, forward_iterator<const char*>(s+10)); |
71 | check_advance<Distance>(bidirectional_iterator<const char*>(s), 10, bidirectional_iterator<const char*>(s+10)); |
72 | check_advance<Distance>(random_access_iterator<const char*>(s), 10, random_access_iterator<const char*>(s+10)); |
73 | } |
74 | |
75 | // Check with unsigned distance types to catch signedness-change issues |
76 | { |
77 | typedef std::size_t Distance; |
78 | check_advance<Distance>(cpp17_input_iterator<const char*>(s), 10u, cpp17_input_iterator<const char*>(s+10)); |
79 | check_advance<Distance>(forward_iterator<const char*>(s), 10u, forward_iterator<const char*>(s+10)); |
80 | check_advance<Distance>(bidirectional_iterator<const char*>(s), 10u, bidirectional_iterator<const char*>(s+10)); |
81 | check_advance<Distance>(random_access_iterator<const char*>(s), 10u, random_access_iterator<const char*>(s+10)); |
82 | } |
83 | |
84 | return true; |
85 | } |
86 | |
87 | int main(int, char**) |
88 | { |
89 | tests(); |
90 | #if TEST_STD_VER >= 17 |
91 | static_assert(tests(), "" ); |
92 | #endif |
93 | return 0; |
94 | } |
95 | |