]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright Thomas Witt 2003, Jeremy Siek 2004. |
2 | ||
3 | // Distributed under the Boost Software License, Version 1.0. (See | |
4 | // accompanying file LICENSE_1_0.txt or copy at | |
5 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | #include <boost/iterator/reverse_iterator.hpp> | |
8 | #include <boost/iterator/new_iterator_tests.hpp> | |
9 | #include <boost/concept_check.hpp> | |
10 | #include <boost/concept_archetype.hpp> | |
11 | #include <boost/iterator/iterator_concepts.hpp> | |
12 | #include <boost/iterator/iterator_archetypes.hpp> | |
13 | #include <boost/cstdlib.hpp> | |
14 | #include <algorithm> | |
15 | #include <deque> | |
16 | #include <iostream> | |
17 | ||
18 | using boost::dummyT; | |
19 | ||
20 | // Test reverse iterator | |
21 | int main() | |
22 | { | |
f67539c2 | 23 | dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), |
7c673cae FG |
24 | dummyT(3), dummyT(4), dummyT(5) }; |
25 | const int N = sizeof(array)/sizeof(dummyT); | |
26 | ||
27 | // Concept checks | |
28 | // Adapting old-style iterators | |
29 | { | |
30 | typedef boost::reverse_iterator<boost::bidirectional_iterator_archetype<dummyT> > Iter; | |
31 | boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); | |
32 | boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); | |
33 | boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); | |
34 | boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); | |
35 | } | |
36 | { | |
37 | typedef boost::reverse_iterator<boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter; | |
38 | boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >(); | |
39 | boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); | |
40 | boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); | |
41 | boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); | |
42 | } | |
43 | // Adapting new-style iterators | |
44 | { | |
45 | typedef boost::iterator_archetype< | |
46 | const dummyT | |
47 | , boost::iterator_archetypes::readable_iterator_t | |
48 | , boost::bidirectional_traversal_tag | |
49 | > iter; | |
50 | typedef boost::reverse_iterator<iter> Iter; | |
51 | boost::function_requires< boost::InputIteratorConcept<Iter> >(); | |
52 | boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); | |
53 | boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); | |
54 | } | |
55 | #if 0 | |
56 | // It does not seem feasible to make this work. Need to change docs to | |
57 | // require at lease Readable for the base iterator. -Jeremy | |
58 | { | |
59 | typedef boost::iterator_archetype< | |
60 | dummyT | |
61 | , boost::iterator_archetypes::writable_iterator_t | |
62 | , boost::bidirectional_traversal_tag | |
63 | > iter; | |
64 | typedef boost::reverse_iterator<iter> Iter; | |
65 | boost::function_requires< boost_concepts::WritableIteratorConcept<Iter, dummyT> >(); | |
66 | boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); | |
67 | } | |
68 | #endif | |
69 | #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker. | |
70 | { | |
71 | typedef boost::iterator_archetype< | |
72 | dummyT | |
73 | , boost::iterator_archetypes::readable_writable_iterator_t | |
74 | , boost::bidirectional_traversal_tag | |
75 | > iter; | |
76 | typedef boost::reverse_iterator<iter> Iter; | |
77 | boost::function_requires< boost::InputIteratorConcept<Iter> >(); | |
78 | boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); | |
79 | boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); | |
80 | boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); | |
81 | } | |
82 | { | |
83 | typedef boost::iterator_archetype< | |
84 | const dummyT | |
85 | , boost::iterator_archetypes::readable_lvalue_iterator_t | |
86 | , boost::bidirectional_traversal_tag | |
87 | > iter; | |
88 | typedef boost::reverse_iterator<iter> Iter; | |
89 | boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); | |
90 | boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); | |
91 | boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); | |
92 | boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); | |
93 | } | |
94 | { | |
95 | typedef boost::iterator_archetype< | |
96 | dummyT | |
97 | , boost::iterator_archetypes::writable_lvalue_iterator_t | |
98 | , boost::bidirectional_traversal_tag | |
99 | > iter; | |
100 | typedef boost::reverse_iterator<iter> Iter; | |
101 | boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); | |
102 | boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); | |
103 | boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); | |
104 | boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); | |
105 | } | |
106 | #endif | |
f67539c2 | 107 | |
7c673cae FG |
108 | // Test reverse_iterator |
109 | { | |
110 | dummyT reversed[N]; | |
111 | std::copy(array, array + N, reversed); | |
112 | std::reverse(reversed, reversed + N); | |
f67539c2 | 113 | |
7c673cae | 114 | typedef boost::reverse_iterator<dummyT*> reverse_iterator; |
f67539c2 | 115 | |
7c673cae FG |
116 | reverse_iterator i(reversed + N); |
117 | boost::random_access_iterator_test(i, N, array); | |
118 | ||
119 | boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); | |
120 | ||
121 | typedef boost::reverse_iterator<const dummyT*> const_reverse_iterator; | |
f67539c2 | 122 | |
7c673cae FG |
123 | const_reverse_iterator j(reversed + N); |
124 | boost::random_access_iterator_test(j, N, array); | |
125 | ||
126 | const dummyT* const_reversed = reversed; | |
f67539c2 | 127 | |
7c673cae | 128 | boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); |
f67539c2 | 129 | |
7c673cae FG |
130 | boost::const_nonconst_iterator_test(i, ++j); |
131 | } | |
132 | ||
133 | // Test reverse_iterator again, with traits fully deducible on all platforms | |
134 | { | |
135 | std::deque<dummyT> reversed_container; | |
136 | std::reverse_copy(array, array + N, std::back_inserter(reversed_container)); | |
137 | const std::deque<dummyT>::iterator reversed = reversed_container.begin(); | |
138 | ||
139 | ||
140 | typedef boost::reverse_iterator< | |
141 | std::deque<dummyT>::iterator> reverse_iterator; | |
142 | typedef boost::reverse_iterator< | |
143 | std::deque<dummyT>::const_iterator> const_reverse_iterator; | |
144 | ||
145 | // MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation | |
146 | // (e.g. "reversed + N") is used in the constructor below. | |
147 | const std::deque<dummyT>::iterator finish = reversed_container.end(); | |
148 | reverse_iterator i(finish); | |
f67539c2 | 149 | |
7c673cae FG |
150 | boost::random_access_iterator_test(i, N, array); |
151 | boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); | |
152 | ||
153 | const_reverse_iterator j = reverse_iterator(finish); | |
154 | boost::random_access_iterator_test(j, N, array); | |
155 | ||
156 | const std::deque<dummyT>::const_iterator const_reversed = reversed; | |
157 | boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); | |
f67539c2 | 158 | |
7c673cae FG |
159 | // Many compilers' builtin deque iterators don't interoperate well, though |
160 | // STLport fixes that problem. | |
161 | #if defined(__SGI_STL_PORT) \ | |
162 | || !BOOST_WORKAROUND(__GNUC__, <= 2) \ | |
163 | && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, <= 1)) \ | |
164 | && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) \ | |
165 | && !BOOST_WORKAROUND(__LIBCOMO_VERSION__, BOOST_TESTED_AT(29)) \ | |
166 | && !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1) | |
f67539c2 | 167 | |
7c673cae | 168 | boost::const_nonconst_iterator_test(i, ++j); |
f67539c2 | 169 | |
7c673cae FG |
170 | #endif |
171 | } | |
172 | ||
173 | return boost::report_errors(); | |
174 | } |