the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 2419 lines 67 kB view raw
1//----------------------------------------------------------------------------- 2// boost variant/variant.hpp header file 3// See http://www.boost.org for updates, documentation, and revision history. 4//----------------------------------------------------------------------------- 5// 6// Copyright (c) 2002-2003 7// Eric Friedman, Itay Maman 8// 9// Distributed under the Boost Software License, Version 1.0. (See 10// accompanying file LICENSE_1_0.txt or copy at 11// http://www.boost.org/LICENSE_1_0.txt) 12 13#ifndef BOOST_VARIANT_VARIANT_HPP 14#define BOOST_VARIANT_VARIANT_HPP 15 16#include <cstddef> // for std::size_t 17#include <new> // for placement new 18 19#if !defined(BOOST_NO_TYPEID) 20#include <typeinfo> // for typeid, std::type_info 21#endif // BOOST_NO_TYPEID 22 23#include "boost/variant/detail/config.hpp" 24#include "boost/mpl/aux_/config/eti.hpp" 25#include "boost/mpl/aux_/value_wknd.hpp" 26 27#include "boost/variant/variant_fwd.hpp" 28#include "boost/variant/detail/backup_holder.hpp" 29#include "boost/variant/detail/enable_recursive_fwd.hpp" 30#include "boost/variant/detail/forced_return.hpp" 31#include "boost/variant/detail/initializer.hpp" 32#include "boost/variant/detail/make_variant_list.hpp" 33#include "boost/variant/detail/over_sequence.hpp" 34#include "boost/variant/detail/visitation_impl.hpp" 35#include "boost/variant/detail/hash_variant.hpp" 36 37#include "boost/variant/detail/generic_result_type.hpp" 38#include "boost/variant/detail/has_nothrow_move.hpp" 39#include "boost/variant/detail/move.hpp" 40 41#include "boost/detail/reference_content.hpp" 42#include "boost/aligned_storage.hpp" 43#include "boost/blank.hpp" 44#include "boost/math/common_factor_ct.hpp" 45#include "boost/static_assert.hpp" 46#include "boost/preprocessor/cat.hpp" 47#include "boost/preprocessor/repeat.hpp" 48#include "boost/type_traits/alignment_of.hpp" 49#include "boost/type_traits/add_const.hpp" 50#include "boost/type_traits/has_nothrow_constructor.hpp" 51#include "boost/type_traits/has_nothrow_copy.hpp" 52#include "boost/type_traits/is_const.hpp" 53#include "boost/type_traits/is_same.hpp" 54#include "boost/type_traits/is_rvalue_reference.hpp" 55#include "boost/utility/enable_if.hpp" 56#include "boost/utility/declval.hpp" 57#include "boost/variant/recursive_wrapper_fwd.hpp" 58#include "boost/variant/static_visitor.hpp" 59 60#include "boost/mpl/assert.hpp" 61#include "boost/mpl/begin_end.hpp" 62#include "boost/mpl/bool.hpp" 63#include "boost/mpl/deref.hpp" 64#include "boost/mpl/empty.hpp" 65#include "boost/mpl/eval_if.hpp" 66#include "boost/mpl/find_if.hpp" 67#include "boost/mpl/fold.hpp" 68#include "boost/mpl/front.hpp" 69#include "boost/mpl/identity.hpp" 70#include "boost/mpl/if.hpp" 71#include "boost/mpl/int.hpp" 72#include "boost/mpl/is_sequence.hpp" 73#include "boost/mpl/iterator_range.hpp" 74#include "boost/mpl/iter_fold_if.hpp" 75#include "boost/mpl/logical.hpp" 76#include "boost/mpl/max_element.hpp" 77#include "boost/mpl/next.hpp" 78#include "boost/mpl/not.hpp" 79#include "boost/mpl/pair.hpp" 80#include "boost/mpl/protect.hpp" 81#include "boost/mpl/push_front.hpp" 82#include "boost/mpl/same_as.hpp" 83#include "boost/mpl/size_t.hpp" 84#include "boost/mpl/sizeof.hpp" 85#include "boost/mpl/transform.hpp" 86 87/////////////////////////////////////////////////////////////////////////////// 88// Implementation Macros: 89// 90// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT 91// Defined in boost/variant/detail/visitation_impl.hpp. 92// 93// BOOST_VARIANT_MINIMIZE_SIZE 94// When #defined, implementation employs all known means to minimize the 95// size of variant obje cts. However, often unsuccessful due to alignment 96// issues, and potentially harmful to runtime speed, so not enabled by 97// default. (TODO: Investigate further.) 98 99#if defined(BOOST_VARIANT_MINIMIZE_SIZE) 100# include <climits> // for SCHAR_MAX 101# include "boost/mpl/eval_if.hpp" 102# include "boost/mpl/equal_to.hpp" 103# include "boost/mpl/identity.hpp" 104# include "boost/mpl/int.hpp" 105# include "boost/mpl/if.hpp" 106# include "boost/mpl/less.hpp" 107# include "boost/mpl/long.hpp" 108# include "boost/mpl/O1_size.hpp" 109#endif 110 111 112namespace boost { 113 114namespace detail { namespace variant { 115 116/////////////////////////////////////////////////////////////////////////////// 117// (detail) metafunction max_value 118// 119// Finds the maximum value of the unary metafunction F over Sequence. 120// 121template <typename Sequence, typename F> 122struct max_value 123{ 124private: // helpers, for metafunction result (below) 125 126 typedef typename mpl::transform1<Sequence, F>::type transformed_; 127 typedef typename mpl::max_element<transformed_ 128 129 >::type max_it; 130 131public: // metafunction result 132 133 typedef typename mpl::deref<max_it>::type 134 type; 135 136}; 137 138struct add_alignment 139{ 140 template <typename State, typename Item> 141 struct apply 142 : mpl::size_t< 143 ::boost::math::static_lcm< 144 BOOST_MPL_AUX_VALUE_WKND(State)::value 145 , ::boost::alignment_of<Item>::value 146 >::value 147 > 148 {}; 149}; 150 151/////////////////////////////////////////////////////////////////////////////// 152// (detail) metafunction find_fallback_type 153// 154// Provides a fallback (i.e., nothrow default-constructible) type from the 155// specified sequence, or no_fallback_type if not found. 156// 157// This implementation is designed to prefer boost::blank over other potential 158// fallback types, regardless of its position in the specified sequence. 159// 160 161class no_fallback_type; 162 163struct find_fallback_type_pred 164{ 165 template <typename Iterator> 166 struct apply 167 { 168 private: 169 typedef typename mpl::deref<Iterator>::type t_; 170 171 public: 172 typedef mpl::not_< has_nothrow_constructor<t_> > type; 173 }; 174}; 175 176template <typename Types> 177struct find_fallback_type 178{ 179private: // helpers, for metafunction result (below) 180 181 typedef typename mpl::end<Types>::type end_it; 182 183 // [Find the first suitable fallback type...] 184 185 typedef typename mpl::iter_fold_if< 186 Types 187 , mpl::int_<0>, mpl::protect< mpl::next<> > 188 , mpl::protect< find_fallback_type_pred > 189 >::type first_result_; 190 191 typedef typename first_result_::first first_result_index; 192 typedef typename first_result_::second first_result_it; 193 194 // [...now search the rest of the sequence for boost::blank...] 195 196 typedef typename mpl::iter_fold_if< 197 mpl::iterator_range< first_result_it,end_it > 198 , first_result_index, mpl::protect< mpl::next<> > 199 , mpl::protect< mpl::not_same_as<boost::blank> > 200 >::type second_result_; 201 202 typedef typename second_result_::second second_result_it; 203 204public: // metafunction result 205 206 // [...and return the results of the search:] 207 typedef typename mpl::eval_if< 208 is_same< second_result_it,end_it > 209 , mpl::if_< 210 is_same< first_result_it,end_it > 211 , mpl::pair< no_fallback_type,no_fallback_type > 212 , first_result_ 213 > 214 , mpl::identity< second_result_ > 215 >::type type; 216 217}; 218 219#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) 220 221template<> 222struct find_fallback_type<int> 223{ 224 typedef mpl::pair< no_fallback_type,no_fallback_type > type; 225}; 226 227#endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround 228 229/////////////////////////////////////////////////////////////////////////////// 230// (detail) metafunction make_storage 231// 232// Provides an aligned storage type capable of holding any of the types 233// specified in the given type-sequence. 234// 235 236template <typename Types, typename NeverUsesBackupFlag> 237struct make_storage 238{ 239private: // helpers, for metafunction result (below) 240 241 typedef typename mpl::eval_if< 242 NeverUsesBackupFlag 243 , mpl::identity< Types > 244 , mpl::push_front< 245 Types, backup_holder<void*> 246 > 247 >::type types; 248 249 typedef typename max_value< 250 types, mpl::sizeof_<mpl::_1> 251 >::type max_size; 252 253#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) 254 255 typedef typename mpl::fold< 256 types 257 , mpl::size_t<1> 258 , add_alignment 259 >::type max_alignment; 260 261#else // borland 262 263 // temporary workaround -- use maximal alignment 264 typedef mpl::size_t< -1 > max_alignment; 265 266#endif // borland workaround 267 268public: // metafunction result 269 270#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) 271 272 typedef ::boost::aligned_storage< 273 BOOST_MPL_AUX_VALUE_WKND(max_size)::value 274 , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value 275 > type; 276 277#else // MSVC7 and below 278 279 BOOST_STATIC_CONSTANT(std::size_t, msvc_max_size_c = max_size::value); 280 BOOST_STATIC_CONSTANT(std::size_t, msvc_max_alignment_c = max_alignment::value); 281 282 typedef ::boost::aligned_storage< 283 msvc_max_size_c 284 , msvc_max_alignment_c 285 > type; 286 287#endif // MSVC workaround 288 289}; 290 291#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) 292 293template<> 294struct make_storage<int,int> 295{ 296 typedef int type; 297}; 298 299#endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround 300 301/////////////////////////////////////////////////////////////////////////////// 302// (detail) class destroyer 303// 304// Internal visitor that destroys the value it visits. 305// 306struct destroyer 307 : public static_visitor<> 308{ 309public: // visitor interfaces 310 311 template <typename T> 312 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 313 internal_visit(T& operand, int) const 314 { 315 operand.~T(); 316 317#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) || \ 318 BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) 319 operand; // suppresses warnings 320#endif 321 322 BOOST_VARIANT_AUX_RETURN_VOID; 323 } 324 325}; 326 327/////////////////////////////////////////////////////////////////////////////// 328// (detail) class template known_get 329// 330// Visitor that returns a reference to content of the specified type. 331// 332// Precondition: visited variant MUST contain logical content of type T. 333// 334template <typename T> 335class known_get 336 : public static_visitor<T&> 337{ 338 339#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) 340 341public: // visitor interface 342 343 T& operator()(T& operand) const BOOST_NOEXCEPT 344 { 345 return operand; 346 } 347 348 template <typename U> 349 T& operator()(U&) const 350 { 351 // logical error to be here: see precondition above 352 BOOST_ASSERT(false); 353 return ::boost::detail::variant::forced_return< T& >(); 354 } 355 356#else // MSVC6 357 358private: // helpers, for visitor interface (below) 359 360 T& execute(T& operand, mpl::true_) const 361 { 362 return operand; 363 } 364 365 template <typename U> 366 T& execute(U& operand, mpl::false_) const 367 { 368 // logical error to be here: see precondition above 369 BOOST_ASSERT(false); 370 return ::boost::detail::variant::forced_return< T& >(); 371 } 372 373public: // visitor interface 374 375 template <typename U> 376 T& operator()(U& operand) const 377 { 378 typedef typename is_same< U,T >::type 379 U_is_T; 380 381 return execute(operand, U_is_T()); 382 } 383 384#endif // MSVC6 workaround 385 386}; 387 388/////////////////////////////////////////////////////////////////////////////// 389// (detail) class copy_into 390// 391// Internal visitor that copies the value it visits into the given buffer. 392// 393class copy_into 394 : public static_visitor<> 395{ 396private: // representation 397 398 void* storage_; 399 400public: // structors 401 402 explicit copy_into(void* storage) BOOST_NOEXCEPT 403 : storage_(storage) 404 { 405 } 406 407public: // internal visitor interface 408 409 template <typename T> 410 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 411 internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const 412 { 413 new(storage_) T( operand.get() ); 414 BOOST_VARIANT_AUX_RETURN_VOID; 415 } 416 417 template <typename T> 418 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 419 internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const 420 { 421 new(storage_) T( operand.get() ); 422 BOOST_VARIANT_AUX_RETURN_VOID; 423 } 424 425 template <typename T> 426 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 427 internal_visit(const T& operand, int) const 428 { 429 new(storage_) T(operand); 430 BOOST_VARIANT_AUX_RETURN_VOID; 431 } 432 433}; 434 435/////////////////////////////////////////////////////////////////////////////// 436// (detail) class move_into 437// 438// Internal visitor that moves the value it visits into the given buffer. 439// 440#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 441class move_into 442 : public static_visitor<> 443{ 444private: // representation 445 446 void* storage_; 447 448public: // structors 449 450 explicit move_into(void* storage) BOOST_NOEXCEPT 451 : storage_(storage) 452 { 453 } 454 455public: // internal visitor interface 456 457 template <typename T> 458 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 459 internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const 460 { 461 new(storage_) T( ::boost::detail::variant::move(operand.get()) ); 462 BOOST_VARIANT_AUX_RETURN_VOID; 463 } 464 465 template <typename T> 466 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 467 internal_visit(T& operand, int) const BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(boost::declval<T>()))) 468 { 469 new(storage_) T(::boost::detail::variant::move(operand)); 470 BOOST_VARIANT_AUX_RETURN_VOID; 471 } 472}; 473#endif 474 475/////////////////////////////////////////////////////////////////////////////// 476// (detail) class assign_storage 477// 478// Internal visitor that assigns the given storage (which must be a 479// constructed value of the same type) to the value it visits. 480// 481struct assign_storage 482 : public static_visitor<> 483{ 484private: // representation 485 486 const void* rhs_storage_; 487 488public: // structors 489 490 explicit assign_storage(const void* rhs_storage) BOOST_NOEXCEPT 491 : rhs_storage_(rhs_storage) 492 { 493 } 494 495public: // internal visitor interfaces 496 497 template <typename T> 498 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 499 internal_visit(backup_holder<T>& lhs_content, long) const 500 { 501 lhs_content.get() 502 = static_cast< const backup_holder<T>* >(rhs_storage_)->get(); 503 BOOST_VARIANT_AUX_RETURN_VOID; 504 } 505 506 template <typename T> 507 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 508 internal_visit(const backup_holder<T>& lhs_content, long) const 509 { 510 lhs_content.get() 511 = static_cast< const backup_holder<T>* >(rhs_storage_)->get(); 512 BOOST_VARIANT_AUX_RETURN_VOID; 513 } 514 515 template <typename T> 516 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 517 internal_visit(T& lhs_content, int) const 518 { 519 // NOTE TO USER : 520 // Compile error here indicates one of variant's bounded types does 521 // not meet the requirements of the Assignable concept. Thus, 522 // variant is not Assignable. 523 // 524 // Hint: Are any of the bounded types const-qualified or references? 525 // 526 lhs_content = *static_cast< const T* >(rhs_storage_); 527 BOOST_VARIANT_AUX_RETURN_VOID; 528 } 529 530}; 531 532/////////////////////////////////////////////////////////////////////////////// 533// (detail) class move_storage 534// 535// Internal visitor that moves the given storage (which must be a 536// constructed value of the same type) to the value it visits. 537// 538struct move_storage 539 : public static_visitor<> 540{ 541private: // representation 542 543 void* rhs_storage_; 544 545public: // structors 546 547 explicit move_storage(void* rhs_storage) BOOST_NOEXCEPT 548 : rhs_storage_(rhs_storage) 549 { 550 } 551 552public: // internal visitor interfaces 553 554 template <typename T> 555 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 556 internal_visit(backup_holder<T>& lhs_content, long) const 557 { 558 lhs_content.get() 559 = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get()); 560 BOOST_VARIANT_AUX_RETURN_VOID; 561 } 562 563 template <typename T> 564 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 565 internal_visit(const backup_holder<T>& lhs_content, long) const 566 { 567 lhs_content.get() 568 = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get()); 569 BOOST_VARIANT_AUX_RETURN_VOID; 570 } 571 572 template <typename T> 573 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 574 internal_visit(T& lhs_content, int) const 575 { 576 // NOTE TO USER : 577 // Compile error here indicates one of variant's bounded types does 578 // not meet the requirements of the Assignable concept. Thus, 579 // variant is not Assignable. 580 // 581 // Hint: Are any of the bounded types const-qualified or references? 582 // 583 lhs_content = ::boost::detail::variant::move(*static_cast<T* >(rhs_storage_)); 584 BOOST_VARIANT_AUX_RETURN_VOID; 585 } 586 587}; 588 589/////////////////////////////////////////////////////////////////////////////// 590// (detail) class direct_assigner 591// 592// Generic static visitor that: if and only if the visited value is of the 593// specified type, assigns the given value to the visited value and returns 594// true; else returns false. 595// 596template <typename T> 597class direct_assigner 598 : public static_visitor<bool> 599{ 600private: // representation 601 602 const T& rhs_; 603 604public: // structors 605 606 explicit direct_assigner(const T& rhs) BOOST_NOEXCEPT 607 : rhs_(rhs) 608 { 609 } 610 611#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) 612 613public: // visitor interface 614 615 bool operator()(T& lhs) 616 { 617 lhs = rhs_; 618 return true; 619 } 620 621 template <typename U> 622 bool operator()(U&) BOOST_NOEXCEPT 623 { 624 return false; 625 } 626 627#else // MSVC6 628 629private: // helpers, for visitor interface (below) 630 631 bool execute(T& lhs, mpl::true_) 632 { 633 lhs = rhs_; 634 return true; 635 } 636 637 template <typename U> 638 bool execute(U&, mpl::false_) 639 { 640 return false; 641 } 642 643public: // visitor interface 644 645 template <typename U> 646 bool operator()(U& lhs) 647 { 648 typedef typename is_same<U,T>::type U_is_T; 649 return execute(lhs, U_is_T()); 650 } 651 652#endif // MSVC6 workaround 653 654#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) 655private: 656 // silence MSVC warning C4512: assignment operator could not be generated 657 direct_assigner& operator= (direct_assigner const&); 658#endif 659}; 660 661/////////////////////////////////////////////////////////////////////////////// 662// (detail) class direct_mover 663// 664// Generic static visitor that: if and only if the visited value is of the 665// specified type, move assigns the given value to the visited value and returns 666// true; else returns false. 667// 668template <typename T> 669class direct_mover 670 : public static_visitor<bool> 671{ 672private: // representation 673 674 T& rhs_; 675 676public: // structors 677 678 explicit direct_mover(T& rhs) BOOST_NOEXCEPT 679 : rhs_(rhs) 680 { 681 } 682 683#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) 684 685public: // visitor interface 686 687 bool operator()(T& lhs) 688 { 689 lhs = ::boost::detail::variant::move(rhs_); 690 return true; 691 } 692 693 template <typename U> 694 bool operator()(U&) BOOST_NOEXCEPT 695 { 696 return false; 697 } 698 699#else // MSVC6 700 701public: // visitor interface 702 703 template <typename U> 704 bool operator()(U& lhs) 705 { 706 // MSVC6 can not use direct_mover class 707 return direct_assigner(rhs_)(lhs); 708 } 709 710#endif // MSVC6 workaround 711 712#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) 713private: 714 // silence MSVC warning C4512: assignment operator could not be generated 715 direct_mover& operator= (direct_mover const&); 716#endif 717}; 718 719 720/////////////////////////////////////////////////////////////////////////////// 721// (detail) class backup_assigner 722// 723// Internal visitor that "assigns" the given value to the visited value, 724// using backup to recover if the destroy-copy sequence fails. 725// 726// NOTE: This needs to be a friend of variant, as it needs access to 727// indicate_which, indicate_backup_which, etc. 728// 729template <typename Variant> 730class backup_assigner 731 : public static_visitor<> 732{ 733private: // representation 734 735 Variant& lhs_; 736 int rhs_which_; 737 const void* rhs_content_; 738 void (*copy_rhs_content_)(void*, const void*); 739 740public: // structors 741 742 template<class RhsT> 743 backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content) 744 : lhs_(lhs) 745 , rhs_which_(rhs_which) 746 , rhs_content_(&rhs_content) 747 , copy_rhs_content_(&construct_impl<RhsT>) 748 { 749 } 750 751private: // helpers, for visitor interface (below) 752 753 template<class RhsT> 754 static void construct_impl(void* addr, const void* obj) 755 { 756 new(addr) RhsT(*static_cast<const RhsT*>(obj)); 757 } 758 759 template <typename LhsT> 760 void backup_assign_impl( 761 LhsT& lhs_content 762 , mpl::true_// has_nothrow_move 763 ) 764 { 765 // Move lhs content to backup... 766 LhsT backup_lhs_content( 767 ::boost::detail::variant::move(lhs_content) 768 ); // nothrow 769 770 // ...destroy lhs content... 771 lhs_content.~LhsT(); // nothrow 772 773 try 774 { 775 // ...and attempt to copy rhs content into lhs storage: 776 copy_rhs_content_(lhs_.storage_.address(), rhs_content_); 777 } 778 catch (...) 779 { 780 // In case of failure, restore backup content to lhs storage... 781 new(lhs_.storage_.address()) 782 LhsT( 783 ::boost::detail::variant::move(backup_lhs_content) 784 ); // nothrow 785 786 // ...and rethrow: 787 throw; 788 } 789 790 // In case of success, indicate new content type: 791 lhs_.indicate_which(rhs_which_); // nothrow 792 } 793 794 template <typename LhsT> 795 void backup_assign_impl( 796 LhsT& lhs_content 797 , mpl::false_// has_nothrow_move 798 ) 799 { 800 // Backup lhs content... 801 LhsT* backup_lhs_ptr = new LhsT(lhs_content); 802 803 // ...destroy lhs content... 804 lhs_content.~LhsT(); // nothrow 805 806 try 807 { 808 // ...and attempt to copy rhs content into lhs storage: 809 copy_rhs_content_(lhs_.storage_.address(), rhs_content_); 810 } 811 catch (...) 812 { 813 // In case of failure, copy backup pointer to lhs storage... 814 new(lhs_.storage_.address()) 815 backup_holder<LhsT>( backup_lhs_ptr ); // nothrow 816 817 // ...indicate now using backup... 818 lhs_.indicate_backup_which( lhs_.which() ); // nothrow 819 820 // ...and rethrow: 821 throw; 822 } 823 824 // In case of success, indicate new content type... 825 lhs_.indicate_which(rhs_which_); // nothrow 826 827 // ...and delete backup: 828 delete backup_lhs_ptr; // nothrow 829 } 830 831public: // visitor interface 832 833 template <typename LhsT> 834 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 835 internal_visit(LhsT& lhs_content, int) 836 { 837 typedef typename has_nothrow_move_constructor<LhsT>::type 838 nothrow_move; 839 840 backup_assign_impl( lhs_content, nothrow_move() ); 841 842 BOOST_VARIANT_AUX_RETURN_VOID; 843 } 844 845#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) 846private: 847 // silence MSVC warning C4512: assignment operator could not be generated 848 backup_assigner& operator= (backup_assigner const&); 849#endif 850}; 851 852/////////////////////////////////////////////////////////////////////////////// 853// (detail) class swap_with 854// 855// Visitor that swaps visited value with content of given variant. 856// 857// Precondition: Given variant MUST have same logical type as visited value. 858// 859template <typename Variant> 860struct swap_with 861 : public static_visitor<> 862{ 863private: // representation 864 865 Variant& toswap_; 866 867public: // structors 868 869 explicit swap_with(Variant& toswap) 870 : toswap_(toswap) 871 { 872 } 873 874public: // internal visitor interfaces 875 876 template <typename T> 877 void operator()(T& operand) const 878 { 879 // Since the precondition ensures types are same, get T... 880 known_get<T> getter; 881 T& other = toswap_.apply_visitor(getter); 882 883 // ...and swap: 884 ::boost::detail::variant::move_swap( operand, other ); 885 } 886 887private: 888 swap_with& operator=(const swap_with&); 889 890}; 891 892/////////////////////////////////////////////////////////////////////////////// 893// (detail) class reflect 894// 895// Generic static visitor that performs a typeid on the value it visits. 896// 897 898#if !defined(BOOST_NO_TYPEID) 899 900class reflect 901 : public static_visitor<const std::type_info&> 902{ 903public: // visitor interfaces 904 905 template <typename T> 906 const std::type_info& operator()(const T&) const BOOST_NOEXCEPT 907 { 908 return typeid(T); 909 } 910 911}; 912 913#endif // BOOST_NO_TYPEID 914 915/////////////////////////////////////////////////////////////////////////////// 916// (detail) class comparer 917// 918// Generic static visitor that compares the content of the given lhs variant 919// with the visited rhs content using Comp. 920// 921// Precondition: lhs.which() == rhs.which() 922// 923template <typename Variant, typename Comp> 924class comparer 925 : public static_visitor<bool> 926{ 927private: // representation 928 929 const Variant& lhs_; 930 931public: // structors 932 933 explicit comparer(const Variant& lhs) BOOST_NOEXCEPT 934 : lhs_(lhs) 935 { 936 } 937 938public: // visitor interfaces 939 940 template <typename T> 941 bool operator()(const T& rhs_content) const 942 { 943 // Since the precondition ensures lhs and rhs types are same, get T... 944 known_get<const T> getter; 945 const T& lhs_content = lhs_.apply_visitor(getter); 946 947 // ...and compare lhs and rhs contents: 948 return Comp()(lhs_content, rhs_content); 949 } 950 951private: 952 comparer& operator=(const comparer&); 953 954}; 955 956/////////////////////////////////////////////////////////////////////////////// 957// (detail) class equal_comp 958// 959// Generic function object compares lhs with rhs using operator==. 960// 961struct equal_comp 962{ 963 template <typename T> 964 bool operator()(const T& lhs, const T& rhs) const 965 { 966 return lhs == rhs; 967 } 968}; 969 970/////////////////////////////////////////////////////////////////////////////// 971// (detail) class less_comp 972// 973// Generic function object compares lhs with rhs using operator<. 974// 975struct less_comp 976{ 977 template <typename T> 978 bool operator()(const T& lhs, const T& rhs) const 979 { 980 return lhs < rhs; 981 } 982}; 983 984/////////////////////////////////////////////////////////////////////////////// 985// (detail) class template invoke_visitor 986// 987// Internal visitor that invokes the given visitor using: 988// * for wrappers (e.g., recursive_wrapper), the wrapper's held value. 989// * for all other values, the value itself. 990// 991template <typename Visitor> 992class invoke_visitor 993{ 994private: // representation 995 996 Visitor& visitor_; 997 998public: // visitor typedefs 999 1000 typedef typename Visitor::result_type 1001 result_type; 1002 1003public: // structors 1004 1005 explicit invoke_visitor(Visitor& visitor) BOOST_NOEXCEPT 1006 : visitor_(visitor) 1007 { 1008 } 1009 1010#if !defined(BOOST_NO_VOID_RETURNS) 1011 1012public: // internal visitor interfaces 1013 1014 template <typename T> 1015 result_type internal_visit(T& operand, int) 1016 { 1017 return visitor_(operand); 1018 } 1019 1020# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564)) 1021 template <typename T> 1022 result_type internal_visit(const T& operand, int) 1023 { 1024 return visitor_(operand); 1025 } 1026# endif 1027 1028#else // defined(BOOST_NO_VOID_RETURNS) 1029 1030private: // helpers, for internal visitor interfaces (below) 1031 1032 template <typename T> 1033 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1034 visit_impl(T& operand, mpl::false_) 1035 { 1036 return visitor_(operand); 1037 } 1038 1039 template <typename T> 1040 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 1041 visit_impl(T& operand, mpl::true_) 1042 { 1043 visitor_(operand); 1044 BOOST_VARIANT_AUX_RETURN_VOID; 1045 } 1046 1047public: // internal visitor interfaces 1048 1049 template <typename T> 1050 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1051 internal_visit(T& operand, int) 1052 { 1053 typedef typename is_same<result_type, void>::type 1054 has_void_result_type; 1055 1056 return visit_impl(operand, has_void_result_type()); 1057 } 1058 1059#endif // BOOST_NO_VOID_RETURNS) workaround 1060 1061public: // internal visitor interfaces, cont. 1062 1063 template <typename T> 1064 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1065 internal_visit(boost::recursive_wrapper<T>& operand, long) 1066 { 1067 return internal_visit( operand.get(), 1L ); 1068 } 1069 1070 template <typename T> 1071 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1072 internal_visit(const boost::recursive_wrapper<T>& operand, long) 1073 { 1074 return internal_visit( operand.get(), 1L ); 1075 } 1076 1077 template <typename T> 1078 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1079 internal_visit(boost::detail::reference_content<T>& operand, long) 1080 { 1081 return internal_visit( operand.get(), 1L ); 1082 } 1083 1084 template <typename T> 1085 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1086 internal_visit(const boost::detail::reference_content<T>& operand, long) 1087 { 1088 return internal_visit( operand.get(), 1L ); 1089 } 1090 1091 template <typename T> 1092 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1093 internal_visit(boost::detail::variant::backup_holder<T>& operand, long) 1094 { 1095 return internal_visit( operand.get(), 1L ); 1096 } 1097 1098 template <typename T> 1099 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) 1100 internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) 1101 { 1102 return internal_visit( operand.get(), 1L ); 1103 } 1104 1105#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) 1106private: 1107 // silence MSVC warning C4512: assignment operator could not be generated 1108 invoke_visitor& operator= (invoke_visitor const&); 1109#endif 1110}; 1111 1112}} // namespace detail::variant 1113 1114/////////////////////////////////////////////////////////////////////////////// 1115// class template variant (concept inspired by Andrei Alexandrescu) 1116// 1117// See docs and boost/variant/variant_fwd.hpp for more information. 1118// 1119template < 1120 typename T0_ 1121 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T) 1122 > 1123class variant 1124{ 1125private: // helpers, for typedefs (below) 1126 1127 typedef variant wknd_self_t; 1128 1129 struct is_recursive_ 1130 : detail::variant::is_recursive_flag<T0_> 1131 { 1132 }; 1133 1134 typedef typename mpl::eval_if< 1135 is_recursive_ 1136 , T0_ 1137 , mpl::identity< T0_ > 1138 >::type unwrapped_T0_; 1139 1140 struct is_sequence_based_ 1141 : detail::variant::is_over_sequence<unwrapped_T0_> 1142 { 1143 }; 1144 1145#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) 1146 1147private: // helpers, for typedefs (below) 1148 1149 typedef typename mpl::eval_if< 1150 is_sequence_based_ 1151 , unwrapped_T0_ // over_sequence<...>::type 1152 , detail::variant::make_variant_list< 1153 unwrapped_T0_ 1154 , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T) 1155 > 1156 >::type specified_types; 1157 1158 BOOST_STATIC_ASSERT(( 1159 ::boost::mpl::not_< mpl::empty<specified_types> >::value 1160 )); 1161 1162 typedef typename mpl::eval_if< 1163 is_recursive_ 1164 , mpl::transform< 1165 specified_types 1166 , mpl::protect< 1167 detail::variant::quoted_enable_recursive<wknd_self_t> 1168 > 1169 > 1170 , mpl::identity< specified_types > 1171 >::type recursive_enabled_types; 1172 1173public: // public typedefs 1174 1175 typedef typename mpl::transform< 1176 recursive_enabled_types 1177 , unwrap_recursive<mpl::_1> 1178 >::type types; 1179 1180private: // internal typedefs 1181 1182 typedef typename mpl::transform< 1183 recursive_enabled_types 1184 , mpl::protect< detail::make_reference_content<> > 1185 >::type internal_types; 1186 1187 typedef typename mpl::front< 1188 internal_types 1189 >::type internal_T0; 1190 1191#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT) 1192 1193private: // helpers, for typedefs (below) 1194 1195 typedef unwrapped_T0_ T0; 1196 1197 #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \ 1198 typedef typename mpl::eval_if< \ 1199 is_recursive_ \ 1200 , detail::variant::enable_recursive< \ 1201 BOOST_PP_CAT(T,N) \ 1202 , wknd_self_t \ 1203 > \ 1204 , mpl::identity< BOOST_PP_CAT(T,N) > \ 1205 >::type BOOST_PP_CAT(recursive_enabled_T,N); \ 1206 /**/ 1207 1208 BOOST_PP_REPEAT( 1209 BOOST_VARIANT_LIMIT_TYPES 1210 , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS 1211 , _ 1212 ) 1213 1214 #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS 1215 1216 #define BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS(z,N,_) \ 1217 typedef typename unwrap_recursive< \ 1218 BOOST_PP_CAT(recursive_enabled_T,N) \ 1219 >::type BOOST_PP_CAT(public_T,N); \ 1220 /**/ 1221 1222 BOOST_PP_REPEAT( 1223 BOOST_VARIANT_LIMIT_TYPES 1224 , BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS 1225 , _ 1226 ) 1227 1228 #undef BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS 1229 1230public: // public typedefs 1231 1232 typedef typename detail::variant::make_variant_list< 1233 BOOST_VARIANT_ENUM_PARAMS(public_T) 1234 >::type types; 1235 1236private: // helpers, for internal typedefs (below) 1237 1238 #define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \ 1239 typedef detail::make_reference_content< \ 1240 BOOST_PP_CAT(recursive_enabled_T,N) \ 1241 >::type BOOST_PP_CAT(internal_T,N); \ 1242 /**/ 1243 1244 BOOST_PP_REPEAT( 1245 BOOST_VARIANT_LIMIT_TYPES 1246 , BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS 1247 , _ 1248 ) 1249 1250 #undef BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS 1251 1252private: // internal typedefs 1253 1254 typedef typename detail::variant::make_variant_list< 1255 BOOST_VARIANT_ENUM_PARAMS(internal_T) 1256 >::type internal_types; 1257 1258private: // static precondition assertions 1259 1260 // NOTE TO USER : 1261 // variant< type-sequence > syntax is not supported on this compiler! 1262 // 1263 BOOST_MPL_ASSERT_NOT(( is_sequence_based_ )); 1264 1265#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround 1266 1267private: // helpers, for representation (below) 1268 1269 typedef typename detail::variant::find_fallback_type< 1270 internal_types 1271 >::type fallback_type_result_; 1272 1273 typedef typename fallback_type_result_::first 1274 fallback_type_index_; 1275 typedef typename fallback_type_result_::second 1276 fallback_type_; 1277 1278 struct has_fallback_type_ 1279 : mpl::not_< 1280 is_same< fallback_type_, detail::variant::no_fallback_type > 1281 > 1282 { 1283 }; 1284 1285 typedef has_fallback_type_ 1286 never_uses_backup_flag; 1287 1288 typedef typename detail::variant::make_storage< 1289 internal_types, never_uses_backup_flag 1290 >::type storage_t; 1291 1292private: // helpers, for representation (below) 1293 1294 // which_ on: 1295 // * [0, size<internal_types>) indicates stack content 1296 // * [-size<internal_types>, 0) indicates pointer to heap backup 1297 // if which_ >= 0: 1298 // * then which() -> which_ 1299 // * else which() -> -(which_ + 1) 1300 1301#if !defined(BOOST_VARIANT_MINIMIZE_SIZE) 1302 1303 typedef int which_t; 1304 1305#else // defined(BOOST_VARIANT_MINIMIZE_SIZE) 1306 1307 // [if O1_size available, then attempt which_t size optimization...] 1308 // [select signed char if fewer than SCHAR_MAX types, else signed int:] 1309 typedef typename mpl::eval_if< 1310 mpl::equal_to< mpl::O1_size<internal_types>, mpl::long_<-1> > 1311 , mpl::identity< int > 1312 , mpl::if_< 1313 mpl::less< mpl::O1_size<internal_types>, mpl::int_<SCHAR_MAX> > 1314 , signed char 1315 , int 1316 > 1317 >::type which_t; 1318 1319#endif // BOOST_VARIANT_MINIMIZE_SIZE switch 1320 1321// representation -- private when possible 1322#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) 1323 private: 1324#else 1325 public: 1326#endif 1327 1328 which_t which_; 1329 storage_t storage_; 1330 1331 void indicate_which(int which_arg) BOOST_NOEXCEPT 1332 { 1333 which_ = static_cast<which_t>( which_arg ); 1334 } 1335 1336 void indicate_backup_which(int which_arg) BOOST_NOEXCEPT 1337 { 1338 which_ = static_cast<which_t>( -(which_arg + 1) ); 1339 } 1340 1341private: // helpers, for queries (below) 1342 1343 bool using_backup() const BOOST_NOEXCEPT 1344 { 1345 return which_ < 0; 1346 } 1347 1348public: // queries 1349 1350 int which() const BOOST_NOEXCEPT 1351 { 1352 // If using heap backup... 1353 if (using_backup()) 1354 // ...then return adjusted which_: 1355 return -(which_ + 1); 1356 1357 // Otherwise, return which_ directly: 1358 return which_; 1359 } 1360 1361private: // helpers, for structors (below) 1362 1363 struct initializer 1364 : BOOST_VARIANT_AUX_INITIALIZER_T( 1365 recursive_enabled_types, recursive_enabled_T 1366 ) 1367 { 1368 }; 1369 1370 void destroy_content() 1371 { 1372 detail::variant::destroyer visitor; 1373 this->internal_apply_visitor(visitor); 1374 } 1375 1376public: // structors 1377 1378 ~variant() 1379 { 1380 destroy_content(); 1381 } 1382 1383 variant() 1384 { 1385 // NOTE TO USER : 1386 // Compile error from here indicates that the first bound 1387 // type is not default-constructible, and so variant cannot 1388 // support its own default-construction. 1389 // 1390 new( storage_.address() ) internal_T0(); 1391 indicate_which(0); // zero is the index of the first bounded type 1392 } 1393 1394private: // helpers, for structors, cont. (below) 1395 1396 class convert_copy_into 1397 : public static_visitor<int> 1398 { 1399 private: // representation 1400 1401 void* storage_; 1402 1403 public: // structors 1404 1405 explicit convert_copy_into(void* storage) BOOST_NOEXCEPT 1406 : storage_(storage) 1407 { 1408 } 1409 1410 public: // internal visitor interfaces (below) 1411 1412 template <typename T> 1413 int internal_visit(T& operand, int) const 1414 { 1415 // NOTE TO USER : 1416 // Compile error here indicates one of the source variant's types 1417 // cannot be unambiguously converted to the destination variant's 1418 // types (or that no conversion exists). 1419 // 1420 return initializer::initialize(storage_, operand); 1421 } 1422 1423# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564)) 1424 template <typename T> 1425 result_type internal_visit(const T& operand, int) const 1426 { 1427 return initializer::initialize(storage_, operand); 1428 } 1429# endif 1430 1431 template <typename T> 1432 int internal_visit(boost::detail::reference_content<T>& operand, long) const 1433 { 1434 return internal_visit( operand.get(), 1L ); 1435 } 1436 1437 template <typename T> 1438 int internal_visit(const boost::detail::reference_content<T>& operand, long) const 1439 { 1440 return internal_visit( operand.get(), 1L ); 1441 } 1442 1443 template <typename T> 1444 int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const 1445 { 1446 return internal_visit( operand.get(), 1L ); 1447 } 1448 1449 template <typename T> 1450 int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const 1451 { 1452 return internal_visit( operand.get(), 1L ); 1453 } 1454 1455 template <typename T> 1456 int internal_visit(boost::recursive_wrapper<T>& operand, long) const 1457 { 1458 return internal_visit( operand.get(), 1L ); 1459 } 1460 1461 template <typename T> 1462 int internal_visit(const boost::recursive_wrapper<T>& operand, long) const 1463 { 1464 return internal_visit( operand.get(), 1L ); 1465 } 1466 1467 }; 1468 1469 friend class convert_copy_into; 1470 1471#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1472 class convert_move_into 1473 : public static_visitor<int> 1474 { 1475 private: // representation 1476 1477 void* storage_; 1478 1479 public: // structors 1480 1481 explicit convert_move_into(void* storage) BOOST_NOEXCEPT 1482 : storage_(storage) 1483 { 1484 } 1485 1486 public: // internal visitor interfaces (below) 1487 1488 template <typename T> 1489 int internal_visit(T& operand, int) const 1490 { 1491 // NOTE TO USER : 1492 // Compile error here indicates one of the source variant's types 1493 // cannot be unambiguously converted to the destination variant's 1494 // types (or that no conversion exists). 1495 // 1496 return initializer::initialize(storage_, detail::variant::move(operand) ); 1497 } 1498 1499 template <typename T> 1500 int internal_visit(boost::detail::reference_content<T>& operand, long) const 1501 { 1502 return internal_visit( operand.get(), 1L ); 1503 } 1504 1505 template <typename T> 1506 int internal_visit(const boost::detail::reference_content<T>& operand, long) const 1507 { 1508 return internal_visit( operand.get(), 1L ); 1509 } 1510 1511 template <typename T> 1512 int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const 1513 { 1514 return internal_visit( operand.get(), 1L ); 1515 } 1516 1517 template <typename T> 1518 int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const 1519 { 1520 return internal_visit( operand.get(), 1L ); 1521 } 1522 1523 template <typename T> 1524 int internal_visit(boost::recursive_wrapper<T>& operand, long) const 1525 { 1526 return internal_visit( operand.get(), 1L ); 1527 } 1528 1529 template <typename T> 1530 int internal_visit(const boost::recursive_wrapper<T>& operand, long) const 1531 { 1532 return internal_visit( operand.get(), 1L ); 1533 } 1534 }; 1535 1536 friend class convert_move_into; 1537#endif 1538 1539private: // helpers, for structors, below 1540 1541 template <typename T> 1542 void convert_construct( 1543 T& operand 1544 , int 1545 , mpl::false_ = mpl::false_() // is_foreign_variant 1546 ) 1547 { 1548 // NOTE TO USER : 1549 // Compile error here indicates that the given type is not 1550 // unambiguously convertible to one of the variant's types 1551 // (or that no conversion exists). 1552 // 1553 indicate_which( 1554 initializer::initialize( 1555 storage_.address() 1556 , operand 1557 ) 1558 ); 1559 } 1560 1561#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1562 template <typename T> 1563 typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type convert_construct( 1564 T&& operand 1565 , int 1566 , mpl::false_ = mpl::false_() // is_foreign_variant 1567 ) 1568 { 1569 // NOTE TO USER : 1570 // Compile error here indicates that the given type is not 1571 // unambiguously convertible to one of the variant's types 1572 // (or that no conversion exists). 1573 // 1574 indicate_which( 1575 initializer::initialize( 1576 storage_.address() 1577 , detail::variant::move(operand) 1578 ) 1579 ); 1580 } 1581#endif 1582 1583 template <typename Variant> 1584 void convert_construct( 1585 Variant& operand 1586 , long 1587 , mpl::true_// is_foreign_variant 1588 ) 1589 { 1590 convert_copy_into visitor(storage_.address()); 1591 indicate_which( 1592 operand.internal_apply_visitor(visitor) 1593 ); 1594 } 1595 1596#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1597 template <typename Variant> 1598 typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct( 1599 Variant&& operand 1600 , long 1601 , mpl::true_// is_foreign_variant 1602 ) 1603 { 1604 convert_move_into visitor(storage_.address()); 1605 indicate_which( 1606 operand.internal_apply_visitor(visitor) 1607 ); 1608 } 1609#endif 1610 1611 template <typename Variant> 1612 void convert_construct_variant(Variant& operand) 1613 { 1614 // [Determine if the given variant is itself a bounded type, or if its 1615 // content needs to be converted (i.e., it is a 'foreign' variant):] 1616 // 1617 1618 typedef typename mpl::find_if< 1619 types 1620 , is_same< 1621 add_const<mpl::_1> 1622 , const Variant 1623 > 1624 >::type found_it; 1625 1626 typedef typename mpl::end<types>::type not_found; 1627 typedef typename is_same< 1628 found_it, not_found 1629 >::type is_foreign_variant; 1630 1631 // Convert construct from operand: 1632 convert_construct( 1633 operand, 1L 1634 , is_foreign_variant() 1635 ); 1636 } 1637 1638#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1639 template <typename Variant> 1640 typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct_variant(Variant&& operand) 1641 { 1642 // [Determine if the given variant is itself a bounded type, or if its 1643 // content needs to be converted (i.e., it is a 'foreign' variant):] 1644 // 1645 1646 typedef typename mpl::find_if< 1647 types 1648 , is_same< 1649 add_const<mpl::_1> 1650 , const Variant 1651 > 1652 >::type found_it; 1653 1654 typedef typename mpl::end<types>::type not_found; 1655 typedef typename is_same< 1656 found_it, not_found 1657 >::type is_foreign_variant; 1658 1659 // Convert move construct from operand: 1660 convert_construct( 1661 detail::variant::move(operand), 1L 1662 , is_foreign_variant() 1663 ); 1664 } 1665#endif 1666 1667 template <BOOST_VARIANT_ENUM_PARAMS(typename U)> 1668 void convert_construct( 1669 boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand 1670 , long 1671 ) 1672 { 1673 convert_construct_variant(operand); 1674 } 1675 1676 template <BOOST_VARIANT_ENUM_PARAMS(typename U)> 1677 void convert_construct( 1678 const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand 1679 , long 1680 ) 1681 { 1682 convert_construct_variant(operand); 1683 } 1684 1685#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1686 template <BOOST_VARIANT_ENUM_PARAMS(typename U)> 1687 void convert_construct( 1688 boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&& operand 1689 , long 1690 ) 1691 { 1692 convert_construct_variant( detail::variant::move(operand) ); 1693 } 1694#endif 1695 1696public: // structors, cont. 1697 1698#if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) 1699 1700 template <typename T> 1701 variant(const T& operand) 1702 { 1703 convert_construct(operand, 1L); 1704 } 1705 1706 template <typename T> 1707 variant(T& operand) 1708 { 1709 convert_construct(operand, 1L); 1710 } 1711 1712#elif defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) 1713 1714 // For compilers that cannot distinguish between T& and const T& in 1715 // template constructors, but do fully support SFINAE, we can workaround: 1716 1717 template <typename T> 1718 variant(const T& operand) 1719 { 1720 convert_construct(operand, 1L); 1721 } 1722 1723 template <typename T> 1724 variant( 1725 T& operand 1726 , typename enable_if< 1727 mpl::not_< is_const<T> > 1728 , void 1729 >::type* = 0 1730 ) 1731 { 1732 convert_construct(operand, 1L); 1733 } 1734 1735#else // !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) 1736 1737 // For compilers that cannot distinguish between T& and const T& in 1738 // template constructors, and do NOT support SFINAE, we can't workaround: 1739 1740 template <typename T> 1741 variant(const T& operand) 1742 { 1743 convert_construct(operand, 1L); 1744 } 1745#endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds 1746 1747#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1748 template <class T> 1749 variant(T&& operand, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type* = 0) 1750 { 1751 convert_construct( detail::variant::move(operand), 1L); 1752 } 1753#endif 1754 1755public: // structors, cont. 1756 1757 // [MSVC6 requires copy constructor appear after template constructors] 1758 variant(const variant& operand) 1759 { 1760 // Copy the value of operand into *this... 1761 detail::variant::copy_into visitor( storage_.address() ); 1762 operand.internal_apply_visitor(visitor); 1763 1764 // ...and activate the *this's primary storage on success: 1765 indicate_which(operand.which()); 1766 } 1767 1768#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1769 variant(variant&& operand) 1770 { 1771 // Move the value of operand into *this... 1772 detail::variant::move_into visitor( storage_.address() ); 1773 operand.internal_apply_visitor(visitor); 1774 1775 // ...and activate the *this's primary storage on success: 1776 indicate_which(operand.which()); 1777 } 1778#endif 1779 1780private: // helpers, for modifiers (below) 1781 1782# if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) 1783 template <typename Variant> 1784 friend class detail::variant::backup_assigner; 1785# endif 1786 1787 // class assigner 1788 // 1789 // Internal visitor that "assigns" the visited value to the given variant 1790 // by appropriate destruction and copy-construction. 1791 // 1792 1793 class assigner 1794 : public static_visitor<> 1795 { 1796 private: // representation 1797 1798 variant& lhs_; 1799 int rhs_which_; 1800 1801 public: // structors 1802 1803 assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT 1804 : lhs_(lhs) 1805 , rhs_which_(rhs_which) 1806 { 1807 } 1808 1809 private: // helpers, for internal visitor interface (below) 1810 1811 template <typename RhsT, typename B1, typename B2> 1812 void assign_impl( 1813 const RhsT& rhs_content 1814 , mpl::true_// has_nothrow_copy 1815 , B1// has_nothrow_move_constructor 1816 , B2// has_fallback_type 1817 ) 1818 { 1819 // Destroy lhs's content... 1820 lhs_.destroy_content(); // nothrow 1821 1822 // ...copy rhs content into lhs's storage... 1823 new(lhs_.storage_.address()) 1824 RhsT( rhs_content ); // nothrow 1825 1826 // ...and indicate new content type: 1827 lhs_.indicate_which(rhs_which_); // nothrow 1828 } 1829 1830 template <typename RhsT, typename B> 1831 void assign_impl( 1832 const RhsT& rhs_content 1833 , mpl::false_// has_nothrow_copy 1834 , mpl::true_// has_nothrow_move_constructor 1835 , B// has_fallback_type 1836 ) 1837 { 1838 // Attempt to make a temporary copy (so as to move it below)... 1839 RhsT temp(rhs_content); 1840 1841 // ...and upon success destroy lhs's content... 1842 lhs_.destroy_content(); // nothrow 1843 1844 // ...move the temporary copy into lhs's storage... 1845 new(lhs_.storage_.address()) 1846 RhsT( detail::variant::move(temp) ); // nothrow 1847 1848 // ...and indicate new content type: 1849 lhs_.indicate_which(rhs_which_); // nothrow 1850 } 1851 1852 template <typename RhsT> 1853 void assign_impl( 1854 const RhsT& rhs_content 1855 , mpl::false_// has_nothrow_copy 1856 , mpl::false_// has_nothrow_move_constructor 1857 , mpl::true_// has_fallback_type 1858 ) 1859 { 1860 // Destroy lhs's content... 1861 lhs_.destroy_content(); // nothrow 1862 1863 try 1864 { 1865 // ...and attempt to copy rhs's content into lhs's storage: 1866 new(lhs_.storage_.address()) 1867 RhsT( rhs_content ); 1868 } 1869 catch (...) 1870 { 1871 // In case of failure, default-construct fallback type in lhs's storage... 1872 new (lhs_.storage_.address()) 1873 fallback_type_; // nothrow 1874 1875 // ...indicate construction of fallback type... 1876 lhs_.indicate_which( 1877 BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value 1878 ); // nothrow 1879 1880 // ...and rethrow: 1881 throw; 1882 } 1883 1884 // In the event of success, indicate new content type: 1885 lhs_.indicate_which(rhs_which_); // nothrow 1886 } 1887 1888 template <typename RhsT> 1889 void assign_impl( 1890 const RhsT& rhs_content 1891 , mpl::false_// has_nothrow_copy 1892 , mpl::false_// has_nothrow_move_constructor 1893 , mpl::false_// has_fallback_type 1894 ) 1895 { 1896 detail::variant::backup_assigner<wknd_self_t> 1897 visitor(lhs_, rhs_which_, rhs_content); 1898 lhs_.internal_apply_visitor(visitor); 1899 } 1900 1901 public: // internal visitor interfaces 1902 1903 template <typename RhsT> 1904 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 1905 internal_visit(const RhsT& rhs_content, int) 1906 { 1907 typedef typename has_nothrow_copy<RhsT>::type 1908 nothrow_copy; 1909 typedef typename mpl::or_< // reduces compile-time 1910 nothrow_copy 1911 , detail::variant::has_nothrow_move_constructor<RhsT> 1912 >::type nothrow_move_constructor; 1913 1914 assign_impl( 1915 rhs_content 1916 , nothrow_copy() 1917 , nothrow_move_constructor() 1918 , has_fallback_type_() 1919 ); 1920 1921 BOOST_VARIANT_AUX_RETURN_VOID; 1922 } 1923 1924#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) 1925 private: 1926 // silence MSVC warning C4512: assignment operator could not be generated 1927 assigner& operator= (assigner const&); 1928#endif 1929 }; 1930 1931 friend class assigner; 1932 1933#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1934 // class move_assigner 1935 // 1936 // Internal visitor that "move assigns" the visited value to the given variant 1937 // by appropriate destruction and move-construction. 1938 // 1939 1940 class move_assigner 1941 : public static_visitor<> 1942 { 1943 private: // representation 1944 1945 variant& lhs_; 1946 int rhs_which_; 1947 1948 public: // structors 1949 1950 move_assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT 1951 : lhs_(lhs) 1952 , rhs_which_(rhs_which) 1953 { 1954 } 1955 1956 private: // helpers, for internal visitor interface (below) 1957 1958 template <typename RhsT, typename B1, typename B2> 1959 void assign_impl( 1960 RhsT& rhs_content 1961 , mpl::true_// has_nothrow_copy 1962 , mpl::false_// has_nothrow_move_constructor 1963 , B2// has_fallback_type 1964 ) 1965 { 1966 // Destroy lhs's content... 1967 lhs_.destroy_content(); // nothrow 1968 1969 // ...copy rhs content into lhs's storage... 1970 new(lhs_.storage_.address()) 1971 RhsT( rhs_content ); // nothrow 1972 1973 // ...and indicate new content type: 1974 lhs_.indicate_which(rhs_which_); // nothrow 1975 } 1976 1977 template <typename RhsT, typename B> 1978 void assign_impl( 1979 RhsT& rhs_content 1980 , mpl::true_// has_nothrow_copy 1981 , mpl::true_// has_nothrow_move_constructor 1982 , B// has_fallback_type 1983 ) 1984 { 1985 // ...destroy lhs's content... 1986 lhs_.destroy_content(); // nothrow 1987 1988 // ...move the rhs_content into lhs's storage... 1989 new(lhs_.storage_.address()) 1990 RhsT( detail::variant::move(rhs_content) ); // nothrow 1991 1992 // ...and indicate new content type: 1993 lhs_.indicate_which(rhs_which_); // nothrow 1994 } 1995 1996 template <typename RhsT> 1997 void assign_impl( 1998 RhsT& rhs_content 1999 , mpl::false_// has_nothrow_copy 2000 , mpl::false_// has_nothrow_move_constructor 2001 , mpl::true_// has_fallback_type 2002 ) 2003 { 2004 // Destroy lhs's content... 2005 lhs_.destroy_content(); // nothrow 2006 2007 try 2008 { 2009 // ...and attempt to copy rhs's content into lhs's storage: 2010 new(lhs_.storage_.address()) 2011 RhsT( detail::variant::move(rhs_content) ); 2012 } 2013 catch (...) 2014 { 2015 // In case of failure, default-construct fallback type in lhs's storage... 2016 new (lhs_.storage_.address()) 2017 fallback_type_; // nothrow 2018 2019 // ...indicate construction of fallback type... 2020 lhs_.indicate_which( 2021 BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value 2022 ); // nothrow 2023 2024 // ...and rethrow: 2025 throw; 2026 } 2027 2028 // In the event of success, indicate new content type: 2029 lhs_.indicate_which(rhs_which_); // nothrow 2030 } 2031 2032 template <typename RhsT> 2033 void assign_impl( 2034 const RhsT& rhs_content 2035 , mpl::false_// has_nothrow_copy 2036 , mpl::false_// has_nothrow_move_constructor 2037 , mpl::false_// has_fallback_type 2038 ) 2039 { 2040 detail::variant::backup_assigner<wknd_self_t> 2041 visitor(lhs_, rhs_which_, rhs_content); 2042 lhs_.internal_apply_visitor(visitor); 2043 } 2044 2045 public: // internal visitor interfaces 2046 2047 template <typename RhsT> 2048 BOOST_VARIANT_AUX_RETURN_VOID_TYPE 2049 internal_visit(RhsT& rhs_content, int) 2050 { 2051 typedef typename detail::variant::has_nothrow_move_constructor<RhsT>::type 2052 nothrow_move_constructor; 2053 typedef typename mpl::or_< // reduces compile-time 2054 nothrow_move_constructor 2055 , has_nothrow_copy<RhsT> 2056 >::type nothrow_copy; 2057 2058 assign_impl( 2059 rhs_content 2060 , nothrow_copy() 2061 , nothrow_move_constructor() 2062 , has_fallback_type_() 2063 ); 2064 2065 BOOST_VARIANT_AUX_RETURN_VOID; 2066 } 2067 2068#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600)) 2069 private: 2070 // silence MSVC warning C4512: assignment operator could not be generated 2071 move_assigner& operator= (move_assigner const&); 2072#endif 2073 }; 2074 2075 friend class move_assigner; 2076#endif // BOOST_NO_CXX11_RVALUE_REFERENCES 2077 2078 void variant_assign(const variant& rhs) 2079 { 2080 // If the contained types are EXACTLY the same... 2081 if (which_ == rhs.which_) 2082 { 2083 // ...then assign rhs's storage to lhs's content: 2084 detail::variant::assign_storage visitor(rhs.storage_.address()); 2085 this->internal_apply_visitor(visitor); 2086 } 2087 else 2088 { 2089 // Otherwise, perform general (copy-based) variant assignment: 2090 assigner visitor(*this, rhs.which()); 2091 rhs.internal_apply_visitor(visitor); 2092 } 2093 } 2094 2095#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 2096 void variant_assign(variant&& rhs) 2097 { 2098 // If the contained types are EXACTLY the same... 2099 if (which_ == rhs.which_) 2100 { 2101 // ...then move rhs's storage to lhs's content: 2102 detail::variant::move_storage visitor(rhs.storage_.address()); 2103 this->internal_apply_visitor(visitor); 2104 } 2105 else 2106 { 2107 // Otherwise, perform general (move-based) variant assignment: 2108 move_assigner visitor(*this, rhs.which()); 2109 rhs.internal_apply_visitor(visitor); 2110 } 2111 } 2112#endif // BOOST_NO_CXX11_RVALUE_REFERENCES 2113 2114private: // helpers, for modifiers (below) 2115 2116 template <typename T> 2117 void assign(const T& rhs) 2118 { 2119 // If direct T-to-T assignment is not possible... 2120 detail::variant::direct_assigner<T> direct_assign(rhs); 2121 if (this->apply_visitor(direct_assign) == false) 2122 { 2123 // ...then convert rhs to variant and assign: 2124 // 2125 // While potentially inefficient, the following construction of a 2126 // variant allows T as any type convertible to one of the bounded 2127 // types without excessive code redundancy. 2128 // 2129 variant temp(rhs); 2130 variant_assign( detail::variant::move(temp) ); 2131 } 2132 } 2133 2134#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 2135 template <typename T> 2136 void move_assign(T&& rhs) 2137 { 2138 // If direct T-to-T move assignment is not possible... 2139 detail::variant::direct_mover<T> direct_move(rhs); 2140 if (this->apply_visitor(direct_move) == false) 2141 { 2142 // ...then convert rhs to variant and assign: 2143 // 2144 // While potentially inefficient, the following construction of a 2145 // variant allows T as any type convertible to one of the bounded 2146 // types without excessive code redundancy. 2147 // 2148 variant temp( detail::variant::move(rhs) ); 2149 variant_assign( detail::variant::move(temp) ); 2150 } 2151 } 2152#endif // BOOST_NO_CXX11_RVALUE_REFERENCES 2153 2154public: // modifiers 2155 2156#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 2157 template <class T> 2158 typename boost::enable_if<boost::is_rvalue_reference<T&&>, variant& >::type operator=(T&& rhs) 2159 { 2160 move_assign( detail::variant::move(rhs) ); 2161 return *this; 2162 } 2163#endif // BOOST_NO_CXX11_RVALUE_REFERENCES 2164 2165 template <typename T> 2166 variant& operator=(const T& rhs) 2167 { 2168 assign(rhs); 2169 return *this; 2170 } 2171 2172 // [MSVC6 requires copy assign appear after templated operator=] 2173 variant& operator=(const variant& rhs) 2174 { 2175 variant_assign(rhs); 2176 return *this; 2177 } 2178 2179#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 2180 variant& operator=(variant&& rhs) 2181 { 2182 variant_assign( detail::variant::move(rhs) ); 2183 return *this; 2184 } 2185#endif // BOOST_NO_CXX11_RVALUE_REFERENCES 2186 2187 void swap(variant& rhs) 2188 { 2189 // If the contained types are the same... 2190 if (which() == rhs.which()) 2191 { 2192 // ...then swap the values directly: 2193 detail::variant::swap_with<variant> visitor(rhs); 2194 this->apply_visitor(visitor); 2195 } 2196 else 2197 { 2198 // ...otherwise, perform general variant swap: 2199 variant tmp( detail::variant::move(rhs) ); 2200 rhs = detail::variant::move(*this); 2201 *this = detail::variant::move(tmp); 2202 } 2203 } 2204 2205public: // queries 2206 2207 // 2208 // NOTE: member which() defined above. 2209 // 2210 2211 bool empty() const BOOST_NOEXCEPT 2212 { 2213 return false; 2214 } 2215 2216#if !defined(BOOST_NO_TYPEID) 2217 const std::type_info& type() const 2218 { 2219 detail::variant::reflect visitor; 2220 return this->apply_visitor(visitor); 2221 } 2222#endif 2223 2224public: // prevent comparison with foreign types 2225 2226#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) 2227 2228# define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \ 2229 void 2230 2231#else // MSVC7 2232 2233 // 2234 // MSVC7 gives error about return types for above being different than 2235 // the true comparison operator overloads: 2236 // 2237 2238# define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \ 2239 bool 2240 2241#endif // MSVC7 workaround 2242 2243 template <typename U> 2244 BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE 2245 operator==(const U&) const 2246 { 2247 BOOST_STATIC_ASSERT( false && sizeof(U) ); 2248 } 2249 2250 template <typename U> 2251 BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE 2252 operator<(const U&) const 2253 { 2254 BOOST_STATIC_ASSERT( false && sizeof(U) ); 2255 } 2256 2257public: // comparison operators 2258 2259 // [MSVC6 requires these operators appear after template operators] 2260 2261 bool operator==(const variant& rhs) const 2262 { 2263 if (this->which() != rhs.which()) 2264 return false; 2265 2266 detail::variant::comparer< 2267 variant, detail::variant::equal_comp 2268 > visitor(*this); 2269 return rhs.apply_visitor(visitor); 2270 } 2271 2272 bool operator<(const variant& rhs) const 2273 { 2274 // 2275 // Dirk Schreib suggested this collating order. 2276 // 2277 2278 if (this->which() != rhs.which()) 2279 return this->which() < rhs.which(); 2280 2281 detail::variant::comparer< 2282 variant, detail::variant::less_comp 2283 > visitor(*this); 2284 return rhs.apply_visitor(visitor); 2285 } 2286 2287// helpers, for visitation support (below) -- private when possible 2288#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) 2289 2290 template < BOOST_VARIANT_ENUM_PARAMS(typename U) > 2291 friend class variant; 2292 2293private: 2294 2295#else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) 2296 2297public: 2298 2299#endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) 2300 2301 template <typename Visitor, typename VoidPtrCV> 2302 static 2303 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE( 2304 typename Visitor::result_type 2305 ) 2306 internal_apply_visitor_impl( 2307 int internal_which 2308 , int logical_which 2309 , Visitor& visitor 2310 , VoidPtrCV storage 2311 ) 2312 { 2313 typedef mpl::int_<0> first_which; 2314 typedef typename mpl::begin<internal_types>::type first_it; 2315 typedef typename mpl::end<internal_types>::type last_it; 2316 2317 typedef detail::variant::visitation_impl_step< 2318 first_it, last_it 2319 > first_step; 2320 2321 return detail::variant::visitation_impl( 2322 internal_which, logical_which 2323 , visitor, storage, mpl::false_() 2324 , never_uses_backup_flag() 2325 , static_cast<first_which*>(0), static_cast<first_step*>(0) 2326 ); 2327 } 2328 2329 template <typename Visitor> 2330 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE( 2331 typename Visitor::result_type 2332 ) 2333 internal_apply_visitor(Visitor& visitor) 2334 { 2335 return internal_apply_visitor_impl( 2336 which_, which(), visitor, storage_.address() 2337 ); 2338 } 2339 2340 template <typename Visitor> 2341 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE( 2342 typename Visitor::result_type 2343 ) 2344 internal_apply_visitor(Visitor& visitor) const 2345 { 2346 return internal_apply_visitor_impl( 2347 which_, which(), visitor, storage_.address() 2348 ); 2349 } 2350 2351public: // visitation support 2352 2353 template <typename Visitor> 2354 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE( 2355 typename Visitor::result_type 2356 ) 2357 apply_visitor(Visitor& visitor) 2358 { 2359 detail::variant::invoke_visitor<Visitor> invoker(visitor); 2360 return this->internal_apply_visitor(invoker); 2361 } 2362 2363 template <typename Visitor> 2364 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE( 2365 typename Visitor::result_type 2366 ) 2367 apply_visitor(Visitor& visitor) const 2368 { 2369 detail::variant::invoke_visitor<Visitor> invoker(visitor); 2370 return this->internal_apply_visitor(invoker); 2371 } 2372 2373}; // class variant 2374 2375/////////////////////////////////////////////////////////////////////////////// 2376// metafunction make_variant_over 2377// 2378// See docs and boost/variant/variant_fwd.hpp for more information. 2379// 2380template <typename Types> 2381struct make_variant_over 2382{ 2383private: // precondition assertions 2384 2385#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) 2386 BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value )); 2387#endif 2388 2389public: // metafunction result 2390 2391 typedef variant< 2392 detail::variant::over_sequence< Types > 2393 > type; 2394 2395}; 2396 2397/////////////////////////////////////////////////////////////////////////////// 2398// function template swap 2399// 2400// Swaps two variants of the same type (i.e., identical specification). 2401// 2402template < BOOST_VARIANT_ENUM_PARAMS(typename T) > 2403inline void swap( 2404 variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs 2405 , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs 2406 ) 2407{ 2408 lhs.swap(rhs); 2409} 2410 2411} // namespace boost 2412 2413// implementation additions 2414 2415#if !defined(BOOST_NO_IOSTREAM) 2416#include "boost/variant/detail/variant_io.hpp" 2417#endif // BOOST_NO_IOSTREAM 2418 2419#endif // BOOST_VARIANT_VARIANT_HPP