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: libcpp-has-no-incomplete-ranges
12 
13 // transform_view::<iterator>::difference_type
14 // transform_view::<iterator>::value_type
15 // transform_view::<iterator>::iterator_category
16 // transform_view::<iterator>::iterator_concept
17 
18 #include <ranges>
19 
20 #include "test_macros.h"
21 #include "../types.h"
22 
23 template<class V, class F>
24 concept HasIterCategory = requires { typename std::ranges::transform_view<V, F>::iterator_category; };
25 
test()26 constexpr bool test() {
27   {
28     // Member typedefs for contiguous iterator.
29     static_assert(std::same_as<std::iterator_traits<int*>::iterator_concept, std::contiguous_iterator_tag>);
30     static_assert(std::same_as<std::iterator_traits<int*>::iterator_category, std::random_access_iterator_tag>);
31 
32     using TView = std::ranges::transform_view<MoveOnlyView, Increment>;
33     using TIter = std::ranges::iterator_t<TView>;
34     static_assert(std::same_as<typename TIter::iterator_concept, std::random_access_iterator_tag>);
35     static_assert(std::same_as<typename TIter::iterator_category, std::random_access_iterator_tag>);
36     static_assert(std::same_as<typename TIter::value_type, int>);
37     static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
38   }
39   {
40     // Member typedefs for random access iterator.
41     using TView = std::ranges::transform_view<RandomAccessView, Increment>;
42     using TIter = std::ranges::iterator_t<TView>;
43     static_assert(std::same_as<typename TIter::iterator_concept, std::random_access_iterator_tag>);
44     static_assert(std::same_as<typename TIter::iterator_category, std::random_access_iterator_tag>);
45     static_assert(std::same_as<typename TIter::value_type, int>);
46     static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
47   }
48   {
49     // Member typedefs for random access iterator/not-lvalue-ref.
50     using TView = std::ranges::transform_view<RandomAccessView, PlusOneMutable>;
51     using TIter = std::ranges::iterator_t<TView>;
52     static_assert(std::same_as<typename TIter::iterator_concept, std::random_access_iterator_tag>);
53     static_assert(std::same_as<typename TIter::iterator_category, std::input_iterator_tag>); // Note: this is now input_iterator_tag.
54     static_assert(std::same_as<typename TIter::value_type, int>);
55     static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
56   }
57   {
58     // Member typedefs for bidirectional iterator.
59     using TView = std::ranges::transform_view<BidirectionalView, Increment>;
60     using TIter = std::ranges::iterator_t<TView>;
61     static_assert(std::same_as<typename TIter::iterator_concept, std::bidirectional_iterator_tag>);
62     static_assert(std::same_as<typename TIter::iterator_category, std::bidirectional_iterator_tag>);
63     static_assert(std::same_as<typename TIter::value_type, int>);
64     static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
65   }
66   {
67     // Member typedefs for forward iterator.
68     using TView = std::ranges::transform_view<ForwardView, Increment>;
69     using TIter = std::ranges::iterator_t<TView>;
70     static_assert(std::same_as<typename TIter::iterator_concept, std::forward_iterator_tag>);
71     static_assert(std::same_as<typename TIter::iterator_category, std::forward_iterator_tag>);
72     static_assert(std::same_as<typename TIter::value_type, int>);
73     static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
74   }
75   {
76     // Member typedefs for input iterator.
77     using TView = std::ranges::transform_view<InputView, Increment>;
78     using TIter = std::ranges::iterator_t<TView>;
79     static_assert(std::same_as<typename TIter::iterator_concept, std::input_iterator_tag>);
80     static_assert(!HasIterCategory<InputView, Increment>);
81     static_assert(std::same_as<typename TIter::value_type, int>);
82     static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
83   }
84 
85   return true;
86 }
87 
main(int,char **)88 int main(int, char**) {
89   test();
90   static_assert(test());
91 
92   return 0;
93 }
94