source: XIOS/dev/dev_olga/src/extern/boost/include/boost/foreach.hpp @ 1022

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