1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // foreach.hpp header file |
3 | // |
4 | // Copyright 2004 Eric Niebler. |
5 | // Distributed under the Boost Software License, Version 1.0. (See |
6 | // accompanying file LICENSE_1_0.txt or copy at |
7 | // http://www.boost.org/LICENSE_1_0.txt) |
8 | // See http://www.boost.org/libs/foreach for documentation |
9 | // |
10 | // Credits: |
11 | // Anson Tsao - for the initial inspiration and several good suggestions. |
12 | // Thorsten Ottosen - for Boost.Range, and for suggesting a way to detect |
13 | // const-qualified rvalues at compile time on VC7.1+ |
14 | // Russell Hind - For help porting to Borland |
15 | // Alisdair Meredith - For help porting to Borland |
16 | // Stefan Slapeta - For help porting to Intel |
17 | // David Jenkins - For help finding a Microsoft Code Analysis bug |
18 | // mimomorin@... - For a patch to use rvalue refs on supporting compilers |
19 | |
20 | #ifndef BOOST_FOREACH |
21 | |
22 | // MS compatible compilers support #pragma once |
23 | #if defined(_MSC_VER) |
24 | # pragma once |
25 | #endif |
26 | |
27 | #include <cstddef> |
28 | #include <utility> // for std::pair |
29 | |
30 | #include <boost/config.hpp> |
31 | #include <boost/detail/workaround.hpp> |
32 | |
33 | // Define a compiler generic null pointer value |
34 | #if defined(BOOST_NO_NULLPTR) |
35 | #define BOOST_FOREACH_NULL 0 |
36 | #else |
37 | #define BOOST_FOREACH_NULL nullptr |
38 | #endif |
39 | |
40 | // Some compilers let us detect even const-qualified rvalues at compile-time |
41 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \ |
42 | || defined(BOOST_MSVC) && !defined(_PREFAST_) \ |
43 | || (BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ <= 5) && !defined(BOOST_INTEL) && \ |
44 | !defined(BOOST_CLANG)) \ |
45 | || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ >= 4) && !defined(BOOST_INTEL) && \ |
46 | !defined(BOOST_CLANG)) |
47 | # define BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION |
48 | #else |
49 | // Some compilers allow temporaries to be bound to non-const references. |
50 | // These compilers make it impossible to for BOOST_FOREACH to detect |
51 | // temporaries and avoid reevaluation of the collection expression. |
52 | # if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x593) \ |
53 | || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \ |
54 | || BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) \ |
55 | || BOOST_WORKAROUND(__DECCXX_VER, <= 60590042) |
56 | # define BOOST_FOREACH_NO_RVALUE_DETECTION |
57 | # endif |
58 | // Some compilers do not correctly implement the lvalue/rvalue conversion |
59 | // rules of the ternary conditional operator. |
60 | # if defined(BOOST_FOREACH_NO_RVALUE_DETECTION) \ |
61 | || defined(BOOST_NO_SFINAE) \ |
62 | || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ |
63 | || BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1400)) \ |
64 | || (BOOST_WORKAROUND(__GNUC__, == 3) && (__GNUC_MINOR__ <= 3) && defined(__APPLE_CC__)) \ |
65 | || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ |
66 | || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) \ |
67 | || BOOST_WORKAROUND(__SUNPRO_CC, >= 0x5100) \ |
68 | || BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x590)) |
69 | # define BOOST_FOREACH_NO_CONST_RVALUE_DETECTION |
70 | # else |
71 | # define BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION |
72 | # endif |
73 | #endif |
74 | |
75 | #include <boost/mpl/if.hpp> |
76 | #include <boost/mpl/assert.hpp> |
77 | #include <boost/mpl/logical.hpp> |
78 | #include <boost/mpl/eval_if.hpp> |
79 | #include <boost/noncopyable.hpp> |
80 | #include <boost/range/end.hpp> |
81 | #include <boost/range/begin.hpp> |
82 | #include <boost/range/rend.hpp> |
83 | #include <boost/range/rbegin.hpp> |
84 | #include <boost/range/iterator.hpp> |
85 | #include <boost/range/reverse_iterator.hpp> |
86 | #include <boost/type_traits/is_array.hpp> |
87 | #include <boost/type_traits/is_const.hpp> |
88 | #include <boost/type_traits/is_abstract.hpp> |
89 | #include <boost/type_traits/is_base_and_derived.hpp> |
90 | #include <boost/type_traits/is_rvalue_reference.hpp> |
91 | #include <boost/iterator/iterator_traits.hpp> |
92 | #include <boost/utility/addressof.hpp> |
93 | #include <boost/foreach_fwd.hpp> |
94 | |
95 | #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION |
96 | # include <new> |
97 | # include <boost/aligned_storage.hpp> |
98 | # include <boost/utility/enable_if.hpp> |
99 | # include <boost/type_traits/remove_const.hpp> |
100 | #endif |
101 | |
102 | namespace boost |
103 | { |
104 | |
105 | // forward declarations for iterator_range |
106 | template<typename T> |
107 | class iterator_range; |
108 | |
109 | // forward declarations for sub_range |
110 | template<typename T> |
111 | class sub_range; |
112 | |
113 | namespace foreach |
114 | { |
115 | /////////////////////////////////////////////////////////////////////////////// |
116 | // in_range |
117 | // |
118 | template<typename T> |
119 | inline std::pair<T, T> in_range(T begin, T end) |
120 | { |
121 | return std::make_pair(begin, end); |
122 | } |
123 | |
124 | /////////////////////////////////////////////////////////////////////////////// |
125 | // boost::foreach::is_lightweight_proxy |
126 | // Specialize this for user-defined collection types if they are inexpensive to copy. |
127 | // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. |
128 | template<typename T> |
129 | struct is_lightweight_proxy |
130 | : boost::mpl::false_ |
131 | { |
132 | }; |
133 | |
134 | /////////////////////////////////////////////////////////////////////////////// |
135 | // boost::foreach::is_noncopyable |
136 | // Specialize this for user-defined collection types if they cannot be copied. |
137 | // This also tells BOOST_FOREACH to avoid the rvalue/lvalue detection stuff. |
138 | template<typename T> |
139 | struct is_noncopyable |
140 | #if !defined(BOOST_BROKEN_IS_BASE_AND_DERIVED) && !defined(BOOST_NO_IS_ABSTRACT) |
141 | : boost::mpl::or_< |
142 | boost::is_abstract<T> |
143 | , boost::is_base_and_derived<boost::noncopyable, T> |
144 | > |
145 | #elif !defined(BOOST_BROKEN_IS_BASE_AND_DERIVED) |
146 | : boost::is_base_and_derived<boost::noncopyable, T> |
147 | #elif !defined(BOOST_NO_IS_ABSTRACT) |
148 | : boost::is_abstract<T> |
149 | #else |
150 | : boost::mpl::false_ |
151 | #endif |
152 | { |
153 | }; |
154 | |
155 | } // namespace foreach |
156 | |
157 | } // namespace boost |
158 | |
159 | // vc6/7 needs help ordering the following overloads |
160 | #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING |
161 | # define BOOST_FOREACH_TAG_DEFAULT ... |
162 | #else |
163 | # define BOOST_FOREACH_TAG_DEFAULT boost::foreach::tag |
164 | #endif |
165 | |
166 | /////////////////////////////////////////////////////////////////////////////// |
167 | // boost_foreach_is_lightweight_proxy |
168 | // Another customization point for the is_lightweight_proxy optimization, |
169 | // this one works on legacy compilers. Overload boost_foreach_is_lightweight_proxy |
170 | // at the global namespace for your type. |
171 | template<typename T> |
172 | inline boost::foreach::is_lightweight_proxy<T> * |
173 | boost_foreach_is_lightweight_proxy(T *&, BOOST_FOREACH_TAG_DEFAULT) { return 0; } |
174 | |
175 | template<typename T> |
176 | inline boost::mpl::true_ * |
177 | boost_foreach_is_lightweight_proxy(std::pair<T, T> *&, boost::foreach::tag) { return 0; } |
178 | |
179 | template<typename T> |
180 | inline boost::mpl::true_ * |
181 | boost_foreach_is_lightweight_proxy(boost::iterator_range<T> *&, boost::foreach::tag) { return 0; } |
182 | |
183 | template<typename T> |
184 | inline boost::mpl::true_ * |
185 | boost_foreach_is_lightweight_proxy(boost::sub_range<T> *&, boost::foreach::tag) { return 0; } |
186 | |
187 | template<typename T> |
188 | inline boost::mpl::true_ * |
189 | boost_foreach_is_lightweight_proxy(T **&, boost::foreach::tag) { return 0; } |
190 | |
191 | /////////////////////////////////////////////////////////////////////////////// |
192 | // boost_foreach_is_noncopyable |
193 | // Another customization point for the is_noncopyable trait, |
194 | // this one works on legacy compilers. Overload boost_foreach_is_noncopyable |
195 | // at the global namespace for your type. |
196 | template<typename T> |
197 | inline boost::foreach::is_noncopyable<T> * |
198 | boost_foreach_is_noncopyable(T *&, BOOST_FOREACH_TAG_DEFAULT) { return 0; } |
199 | |
200 | namespace boost |
201 | { |
202 | |
203 | namespace foreach_detail_ |
204 | { |
205 | |
206 | /////////////////////////////////////////////////////////////////////////////// |
207 | // Define some utilities for assessing the properties of expressions |
208 | // |
209 | template<typename Bool1, typename Bool2> |
210 | inline boost::mpl::and_<Bool1, Bool2> *and_(Bool1 *, Bool2 *) { return 0; } |
211 | |
212 | template<typename Bool1, typename Bool2, typename Bool3> |
213 | inline boost::mpl::and_<Bool1, Bool2, Bool3> *and_(Bool1 *, Bool2 *, Bool3 *) { return 0; } |
214 | |
215 | template<typename Bool1, typename Bool2> |
216 | inline boost::mpl::or_<Bool1, Bool2> *or_(Bool1 *, Bool2 *) { return 0; } |
217 | |
218 | template<typename Bool1, typename Bool2, typename Bool3> |
219 | inline boost::mpl::or_<Bool1, Bool2, Bool3> *or_(Bool1 *, Bool2 *, Bool3 *) { return 0; } |
220 | |
221 | template<typename Bool1> |
222 | inline boost::mpl::not_<Bool1> *not_(Bool1 *) { return 0; } |
223 | |
224 | template<typename T> |
225 | inline boost::is_array<T> *is_array_(T const &) { return 0; } |
226 | |
227 | template<typename T> |
228 | inline boost::is_const<T> *is_const_(T &) { return 0; } |
229 | |
230 | #ifndef BOOST_FOREACH_NO_RVALUE_DETECTION |
231 | template<typename T> |
232 | inline boost::mpl::true_ *is_const_(T const &) { return 0; } |
233 | #endif |
234 | |
235 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES |
236 | template<typename T> |
237 | inline boost::mpl::false_ *is_rvalue_(T &, int) { return 0; } |
238 | |
239 | template<typename T> |
240 | inline boost::mpl::true_ *is_rvalue_(T const &, ...) { return 0; } |
241 | #else |
242 | template<typename T> |
243 | inline boost::is_rvalue_reference<T &&> *is_rvalue_(T &&, int) { return 0; } |
244 | #endif |
245 | |
246 | /////////////////////////////////////////////////////////////////////////////// |
247 | // auto_any_t/auto_any |
248 | // General utility for putting an object of any type into automatic storage |
249 | struct auto_any_base |
250 | { |
251 | // auto_any_base must evaluate to false in boolean context so that |
252 | // they can be declared in if() statements. |
253 | operator bool() const |
254 | { |
255 | return false; |
256 | } |
257 | }; |
258 | |
259 | template<typename T> |
260 | struct auto_any : auto_any_base |
261 | { |
262 | explicit auto_any(T const &t) |
263 | : item(t) |
264 | { |
265 | } |
266 | |
267 | // temporaries of type auto_any will be bound to const auto_any_base |
268 | // references, but we still want to be able to mutate the stored |
269 | // data, so declare it as mutable. |
270 | mutable T item; |
271 | }; |
272 | |
273 | typedef auto_any_base const &auto_any_t; |
274 | |
275 | template<typename T, typename C> |
276 | inline BOOST_DEDUCED_TYPENAME boost::mpl::if_<C, T const, T>::type &auto_any_cast(auto_any_t a) |
277 | { |
278 | return static_cast<auto_any<T> const &>(a).item; |
279 | } |
280 | |
281 | typedef boost::mpl::true_ const_; |
282 | |
283 | /////////////////////////////////////////////////////////////////////////////// |
284 | // type2type |
285 | // |
286 | template<typename T, typename C = boost::mpl::false_> |
287 | struct type2type |
288 | : boost::mpl::if_<C, T const, T> |
289 | { |
290 | }; |
291 | |
292 | template<typename T> |
293 | struct wrap_cstr |
294 | { |
295 | typedef T type; |
296 | }; |
297 | |
298 | template<> |
299 | struct wrap_cstr<char *> |
300 | { |
301 | typedef wrap_cstr<char *> type; |
302 | typedef char *iterator; |
303 | typedef char *const_iterator; |
304 | }; |
305 | |
306 | template<> |
307 | struct wrap_cstr<char const *> |
308 | { |
309 | typedef wrap_cstr<char const *> type; |
310 | typedef char const *iterator; |
311 | typedef char const *const_iterator; |
312 | }; |
313 | |
314 | template<> |
315 | struct wrap_cstr<wchar_t *> |
316 | { |
317 | typedef wrap_cstr<wchar_t *> type; |
318 | typedef wchar_t *iterator; |
319 | typedef wchar_t *const_iterator; |
320 | }; |
321 | |
322 | template<> |
323 | struct wrap_cstr<wchar_t const *> |
324 | { |
325 | typedef wrap_cstr<wchar_t const *> type; |
326 | typedef wchar_t const *iterator; |
327 | typedef wchar_t const *const_iterator; |
328 | }; |
329 | |
330 | template<typename T> |
331 | struct is_char_array |
332 | : mpl::and_< |
333 | is_array<T> |
334 | , mpl::or_< |
335 | is_convertible<T, char const *> |
336 | , is_convertible<T, wchar_t const *> |
337 | > |
338 | > |
339 | {}; |
340 | |
341 | template<typename T, typename C = boost::mpl::false_> |
342 | struct foreach_iterator |
343 | { |
344 | // **** READ THIS IF YOUR COMPILE BREAKS HERE **** |
345 | // |
346 | // There is an ambiguity about how to iterate over arrays of char and wchar_t. |
347 | // Should the last array element be treated as a null terminator to be skipped, or |
348 | // is it just like any other element in the array? To fix the problem, you must |
349 | // say which behavior you want. |
350 | // |
351 | // To treat the container as a null-terminated string, merely cast it to a |
352 | // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ... |
353 | // |
354 | // To treat the container as an array, use boost::as_array() in <boost/range/as_array.hpp>, |
355 | // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ... |
356 | BOOST_MPL_ASSERT_MSG( (!is_char_array<T>::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T&) ); |
357 | |
358 | // If the type is a pointer to a null terminated string (as opposed |
359 | // to an array type), there is no ambiguity. |
360 | typedef BOOST_DEDUCED_TYPENAME wrap_cstr<T>::type container; |
361 | |
362 | typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< |
363 | C |
364 | , range_const_iterator<container> |
365 | , range_mutable_iterator<container> |
366 | >::type type; |
367 | }; |
368 | |
369 | |
370 | template<typename T, typename C = boost::mpl::false_> |
371 | struct foreach_reverse_iterator |
372 | { |
373 | // **** READ THIS IF YOUR COMPILE BREAKS HERE **** |
374 | // |
375 | // There is an ambiguity about how to iterate over arrays of char and wchar_t. |
376 | // Should the last array element be treated as a null terminator to be skipped, or |
377 | // is it just like any other element in the array? To fix the problem, you must |
378 | // say which behavior you want. |
379 | // |
380 | // To treat the container as a null-terminated string, merely cast it to a |
381 | // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ... |
382 | // |
383 | // To treat the container as an array, use boost::as_array() in <boost/range/as_array.hpp>, |
384 | // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ... |
385 | BOOST_MPL_ASSERT_MSG( (!is_char_array<T>::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T&) ); |
386 | |
387 | // If the type is a pointer to a null terminated string (as opposed |
388 | // to an array type), there is no ambiguity. |
389 | typedef BOOST_DEDUCED_TYPENAME wrap_cstr<T>::type container; |
390 | |
391 | typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< |
392 | C |
393 | , range_reverse_iterator<container const> |
394 | , range_reverse_iterator<container> |
395 | >::type type; |
396 | }; |
397 | |
398 | template<typename T, typename C = boost::mpl::false_> |
399 | struct foreach_reference |
400 | : iterator_reference<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> |
401 | { |
402 | }; |
403 | |
404 | /////////////////////////////////////////////////////////////////////////////// |
405 | // encode_type |
406 | // |
407 | template<typename T> |
408 | inline type2type<T> *encode_type(T &, boost::false_type*) { return 0; } |
409 | |
410 | template<typename T> |
411 | inline type2type<T, const_> *encode_type(T const &, boost::true_type*) { return 0; } |
412 | |
413 | template<typename T> |
414 | inline type2type<T> *encode_type(T &, boost::mpl::false_*) { return 0; } |
415 | |
416 | template<typename T> |
417 | inline type2type<T, const_> *encode_type(T const &, boost::mpl::true_*) { return 0; } |
418 | |
419 | /////////////////////////////////////////////////////////////////////////////// |
420 | // set_false |
421 | // |
422 | inline bool set_false(bool &b) |
423 | { |
424 | b = false; |
425 | return false; |
426 | } |
427 | |
428 | /////////////////////////////////////////////////////////////////////////////// |
429 | // to_ptr |
430 | // |
431 | template<typename T> |
432 | inline T *&to_ptr(T const &) |
433 | { |
434 | static T *t = 0; |
435 | return t; |
436 | } |
437 | |
438 | // Borland needs a little extra help with arrays |
439 | #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
440 | template<typename T,std::size_t N> |
441 | inline T (*&to_ptr(T (&)[N]))[N] |
442 | { |
443 | static T (*t)[N] = 0; |
444 | return t; |
445 | } |
446 | |
447 | /////////////////////////////////////////////////////////////////////////////// |
448 | // derefof |
449 | // |
450 | template<typename T> |
451 | inline T &derefof(T *t) |
452 | { |
453 | // This is a work-around for a compiler bug in Borland. If T* is a pointer to array type U(*)[N], |
454 | // then dereferencing it results in a U* instead of U(&)[N]. The cast forces the issue. |
455 | return reinterpret_cast<T &>( |
456 | *const_cast<char *>( |
457 | reinterpret_cast<char const volatile *>(t) |
458 | ) |
459 | ); |
460 | } |
461 | |
462 | # define BOOST_FOREACH_DEREFOF(T) boost::foreach_detail_::derefof(*T) |
463 | #else |
464 | # define BOOST_FOREACH_DEREFOF(T) (*T) |
465 | #endif |
466 | |
467 | #if defined(BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION) \ |
468 | && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
469 | /////////////////////////////////////////////////////////////////////////////// |
470 | // Rvalue references makes it drop-dead simple to detect at compile time |
471 | // whether an expression is an rvalue. |
472 | /////////////////////////////////////////////////////////////////////////////// |
473 | |
474 | # define BOOST_FOREACH_IS_RVALUE(COL) \ |
475 | boost::foreach_detail_::is_rvalue_((COL), 0) |
476 | |
477 | #elif defined(BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION) \ |
478 | && defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
479 | /////////////////////////////////////////////////////////////////////////////// |
480 | // Detect at compile-time whether an expression yields an rvalue or |
481 | // an lvalue. This is rather non-standard, but some popular compilers |
482 | // accept it. |
483 | /////////////////////////////////////////////////////////////////////////////// |
484 | |
485 | /////////////////////////////////////////////////////////////////////////////// |
486 | // rvalue_probe |
487 | // |
488 | template<typename T> |
489 | struct rvalue_probe |
490 | { |
491 | struct private_type_ {}; |
492 | // can't ever return an array by value |
493 | typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< |
494 | boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T |
495 | >::type value_type; |
496 | operator value_type() { return *reinterpret_cast<value_type *>(this); } // never called |
497 | operator T &() const { return *reinterpret_cast<T *>(const_cast<rvalue_probe *>(this)); } // never called |
498 | }; |
499 | |
500 | template<typename T> |
501 | rvalue_probe<T> const make_probe(T const &) |
502 | { |
503 | return rvalue_probe<T>(); |
504 | } |
505 | |
506 | # define BOOST_FOREACH_IS_RVALUE(COL) \ |
507 | boost::foreach_detail_::and_( \ |
508 | boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(COL)) \ |
509 | , (true ? 0 : boost::foreach_detail_::is_rvalue_( \ |
510 | (true ? boost::foreach_detail_::make_probe(COL) : (COL)), 0))) |
511 | |
512 | #elif defined(BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION) |
513 | /////////////////////////////////////////////////////////////////////////////// |
514 | // Detect at run-time whether an expression yields an rvalue |
515 | // or an lvalue. This is 100% standard C++, but not all compilers |
516 | // accept it. Also, it causes FOREACH to break when used with non- |
517 | // copyable collection types. |
518 | /////////////////////////////////////////////////////////////////////////////// |
519 | |
520 | /////////////////////////////////////////////////////////////////////////////// |
521 | // rvalue_probe |
522 | // |
523 | template<typename T> |
524 | struct rvalue_probe |
525 | { |
526 | rvalue_probe(T &t, bool &b) |
527 | : value(t) |
528 | , is_rvalue(b) |
529 | { |
530 | } |
531 | |
532 | struct private_type_ {}; |
533 | // can't ever return an array or an abstract type by value |
534 | #ifdef BOOST_NO_IS_ABSTRACT |
535 | typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< |
536 | boost::is_array<T>, private_type_, T |
537 | >::type value_type; |
538 | #else |
539 | typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< |
540 | boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T |
541 | >::type value_type; |
542 | #endif |
543 | |
544 | operator value_type() |
545 | { |
546 | this->is_rvalue = true; |
547 | return this->value; |
548 | } |
549 | |
550 | operator T &() const |
551 | { |
552 | return this->value; |
553 | } |
554 | |
555 | private: |
556 | T &value; |
557 | bool &is_rvalue; |
558 | }; |
559 | |
560 | template<typename T> |
561 | rvalue_probe<T> make_probe(T &t, bool &b) { return rvalue_probe<T>(t, b); } |
562 | |
563 | template<typename T> |
564 | rvalue_probe<T const> make_probe(T const &t, bool &b) { return rvalue_probe<T const>(t, b); } |
565 | |
566 | /////////////////////////////////////////////////////////////////////////////// |
567 | // simple_variant |
568 | // holds either a T or a T const* |
569 | template<typename T> |
570 | struct simple_variant |
571 | { |
572 | simple_variant(T const *t) |
573 | : is_rvalue(false) |
574 | { |
575 | *static_cast<T const **>(this->data.address()) = t; |
576 | } |
577 | |
578 | simple_variant(T const &t) |
579 | : is_rvalue(true) |
580 | { |
581 | ::new(this->data.address()) T(t); |
582 | } |
583 | |
584 | simple_variant(simple_variant const &that) |
585 | : is_rvalue(that.is_rvalue) |
586 | { |
587 | if(this->is_rvalue) |
588 | ::new(this->data.address()) T(*that.get()); |
589 | else |
590 | *static_cast<T const **>(this->data.address()) = that.get(); |
591 | } |
592 | |
593 | ~simple_variant() |
594 | { |
595 | if(this->is_rvalue) |
596 | this->get()->~T(); |
597 | } |
598 | |
599 | T const *get() const |
600 | { |
601 | if(this->is_rvalue) |
602 | return static_cast<T const *>(this->data.address()); |
603 | else |
604 | return *static_cast<T const * const *>(this->data.address()); |
605 | } |
606 | |
607 | private: |
608 | enum size_type { size = sizeof(T) > sizeof(T*) ? sizeof(T) : sizeof(T*) }; |
609 | simple_variant &operator =(simple_variant const &); |
610 | bool const is_rvalue; |
611 | aligned_storage<size> data; |
612 | }; |
613 | |
614 | // If the collection is an array or is noncopyable, it must be an lvalue. |
615 | // If the collection is a lightweight proxy, treat it as an rvalue |
616 | // BUGBUG what about a noncopyable proxy? |
617 | template<typename LValue, typename IsProxy> |
618 | inline BOOST_DEDUCED_TYPENAME boost::enable_if<boost::mpl::or_<LValue, IsProxy>, IsProxy>::type * |
619 | should_copy_impl(LValue *, IsProxy *, bool *) |
620 | { |
621 | return 0; |
622 | } |
623 | |
624 | // Otherwise, we must determine at runtime whether it's an lvalue or rvalue |
625 | inline bool * |
626 | should_copy_impl(boost::mpl::false_ *, boost::mpl::false_ *, bool *is_rvalue) |
627 | { |
628 | return is_rvalue; |
629 | } |
630 | |
631 | #endif |
632 | |
633 | /////////////////////////////////////////////////////////////////////////////// |
634 | // contain |
635 | // |
636 | template<typename T> |
637 | inline auto_any<T> contain(T const &t, boost::mpl::true_ *) // rvalue |
638 | { |
639 | return auto_any<T>(t); |
640 | } |
641 | |
642 | template<typename T> |
643 | inline auto_any<T *> contain(T &t, boost::mpl::false_ *) // lvalue |
644 | { |
645 | // Cannot seem to get sunpro to handle addressof() with array types. |
646 | #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) |
647 | return auto_any<T *>(&t); |
648 | #else |
649 | return auto_any<T *>(boost::addressof(t)); |
650 | #endif |
651 | } |
652 | |
653 | #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION |
654 | template<typename T> |
655 | inline auto_any<simple_variant<T> > |
656 | contain(T const &t, bool *rvalue) |
657 | { |
658 | return auto_any<simple_variant<T> >(*rvalue ? simple_variant<T>(t) : simple_variant<T>(&t)); |
659 | } |
660 | #endif |
661 | |
662 | ///////////////////////////////////////////////////////////////////////////// |
663 | // begin |
664 | // |
665 | template<typename T, typename C> |
666 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> |
667 | begin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue |
668 | { |
669 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( |
670 | boost::begin(auto_any_cast<T, C>(col))); |
671 | } |
672 | |
673 | template<typename T, typename C> |
674 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> |
675 | begin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue |
676 | { |
677 | typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; |
678 | typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; |
679 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( |
680 | iterator(boost::begin(BOOST_FOREACH_DEREFOF((auto_any_cast<type *, boost::mpl::false_>(col)))))); |
681 | } |
682 | |
683 | #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION |
684 | template<typename T> |
685 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> |
686 | begin(auto_any_t col, type2type<T, const_> *, bool *) |
687 | { |
688 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type>( |
689 | boost::begin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); |
690 | } |
691 | #endif |
692 | |
693 | #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING |
694 | template<typename T, typename C> |
695 | inline auto_any<T *> |
696 | begin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings |
697 | { |
698 | return auto_any<T *>(auto_any_cast<T *, boost::mpl::false_>(col)); |
699 | } |
700 | #endif |
701 | |
702 | /////////////////////////////////////////////////////////////////////////////// |
703 | // end |
704 | // |
705 | template<typename T, typename C> |
706 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> |
707 | end(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue |
708 | { |
709 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( |
710 | boost::end(auto_any_cast<T, C>(col))); |
711 | } |
712 | |
713 | template<typename T, typename C> |
714 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> |
715 | end(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue |
716 | { |
717 | typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; |
718 | typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; |
719 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>( |
720 | iterator(boost::end(BOOST_FOREACH_DEREFOF((auto_any_cast<type *, boost::mpl::false_>(col)))))); |
721 | } |
722 | |
723 | #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION |
724 | template<typename T> |
725 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> |
726 | end(auto_any_t col, type2type<T, const_> *, bool *) |
727 | { |
728 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type>( |
729 | boost::end(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); |
730 | } |
731 | #endif |
732 | |
733 | #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING |
734 | template<typename T, typename C> |
735 | inline auto_any<int> |
736 | end(auto_any_t, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings |
737 | { |
738 | return auto_any<int>(0); // not used |
739 | } |
740 | #endif |
741 | |
742 | /////////////////////////////////////////////////////////////////////////////// |
743 | // done |
744 | // |
745 | template<typename T, typename C> |
746 | inline bool done(auto_any_t cur, auto_any_t end, type2type<T, C> *) |
747 | { |
748 | typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; |
749 | return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end); |
750 | } |
751 | |
752 | #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING |
753 | template<typename T, typename C> |
754 | inline bool done(auto_any_t cur, auto_any_t, type2type<T *, C> *) // null-terminated C-style strings |
755 | { |
756 | return ! *auto_any_cast<T *, boost::mpl::false_>(cur); |
757 | } |
758 | #endif |
759 | |
760 | /////////////////////////////////////////////////////////////////////////////// |
761 | // next |
762 | // |
763 | template<typename T, typename C> |
764 | inline void next(auto_any_t cur, type2type<T, C> *) |
765 | { |
766 | typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; |
767 | ++auto_any_cast<iter_t, boost::mpl::false_>(cur); |
768 | } |
769 | |
770 | /////////////////////////////////////////////////////////////////////////////// |
771 | // deref |
772 | // |
773 | template<typename T, typename C> |
774 | inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type |
775 | deref(auto_any_t cur, type2type<T, C> *) |
776 | { |
777 | typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; |
778 | return *auto_any_cast<iter_t, boost::mpl::false_>(cur); |
779 | } |
780 | |
781 | ///////////////////////////////////////////////////////////////////////////// |
782 | // rbegin |
783 | // |
784 | template<typename T, typename C> |
785 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> |
786 | rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue |
787 | { |
788 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( |
789 | boost::rbegin(auto_any_cast<T, C>(col))); |
790 | } |
791 | |
792 | template<typename T, typename C> |
793 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> |
794 | rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue |
795 | { |
796 | typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; |
797 | typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; |
798 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( |
799 | iterator(boost::rbegin(BOOST_FOREACH_DEREFOF((auto_any_cast<type *, boost::mpl::false_>(col)))))); |
800 | } |
801 | |
802 | #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION |
803 | template<typename T> |
804 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> |
805 | rbegin(auto_any_t col, type2type<T, const_> *, bool *) |
806 | { |
807 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type>( |
808 | boost::rbegin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); |
809 | } |
810 | #endif |
811 | |
812 | #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING |
813 | template<typename T, typename C> |
814 | inline auto_any<reverse_iterator<T *> > |
815 | rbegin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings |
816 | { |
817 | T *p = auto_any_cast<T *, boost::mpl::false_>(col); |
818 | while(0 != *p) |
819 | ++p; |
820 | return auto_any<reverse_iterator<T *> >(reverse_iterator<T *>(p)); |
821 | } |
822 | #endif |
823 | |
824 | /////////////////////////////////////////////////////////////////////////////// |
825 | // rend |
826 | // |
827 | template<typename T, typename C> |
828 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> |
829 | rend(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue |
830 | { |
831 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( |
832 | boost::rend(auto_any_cast<T, C>(col))); |
833 | } |
834 | |
835 | template<typename T, typename C> |
836 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> |
837 | rend(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue |
838 | { |
839 | typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; |
840 | typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; |
841 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type>( |
842 | iterator(boost::rend(BOOST_FOREACH_DEREFOF((auto_any_cast<type *, boost::mpl::false_>(col)))))); |
843 | } |
844 | |
845 | #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION |
846 | template<typename T> |
847 | inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> |
848 | rend(auto_any_t col, type2type<T, const_> *, bool *) |
849 | { |
850 | return auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type>( |
851 | boost::rend(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get())); |
852 | } |
853 | #endif |
854 | |
855 | #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING |
856 | template<typename T, typename C> |
857 | inline auto_any<reverse_iterator<T *> > |
858 | rend(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings |
859 | { |
860 | return auto_any<reverse_iterator<T *> >( |
861 | reverse_iterator<T *>(auto_any_cast<T *, boost::mpl::false_>(col))); |
862 | } |
863 | #endif |
864 | |
865 | /////////////////////////////////////////////////////////////////////////////// |
866 | // rdone |
867 | // |
868 | template<typename T, typename C> |
869 | inline bool rdone(auto_any_t cur, auto_any_t end, type2type<T, C> *) |
870 | { |
871 | typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; |
872 | return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end); |
873 | } |
874 | |
875 | /////////////////////////////////////////////////////////////////////////////// |
876 | // rnext |
877 | // |
878 | template<typename T, typename C> |
879 | inline void rnext(auto_any_t cur, type2type<T, C> *) |
880 | { |
881 | typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; |
882 | ++auto_any_cast<iter_t, boost::mpl::false_>(cur); |
883 | } |
884 | |
885 | /////////////////////////////////////////////////////////////////////////////// |
886 | // rderef |
887 | // |
888 | template<typename T, typename C> |
889 | inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type |
890 | rderef(auto_any_t cur, type2type<T, C> *) |
891 | { |
892 | typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; |
893 | return *auto_any_cast<iter_t, boost::mpl::false_>(cur); |
894 | } |
895 | |
896 | } // namespace foreach_detail_ |
897 | } // namespace boost |
898 | |
899 | // Suppress a bogus code analysis warning on vc8+ |
900 | #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) |
901 | # define BOOST_FOREACH_SUPPRESS_WARNINGS() __pragma(warning(suppress:6001)) |
902 | #else |
903 | # define BOOST_FOREACH_SUPPRESS_WARNINGS() |
904 | #endif |
905 | |
906 | /////////////////////////////////////////////////////////////////////////////// |
907 | // Define a macro for giving hidden variables a unique name. Not strictly |
908 | // needed, but eliminates some warnings on some compilers. |
909 | #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500)) |
910 | // With some versions of MSVC, use of __LINE__ to create unique identifiers |
911 | // can fail when the Edit-and-Continue debug flag is used. |
912 | # define BOOST_FOREACH_ID(x) x |
913 | #else |
914 | # define BOOST_FOREACH_ID(x) BOOST_PP_CAT(x, __LINE__) |
915 | #endif |
916 | |
917 | // A sneaky way to get the type of the collection without evaluating the expression |
918 | #define BOOST_FOREACH_TYPEOF(COL) \ |
919 | (true ? BOOST_FOREACH_NULL : boost::foreach_detail_::encode_type(COL, boost::foreach_detail_::is_const_(COL))) |
920 | |
921 | // returns true_* if the type is noncopyable |
922 | #define BOOST_FOREACH_IS_NONCOPYABLE(COL) \ |
923 | boost_foreach_is_noncopyable( \ |
924 | boost::foreach_detail_::to_ptr(COL) \ |
925 | , boost_foreach_argument_dependent_lookup_hack_value) |
926 | |
927 | // returns true_* if the type is a lightweight proxy (and is not noncopyable) |
928 | #define BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL) \ |
929 | boost::foreach_detail_::and_( \ |
930 | boost::foreach_detail_::not_(BOOST_FOREACH_IS_NONCOPYABLE(COL)) \ |
931 | , boost_foreach_is_lightweight_proxy( \ |
932 | boost::foreach_detail_::to_ptr(COL) \ |
933 | , boost_foreach_argument_dependent_lookup_hack_value)) |
934 | |
935 | #if defined(BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION) |
936 | /////////////////////////////////////////////////////////////////////////////// |
937 | // R-values and const R-values supported here with zero runtime overhead |
938 | /////////////////////////////////////////////////////////////////////////////// |
939 | |
940 | // No variable is needed to track the rvalue-ness of the collection expression |
941 | # define BOOST_FOREACH_PREAMBLE() \ |
942 | BOOST_FOREACH_SUPPRESS_WARNINGS() |
943 | |
944 | // Evaluate the collection expression |
945 | # define BOOST_FOREACH_EVALUATE(COL) \ |
946 | (COL) |
947 | |
948 | # define BOOST_FOREACH_SHOULD_COPY(COL) \ |
949 | (true ? BOOST_FOREACH_NULL : boost::foreach_detail_::or_( \ |
950 | BOOST_FOREACH_IS_RVALUE(COL) \ |
951 | , BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL))) |
952 | |
953 | #elif defined(BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION) |
954 | /////////////////////////////////////////////////////////////////////////////// |
955 | // R-values and const R-values supported here |
956 | /////////////////////////////////////////////////////////////////////////////// |
957 | |
958 | // Declare a variable to track the rvalue-ness of the collection expression |
959 | # define BOOST_FOREACH_PREAMBLE() \ |
960 | BOOST_FOREACH_SUPPRESS_WARNINGS() \ |
961 | if (bool BOOST_FOREACH_ID(_foreach_is_rvalue) = false) {} else |
962 | |
963 | // Evaluate the collection expression, and detect if it is an lvalue or and rvalue |
964 | # define BOOST_FOREACH_EVALUATE(COL) \ |
965 | (true ? boost::foreach_detail_::make_probe((COL), BOOST_FOREACH_ID(_foreach_is_rvalue)) : (COL)) |
966 | |
967 | // The rvalue/lvalue-ness of the collection expression is determined dynamically, unless |
968 | // the type is an array or is noncopyable or is non-const, in which case we know it's an lvalue. |
969 | // If the type happens to be a lightweight proxy, always make a copy. |
970 | # define BOOST_FOREACH_SHOULD_COPY(COL) \ |
971 | (boost::foreach_detail_::should_copy_impl( \ |
972 | true ? BOOST_FOREACH_NULL : boost::foreach_detail_::or_( \ |
973 | boost::foreach_detail_::is_array_(COL) \ |
974 | , BOOST_FOREACH_IS_NONCOPYABLE(COL) \ |
975 | , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(COL))) \ |
976 | , true ? BOOST_FOREACH_NULL : BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL) \ |
977 | , &BOOST_FOREACH_ID(_foreach_is_rvalue))) |
978 | |
979 | #elif !defined(BOOST_FOREACH_NO_RVALUE_DETECTION) |
980 | /////////////////////////////////////////////////////////////////////////////// |
981 | // R-values supported here, const R-values NOT supported here |
982 | /////////////////////////////////////////////////////////////////////////////// |
983 | |
984 | // No variable is needed to track the rvalue-ness of the collection expression |
985 | # define BOOST_FOREACH_PREAMBLE() \ |
986 | BOOST_FOREACH_SUPPRESS_WARNINGS() |
987 | |
988 | // Evaluate the collection expression |
989 | # define BOOST_FOREACH_EVALUATE(COL) \ |
990 | (COL) |
991 | |
992 | // Determine whether the collection expression is an lvalue or an rvalue. |
993 | // NOTE: this gets the answer wrong for const rvalues. |
994 | # define BOOST_FOREACH_SHOULD_COPY(COL) \ |
995 | (true ? BOOST_FOREACH_NULL : boost::foreach_detail_::or_( \ |
996 | boost::foreach_detail_::is_rvalue_((COL), 0) \ |
997 | , BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL))) |
998 | |
999 | #else |
1000 | /////////////////////////////////////////////////////////////////////////////// |
1001 | // R-values NOT supported here |
1002 | /////////////////////////////////////////////////////////////////////////////// |
1003 | |
1004 | // No variable is needed to track the rvalue-ness of the collection expression |
1005 | # define BOOST_FOREACH_PREAMBLE() \ |
1006 | BOOST_FOREACH_SUPPRESS_WARNINGS() |
1007 | |
1008 | // Evaluate the collection expression |
1009 | # define BOOST_FOREACH_EVALUATE(COL) \ |
1010 | (COL) |
1011 | |
1012 | // Can't use rvalues with BOOST_FOREACH (unless they are lightweight proxies) |
1013 | # define BOOST_FOREACH_SHOULD_COPY(COL) \ |
1014 | (true ? BOOST_FOREACH_NULL : BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL)) |
1015 | |
1016 | #endif |
1017 | |
1018 | #define BOOST_FOREACH_CONTAIN(COL) \ |
1019 | boost::foreach_detail_::contain( \ |
1020 | BOOST_FOREACH_EVALUATE(COL) \ |
1021 | , BOOST_FOREACH_SHOULD_COPY(COL)) |
1022 | |
1023 | #define BOOST_FOREACH_BEGIN(COL) \ |
1024 | boost::foreach_detail_::begin( \ |
1025 | BOOST_FOREACH_ID(_foreach_col) \ |
1026 | , BOOST_FOREACH_TYPEOF(COL) \ |
1027 | , BOOST_FOREACH_SHOULD_COPY(COL)) |
1028 | |
1029 | #define BOOST_FOREACH_END(COL) \ |
1030 | boost::foreach_detail_::end( \ |
1031 | BOOST_FOREACH_ID(_foreach_col) \ |
1032 | , BOOST_FOREACH_TYPEOF(COL) \ |
1033 | , BOOST_FOREACH_SHOULD_COPY(COL)) |
1034 | |
1035 | #define BOOST_FOREACH_DONE(COL) \ |
1036 | boost::foreach_detail_::done( \ |
1037 | BOOST_FOREACH_ID(_foreach_cur) \ |
1038 | , BOOST_FOREACH_ID(_foreach_end) \ |
1039 | , BOOST_FOREACH_TYPEOF(COL)) |
1040 | |
1041 | #define BOOST_FOREACH_NEXT(COL) \ |
1042 | boost::foreach_detail_::next( \ |
1043 | BOOST_FOREACH_ID(_foreach_cur) \ |
1044 | , BOOST_FOREACH_TYPEOF(COL)) |
1045 | |
1046 | #define BOOST_FOREACH_DEREF(COL) \ |
1047 | boost::foreach_detail_::deref( \ |
1048 | BOOST_FOREACH_ID(_foreach_cur) \ |
1049 | , BOOST_FOREACH_TYPEOF(COL)) |
1050 | |
1051 | #define BOOST_FOREACH_RBEGIN(COL) \ |
1052 | boost::foreach_detail_::rbegin( \ |
1053 | BOOST_FOREACH_ID(_foreach_col) \ |
1054 | , BOOST_FOREACH_TYPEOF(COL) \ |
1055 | , BOOST_FOREACH_SHOULD_COPY(COL)) |
1056 | |
1057 | #define BOOST_FOREACH_REND(COL) \ |
1058 | boost::foreach_detail_::rend( \ |
1059 | BOOST_FOREACH_ID(_foreach_col) \ |
1060 | , BOOST_FOREACH_TYPEOF(COL) \ |
1061 | , BOOST_FOREACH_SHOULD_COPY(COL)) |
1062 | |
1063 | #define BOOST_FOREACH_RDONE(COL) \ |
1064 | boost::foreach_detail_::rdone( \ |
1065 | BOOST_FOREACH_ID(_foreach_cur) \ |
1066 | , BOOST_FOREACH_ID(_foreach_end) \ |
1067 | , BOOST_FOREACH_TYPEOF(COL)) |
1068 | |
1069 | #define BOOST_FOREACH_RNEXT(COL) \ |
1070 | boost::foreach_detail_::rnext( \ |
1071 | BOOST_FOREACH_ID(_foreach_cur) \ |
1072 | , BOOST_FOREACH_TYPEOF(COL)) |
1073 | |
1074 | #define BOOST_FOREACH_RDEREF(COL) \ |
1075 | boost::foreach_detail_::rderef( \ |
1076 | BOOST_FOREACH_ID(_foreach_cur) \ |
1077 | , BOOST_FOREACH_TYPEOF(COL)) |
1078 | |
1079 | /////////////////////////////////////////////////////////////////////////////// |
1080 | // BOOST_FOREACH |
1081 | // |
1082 | // For iterating over collections. Collections can be |
1083 | // arrays, null-terminated strings, or STL containers. |
1084 | // The loop variable can be a value or reference. For |
1085 | // example: |
1086 | // |
1087 | // std::list<int> int_list(/*stuff*/); |
1088 | // BOOST_FOREACH(int &i, int_list) |
1089 | // { |
1090 | // /* |
1091 | // * loop body goes here. |
1092 | // * i is a reference to the int in int_list. |
1093 | // */ |
1094 | // } |
1095 | // |
1096 | // Alternately, you can declare the loop variable first, |
1097 | // so you can access it after the loop finishes. Obviously, |
1098 | // if you do it this way, then the loop variable cannot be |
1099 | // a reference. |
1100 | // |
1101 | // int i; |
1102 | // BOOST_FOREACH(i, int_list) |
1103 | // { ... } |
1104 | // |
1105 | #define BOOST_FOREACH(VAR, COL) \ |
1106 | BOOST_FOREACH_PREAMBLE() \ |
1107 | if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \ |
1108 | if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \ |
1109 | if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else \ |
1110 | for (bool BOOST_FOREACH_ID(_foreach_continue) = true; \ |
1111 | BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL); \ |
1112 | BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \ |
1113 | if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \ |
1114 | for (VAR = BOOST_FOREACH_DEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true) |
1115 | |
1116 | /////////////////////////////////////////////////////////////////////////////// |
1117 | // BOOST_REVERSE_FOREACH |
1118 | // |
1119 | // For iterating over collections in reverse order. In |
1120 | // all other respects, BOOST_REVERSE_FOREACH is like |
1121 | // BOOST_FOREACH. |
1122 | // |
1123 | #define BOOST_REVERSE_FOREACH(VAR, COL) \ |
1124 | BOOST_FOREACH_PREAMBLE() \ |
1125 | if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \ |
1126 | if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_RBEGIN(COL)) {} else \ |
1127 | if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_REND(COL)) {} else \ |
1128 | for (bool BOOST_FOREACH_ID(_foreach_continue) = true; \ |
1129 | BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_RDONE(COL); \ |
1130 | BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_RNEXT(COL) : (void)0) \ |
1131 | if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \ |
1132 | for (VAR = BOOST_FOREACH_RDEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true) |
1133 | |
1134 | #endif |
1135 | |