]>
Commit | Line | Data |
---|---|---|
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 |