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 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: libcpp-no-concepts
11 // UNSUPPORTED: gcc-10
12 
13 // constexpr counted_iterator operator+(iter_difference_t<I> n) const
14 //     requires random_access_iterator<I>;
15 // friend constexpr counted_iterator operator+(
16 //   iter_difference_t<I> n, const counted_iterator& x)
17 //     requires random_access_iterator<I>;
18 // constexpr counted_iterator& operator+=(iter_difference_t<I> n)
19 //     requires random_access_iterator<I>;
20 
21 #include <iterator>
22 
23 #include "test_macros.h"
24 #include "test_iterators.h"
25 
26 template<class Iter>
27 concept PlusEnabled = requires(Iter& iter) {
28   iter + 1;
29 };
30 
31 template<class Iter>
32 concept PlusEqEnabled = requires(Iter& iter) {
33   iter += 1;
34 };
35 
36 constexpr bool test() {
37   int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
38 
39   {
40     {
41       using Counted = std::counted_iterator<random_access_iterator<int*>>;
42       std::counted_iterator iter(random_access_iterator<int*>{buffer}, 8);
43       assert(iter + 2 == Counted(random_access_iterator<int*>{buffer + 2}, 6));
44       assert(iter + 0 == Counted(random_access_iterator<int*>{buffer}, 8));
45 
46       ASSERT_SAME_TYPE(decltype(iter + 2), Counted);
47     }
48     {
49       using Counted = const std::counted_iterator<random_access_iterator<int*>>;
50       const std::counted_iterator iter(random_access_iterator<int*>{buffer}, 8);
51       assert(iter + 8 == Counted(random_access_iterator<int*>{buffer + 8}, 0));
52       assert(iter + 0 == Counted(random_access_iterator<int*>{buffer}, 8));
53 
54       ASSERT_SAME_TYPE(decltype(iter + 2), std::remove_const_t<Counted>);
55     }
56   }
57 
58   {
59     {
60       using Counted = std::counted_iterator<random_access_iterator<int*>>;
61       std::counted_iterator iter(random_access_iterator<int*>{buffer}, 8);
62       assert(2 + iter == Counted(random_access_iterator<int*>{buffer + 2}, 6));
63       assert(0 + iter == Counted(random_access_iterator<int*>{buffer}, 8));
64 
65       ASSERT_SAME_TYPE(decltype(iter + 2), Counted);
66     }
67     {
68       using Counted = const std::counted_iterator<random_access_iterator<int*>>;
69       const std::counted_iterator iter(random_access_iterator<int*>{buffer}, 8);
70       assert(8 + iter == Counted(random_access_iterator<int*>{buffer + 8}, 0));
71       assert(0 + iter == Counted(random_access_iterator<int*>{buffer}, 8));
72 
73       ASSERT_SAME_TYPE(decltype(iter + 2), std::remove_const_t<Counted>);
74     }
75   }
76 
77   {
78     {
79       using Counted = std::counted_iterator<random_access_iterator<int*>>;
80       std::counted_iterator iter(random_access_iterator<int*>{buffer}, 8);
81       assert((iter += 2) == Counted(random_access_iterator<int*>{buffer + 2}, 6));
82       assert((iter += 0) == Counted(random_access_iterator<int*>{buffer + 2}, 6));
83 
84       ASSERT_SAME_TYPE(decltype(iter += 2), Counted&);
85     }
86     {
87       using Counted = std::counted_iterator<contiguous_iterator<int*>>;
88       std::counted_iterator iter(contiguous_iterator<int*>{buffer}, 8);
89       assert((iter += 8) == Counted(contiguous_iterator<int*>{buffer + 8}, 0));
90       assert((iter += 0) == Counted(contiguous_iterator<int*>{buffer + 8}, 0));
91 
92       ASSERT_SAME_TYPE(decltype(iter += 2), Counted&);
93     }
94     {
95       static_assert( PlusEnabled<std::counted_iterator<random_access_iterator<int*>>>);
96       static_assert(!PlusEnabled<std::counted_iterator<bidirectional_iterator<int*>>>);
97 
98       static_assert( PlusEqEnabled<      std::counted_iterator<random_access_iterator<int*>>>);
99       static_assert(!PlusEqEnabled<const std::counted_iterator<random_access_iterator<int*>>>);
100     }
101   }
102 
103   return true;
104 }
105 
106 int main(int, char**) {
107   test();
108   static_assert(test());
109 
110   return 0;
111 }
112