Line data Source code
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(__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(__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 195331 : operator bool() const
254 : {
255 195331 : return false;
256 : }
257 : };
258 :
259 : template<typename T>
260 0 : struct auto_any : auto_any_base
261 : {
262 195331 : explicit auto_any(T const &t)
263 1075 : : 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 1367097 : inline BOOST_DEDUCED_TYPENAME boost::mpl::if_<C, T const, T>::type &auto_any_cast(auto_any_t a)
277 : {
278 1166108 : 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 309526 : inline bool set_false(bool &b)
423 : {
424 309526 : b = false;
425 309526 : 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(__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 2147 : inline auto_any<T> contain(T const &t, boost::mpl::true_ *) // rvalue
638 : {
639 0 : return auto_any<T>(t);
640 : }
641 :
642 : template<typename T>
643 193184 : 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 2137 : 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 2147 : 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 2147 : 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 193184 : 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 193184 : 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 2147 : 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 2147 : 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 193184 : 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 193184 : 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 536630 : 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 536630 : 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 341299 : inline void next(auto_any_t cur, type2type<T, C> *)
765 : {
766 : typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t;
767 341299 : ++auto_any_cast<iter_t, boost::mpl::false_>(cur);
768 341299 : }
769 :
770 : ///////////////////////////////////////////////////////////////////////////////
771 : // deref
772 : //
773 : template<typename T, typename C>
774 : inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type
775 309526 : deref(auto_any_t cur, type2type<T, C> *)
776 : {
777 : typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t;
778 395140 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : ++auto_any_cast<iter_t, boost::mpl::false_>(cur);
883 0 : }
884 :
885 : ///////////////////////////////////////////////////////////////////////////////
886 : // rderef
887 : //
888 : template<typename T, typename C>
889 : inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type
890 0 : rderef(auto_any_t cur, type2type<T, C> *)
891 : {
892 : typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t;
893 0 : 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
|