Ticket #3998: foreach_separate_headers_for_extensibility.patch
File foreach_separate_headers_for_extensibility.patch, 89.1 KB (added by , 13 years ago) |
---|
-
boost/foreach.hpp
23 23 # pragma once 24 24 #endif 25 25 26 #include <boost/foreach_extensibility.hpp> 27 26 28 #include <cstddef> 27 29 #include <utility> // for std::pair 28 30 … … 77 79 #include <boost/type_traits/is_array.hpp> 78 80 #include <boost/type_traits/is_const.hpp> 79 81 #include <boost/type_traits/is_abstract.hpp> 80 #include <boost/type_traits/is_base_and_derived.hpp>81 82 #include <boost/iterator/iterator_traits.hpp> 82 83 #include <boost/utility/addressof.hpp> 83 84 … … 121 122 // 122 123 typedef boost_foreach_argument_dependent_lookup_hack tag; 123 124 124 ///////////////////////////////////////////////////////////////////////////////125 // boost::foreach::is_lightweight_proxy126 // 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_proxy130 : boost::mpl::false_131 {132 };133 134 ///////////////////////////////////////////////////////////////////////////////135 // boost::foreach::is_noncopyable136 // 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_noncopyable140 #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 #else150 : boost::mpl::false_151 #endif152 {153 };154 155 125 } // namespace foreach 156 126 157 127 } // namespace boost -
boost/foreach_extensibility.hpp
1 1 /////////////////////////////////////////////////////////////////////////////// 2 // foreach .hpp header file2 // foreach_extensibility.hpp header file 3 3 // 4 4 // Copyright 2004 Eric Niebler. 5 5 // Distributed under the Boost Software License, Version 1.0. (See 6 6 // accompanying file LICENSE_1_0.txt or copy at 7 7 // http://www.boost.org/LICENSE_1_0.txt) 8 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 detect13 // const-qualified rvalues at compile time on VC7.1+14 // Russell Hind - For help porting to Borland15 // Alisdair Meredith - For help porting to Borland16 // Stefan Slapeta - For help porting to Intel17 // David Jenkins - For help finding a Microsoft Code Analysis bug18 9 19 #ifndef BOOST_FOREACH 10 #ifndef BOOST_FOREACH_EXTENSIBILITY_HPP_20100311 11 #define BOOST_FOREACH_EXTENSIBILITY_HPP_20100311 20 12 21 13 // MS compatible compilers support #pragma once 22 14 #if defined(_MSC_VER) && (_MSC_VER >= 1020) 23 15 # pragma once 24 16 #endif 25 17 26 #include <cstddef> 27 #include <utility> // for std::pair 18 #include <boost/foreach_extensibility_fwd.hpp> 28 19 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> 20 #include <boost/mpl/bool.hpp> 21 #include <boost/mpl/or.hpp> 70 22 #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 23 #include <boost/type_traits/is_abstract.hpp> 80 24 #include <boost/type_traits/is_base_and_derived.hpp> 81 #include <boost/iterator/iterator_traits.hpp>82 #include <boost/utility/addressof.hpp>83 25 84 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION85 # include <new>86 # include <boost/aligned_storage.hpp>87 # include <boost/utility/enable_if.hpp>88 # include <boost/type_traits/remove_const.hpp>89 #endif90 91 // This must be at global scope, hence the uglified name92 enum boost_foreach_argument_dependent_lookup_hack93 {94 boost_foreach_argument_dependent_lookup_hack_value95 };96 97 26 namespace boost 98 27 { 99 28 100 // forward declarations for iterator_range101 template<typename T>102 class iterator_range;103 104 // forward declarations for sub_range105 template<typename T>106 class sub_range;107 108 29 namespace foreach 109 30 { 110 ///////////////////////////////////////////////////////////////////////////////111 // in_range112 //113 31 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::tag121 //122 typedef boost_foreach_argument_dependent_lookup_hack tag;123 124 ///////////////////////////////////////////////////////////////////////////////125 // boost::foreach::is_lightweight_proxy126 // 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 32 struct is_lightweight_proxy 130 33 : boost::mpl::false_ 131 34 { 132 35 }; 133 36 134 ///////////////////////////////////////////////////////////////////////////////135 // boost::foreach::is_noncopyable136 // 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 37 template<typename T> 139 38 struct is_noncopyable 140 39 #if !defined(BOOST_BROKEN_IS_BASE_AND_DERIVED) && !defined(BOOST_NO_IS_ABSTRACT) … … 156 55 157 56 } // namespace boost 158 57 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::mpl::false_ *is_rvalue_(T &, int) { return 0; } 226 227 template<typename T> 228 inline boost::mpl::true_ *is_rvalue_(T const &, ...) { return 0; } 229 230 template<typename T> 231 inline boost::is_array<T> *is_array_(T const &) { return 0; } 232 233 template<typename T> 234 inline boost::is_const<T> *is_const_(T &) { return 0; } 235 236 #ifndef BOOST_FOREACH_NO_RVALUE_DETECTION 237 template<typename T> 238 inline boost::mpl::true_ *is_const_(T const &) { return 0; } 239 #endif 240 241 /////////////////////////////////////////////////////////////////////////////// 242 // auto_any_t/auto_any 243 // General utility for putting an object of any type into automatic storage 244 struct auto_any_base 245 { 246 // auto_any_base must evaluate to false in boolean context so that 247 // they can be declared in if() statements. 248 operator bool() const 249 { 250 return false; 251 } 252 }; 253 254 template<typename T> 255 struct auto_any : auto_any_base 256 { 257 auto_any(T const &t) 258 : item(t) 259 { 260 } 261 262 // temporaries of type auto_any will be bound to const auto_any_base 263 // references, but we still want to be able to mutate the stored 264 // data, so declare it as mutable. 265 mutable T item; 266 }; 267 268 typedef auto_any_base const &auto_any_t; 269 270 template<typename T, typename C> 271 inline BOOST_DEDUCED_TYPENAME boost::mpl::if_<C, T const, T>::type &auto_any_cast(auto_any_t a) 272 { 273 return static_cast<auto_any<T> const &>(a).item; 274 } 275 276 typedef boost::mpl::true_ const_; 277 278 /////////////////////////////////////////////////////////////////////////////// 279 // type2type 280 // 281 template<typename T, typename C = boost::mpl::false_> 282 struct type2type 283 : boost::mpl::if_<C, T const, T> 284 { 285 }; 286 287 template<typename T> 288 struct wrap_cstr 289 { 290 typedef T type; 291 }; 292 293 template<> 294 struct wrap_cstr<char *> 295 { 296 typedef wrap_cstr<char *> type; 297 typedef char *iterator; 298 typedef char *const_iterator; 299 }; 300 301 template<> 302 struct wrap_cstr<char const *> 303 { 304 typedef wrap_cstr<char const *> type; 305 typedef char const *iterator; 306 typedef char const *const_iterator; 307 }; 308 309 template<> 310 struct wrap_cstr<wchar_t *> 311 { 312 typedef wrap_cstr<wchar_t *> type; 313 typedef wchar_t *iterator; 314 typedef wchar_t *const_iterator; 315 }; 316 317 template<> 318 struct wrap_cstr<wchar_t const *> 319 { 320 typedef wrap_cstr<wchar_t const *> type; 321 typedef wchar_t const *iterator; 322 typedef wchar_t const *const_iterator; 323 }; 324 325 template<typename T> 326 struct is_char_array 327 : mpl::and_< 328 is_array<T> 329 , mpl::or_< 330 is_convertible<T, char const *> 331 , is_convertible<T, wchar_t const *> 332 > 333 > 334 {}; 335 336 template<typename T, typename C = boost::mpl::false_> 337 struct foreach_iterator 338 { 339 // **** READ THIS IF YOUR COMPILE BREAKS HERE **** 340 // 341 // There is an ambiguity about how to iterate over arrays of char and wchar_t. 342 // Should the last array element be treated as a null terminator to be skipped, or 343 // is it just like any other element in the array? To fix the problem, you must 344 // say which behavior you want. 345 // 346 // To treat the container as a null-terminated string, merely cast it to a 347 // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ... 348 // 349 // To treat the container as an array, use boost::as_array() in <boost/range/as_array.hpp>, 350 // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ... 351 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 352 BOOST_MPL_ASSERT_MSG( (!is_char_array<T>::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T&) ); 353 #endif 354 355 // If the type is a pointer to a null terminated string (as opposed 356 // to an array type), there is no ambiguity. 357 typedef BOOST_DEDUCED_TYPENAME wrap_cstr<T>::type container; 358 359 typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< 360 C 361 , range_const_iterator<container> 362 , range_mutable_iterator<container> 363 >::type type; 364 }; 365 366 367 template<typename T, typename C = boost::mpl::false_> 368 struct foreach_reverse_iterator 369 { 370 // **** READ THIS IF YOUR COMPILE BREAKS HERE **** 371 // 372 // There is an ambiguity about how to iterate over arrays of char and wchar_t. 373 // Should the last array element be treated as a null terminator to be skipped, or 374 // is it just like any other element in the array? To fix the problem, you must 375 // say which behavior you want. 376 // 377 // To treat the container as a null-terminated string, merely cast it to a 378 // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ... 379 // 380 // To treat the container as an array, use boost::as_array() in <boost/range/as_array.hpp>, 381 // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ... 382 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 383 BOOST_MPL_ASSERT_MSG( (!is_char_array<T>::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T&) ); 384 #endif 385 386 // If the type is a pointer to a null terminated string (as opposed 387 // to an array type), there is no ambiguity. 388 typedef BOOST_DEDUCED_TYPENAME wrap_cstr<T>::type container; 389 390 typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< 391 C 392 , range_reverse_iterator<container const> 393 , range_reverse_iterator<container> 394 >::type type; 395 }; 396 397 template<typename T, typename C = boost::mpl::false_> 398 struct foreach_reference 399 : iterator_reference<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 400 { 401 }; 402 403 /////////////////////////////////////////////////////////////////////////////// 404 // encode_type 405 // 406 template<typename T> 407 inline type2type<T> *encode_type(T &, boost::mpl::false_ *) { return 0; } 408 409 template<typename T> 410 inline type2type<T, const_> *encode_type(T const &, boost::mpl::true_ *) { return 0; } 411 412 /////////////////////////////////////////////////////////////////////////////// 413 // set_false 414 // 415 inline bool set_false(bool &b) 416 { 417 b = false; 418 return false; 419 } 420 421 /////////////////////////////////////////////////////////////////////////////// 422 // to_ptr 423 // 424 template<typename T> 425 inline T *&to_ptr(T const &) 426 { 427 static T *t = 0; 428 return t; 429 } 430 431 // Borland needs a little extra help with arrays 432 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 433 template<typename T,std::size_t N> 434 inline T (*&to_ptr(T (&)[N]))[N] 435 { 436 static T (*t)[N] = 0; 437 return t; 438 } 439 #endif 440 441 /////////////////////////////////////////////////////////////////////////////// 442 // derefof 443 // 444 template<typename T> 445 inline T &derefof(T *t) 446 { 447 // This is a work-around for a compiler bug in Borland. If T* is a pointer to array type U(*)[N], 448 // then dereferencing it results in a U* instead of U(&)[N]. The cast forces the issue. 449 return reinterpret_cast<T &>( 450 *const_cast<char *>( 451 reinterpret_cast<char const volatile *>(t) 452 ) 453 ); 454 } 455 456 #ifdef BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION 457 /////////////////////////////////////////////////////////////////////////////// 458 // Detect at compile-time whether an expression yields an rvalue or 459 // an lvalue. This is rather non-standard, but some popular compilers 460 // accept it. 461 /////////////////////////////////////////////////////////////////////////////// 462 463 /////////////////////////////////////////////////////////////////////////////// 464 // rvalue_probe 465 // 466 template<typename T> 467 struct rvalue_probe 468 { 469 struct private_type_ {}; 470 // can't ever return an array by value 471 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< 472 boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T 473 >::type value_type; 474 operator value_type() { return *reinterpret_cast<value_type *>(this); } // never called 475 operator T &() const { return *reinterpret_cast<T *>(const_cast<rvalue_probe *>(this)); } // never called 476 }; 477 478 template<typename T> 479 rvalue_probe<T> const make_probe(T const &) 480 { 481 return rvalue_probe<T>(); 482 } 483 484 # define BOOST_FOREACH_IS_RVALUE(COL) \ 485 boost::foreach_detail_::and_( \ 486 boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(COL)) \ 487 , (true ? 0 : boost::foreach_detail_::is_rvalue_( \ 488 (true ? boost::foreach_detail_::make_probe(COL) : (COL)), 0))) 489 490 #elif defined(BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION) 491 /////////////////////////////////////////////////////////////////////////////// 492 // Detect at run-time whether an expression yields an rvalue 493 // or an lvalue. This is 100% standard C++, but not all compilers 494 // accept it. Also, it causes FOREACH to break when used with non- 495 // copyable collection types. 496 /////////////////////////////////////////////////////////////////////////////// 497 498 /////////////////////////////////////////////////////////////////////////////// 499 // rvalue_probe 500 // 501 template<typename T> 502 struct rvalue_probe 503 { 504 rvalue_probe(T &t, bool &b) 505 : value(t) 506 , is_rvalue(b) 507 { 508 } 509 510 struct private_type_ {}; 511 // can't ever return an array or an abstract type by value 512 #ifdef BOOST_NO_IS_ABSTRACT 513 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< 514 boost::is_array<T>, private_type_, T 515 >::type value_type; 516 #else 517 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< 518 boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T 519 >::type value_type; 520 #endif 521 522 operator value_type() 523 { 524 this->is_rvalue = true; 525 return this->value; 526 } 527 528 operator T &() const 529 { 530 return this->value; 531 } 532 533 private: 534 T &value; 535 bool &is_rvalue; 536 }; 537 538 template<typename T> 539 rvalue_probe<T> make_probe(T &t, bool &b) { return rvalue_probe<T>(t, b); } 540 541 template<typename T> 542 rvalue_probe<T const> make_probe(T const &t, bool &b) { return rvalue_probe<T const>(t, b); } 543 544 /////////////////////////////////////////////////////////////////////////////// 545 // simple_variant 546 // holds either a T or a T const* 547 template<typename T> 548 struct simple_variant 549 { 550 simple_variant(T const *t) 551 : is_rvalue(false) 552 { 553 *static_cast<T const **>(this->data.address()) = t; 554 } 555 556 simple_variant(T const &t) 557 : is_rvalue(true) 558 { 559 ::new(this->data.address()) T(t); 560 } 561 562 simple_variant(simple_variant const &that) 563 : is_rvalue(that.is_rvalue) 564 { 565 if(this->is_rvalue) 566 ::new(this->data.address()) T(*that.get()); 567 else 568 *static_cast<T const **>(this->data.address()) = that.get(); 569 } 570 571 ~simple_variant() 572 { 573 if(this->is_rvalue) 574 this->get()->~T(); 575 } 576 577 T const *get() const 578 { 579 if(this->is_rvalue) 580 return static_cast<T const *>(this->data.address()); 581 else 582 return *static_cast<T const * const *>(this->data.address()); 583 } 584 585 private: 586 enum size_type { size = sizeof(T) > sizeof(T*) ? sizeof(T) : sizeof(T*) }; 587 simple_variant &operator =(simple_variant const &); 588 bool const is_rvalue; 589 aligned_storage<size> data; 590 }; 591 592 // If the collection is an array or is noncopyable, it must be an lvalue. 593 // If the collection is a lightweight proxy, treat it as an rvalue 594 // BUGBUG what about a noncopyable proxy? 595 template<typename LValue, typename IsProxy> 596 inline BOOST_DEDUCED_TYPENAME boost::enable_if<boost::mpl::or_<LValue, IsProxy>, IsProxy>::type * 597 should_copy_impl(LValue *, IsProxy *, bool *) 598 { 599 return 0; 600 } 601 602 // Otherwise, we must determine at runtime whether it's an lvalue or rvalue 603 inline bool * 604 should_copy_impl(boost::mpl::false_ *, boost::mpl::false_ *, bool *is_rvalue) 605 { 606 return is_rvalue; 607 } 608 609 #endif 610 611 /////////////////////////////////////////////////////////////////////////////// 612 // contain 613 // 614 template<typename T> 615 inline auto_any<T> contain(T const &t, boost::mpl::true_ *) // rvalue 616 { 617 return t; 618 } 619 620 template<typename T> 621 inline auto_any<T *> contain(T &t, boost::mpl::false_ *) // lvalue 622 { 623 // Cannot seem to get sunpro to handle addressof() with array types. 624 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) 625 return &t; 626 #else 627 return boost::addressof(t); 628 #endif 629 } 630 631 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 632 template<typename T> 633 auto_any<simple_variant<T> > 634 contain(T const &t, bool *rvalue) 635 { 636 return *rvalue ? simple_variant<T>(t) : simple_variant<T>(&t); 637 } 638 #endif 639 640 ///////////////////////////////////////////////////////////////////////////// 641 // begin 642 // 643 template<typename T, typename C> 644 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 645 begin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 646 { 647 return boost::begin(auto_any_cast<T, C>(col)); 648 } 649 650 template<typename T, typename C> 651 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 652 begin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 653 { 654 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 655 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; 656 return iterator(boost::begin(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 657 } 658 659 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 660 template<typename T> 661 auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> 662 begin(auto_any_t col, type2type<T, const_> *, bool *) 663 { 664 return boost::begin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 665 } 666 #endif 667 668 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 669 template<typename T, typename C> 670 inline auto_any<T *> 671 begin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 672 { 673 return auto_any_cast<T *, boost::mpl::false_>(col); 674 } 675 #endif 676 677 /////////////////////////////////////////////////////////////////////////////// 678 // end 679 // 680 template<typename T, typename C> 681 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 682 end(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 683 { 684 return boost::end(auto_any_cast<T, C>(col)); 685 } 686 687 template<typename T, typename C> 688 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 689 end(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 690 { 691 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 692 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; 693 return iterator(boost::end(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 694 } 695 696 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 697 template<typename T> 698 auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> 699 end(auto_any_t col, type2type<T, const_> *, bool *) 700 { 701 return boost::end(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 702 } 703 #endif 704 705 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 706 template<typename T, typename C> 707 inline auto_any<int> 708 end(auto_any_t, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 709 { 710 return 0; // not used 711 } 712 #endif 713 714 /////////////////////////////////////////////////////////////////////////////// 715 // done 716 // 717 template<typename T, typename C> 718 inline bool done(auto_any_t cur, auto_any_t end, type2type<T, C> *) 719 { 720 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; 721 return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end); 722 } 723 724 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 725 template<typename T, typename C> 726 inline bool done(auto_any_t cur, auto_any_t, type2type<T *, C> *) // null-terminated C-style strings 727 { 728 return ! *auto_any_cast<T *, boost::mpl::false_>(cur); 729 } 730 #endif 731 732 /////////////////////////////////////////////////////////////////////////////// 733 // next 734 // 735 template<typename T, typename C> 736 inline void next(auto_any_t cur, type2type<T, C> *) 737 { 738 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; 739 ++auto_any_cast<iter_t, boost::mpl::false_>(cur); 740 } 741 742 /////////////////////////////////////////////////////////////////////////////// 743 // deref 744 // 745 template<typename T, typename C> 746 inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type 747 deref(auto_any_t cur, type2type<T, C> *) 748 { 749 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; 750 return *auto_any_cast<iter_t, boost::mpl::false_>(cur); 751 } 752 753 ///////////////////////////////////////////////////////////////////////////// 754 // rbegin 755 // 756 template<typename T, typename C> 757 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 758 rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 759 { 760 return boost::rbegin(auto_any_cast<T, C>(col)); 761 } 762 763 template<typename T, typename C> 764 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 765 rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 766 { 767 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 768 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; 769 return iterator(boost::rbegin(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 770 } 771 772 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 773 template<typename T> 774 auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> 775 rbegin(auto_any_t col, type2type<T, const_> *, bool *) 776 { 777 return boost::rbegin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 778 } 779 #endif 780 781 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 782 template<typename T, typename C> 783 inline auto_any<reverse_iterator<T *> > 784 rbegin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 785 { 786 T *p = auto_any_cast<T *, boost::mpl::false_>(col); 787 while(0 != *p) 788 ++p; 789 return reverse_iterator<T *>(p); 790 } 791 #endif 792 793 /////////////////////////////////////////////////////////////////////////////// 794 // rend 795 // 796 template<typename T, typename C> 797 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 798 rend(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 799 { 800 return boost::rend(auto_any_cast<T, C>(col)); 801 } 802 803 template<typename T, typename C> 804 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 805 rend(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 806 { 807 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 808 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; 809 return iterator(boost::rend(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 810 } 811 812 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 813 template<typename T> 814 auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> 815 rend(auto_any_t col, type2type<T, const_> *, bool *) 816 { 817 return boost::rend(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 818 } 819 #endif 820 821 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 822 template<typename T, typename C> 823 inline auto_any<reverse_iterator<T *> > 824 rend(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 825 { 826 return reverse_iterator<T *>(auto_any_cast<T *, boost::mpl::false_>(col)); 827 } 828 #endif 829 830 /////////////////////////////////////////////////////////////////////////////// 831 // rdone 832 // 833 template<typename T, typename C> 834 inline bool rdone(auto_any_t cur, auto_any_t end, type2type<T, C> *) 835 { 836 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; 837 return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end); 838 } 839 840 /////////////////////////////////////////////////////////////////////////////// 841 // rnext 842 // 843 template<typename T, typename C> 844 inline void rnext(auto_any_t cur, type2type<T, C> *) 845 { 846 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; 847 ++auto_any_cast<iter_t, boost::mpl::false_>(cur); 848 } 849 850 /////////////////////////////////////////////////////////////////////////////// 851 // rderef 852 // 853 template<typename T, typename C> 854 inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type 855 rderef(auto_any_t cur, type2type<T, C> *) 856 { 857 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; 858 return *auto_any_cast<iter_t, boost::mpl::false_>(cur); 859 } 860 861 } // namespace foreach_detail_ 862 } // namespace boost 863 864 // Suppress a bogus code analysis warning on vc8+ 865 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 866 # define BOOST_FOREACH_SUPPRESS_WARNINGS() __pragma(warning(suppress:6001)) 867 #else 868 # define BOOST_FOREACH_SUPPRESS_WARNINGS() 869 #endif 870 871 /////////////////////////////////////////////////////////////////////////////// 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 58 #endif// BOOST_FOREACH_EXTENSIBILITY_HPP_20100311 -
boost/foreach_extensibility_fwd.hpp
1 1 /////////////////////////////////////////////////////////////////////////////// 2 // foreach .hpp header file2 // foreach_extensibility_fwd.hpp header file 3 3 // 4 4 // Copyright 2004 Eric Niebler. 5 5 // Distributed under the Boost Software License, Version 1.0. (See 6 6 // accompanying file LICENSE_1_0.txt or copy at 7 7 // http://www.boost.org/LICENSE_1_0.txt) 8 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 detect13 // const-qualified rvalues at compile time on VC7.1+14 // Russell Hind - For help porting to Borland15 // Alisdair Meredith - For help porting to Borland16 // Stefan Slapeta - For help porting to Intel17 // David Jenkins - For help finding a Microsoft Code Analysis bug18 9 19 #ifndef BOOST_FOREACH 10 #ifndef BOOST_FOREACH_EXTENSIBILITY_FWD_HPP_20100311 11 #define BOOST_FOREACH_EXTENSIBILITY_FWD_HPP_20100311 20 12 21 13 // MS compatible compilers support #pragma once 22 14 #if defined(_MSC_VER) && (_MSC_VER >= 1020) 23 15 # pragma once 24 16 #endif 25 17 26 #include <cstddef>27 #include <utility> // for std::pair28 29 #include <boost/config.hpp>30 #include <boost/detail/workaround.hpp>31 32 // Some compilers let us detect even const-qualified rvalues at compile-time33 #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_DETECTION37 #else38 // Some compilers allow temporaries to be bound to non-const references.39 // These compilers make it impossible to for BOOST_FOREACH to detect40 // 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_DETECTION47 # endif48 // Some compilers do not correctly implement the lvalue/rvalue conversion49 // 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_DETECTION61 # else62 # define BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION63 # endif64 #endif65 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_DETECTION85 # include <new>86 # include <boost/aligned_storage.hpp>87 # include <boost/utility/enable_if.hpp>88 # include <boost/type_traits/remove_const.hpp>89 #endif90 91 // This must be at global scope, hence the uglified name92 enum boost_foreach_argument_dependent_lookup_hack93 {94 boost_foreach_argument_dependent_lookup_hack_value95 };96 97 18 namespace boost 98 19 { 99 20 100 // forward declarations for iterator_range101 template<typename T>102 class iterator_range;103 104 // forward declarations for sub_range105 template<typename T>106 class sub_range;107 108 21 namespace foreach 109 22 { 110 23 /////////////////////////////////////////////////////////////////////////////// 111 // in_range112 //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::tag121 //122 typedef boost_foreach_argument_dependent_lookup_hack tag;123 124 ///////////////////////////////////////////////////////////////////////////////125 24 // boost::foreach::is_lightweight_proxy 126 25 // Specialize this for user-defined collection types if they are inexpensive to copy. 127 26 // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. 128 27 template<typename T> 129 struct is_lightweight_proxy 130 : boost::mpl::false_ 131 { 132 }; 28 struct is_lightweight_proxy; 133 29 134 30 /////////////////////////////////////////////////////////////////////////////// 135 31 // boost::foreach::is_noncopyable 136 32 // Specialize this for user-defined collection types if they cannot be copied. 137 33 // This also tells BOOST_FOREACH to avoid the rvalue/lvalue detection stuff. 138 34 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 }; 35 struct is_noncopyable; 154 36 155 37 } // namespace foreach 156 38 157 39 } // namespace boost 158 40 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::mpl::false_ *is_rvalue_(T &, int) { return 0; } 226 227 template<typename T> 228 inline boost::mpl::true_ *is_rvalue_(T const &, ...) { return 0; } 229 230 template<typename T> 231 inline boost::is_array<T> *is_array_(T const &) { return 0; } 232 233 template<typename T> 234 inline boost::is_const<T> *is_const_(T &) { return 0; } 235 236 #ifndef BOOST_FOREACH_NO_RVALUE_DETECTION 237 template<typename T> 238 inline boost::mpl::true_ *is_const_(T const &) { return 0; } 239 #endif 240 241 /////////////////////////////////////////////////////////////////////////////// 242 // auto_any_t/auto_any 243 // General utility for putting an object of any type into automatic storage 244 struct auto_any_base 245 { 246 // auto_any_base must evaluate to false in boolean context so that 247 // they can be declared in if() statements. 248 operator bool() const 249 { 250 return false; 251 } 252 }; 253 254 template<typename T> 255 struct auto_any : auto_any_base 256 { 257 auto_any(T const &t) 258 : item(t) 259 { 260 } 261 262 // temporaries of type auto_any will be bound to const auto_any_base 263 // references, but we still want to be able to mutate the stored 264 // data, so declare it as mutable. 265 mutable T item; 266 }; 267 268 typedef auto_any_base const &auto_any_t; 269 270 template<typename T, typename C> 271 inline BOOST_DEDUCED_TYPENAME boost::mpl::if_<C, T const, T>::type &auto_any_cast(auto_any_t a) 272 { 273 return static_cast<auto_any<T> const &>(a).item; 274 } 275 276 typedef boost::mpl::true_ const_; 277 278 /////////////////////////////////////////////////////////////////////////////// 279 // type2type 280 // 281 template<typename T, typename C = boost::mpl::false_> 282 struct type2type 283 : boost::mpl::if_<C, T const, T> 284 { 285 }; 286 287 template<typename T> 288 struct wrap_cstr 289 { 290 typedef T type; 291 }; 292 293 template<> 294 struct wrap_cstr<char *> 295 { 296 typedef wrap_cstr<char *> type; 297 typedef char *iterator; 298 typedef char *const_iterator; 299 }; 300 301 template<> 302 struct wrap_cstr<char const *> 303 { 304 typedef wrap_cstr<char const *> type; 305 typedef char const *iterator; 306 typedef char const *const_iterator; 307 }; 308 309 template<> 310 struct wrap_cstr<wchar_t *> 311 { 312 typedef wrap_cstr<wchar_t *> type; 313 typedef wchar_t *iterator; 314 typedef wchar_t *const_iterator; 315 }; 316 317 template<> 318 struct wrap_cstr<wchar_t const *> 319 { 320 typedef wrap_cstr<wchar_t const *> type; 321 typedef wchar_t const *iterator; 322 typedef wchar_t const *const_iterator; 323 }; 324 325 template<typename T> 326 struct is_char_array 327 : mpl::and_< 328 is_array<T> 329 , mpl::or_< 330 is_convertible<T, char const *> 331 , is_convertible<T, wchar_t const *> 332 > 333 > 334 {}; 335 336 template<typename T, typename C = boost::mpl::false_> 337 struct foreach_iterator 338 { 339 // **** READ THIS IF YOUR COMPILE BREAKS HERE **** 340 // 341 // There is an ambiguity about how to iterate over arrays of char and wchar_t. 342 // Should the last array element be treated as a null terminator to be skipped, or 343 // is it just like any other element in the array? To fix the problem, you must 344 // say which behavior you want. 345 // 346 // To treat the container as a null-terminated string, merely cast it to a 347 // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ... 348 // 349 // To treat the container as an array, use boost::as_array() in <boost/range/as_array.hpp>, 350 // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ... 351 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 352 BOOST_MPL_ASSERT_MSG( (!is_char_array<T>::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T&) ); 353 #endif 354 355 // If the type is a pointer to a null terminated string (as opposed 356 // to an array type), there is no ambiguity. 357 typedef BOOST_DEDUCED_TYPENAME wrap_cstr<T>::type container; 358 359 typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< 360 C 361 , range_const_iterator<container> 362 , range_mutable_iterator<container> 363 >::type type; 364 }; 365 366 367 template<typename T, typename C = boost::mpl::false_> 368 struct foreach_reverse_iterator 369 { 370 // **** READ THIS IF YOUR COMPILE BREAKS HERE **** 371 // 372 // There is an ambiguity about how to iterate over arrays of char and wchar_t. 373 // Should the last array element be treated as a null terminator to be skipped, or 374 // is it just like any other element in the array? To fix the problem, you must 375 // say which behavior you want. 376 // 377 // To treat the container as a null-terminated string, merely cast it to a 378 // char const *, as in BOOST_FOREACH( char ch, (char const *)"hello" ) ... 379 // 380 // To treat the container as an array, use boost::as_array() in <boost/range/as_array.hpp>, 381 // as in BOOST_FOREACH( char ch, boost::as_array("hello") ) ... 382 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 383 BOOST_MPL_ASSERT_MSG( (!is_char_array<T>::value), IS_THIS_AN_ARRAY_OR_A_NULL_TERMINATED_STRING, (T&) ); 384 #endif 385 386 // If the type is a pointer to a null terminated string (as opposed 387 // to an array type), there is no ambiguity. 388 typedef BOOST_DEDUCED_TYPENAME wrap_cstr<T>::type container; 389 390 typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if< 391 C 392 , range_reverse_iterator<container const> 393 , range_reverse_iterator<container> 394 >::type type; 395 }; 396 397 template<typename T, typename C = boost::mpl::false_> 398 struct foreach_reference 399 : iterator_reference<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 400 { 401 }; 402 403 /////////////////////////////////////////////////////////////////////////////// 404 // encode_type 405 // 406 template<typename T> 407 inline type2type<T> *encode_type(T &, boost::mpl::false_ *) { return 0; } 408 409 template<typename T> 410 inline type2type<T, const_> *encode_type(T const &, boost::mpl::true_ *) { return 0; } 411 412 /////////////////////////////////////////////////////////////////////////////// 413 // set_false 414 // 415 inline bool set_false(bool &b) 416 { 417 b = false; 418 return false; 419 } 420 421 /////////////////////////////////////////////////////////////////////////////// 422 // to_ptr 423 // 424 template<typename T> 425 inline T *&to_ptr(T const &) 426 { 427 static T *t = 0; 428 return t; 429 } 430 431 // Borland needs a little extra help with arrays 432 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 433 template<typename T,std::size_t N> 434 inline T (*&to_ptr(T (&)[N]))[N] 435 { 436 static T (*t)[N] = 0; 437 return t; 438 } 439 #endif 440 441 /////////////////////////////////////////////////////////////////////////////// 442 // derefof 443 // 444 template<typename T> 445 inline T &derefof(T *t) 446 { 447 // This is a work-around for a compiler bug in Borland. If T* is a pointer to array type U(*)[N], 448 // then dereferencing it results in a U* instead of U(&)[N]. The cast forces the issue. 449 return reinterpret_cast<T &>( 450 *const_cast<char *>( 451 reinterpret_cast<char const volatile *>(t) 452 ) 453 ); 454 } 455 456 #ifdef BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION 457 /////////////////////////////////////////////////////////////////////////////// 458 // Detect at compile-time whether an expression yields an rvalue or 459 // an lvalue. This is rather non-standard, but some popular compilers 460 // accept it. 461 /////////////////////////////////////////////////////////////////////////////// 462 463 /////////////////////////////////////////////////////////////////////////////// 464 // rvalue_probe 465 // 466 template<typename T> 467 struct rvalue_probe 468 { 469 struct private_type_ {}; 470 // can't ever return an array by value 471 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< 472 boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T 473 >::type value_type; 474 operator value_type() { return *reinterpret_cast<value_type *>(this); } // never called 475 operator T &() const { return *reinterpret_cast<T *>(const_cast<rvalue_probe *>(this)); } // never called 476 }; 477 478 template<typename T> 479 rvalue_probe<T> const make_probe(T const &) 480 { 481 return rvalue_probe<T>(); 482 } 483 484 # define BOOST_FOREACH_IS_RVALUE(COL) \ 485 boost::foreach_detail_::and_( \ 486 boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(COL)) \ 487 , (true ? 0 : boost::foreach_detail_::is_rvalue_( \ 488 (true ? boost::foreach_detail_::make_probe(COL) : (COL)), 0))) 489 490 #elif defined(BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION) 491 /////////////////////////////////////////////////////////////////////////////// 492 // Detect at run-time whether an expression yields an rvalue 493 // or an lvalue. This is 100% standard C++, but not all compilers 494 // accept it. Also, it causes FOREACH to break when used with non- 495 // copyable collection types. 496 /////////////////////////////////////////////////////////////////////////////// 497 498 /////////////////////////////////////////////////////////////////////////////// 499 // rvalue_probe 500 // 501 template<typename T> 502 struct rvalue_probe 503 { 504 rvalue_probe(T &t, bool &b) 505 : value(t) 506 , is_rvalue(b) 507 { 508 } 509 510 struct private_type_ {}; 511 // can't ever return an array or an abstract type by value 512 #ifdef BOOST_NO_IS_ABSTRACT 513 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< 514 boost::is_array<T>, private_type_, T 515 >::type value_type; 516 #else 517 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< 518 boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T 519 >::type value_type; 520 #endif 521 522 operator value_type() 523 { 524 this->is_rvalue = true; 525 return this->value; 526 } 527 528 operator T &() const 529 { 530 return this->value; 531 } 532 533 private: 534 T &value; 535 bool &is_rvalue; 536 }; 537 538 template<typename T> 539 rvalue_probe<T> make_probe(T &t, bool &b) { return rvalue_probe<T>(t, b); } 540 541 template<typename T> 542 rvalue_probe<T const> make_probe(T const &t, bool &b) { return rvalue_probe<T const>(t, b); } 543 544 /////////////////////////////////////////////////////////////////////////////// 545 // simple_variant 546 // holds either a T or a T const* 547 template<typename T> 548 struct simple_variant 549 { 550 simple_variant(T const *t) 551 : is_rvalue(false) 552 { 553 *static_cast<T const **>(this->data.address()) = t; 554 } 555 556 simple_variant(T const &t) 557 : is_rvalue(true) 558 { 559 ::new(this->data.address()) T(t); 560 } 561 562 simple_variant(simple_variant const &that) 563 : is_rvalue(that.is_rvalue) 564 { 565 if(this->is_rvalue) 566 ::new(this->data.address()) T(*that.get()); 567 else 568 *static_cast<T const **>(this->data.address()) = that.get(); 569 } 570 571 ~simple_variant() 572 { 573 if(this->is_rvalue) 574 this->get()->~T(); 575 } 576 577 T const *get() const 578 { 579 if(this->is_rvalue) 580 return static_cast<T const *>(this->data.address()); 581 else 582 return *static_cast<T const * const *>(this->data.address()); 583 } 584 585 private: 586 enum size_type { size = sizeof(T) > sizeof(T*) ? sizeof(T) : sizeof(T*) }; 587 simple_variant &operator =(simple_variant const &); 588 bool const is_rvalue; 589 aligned_storage<size> data; 590 }; 591 592 // If the collection is an array or is noncopyable, it must be an lvalue. 593 // If the collection is a lightweight proxy, treat it as an rvalue 594 // BUGBUG what about a noncopyable proxy? 595 template<typename LValue, typename IsProxy> 596 inline BOOST_DEDUCED_TYPENAME boost::enable_if<boost::mpl::or_<LValue, IsProxy>, IsProxy>::type * 597 should_copy_impl(LValue *, IsProxy *, bool *) 598 { 599 return 0; 600 } 601 602 // Otherwise, we must determine at runtime whether it's an lvalue or rvalue 603 inline bool * 604 should_copy_impl(boost::mpl::false_ *, boost::mpl::false_ *, bool *is_rvalue) 605 { 606 return is_rvalue; 607 } 608 609 #endif 610 611 /////////////////////////////////////////////////////////////////////////////// 612 // contain 613 // 614 template<typename T> 615 inline auto_any<T> contain(T const &t, boost::mpl::true_ *) // rvalue 616 { 617 return t; 618 } 619 620 template<typename T> 621 inline auto_any<T *> contain(T &t, boost::mpl::false_ *) // lvalue 622 { 623 // Cannot seem to get sunpro to handle addressof() with array types. 624 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570)) 625 return &t; 626 #else 627 return boost::addressof(t); 628 #endif 629 } 630 631 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 632 template<typename T> 633 auto_any<simple_variant<T> > 634 contain(T const &t, bool *rvalue) 635 { 636 return *rvalue ? simple_variant<T>(t) : simple_variant<T>(&t); 637 } 638 #endif 639 640 ///////////////////////////////////////////////////////////////////////////// 641 // begin 642 // 643 template<typename T, typename C> 644 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 645 begin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 646 { 647 return boost::begin(auto_any_cast<T, C>(col)); 648 } 649 650 template<typename T, typename C> 651 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 652 begin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 653 { 654 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 655 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; 656 return iterator(boost::begin(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 657 } 658 659 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 660 template<typename T> 661 auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> 662 begin(auto_any_t col, type2type<T, const_> *, bool *) 663 { 664 return boost::begin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 665 } 666 #endif 667 668 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 669 template<typename T, typename C> 670 inline auto_any<T *> 671 begin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 672 { 673 return auto_any_cast<T *, boost::mpl::false_>(col); 674 } 675 #endif 676 677 /////////////////////////////////////////////////////////////////////////////// 678 // end 679 // 680 template<typename T, typename C> 681 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 682 end(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 683 { 684 return boost::end(auto_any_cast<T, C>(col)); 685 } 686 687 template<typename T, typename C> 688 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type> 689 end(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 690 { 691 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 692 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iterator; 693 return iterator(boost::end(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 694 } 695 696 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 697 template<typename T> 698 auto_any<BOOST_DEDUCED_TYPENAME foreach_iterator<T, const_>::type> 699 end(auto_any_t col, type2type<T, const_> *, bool *) 700 { 701 return boost::end(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 702 } 703 #endif 704 705 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 706 template<typename T, typename C> 707 inline auto_any<int> 708 end(auto_any_t, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 709 { 710 return 0; // not used 711 } 712 #endif 713 714 /////////////////////////////////////////////////////////////////////////////// 715 // done 716 // 717 template<typename T, typename C> 718 inline bool done(auto_any_t cur, auto_any_t end, type2type<T, C> *) 719 { 720 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; 721 return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end); 722 } 723 724 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 725 template<typename T, typename C> 726 inline bool done(auto_any_t cur, auto_any_t, type2type<T *, C> *) // null-terminated C-style strings 727 { 728 return ! *auto_any_cast<T *, boost::mpl::false_>(cur); 729 } 730 #endif 731 732 /////////////////////////////////////////////////////////////////////////////// 733 // next 734 // 735 template<typename T, typename C> 736 inline void next(auto_any_t cur, type2type<T, C> *) 737 { 738 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; 739 ++auto_any_cast<iter_t, boost::mpl::false_>(cur); 740 } 741 742 /////////////////////////////////////////////////////////////////////////////// 743 // deref 744 // 745 template<typename T, typename C> 746 inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type 747 deref(auto_any_t cur, type2type<T, C> *) 748 { 749 typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t; 750 return *auto_any_cast<iter_t, boost::mpl::false_>(cur); 751 } 752 753 ///////////////////////////////////////////////////////////////////////////// 754 // rbegin 755 // 756 template<typename T, typename C> 757 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 758 rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 759 { 760 return boost::rbegin(auto_any_cast<T, C>(col)); 761 } 762 763 template<typename T, typename C> 764 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 765 rbegin(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 766 { 767 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 768 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; 769 return iterator(boost::rbegin(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 770 } 771 772 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 773 template<typename T> 774 auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> 775 rbegin(auto_any_t col, type2type<T, const_> *, bool *) 776 { 777 return boost::rbegin(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 778 } 779 #endif 780 781 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 782 template<typename T, typename C> 783 inline auto_any<reverse_iterator<T *> > 784 rbegin(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 785 { 786 T *p = auto_any_cast<T *, boost::mpl::false_>(col); 787 while(0 != *p) 788 ++p; 789 return reverse_iterator<T *>(p); 790 } 791 #endif 792 793 /////////////////////////////////////////////////////////////////////////////// 794 // rend 795 // 796 template<typename T, typename C> 797 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 798 rend(auto_any_t col, type2type<T, C> *, boost::mpl::true_ *) // rvalue 799 { 800 return boost::rend(auto_any_cast<T, C>(col)); 801 } 802 803 template<typename T, typename C> 804 inline auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type> 805 rend(auto_any_t col, type2type<T, C> *, boost::mpl::false_ *) // lvalue 806 { 807 typedef BOOST_DEDUCED_TYPENAME type2type<T, C>::type type; 808 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iterator; 809 return iterator(boost::rend(derefof(auto_any_cast<type *, boost::mpl::false_>(col)))); 810 } 811 812 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 813 template<typename T> 814 auto_any<BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, const_>::type> 815 rend(auto_any_t col, type2type<T, const_> *, bool *) 816 { 817 return boost::rend(*auto_any_cast<simple_variant<T>, boost::mpl::false_>(col).get()); 818 } 819 #endif 820 821 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING 822 template<typename T, typename C> 823 inline auto_any<reverse_iterator<T *> > 824 rend(auto_any_t col, type2type<T *, C> *, boost::mpl::true_ *) // null-terminated C-style strings 825 { 826 return reverse_iterator<T *>(auto_any_cast<T *, boost::mpl::false_>(col)); 827 } 828 #endif 829 830 /////////////////////////////////////////////////////////////////////////////// 831 // rdone 832 // 833 template<typename T, typename C> 834 inline bool rdone(auto_any_t cur, auto_any_t end, type2type<T, C> *) 835 { 836 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; 837 return auto_any_cast<iter_t, boost::mpl::false_>(cur) == auto_any_cast<iter_t, boost::mpl::false_>(end); 838 } 839 840 /////////////////////////////////////////////////////////////////////////////// 841 // rnext 842 // 843 template<typename T, typename C> 844 inline void rnext(auto_any_t cur, type2type<T, C> *) 845 { 846 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; 847 ++auto_any_cast<iter_t, boost::mpl::false_>(cur); 848 } 849 850 /////////////////////////////////////////////////////////////////////////////// 851 // rderef 852 // 853 template<typename T, typename C> 854 inline BOOST_DEDUCED_TYPENAME foreach_reference<T, C>::type 855 rderef(auto_any_t cur, type2type<T, C> *) 856 { 857 typedef BOOST_DEDUCED_TYPENAME foreach_reverse_iterator<T, C>::type iter_t; 858 return *auto_any_cast<iter_t, boost::mpl::false_>(cur); 859 } 860 861 } // namespace foreach_detail_ 862 } // namespace boost 863 864 // Suppress a bogus code analysis warning on vc8+ 865 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 866 # define BOOST_FOREACH_SUPPRESS_WARNINGS() __pragma(warning(suppress:6001)) 867 #else 868 # define BOOST_FOREACH_SUPPRESS_WARNINGS() 869 #endif 870 871 /////////////////////////////////////////////////////////////////////////////// 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 41 #endif// BOOST_FOREACH_EXTENSIBILITY_FWD_HPP_20100311