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