• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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