]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // (C) Copyright David Abrahams 2002. |
2 | // Distributed under the Boost Software License, Version 1.0. (See | |
3 | // accompanying file LICENSE_1_0.txt or copy at | |
4 | // http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | // See http://www.boost.org for most recent version including documentation. | |
7 | ||
8 | // Revision History | |
9 | // 04 Mar 2001 Patches for Intel C++ (Dave Abrahams) | |
10 | // 19 Feb 2001 Take advantage of improved iterator_traits to do more tests | |
11 | // on MSVC. Reordered some #ifdefs for coherency. | |
12 | // (David Abrahams) | |
13 | // 13 Feb 2001 Test new VC6 workarounds (David Abrahams) | |
14 | // 11 Feb 2001 Final fixes for Borland (David Abrahams) | |
15 | // 11 Feb 2001 Some fixes for Borland get it closer on that compiler | |
16 | // (David Abrahams) | |
17 | // 07 Feb 2001 More comprehensive testing; factored out static tests for | |
18 | // better reuse (David Abrahams) | |
19 | // 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a | |
20 | // reference type from operator* (David Abrahams) | |
21 | // 19 Jan 2001 Initial version with iterator operators (David Abrahams) | |
22 | ||
23 | #include <boost/detail/iterator.hpp> | |
24 | #include <boost/type_traits/is_same.hpp> | |
25 | #include <boost/operators.hpp> | |
26 | #include <boost/static_assert.hpp> | |
27 | #include <iterator> | |
28 | #include <vector> | |
29 | #include <list> | |
f67539c2 | 30 | #include <boost/core/lightweight_test.hpp> |
7c673cae FG |
31 | #include <iostream> |
32 | ||
33 | // A UDT for which we can specialize std::iterator_traits<element*> on | |
34 | // compilers which don't support partial specialization. There's no | |
35 | // other reasonable way to test pointers on those compilers. | |
36 | struct element {}; | |
37 | ||
38 | // An iterator for which we can get traits. | |
39 | struct my_iterator1 | |
40 | : boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&> | |
41 | { | |
42 | my_iterator1(const char* p) : m_p(p) {} | |
f67539c2 | 43 | |
7c673cae FG |
44 | bool operator==(const my_iterator1& rhs) const |
45 | { return this->m_p == rhs.m_p; } | |
46 | ||
47 | my_iterator1& operator++() { ++this->m_p; return *this; } | |
48 | const char& operator*() { return *m_p; } | |
49 | private: | |
50 | const char* m_p; | |
51 | }; | |
52 | ||
53 | // Used to prove that we don't require std::iterator<> in the hierarchy under | |
54 | // MSVC6, and that we can compute all the traits for a standard-conforming UDT | |
55 | // iterator. | |
56 | struct my_iterator2 | |
57 | : boost::equality_comparable<my_iterator2 | |
58 | , boost::incrementable<my_iterator2 | |
59 | , boost::dereferenceable<my_iterator2,const char*> > > | |
60 | { | |
61 | typedef char value_type; | |
62 | typedef long difference_type; | |
63 | typedef const char* pointer; | |
64 | typedef const char& reference; | |
65 | typedef std::forward_iterator_tag iterator_category; | |
f67539c2 | 66 | |
7c673cae | 67 | my_iterator2(const char* p) : m_p(p) {} |
f67539c2 | 68 | |
7c673cae FG |
69 | bool operator==(const my_iterator2& rhs) const |
70 | { return this->m_p == rhs.m_p; } | |
71 | ||
72 | my_iterator2& operator++() { ++this->m_p; return *this; } | |
73 | const char& operator*() { return *m_p; } | |
74 | private: | |
75 | const char* m_p; | |
76 | }; | |
77 | ||
78 | // Used to prove that we're not overly confused by the existence of | |
79 | // std::iterator<> in the hierarchy under MSVC6 - we should find that | |
80 | // boost::detail::iterator_traits<my_iterator3>::difference_type is int. | |
81 | struct my_iterator3 : my_iterator1 | |
82 | { | |
83 | typedef int difference_type; | |
84 | my_iterator3(const char* p) | |
85 | : my_iterator1(p) {} | |
86 | }; | |
87 | ||
88 | // | |
89 | // Assertion tools. Used instead of BOOST_STATIC_ASSERT because that | |
90 | // doesn't give us a nice stack backtrace | |
91 | // | |
92 | template <bool = false> struct assertion; | |
93 | ||
94 | template <> struct assertion<true> | |
95 | { | |
96 | typedef char type; | |
97 | }; | |
98 | ||
99 | template <class T, class U> | |
100 | struct assert_same | |
101 | : assertion<(::boost::is_same<T,U>::value)> | |
102 | { | |
103 | }; | |
104 | ||
105 | ||
106 | // Iterator tests | |
107 | template <class Iterator, | |
108 | class value_type, class difference_type, class pointer, class reference, class category> | |
109 | struct non_portable_tests | |
110 | { | |
111 | typedef typename boost::detail::iterator_traits<Iterator>::pointer test_pt; | |
112 | typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt; | |
113 | typedef typename assert_same<test_pt, pointer>::type a1; | |
114 | typedef typename assert_same<test_rt, reference>::type a2; | |
115 | }; | |
116 | ||
117 | template <class Iterator, | |
118 | class value_type, class difference_type, class pointer, class reference, class category> | |
119 | struct portable_tests | |
120 | { | |
121 | typedef typename boost::detail::iterator_traits<Iterator>::difference_type test_dt; | |
122 | typedef typename boost::detail::iterator_traits<Iterator>::iterator_category test_cat; | |
123 | typedef typename assert_same<test_dt, difference_type>::type a1; | |
124 | typedef typename assert_same<test_cat, category>::type a2; | |
125 | }; | |
126 | ||
127 | // Test iterator_traits | |
128 | template <class Iterator, | |
129 | class value_type, class difference_type, class pointer, class reference, class category> | |
130 | struct input_iterator_test | |
131 | : portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | |
132 | { | |
133 | typedef typename boost::detail::iterator_traits<Iterator>::value_type test_vt; | |
134 | typedef typename assert_same<test_vt, value_type>::type a1; | |
135 | }; | |
136 | ||
137 | template <class Iterator, | |
138 | class value_type, class difference_type, class pointer, class reference, class category> | |
139 | struct non_pointer_test | |
140 | : input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category> | |
141 | , non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | |
142 | { | |
143 | }; | |
144 | ||
145 | template <class Iterator, | |
146 | class value_type, class difference_type, class pointer, class reference, class category> | |
147 | struct maybe_pointer_test | |
148 | : portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | |
149 | , non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | |
150 | { | |
151 | }; | |
152 | ||
153 | input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag> | |
154 | istream_iterator_test; | |
155 | ||
156 | #if BOOST_WORKAROUND(__BORLANDC__, <= 0x564) && !defined(__SGI_STL_PORT) | |
157 | typedef ::std::char_traits<char>::off_type distance; | |
158 | non_pointer_test<std::ostream_iterator<int>,int, | |
159 | distance,int*,int&,std::output_iterator_tag> ostream_iterator_test; | |
160 | #elif defined(BOOST_MSVC_STD_ITERATOR) | |
161 | non_pointer_test<std::ostream_iterator<int>, | |
162 | int, void, int*, int&, std::output_iterator_tag> | |
163 | ostream_iterator_test; | |
164 | #elif BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006)) | |
165 | non_pointer_test<std::ostream_iterator<int>, | |
166 | int, long, int*, int&, std::output_iterator_tag> | |
167 | ostream_iterator_test; | |
168 | #else | |
169 | non_pointer_test<std::ostream_iterator<int>, | |
170 | void, void, void, void, std::output_iterator_tag> | |
171 | ostream_iterator_test; | |
172 | #endif | |
173 | ||
174 | ||
175 | #ifdef __KCC | |
176 | typedef long std_list_diff_type; | |
177 | #else | |
178 | typedef std::ptrdiff_t std_list_diff_type; | |
179 | #endif | |
180 | ||
181 | non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag> | |
182 | list_iterator_test; | |
183 | ||
184 | maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag> | |
185 | vector_iterator_test; | |
186 | ||
187 | maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag> | |
188 | int_pointer_test; | |
189 | ||
190 | non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag> | |
191 | my_iterator1_test; | |
f67539c2 | 192 | |
7c673cae FG |
193 | non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag> |
194 | my_iterator2_test; | |
195 | ||
196 | non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag> | |
197 | my_iterator3_test; | |
198 | ||
199 | int main() | |
200 | { | |
201 | char chars[100]; | |
202 | int ints[100]; | |
203 | ||
204 | for (int length = 3; length < 100; length += length / 3) | |
205 | { | |
206 | std::list<int> l(length); | |
207 | BOOST_TEST(boost::detail::distance(l.begin(), l.end()) == length); | |
f67539c2 | 208 | |
7c673cae FG |
209 | std::vector<int> v(length); |
210 | BOOST_TEST(boost::detail::distance(v.begin(), v.end()) == length); | |
211 | ||
212 | BOOST_TEST(boost::detail::distance(&ints[0], ints + length) == length); | |
213 | BOOST_TEST(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length); | |
214 | BOOST_TEST(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length); | |
215 | BOOST_TEST(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length); | |
216 | } | |
217 | return boost::report_errors(); | |
218 | } |