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 | #include <boost/test/detail/workaround.hpp> |
30 | |
31 | #include <boost/type_traits/is_const.hpp> |
32 | |
33 | #include <boost/test/detail/suppress_warnings.hpp> |
34 | |
35 | //____________________________________________________________________________// |
36 | |
37 | namespace boost { |
38 | namespace unit_test { |
39 | namespace for_each { |
40 | |
41 | // ************************************************************************** // |
42 | // ************** static_any ************** // |
43 | // ************************************************************************** // |
44 | |
45 | struct static_any_base |
46 | { |
47 | operator bool() const { return false; } |
48 | }; |
49 | |
50 | //____________________________________________________________________________// |
51 | |
52 | template<typename Iter> |
53 | struct static_any : static_any_base |
54 | { |
55 | static_any( Iter const& t ) : m_it( t ) {} |
56 | |
57 | mutable Iter m_it; |
58 | }; |
59 | |
60 | //____________________________________________________________________________// |
61 | |
62 | typedef static_any_base const& static_any_t; |
63 | |
64 | //____________________________________________________________________________// |
65 | |
66 | template<typename Iter> |
67 | inline Iter& |
68 | static_any_cast( static_any_t a, Iter* = 0 ) |
69 | { |
70 | return static_cast<Iter&>( static_cast<static_any<Iter> const&>( a ).m_it ); |
71 | } |
72 | |
73 | //____________________________________________________________________________// |
74 | |
75 | // ************************************************************************** // |
76 | // ************** is_const ************** // |
77 | // ************************************************************************** // |
78 | |
79 | template<typename C> |
80 | inline is_const<C> |
81 | is_const_coll( C& ) |
82 | { |
83 | return is_const<C>(); |
84 | } |
85 | |
86 | //____________________________________________________________________________// |
87 | |
88 | // ************************************************************************** // |
89 | // ************** begin ************** // |
90 | // ************************************************************************** // |
91 | |
92 | template<typename C> |
93 | inline static_any<BOOST_DEDUCED_TYPENAME C::iterator> |
94 | begin( C& t, mpl::false_ ) |
95 | { |
96 | return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.begin() ); |
97 | } |
98 | |
99 | //____________________________________________________________________________// |
100 | |
101 | template<typename C> |
102 | inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator> |
103 | begin( C const& t, mpl::true_ ) |
104 | { |
105 | return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.begin() ); |
106 | } |
107 | |
108 | //____________________________________________________________________________// |
109 | |
110 | // ************************************************************************** // |
111 | // ************** end ************** // |
112 | // ************************************************************************** // |
113 | |
114 | template<typename C> |
115 | inline static_any<BOOST_DEDUCED_TYPENAME C::iterator> |
116 | end( C& t, mpl::false_ ) |
117 | { |
118 | return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.end() ); |
119 | } |
120 | |
121 | //____________________________________________________________________________// |
122 | |
123 | template<typename C> |
124 | inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator> |
125 | end( C const& t, mpl::true_ ) |
126 | { |
127 | return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.end() ); |
128 | } |
129 | |
130 | //____________________________________________________________________________// |
131 | |
132 | // ************************************************************************** // |
133 | // ************** done ************** // |
134 | // ************************************************************************** // |
135 | |
136 | template<typename C> |
137 | inline bool |
138 | done( static_any_t cur, static_any_t end, C&, mpl::false_ ) |
139 | { |
140 | return static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ) == |
141 | static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( end ); |
142 | } |
143 | |
144 | //____________________________________________________________________________// |
145 | |
146 | template<typename C> |
147 | inline bool |
148 | done( static_any_t cur, static_any_t end, C const&, mpl::true_ ) |
149 | { |
150 | return static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ) == |
151 | static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( end ); |
152 | } |
153 | |
154 | //____________________________________________________________________________// |
155 | |
156 | // ************************************************************************** // |
157 | // ************** next ************** // |
158 | // ************************************************************************** // |
159 | |
160 | template<typename C> |
161 | inline void |
162 | next( static_any_t cur, C&, mpl::false_ ) |
163 | { |
164 | ++static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); |
165 | } |
166 | |
167 | //____________________________________________________________________________// |
168 | |
169 | template<typename C> |
170 | inline void |
171 | next( static_any_t cur, C const&, mpl::true_ ) |
172 | { |
173 | ++static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); |
174 | } |
175 | |
176 | //____________________________________________________________________________// |
177 | |
178 | // ************************************************************************** // |
179 | // ************** prev ************** // |
180 | // ************************************************************************** // |
181 | |
182 | template<typename C> |
183 | inline void |
184 | prev( static_any_t cur, C&, mpl::false_ ) |
185 | { |
186 | --static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); |
187 | } |
188 | |
189 | //____________________________________________________________________________// |
190 | |
191 | template<typename C> |
192 | inline void |
193 | prev( static_any_t cur, C const&, mpl::true_ ) |
194 | { |
195 | --static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); |
196 | } |
197 | |
198 | //____________________________________________________________________________// |
199 | |
200 | // ************************************************************************** // |
201 | // ************** deref ************** // |
202 | // ************************************************************************** // |
203 | |
204 | template<class RefType,typename C> |
205 | inline RefType |
206 | deref( static_any_t cur, C&, ::boost::type<RefType>, mpl::false_ ) |
207 | { |
208 | return *static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ); |
209 | } |
210 | |
211 | //____________________________________________________________________________// |
212 | |
213 | template<class RefType,typename C> |
214 | inline RefType |
215 | deref( static_any_t cur, C const&, ::boost::type<RefType>, mpl::true_ ) |
216 | { |
217 | return *static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ); |
218 | } |
219 | |
220 | //____________________________________________________________________________// |
221 | |
222 | // ************************************************************************** // |
223 | // ************** BOOST_TEST_FOREACH ************** // |
224 | // ************************************************************************** // |
225 | |
226 | #define BOOST_TEST_FE_ANY ::boost::unit_test::for_each::static_any_t |
227 | #define BOOST_TEST_FE_IS_CONST( COL ) ::boost::unit_test::for_each::is_const_coll( COL ) |
228 | |
229 | #define BOOST_TEST_FE_BEG( COL ) \ |
230 | ::boost::unit_test::for_each::begin( \ |
231 | COL, \ |
232 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
233 | /**/ |
234 | |
235 | #define BOOST_TEST_FE_END( COL ) \ |
236 | ::boost::unit_test::for_each::end( \ |
237 | COL, \ |
238 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
239 | /**/ |
240 | |
241 | #define BOOST_TEST_FE_DONE( COL ) \ |
242 | ::boost::unit_test::for_each::done( \ |
243 | BOOST_TEST_FE_CUR_VAR, \ |
244 | BOOST_TEST_FE_END_VAR, \ |
245 | COL, \ |
246 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
247 | /**/ |
248 | |
249 | #define BOOST_TEST_FE_NEXT( COL ) \ |
250 | ::boost::unit_test::for_each::next( \ |
251 | BOOST_TEST_FE_CUR_VAR, \ |
252 | COL, \ |
253 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
254 | /**/ |
255 | |
256 | #define BOOST_TEST_FE_PREV( COL ) \ |
257 | ::boost::unit_test::for_each::prev( \ |
258 | BOOST_TEST_FE_CUR_VAR, \ |
259 | COL, \ |
260 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
261 | /**/ |
262 | |
263 | #define BOOST_FOREACH_NOOP(COL) \ |
264 | ((void)&(COL)) |
265 | |
266 | #define BOOST_TEST_FE_DEREF( COL, RefType ) \ |
267 | ::boost::unit_test::for_each::deref( \ |
268 | BOOST_TEST_FE_CUR_VAR, \ |
269 | COL, \ |
270 | ::boost::type<RefType >(), \ |
271 | BOOST_TEST_FE_IS_CONST( COL ) ) \ |
272 | /**/ |
273 | |
274 | #if BOOST_WORKAROUND( BOOST_MSVC, == 1310 ) |
275 | #define BOOST_TEST_LINE_NUM |
276 | #else |
277 | #define BOOST_TEST_LINE_NUM __LINE__ |
278 | #endif |
279 | |
280 | #define BOOST_TEST_FE_CUR_VAR BOOST_JOIN( _fe_cur_, BOOST_TEST_LINE_NUM ) |
281 | #define BOOST_TEST_FE_END_VAR BOOST_JOIN( _fe_end_, BOOST_TEST_LINE_NUM ) |
282 | #define BOOST_TEST_FE_CON_VAR BOOST_JOIN( _fe_con_, BOOST_TEST_LINE_NUM ) |
283 | |
284 | #define BOOST_TEST_FOREACH( RefType, var, COL ) \ |
285 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \ |
286 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_END( COL ) ) {} else \ |
287 | for( bool BOOST_TEST_FE_CON_VAR = true; \ |
288 | BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); \ |
289 | BOOST_TEST_FE_CON_VAR ? BOOST_TEST_FE_NEXT( COL ) : BOOST_FOREACH_NOOP( COL )) \ |
290 | \ |
291 | if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \ |
292 | for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \ |
293 | !BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \ |
294 | /**/ |
295 | |
296 | #define BOOST_TEST_REVERSE_FOREACH( RefType, var, COL ) \ |
297 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_END( COL ) ) {} else \ |
298 | if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \ |
299 | for( bool BOOST_TEST_FE_CON_VAR = true; \ |
300 | BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); ) \ |
301 | \ |
302 | if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \ |
303 | if( (BOOST_TEST_FE_PREV( COL ), false) ) {} else \ |
304 | for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \ |
305 | !BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \ |
306 | /**/ |
307 | |
308 | //____________________________________________________________________________// |
309 | |
310 | } // namespace for_each |
311 | } // namespace unit_test |
312 | } // namespace boost |
313 | |
314 | #include <boost/test/detail/enable_warnings.hpp> |
315 | |
316 | #endif // BOOST_TEST_UTILS_FOREACH_HPP |
317 | |