1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10
11 // <iterator>
12
13 // __libcpp_is_trivial_iterator<Tp>
14
15 // __libcpp_is_trivial_iterator determines if an iterator is a "trivial" one,
16 // that can be used w/o worrying about its operations throwing exceptions.
17 // Pointers are trivial iterators. Libc++ has three "iterator wrappers":
18 // reverse_iterator, move_iterator, and __wrap_iter. If the underlying iterator
19 // is trivial, then those are as well.
20 //
21
22 #include <iterator>
23 #include <cassert>
24 #include <string>
25 #include <vector>
26 #include <initializer_list>
27
28 #include "test_macros.h"
29 #include "test_iterators.h"
30
31 #if TEST_STD_VER >= 11
32 #define DELETE_FUNCTION = delete
33 #else
34 #define DELETE_FUNCTION
35 #endif
36
37 class T; // incomplete
38
39 class my_input_iterator_tag : public std::input_iterator_tag {};
40
41 template <class It>
42 class my_input_iterator
43 {
44 It it_;
45
46 template <class U> friend class my_input_iterator;
47 public:
48 typedef my_input_iterator_tag iterator_category;
49 typedef typename std::iterator_traits<It>::value_type value_type;
50 typedef typename std::iterator_traits<It>::difference_type difference_type;
51 typedef It pointer;
52 typedef typename std::iterator_traits<It>::reference reference;
53
base() const54 It base() const {return it_;}
55
my_input_iterator()56 my_input_iterator() : it_() {}
my_input_iterator(It it)57 explicit my_input_iterator(It it) : it_(it) {}
58 template <class U>
my_input_iterator(const my_input_iterator<U> & u)59 my_input_iterator(const my_input_iterator<U>& u) :it_(u.it_) {}
60
operator *() const61 reference operator*() const {return *it_;}
operator ->() const62 pointer operator->() const {return it_;}
63
operator ++()64 my_input_iterator& operator++() {++it_; return *this;}
operator ++(int)65 my_input_iterator operator++(int)
66 {my_input_iterator tmp(*this); ++(*this); return tmp;}
67
operator ==(const my_input_iterator & x,const my_input_iterator & y)68 friend bool operator==(const my_input_iterator& x, const my_input_iterator& y)
69 {return x.it_ == y.it_;}
operator !=(const my_input_iterator & x,const my_input_iterator & y)70 friend bool operator!=(const my_input_iterator& x, const my_input_iterator& y)
71 {return !(x == y);}
72
73 template <class T>
74 void operator,(T const &) DELETE_FUNCTION;
75 };
76
77 template <class T, class U>
78 inline
79 bool
operator ==(const my_input_iterator<T> & x,const my_input_iterator<U> & y)80 operator==(const my_input_iterator<T>& x, const my_input_iterator<U>& y)
81 {
82 return x.base() == y.base();
83 }
84
85 template <class T, class U>
86 inline
87 bool
operator !=(const my_input_iterator<T> & x,const my_input_iterator<U> & y)88 operator!=(const my_input_iterator<T>& x, const my_input_iterator<U>& y)
89 {
90 return !(x == y);
91 }
92
93
main()94 int main()
95 {
96 // basic tests
97 static_assert(( std::__libcpp_is_trivial_iterator<char *>::value), "");
98 static_assert(( std::__libcpp_is_trivial_iterator<const char *>::value), "");
99 static_assert(( std::__libcpp_is_trivial_iterator<int *>::value), "");
100 static_assert(( std::__libcpp_is_trivial_iterator<T *>::value), "");
101
102 static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<char *> > ::value), "");
103 static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<const char *> >::value), "");
104 static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<int *> > ::value), "");
105 static_assert(( std::__libcpp_is_trivial_iterator<std::move_iterator<T *> > ::value), "");
106
107 static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<char *> > ::value), "");
108 static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<const char *> >::value), "");
109 static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<int *> > ::value), "");
110 static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<T *> > ::value), "");
111
112 static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<char *> > ::value), "");
113 static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<const char *> >::value), "");
114 static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<int *> > ::value), "");
115 static_assert(( std::__libcpp_is_trivial_iterator<std::__wrap_iter<T *> > ::value), "");
116
117 static_assert(( std::__libcpp_is_trivial_iterator<std::reverse_iterator<std::__wrap_iter<char *> > > ::value), "");
118
119 // iterators in the libc++ test suite
120 static_assert((!std::__libcpp_is_trivial_iterator<output_iterator <char *> >::value), "");
121 static_assert((!std::__libcpp_is_trivial_iterator<input_iterator <char *> >::value), "");
122 static_assert((!std::__libcpp_is_trivial_iterator<forward_iterator <char *> >::value), "");
123 static_assert((!std::__libcpp_is_trivial_iterator<bidirectional_iterator<char *> >::value), "");
124 static_assert((!std::__libcpp_is_trivial_iterator<random_access_iterator<char *> >::value), "");
125 static_assert((!std::__libcpp_is_trivial_iterator<ThrowingIterator <char *> >::value), "");
126 static_assert((!std::__libcpp_is_trivial_iterator<NonThrowingIterator <char *> >::value), "");
127
128
129 // Iterator classification
130 static_assert(( std::__is_input_iterator <char *>::value), "" );
131 static_assert(( std::__is_forward_iterator <char *>::value), "" );
132 static_assert(( std::__is_bidirectional_iterator<char *>::value), "" );
133 static_assert(( std::__is_random_access_iterator<char *>::value), "" );
134 static_assert((!std::__is_exactly_input_iterator<char *>::value), "" );
135
136 static_assert(( std::__is_input_iterator <input_iterator<char *> >::value), "" );
137 static_assert((!std::__is_forward_iterator <input_iterator<char *> >::value), "" );
138 static_assert((!std::__is_bidirectional_iterator<input_iterator<char *> >::value), "" );
139 static_assert((!std::__is_random_access_iterator<input_iterator<char *> >::value), "" );
140 static_assert(( std::__is_exactly_input_iterator<input_iterator<char *> >::value), "" );
141
142 static_assert(( std::__is_input_iterator <forward_iterator<char *> >::value), "" );
143 static_assert(( std::__is_forward_iterator <forward_iterator<char *> >::value), "" );
144 static_assert((!std::__is_bidirectional_iterator<forward_iterator<char *> >::value), "" );
145 static_assert((!std::__is_random_access_iterator<forward_iterator<char *> >::value), "" );
146 static_assert((!std::__is_exactly_input_iterator<forward_iterator<char *> >::value), "" );
147
148 static_assert(( std::__is_input_iterator <bidirectional_iterator<char *> >::value), "" );
149 static_assert(( std::__is_forward_iterator <bidirectional_iterator<char *> >::value), "" );
150 static_assert(( std::__is_bidirectional_iterator<bidirectional_iterator<char *> >::value), "" );
151 static_assert((!std::__is_random_access_iterator<bidirectional_iterator<char *> >::value), "" );
152 static_assert((!std::__is_exactly_input_iterator<bidirectional_iterator<char *> >::value), "" );
153
154 static_assert(( std::__is_input_iterator <random_access_iterator<char *> >::value), "" );
155 static_assert(( std::__is_forward_iterator <random_access_iterator<char *> >::value), "" );
156 static_assert(( std::__is_bidirectional_iterator<random_access_iterator<char *> >::value), "" );
157 static_assert(( std::__is_random_access_iterator<random_access_iterator<char *> >::value), "" );
158 static_assert((!std::__is_exactly_input_iterator<random_access_iterator<char *> >::value), "" );
159
160 static_assert(( std::__is_input_iterator <my_input_iterator<char *> >::value), "" );
161 static_assert((!std::__is_forward_iterator <my_input_iterator<char *> >::value), "" );
162 static_assert((!std::__is_bidirectional_iterator<my_input_iterator<char *> >::value), "" );
163 static_assert((!std::__is_random_access_iterator<my_input_iterator<char *> >::value), "" );
164 static_assert(( std::__is_exactly_input_iterator<my_input_iterator<char *> >::value), "" );
165
166 //
167 // iterators from libc++'s containers
168 //
169
170 // string
171 static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::iterator> ::value), "");
172 static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::const_iterator> ::value), "");
173 static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::reverse_iterator> ::value), "");
174 static_assert(( std::__libcpp_is_trivial_iterator<std::vector<char>::const_reverse_iterator>::value), "");
175
176 // vector
177 static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::iterator> ::value), "");
178 static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::const_iterator> ::value), "");
179 static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::reverse_iterator> ::value), "");
180 static_assert(( std::__libcpp_is_trivial_iterator<std::basic_string<char>::const_reverse_iterator>::value), "");
181
182 #if TEST_STD_VER >= 11
183 // Initializer list (which has no reverse iterators)
184 static_assert(( std::__libcpp_is_trivial_iterator<std::initializer_list<char>::iterator> ::value), "");
185 static_assert(( std::__libcpp_is_trivial_iterator<std::initializer_list<char>::const_iterator> ::value), "");
186 #endif
187
188 }
189