1 | // (C) Copyright Eric Niebler 2004-2005 |
2 | // (C) Copyright Gennadiy Rozental 2001. |
3 | // Distributed under the Boost Software License, Version 1.0. |
4 | // (See accompanying file LICENSE_1_0.txt or copy at |
5 | // http://www.boost.org/LICENSE_1_0.txt) |
6 | |
7 | // See http://www.boost.org/libs/test for the library home page. |
8 | // |
9 | // File : $RCSfile$ |
10 | // |
11 | // Version : $Revision$ |
12 | // |
13 | // Description : this is an abridged version of an excelent BOOST_FOREACH facility |
14 | // presented by Eric Niebler. I am so fond of it so I can't wait till it |
15 | // going to be accepted into Boost. Also I need version with less number of dependencies |
16 | // and more portable. This version doesn't support rvalues and will reeveluate it's |
17 | // parameters, but should be good enough for my purposes. |
18 | // *************************************************************************** |
19 | |
20 | #ifndef BOOST_TEST_UTILS_FOREACH_HPP |
21 | #define BOOST_TEST_UTILS_FOREACH_HPP |
22 | |
23 | // Boost.Test |
24 | #include <boost/test/detail/config.hpp> |
25 | |
26 | // Boost |
27 | #include <boost/type.hpp> |
28 | #include <boost/mpl/bool.hpp> |
29 | |
30 | #include <boost/type_traits/is_const.hpp> |
31 | |
32 | #include <boost/test/detail/suppress_warnings.hpp> |
33 | |
34 | //____________________________________________________________________________// |
35 | |
36 | namespace boost { |
37 | namespace unit_test { |
38 | namespace for_each { |
39 | |
40 | // ************************************************************************** // |
41 | // ************** static_any ************** // |
42 | // ************************************************************************** // |
43 | |
44 | struct static_any_base |
45 | { |
46 | operator bool() const { return false; } |
47 | }; |
48 | |
49 | //____________________________________________________________________________// |
50 | |
51 | template<typename Iter> |
52 | struct static_any : static_any_base |
53 | { |
54 | static_any( Iter const& t ) : m_it( t ) {} |
55 | |
56 | mutable Iter m_it; |
57 | }; |
58 | |
59 | //____________________________________________________________________________// |
60 | |
61 | typedef static_any_base const& static_any_t; |
62 | |
63 | //____________________________________________________________________________// |
64 | |
65 | template<typename Iter> |
66 | inline Iter& |
67 | static_any_cast( static_any_t a, Iter* = 0 ) |
68 | { |
69 | return static_cast<Iter&>( static_cast<static_any<Iter> const&>( a ).m_it ); |
70 | } |
71 | |
72 | //____________________________________________________________________________// |
73 | |
74 | // ************************************************************************** // |
75 | // ************** is_const ************** // |
76 | // ************************************************************************** // |
77 | |
78 | template<typename C> |
79 | inline is_const<C> |
80 | is_const_coll( C& ) |
81 | { |
82 | return is_const<C>(); |
83 | } |
84 | |
85 | //____________________________________________________________________________// |
86 | |
87 | // ************************************************************************** // |
88 | // ************** begin ************** // |
89 | // ************************************************************************** // |
90 | |
91 | template<typename C> |
92 | inline static_any<BOOST_DEDUCED_TYPENAME C::iterator> |
93 | begin( C& t, mpl::false_ ) |
94 | { |
95 | return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.begin() ); |
96 | } |
97 | |
98 | //____________________________________________________________________________// |
99 | |
100 | template<typename C> |
101 | inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator> |
102 | begin( C const& t, mpl::true_ ) |
103 | { |
104 | return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.begin() ); |
105 | } |
106 | |
107 | //____________________________________________________________________________// |
108 | |
109 | // ************************************************************************** // |
110 | // ************** end ************** // |
111 | // ************************************************************************** // |
112 | |
113 | template<typename C> |
114 | inline static_any<BOOST_DEDUCED_TYPENAME C::iterator> |
115 | end( C& t, mpl::false_ ) |
116 | { |
117 | return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.end() ); |
118 | } |
119 | |
120 | //____________________________________________________________________________// |
121 | |
122 | template<typename C> |
123 | inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator> |
124 | end( C const& t, mpl::true_ ) |
125 | { |
126 | return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.end() ); |
127 | } |
128 | |
129 | //____________________________________________________________________________// |
130 | |
131 | // ************************************************************************** // |
132 | // ************** done ************** // |
133 | // ************************************************************************** // |
134 | |
135 | template<typename C> |
136 | inline bool |
137 | done( static_any_t cur, static_any_t end, C&, mpl::false_ ) |
138 | { |
139 | return static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ) == |
140 | static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( end ); |
141 | } |
142 | |
143 | //____________________________________________________________________________// |
144 | |
145 | template<typename C> |
146 | inline bool |
147 | done( static_any_t cur, static_any_t end, C const&, mpl::true_ ) |
148 | { |
149 | return static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ) == |
150 | static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( end ); |
151 | } |
152 | |
153 | //____________________________________________________________________________// |
154 | |
155 | // ************************************************************************** // |
156 | // ************** next ************** // |
157 | // ************************************************************************** // |
158 | |
159 | template<typename C> |
160 | inline void |
161 | next( static_any_t cur, C&, mpl::false_ ) |
162 | { |
163 | ++static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); |
164 | } |
165 | |
166 | //____________________________________________________________________________// |
167 | |
168 | template<typename C> |
169 | inline void |
170 | next( static_any_t cur, C const&, mpl::true_ ) |
171 | { |
172 | ++static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); |
173 | } |
174 | |
175 | //____________________________________________________________________________// |
176 | |
177 | // ************************************************************************** // |
178 | // ************** prev ************** // |
179 | // ************************************************************************** // |
180 | |
181 | template<typename C> |
182 | inline void |
183 | prev( static_any_t cur, C&, mpl::false_ ) |
184 | { |
185 | --static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); |
186 | } |
187 | |
188 | //____________________________________________________________________________// |
189 | |
190 | template<typename C> |
191 | inline void |
192 | prev( static_any_t cur, C const&, mpl::true_ ) |
193 | { |
194 | --static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); |
195 | } |
196 | |
197 | //____________________________________________________________________________// |
198 | |
199 | // ************************************************************************** // |
200 | // ************** deref ************** // |
201 | // ************************************************************************** // |
202 | |
203 | template<class RefType,typename C> |
204 | inline RefType |
205 | deref( static_any_t cur, C&, ::boost::type<RefType>, mpl::false_ ) |
206 | { |
207 | return *static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); |
208 | } |
209 | |
210 | //____________________________________________________________________________// |
211 | |
212 | template<class RefType,typename C> |
213 | inline RefType |
214 | deref( static_any_t cur, C const&, ::boost::type<RefType>, mpl::true_ ) |
215 | { |
216 | return *static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); |
217 | } |
218 | |
219 | //____________________________________________________________________________// |
220 | |
221 | // ************************************************************************** // |
222 | // ************** BOOST_TEST_FOREACH ************** // |
223 | // ************************************************************************** // |
224 | |
225 | #define BOOST_TEST_FE_ANY ::boost::unit_test::for_each::static_any_t |
226 | #define BOOST_TEST_FE_IS_CONST( COL ) ::boost::unit_test::for_each::is_const_coll( COL ) |
227 | |
228 | #define BOOST_TEST_FE_BEG( COL ) \ |
229 | ::boost::unit_test::for_each::begin( \ |
230 | COL, \ |
231 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
232 | /**/ |
233 | |
234 | #define BOOST_TEST_FE_END( COL ) \ |
235 | ::boost::unit_test::for_each::end( \ |
236 | COL, \ |
237 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
238 | /**/ |
239 | |
240 | #define BOOST_TEST_FE_DONE( COL ) \ |
241 | ::boost::unit_test::for_each::done( \ |
242 | BOOST_TEST_FE_CUR_VAR, \ |
243 | BOOST_TEST_FE_END_VAR, \ |
244 | COL, \ |
245 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
246 | /**/ |
247 | |
248 | #define BOOST_TEST_FE_NEXT( COL ) \ |
249 | ::boost::unit_test::for_each::next( \ |
250 | BOOST_TEST_FE_CUR_VAR, \ |
251 | COL, \ |
252 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
253 | /**/ |
254 | |
255 | #define BOOST_TEST_FE_PREV( COL ) \ |
256 | ::boost::unit_test::for_each::prev( \ |
257 | BOOST_TEST_FE_CUR_VAR, \ |
258 | COL, \ |
259 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
260 | /**/ |
261 | |
262 | #define BOOST_FOREACH_NOOP(COL) \ |
263 | ((void)&(COL)) |
264 | |
265 | #define BOOST_TEST_FE_DEREF( COL, RefType ) \ |
266 | ::boost::unit_test::for_each::deref( \ |
267 | BOOST_TEST_FE_CUR_VAR, \ |
268 | COL, \ |
269 | ::boost::type<RefType >(), \ |
270 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
271 | /**/ |
272 | |
273 | #if BOOST_WORKAROUND( BOOST_MSVC, == 1310 ) |
274 | #define BOOST_TEST_LINE_NUM |
275 | #else |
276 | #define BOOST_TEST_LINE_NUM __LINE__ |
277 | #endif |
278 | |
279 | #define BOOST_TEST_FE_CUR_VAR BOOST_JOIN( _fe_cur_, BOOST_TEST_LINE_NUM ) |
280 | #define BOOST_TEST_FE_END_VAR BOOST_JOIN( _fe_end_, BOOST_TEST_LINE_NUM ) |
281 | #define BOOST_TEST_FE_CON_VAR BOOST_JOIN( _fe_con_, BOOST_TEST_LINE_NUM ) |
282 | |
283 | #define BOOST_TEST_FOREACH( RefType, var, COL ) \ |
284 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \ |
285 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_END( COL ) ) {} else \ |
286 | for( bool BOOST_TEST_FE_CON_VAR = true; \ |
287 | BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); \ |
288 | BOOST_TEST_FE_CON_VAR ? BOOST_TEST_FE_NEXT( COL ) : BOOST_FOREACH_NOOP( COL )) \ |
289 | \ |
290 | if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \ |
291 | for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \ |
292 | !BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \ |
293 | /**/ |
294 | |
295 | #define BOOST_TEST_REVERSE_FOREACH( RefType, var, COL ) \ |
296 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_END( COL ) ) {} else \ |
297 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \ |
298 | for( bool BOOST_TEST_FE_CON_VAR = true; \ |
299 | BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); ) \ |
300 | \ |
301 | if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \ |
302 | if( (BOOST_TEST_FE_PREV( COL ), false) ) {} else \ |
303 | for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \ |
304 | !BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \ |
305 | /**/ |
306 | |
307 | //____________________________________________________________________________// |
308 | |
309 | } // namespace for_each |
310 | } // namespace unit_test |
311 | } // namespace boost |
312 | |
313 | #include <boost/test/detail/enable_warnings.hpp> |
314 | |
315 | #endif // BOOST_TEST_UTILS_FOREACH_HPP |
316 | |