PageRenderTime 151ms CodeModel.GetById 67ms app.highlight 73ms RepoModel.GetById 1ms app.codeStats 0ms

/src/contrib/boost/foreach.hpp

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