LCOV - code coverage report
Current view: top level - usr/include/boost - foreach.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 27 44 61.4 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14