Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:33:21

0001 //-----------------------------------------------------------------------------
0002 // boost variant/variant.hpp header file
0003 // See http://www.boost.org for updates, documentation, and revision history.
0004 //-----------------------------------------------------------------------------
0005 //
0006 // Copyright (c) 2002-2003 Eric Friedman, Itay Maman
0007 // Copyright (c) 2012-2024 Antony Polukhin
0008 //
0009 // Distributed under the Boost Software License, Version 1.0. (See
0010 // accompanying file LICENSE_1_0.txt or copy at
0011 // http://www.boost.org/LICENSE_1_0.txt)
0012 
0013 // Thanks to Adam Romanek for providing patches for exception-disabled env.
0014 
0015 #ifndef BOOST_VARIANT_VARIANT_HPP
0016 #define BOOST_VARIANT_VARIANT_HPP
0017 
0018 #include <cstddef> // for std::size_t
0019 #include <new> // for placement new
0020 
0021 #include <boost/type_index.hpp>
0022 
0023 #include <boost/variant/detail/config.hpp>
0024 #include <boost/mpl/aux_/value_wknd.hpp>
0025 
0026 #include <boost/variant/variant_fwd.hpp>
0027 #include <boost/variant/detail/backup_holder.hpp>
0028 #include <boost/variant/detail/enable_recursive_fwd.hpp>
0029 #include <boost/variant/detail/forced_return.hpp>
0030 #include <boost/variant/detail/initializer.hpp>
0031 #include <boost/variant/detail/make_variant_list.hpp>
0032 #include <boost/variant/detail/over_sequence.hpp>
0033 #include <boost/variant/detail/visitation_impl.hpp>
0034 #include <boost/variant/detail/hash_variant.hpp>
0035 #include <boost/variant/detail/std_hash.hpp>
0036 
0037 #include <boost/variant/detail/move.hpp>
0038 
0039 #include <boost/detail/reference_content.hpp>
0040 #include <boost/blank.hpp>
0041 #include <boost/integer/common_factor_ct.hpp>
0042 #include <boost/static_assert.hpp>
0043 #include <boost/type_traits/aligned_storage.hpp>
0044 #include <boost/type_traits/alignment_of.hpp>
0045 #include <boost/type_traits/add_const.hpp>
0046 #include <boost/type_traits/has_nothrow_constructor.hpp>
0047 #include <boost/type_traits/has_nothrow_copy.hpp>
0048 #include <boost/type_traits/is_nothrow_move_assignable.hpp>
0049 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0050 #include <boost/type_traits/is_const.hpp>
0051 #include <boost/type_traits/is_same.hpp>
0052 #include <boost/type_traits/is_rvalue_reference.hpp>
0053 #include <boost/type_traits/is_constructible.hpp>
0054 #include <boost/type_traits/add_lvalue_reference.hpp>
0055 #include <boost/type_traits/declval.hpp>
0056 #include <boost/core/no_exceptions_support.hpp>
0057 #include <boost/core/enable_if.hpp>
0058 #include <boost/variant/recursive_wrapper_fwd.hpp>
0059 #include <boost/variant/static_visitor.hpp>
0060 
0061 #include <boost/mpl/assert.hpp>
0062 #include <boost/mpl/begin_end.hpp>
0063 #include <boost/mpl/bool.hpp>
0064 #include <boost/mpl/deref.hpp>
0065 #include <boost/mpl/empty.hpp>
0066 #include <boost/mpl/eval_if.hpp>
0067 #include <boost/mpl/find_if.hpp>
0068 #include <boost/mpl/fold.hpp>
0069 #include <boost/mpl/front.hpp>
0070 #include <boost/mpl/identity.hpp>
0071 #include <boost/mpl/if.hpp>
0072 #include <boost/mpl/insert_range.hpp>
0073 #include <boost/mpl/int.hpp>
0074 #include <boost/mpl/is_sequence.hpp>
0075 #include <boost/mpl/iterator_range.hpp>
0076 #include <boost/mpl/iter_fold_if.hpp>
0077 #include <boost/mpl/list.hpp>
0078 #include <boost/mpl/logical.hpp>
0079 #include <boost/mpl/max_element.hpp>
0080 #include <boost/mpl/next.hpp>
0081 #include <boost/mpl/not.hpp>
0082 #include <boost/mpl/pair.hpp>
0083 #include <boost/mpl/protect.hpp>
0084 #include <boost/mpl/push_front.hpp>
0085 #include <boost/mpl/same_as.hpp>
0086 #include <boost/mpl/size_t.hpp>
0087 #include <boost/mpl/sizeof.hpp>
0088 #include <boost/mpl/transform.hpp>
0089 
0090 ///////////////////////////////////////////////////////////////////////////////
0091 // Implementation Macros:
0092 //
0093 // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
0094 //   Defined in boost/variant/detail/visitation_impl.hpp.
0095 //
0096 // BOOST_VARIANT_MINIMIZE_SIZE
0097 //   When #defined, implementation employs all known means to minimize the
0098 //   size of variant obje   cts. However, often unsuccessful due to alignment
0099 //   issues, and potentially harmful to runtime speed, so not enabled by
0100 //   default. (TODO: Investigate further.)
0101 
0102 #if defined(BOOST_VARIANT_MINIMIZE_SIZE)
0103 #   include <climits> // for SCHAR_MAX
0104 #   include <boost/mpl/eval_if.hpp>
0105 #   include <boost/mpl/equal_to.hpp>
0106 #   include <boost/mpl/identity.hpp>
0107 #   include <boost/mpl/int.hpp>
0108 #   include <boost/mpl/if.hpp>
0109 #   include <boost/mpl/less.hpp>
0110 #   include <boost/mpl/long.hpp>
0111 #   include <boost/mpl/O1_size.hpp>
0112 #endif
0113 
0114 
0115 namespace boost {
0116 
0117 namespace detail { namespace variant {
0118 
0119 ///////////////////////////////////////////////////////////////////////////////
0120 // (detail) metafunction max_value
0121 //
0122 // Finds the maximum value of the unary metafunction F over Sequence.
0123 //
0124 template <typename Sequence, typename F>
0125 struct max_value
0126 {
0127 private: // helpers, for metafunction result (below)
0128 
0129     typedef typename mpl::transform1<Sequence, F>::type transformed_;
0130     typedef typename mpl::max_element<transformed_
0131 
0132         >::type max_it;
0133 
0134 public: // metafunction result
0135 
0136     typedef typename mpl::deref<max_it>::type
0137         type;
0138 
0139 };
0140 
0141 struct add_alignment
0142 {
0143     template <typename State, typename Item>
0144     struct apply
0145         : mpl::size_t<
0146               ::boost::integer::static_lcm<
0147                   BOOST_MPL_AUX_VALUE_WKND(State)::value
0148                 , ::boost::alignment_of<Item>::value
0149                 >::value
0150             >
0151     {};
0152 };
0153 
0154 ///////////////////////////////////////////////////////////////////////////////
0155 // (detail) metafunction find_fallback_type
0156 //
0157 // Provides a fallback (i.e., nothrow default-constructible) type from the
0158 // specified sequence, or no_fallback_type if not found.
0159 //
0160 // This implementation is designed to prefer boost::blank over other potential
0161 // fallback types, regardless of its position in the specified sequence.
0162 //
0163 
0164 class no_fallback_type;
0165 
0166 struct find_fallback_type_pred
0167 {
0168     template <typename Iterator>
0169     struct apply
0170     {
0171     private:
0172         typedef typename mpl::deref<Iterator>::type t_;
0173 
0174     public:
0175         typedef mpl::not_< has_nothrow_constructor<t_> > type;
0176     };
0177 };
0178 
0179 template <typename Types>
0180 struct find_fallback_type
0181 {
0182 private: // helpers, for metafunction result (below)
0183 
0184     typedef typename mpl::end<Types>::type end_it;
0185 
0186     // [Find the first suitable fallback type...]
0187 
0188     typedef typename mpl::iter_fold_if<
0189           Types
0190         , mpl::int_<0>, mpl::protect< mpl::next<> >
0191         , mpl::protect< find_fallback_type_pred >
0192         >::type first_result_;
0193 
0194     typedef typename first_result_::first first_result_index;
0195     typedef typename first_result_::second first_result_it;
0196 
0197     // [...now search the rest of the sequence for boost::blank...]
0198 
0199     typedef typename mpl::iter_fold_if<
0200           mpl::iterator_range< first_result_it,end_it >
0201         , first_result_index, mpl::protect< mpl::next<> >
0202         , mpl::protect< mpl::not_same_as<boost::blank> >
0203         >::type second_result_;
0204 
0205     typedef typename second_result_::second second_result_it;
0206 
0207 public: // metafunction result
0208 
0209     // [...and return the results of the search:]
0210     typedef typename mpl::eval_if<
0211           is_same< second_result_it,end_it >
0212         , mpl::if_<
0213               is_same< first_result_it,end_it >
0214             , mpl::pair< no_fallback_type,no_fallback_type >
0215             , first_result_
0216             >
0217         , mpl::identity< second_result_ >
0218         >::type type;
0219 
0220 };
0221 
0222 ///////////////////////////////////////////////////////////////////////////////
0223 // (detail) metafunction is_variant_move_noexcept_constructible
0224 //
0225 // Returns true_type if all the types are nothrow move constructible.
0226 //
0227 template <class Types>
0228 struct is_variant_move_noexcept_constructible {
0229     typedef typename boost::mpl::find_if<
0230         Types, mpl::not_<boost::is_nothrow_move_constructible<boost::mpl::_1> >
0231     >::type iterator_t;
0232 
0233     typedef typename boost::mpl::end<Types>::type end_t;
0234     typedef typename boost::is_same<
0235         iterator_t, end_t
0236     >::type type;
0237 };
0238 
0239 ///////////////////////////////////////////////////////////////////////////////
0240 // (detail) metafunction is_variant_move_noexcept_assignable
0241 //
0242 // Returns true_type if all the types are nothrow move constructible.
0243 //
0244 template <class Types>
0245 struct is_variant_move_noexcept_assignable {
0246     typedef typename boost::mpl::find_if<
0247         Types, mpl::not_<boost::is_nothrow_move_assignable<boost::mpl::_1> >
0248     >::type iterator_t;
0249 
0250     typedef typename boost::mpl::end<Types>::type end_t;
0251     typedef typename boost::is_same<
0252         iterator_t, end_t
0253     >::type type;
0254 };
0255 
0256 ///////////////////////////////////////////////////////////////////////////////
0257 // (detail) metafunction is_variant_constructible_from
0258 //
0259 // Derives from true_type if at least one variant's type is constructible from T.
0260 //
0261 template <class T1, class T2>
0262 struct is_constructible_ext:
0263     boost::mpl::or_<
0264         boost::is_constructible<
0265             T1,
0266             T2
0267         >,
0268         boost::is_constructible<
0269             T1,
0270             typename boost::add_lvalue_reference<T2>::type
0271         >
0272     >
0273 {};
0274 
0275 template <class T, class Types>
0276 struct is_variant_constructible_from:
0277     boost::mpl::not_< boost::is_same<
0278         typename boost::mpl::find_if<
0279             Types,
0280             is_constructible_ext<boost::mpl::_1, T>
0281         >::type,
0282         typename boost::mpl::end<Types>::type
0283     > >
0284 {};
0285 
0286 template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
0287 struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >:
0288     boost::is_same<
0289         typename boost::mpl::find_if<
0290             typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::recursive_enabled_types,
0291             mpl::not_< is_variant_constructible_from< boost::mpl::_1, Types> >
0292         >::type,
0293         typename boost::mpl::end< typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::recursive_enabled_types >::type
0294     >
0295 {};
0296 
0297 template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
0298 struct is_variant_constructible_from< const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& , Types >:
0299     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
0300 {};
0301 
0302 template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
0303 struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& , Types >:
0304     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
0305 {};
0306 
0307 template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
0308 struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>&& , Types >:
0309     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
0310 {};
0311 
0312 template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
0313 struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const && , Types >:
0314     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
0315 {};
0316 
0317 
0318 ///////////////////////////////////////////////////////////////////////////////
0319 // (detail) metafunction make_storage
0320 //
0321 // Provides an aligned storage type capable of holding any of the types
0322 // specified in the given type-sequence.
0323 //
0324 
0325 template <typename Types, typename NeverUsesBackupFlag>
0326 struct make_storage
0327 {
0328 private: // helpers, for metafunction result (below)
0329 
0330     typedef typename mpl::eval_if<
0331           NeverUsesBackupFlag
0332         , mpl::identity< Types >
0333         , mpl::push_front<
0334               Types, backup_holder<void*>
0335             >
0336         >::type types;
0337 
0338     typedef typename max_value<
0339           types, mpl::sizeof_<mpl::_1>
0340         >::type max_size;
0341 
0342 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
0343 
0344     typedef typename mpl::fold<
0345           types
0346         , mpl::size_t<1>
0347         , add_alignment
0348         >::type max_alignment;
0349 
0350 #else // borland
0351 
0352     // temporary workaround -- use maximal alignment
0353     typedef mpl::size_t< -1 > max_alignment;
0354 
0355 #endif // borland workaround
0356 
0357 public: // metafunction result
0358 
0359     typedef ::boost::aligned_storage<
0360           BOOST_MPL_AUX_VALUE_WKND(max_size)::value
0361         , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value
0362         > type;
0363 };
0364 
0365 ///////////////////////////////////////////////////////////////////////////////
0366 // (detail) class destroyer
0367 //
0368 // Internal visitor that destroys the value it visits.
0369 //
0370 struct destroyer
0371     : public static_visitor<>
0372 {
0373 public: // visitor interfaces
0374 
0375     template <typename T>
0376     void internal_visit(T& operand, int) const BOOST_NOEXCEPT
0377     {
0378         operand.~T(); // must be noexcept
0379 
0380 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551)) || \
0381     BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0382         (void)operand; // suppresses warnings
0383 #endif
0384     }
0385 
0386 };
0387 
0388 ///////////////////////////////////////////////////////////////////////////////
0389 // (detail) class template known_get
0390 //
0391 // Visitor that returns a reference to content of the specified type.
0392 //
0393 // Precondition: visited variant MUST contain logical content of type T.
0394 //
0395 template <typename T>
0396 class known_get
0397     : public static_visitor<T&>
0398 {
0399 
0400 public: // visitor interface
0401 
0402     T& operator()(T& operand) const BOOST_NOEXCEPT
0403     {
0404         return operand;
0405     }
0406 
0407     template <typename U>
0408     T& operator()(U&) const
0409     {
0410         // logical error to be here: see precondition above
0411         return ::boost::detail::variant::forced_return< T& >();
0412     }
0413 };
0414 
0415 ///////////////////////////////////////////////////////////////////////////////
0416 // (detail) class copy_into
0417 //
0418 // Internal visitor that copies the value it visits into the given buffer.
0419 //
0420 class copy_into
0421     : public static_visitor<>
0422 {
0423 private: // representation
0424 
0425     void* storage_;
0426 
0427 public: // structors
0428 
0429     explicit copy_into(void* storage) BOOST_NOEXCEPT
0430         : storage_(storage)
0431     {
0432     }
0433 
0434 public: // internal visitor interface
0435 
0436     template <typename T>
0437     void internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
0438     {
0439         new(storage_) T( operand.get() );
0440     }
0441 
0442     template <typename T>
0443     void internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
0444     {
0445         new(storage_) T( operand.get() );
0446     }
0447 
0448     template <typename T>
0449     void internal_visit(const T& operand, int) const
0450     {
0451         new(storage_) T(operand);
0452     }
0453 
0454 };
0455 
0456 ///////////////////////////////////////////////////////////////////////////////
0457 // (detail) class move_into
0458 //
0459 // Internal visitor that moves the value it visits into the given buffer.
0460 //
0461 class move_into
0462     : public static_visitor<>
0463 {
0464 private: // representation
0465 
0466     void* storage_;
0467 
0468 public: // structors
0469 
0470     explicit move_into(void* storage) BOOST_NOEXCEPT
0471         : storage_(storage)
0472     {
0473     }
0474 
0475 public: // internal visitor interface
0476 
0477     template <typename T>
0478     void internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
0479     {
0480         new(storage_) T( ::boost::detail::variant::move(operand.get()) );
0481     }
0482 
0483     template <typename T>
0484     void internal_visit(T& operand, int) const BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(boost::declval<T>())))
0485     {
0486         new(storage_) T(::boost::detail::variant::move(operand));
0487     }
0488 };
0489 
0490 ///////////////////////////////////////////////////////////////////////////////
0491 // (detail) class assign_storage
0492 //
0493 // Internal visitor that assigns the given storage (which must be a
0494 // constructed value of the same type) to the value it visits.
0495 //
0496 struct assign_storage
0497     : public static_visitor<>
0498 {
0499 private: // representation
0500 
0501     const void* rhs_storage_;
0502 
0503 public: // structors
0504 
0505     explicit assign_storage(const void* rhs_storage) BOOST_NOEXCEPT
0506         : rhs_storage_(rhs_storage)
0507     {
0508     }
0509 
0510 public: // internal visitor interfaces
0511 
0512     template <typename T>
0513     void internal_visit(backup_holder<T>& lhs_content, long) const
0514     {
0515         lhs_content.get()
0516             = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
0517     }
0518 
0519     template <typename T>
0520     void internal_visit(const backup_holder<T>& lhs_content, long) const
0521     {
0522         lhs_content.get()
0523             = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
0524     }
0525 
0526     template <typename T>
0527     void internal_visit(T& lhs_content, int) const
0528     {
0529         // NOTE TO USER :
0530         // Compile error here indicates one of variant's bounded types does
0531         // not meet the requirements of the Assignable concept. Thus,
0532         // variant is not Assignable.
0533         //
0534         // Hint: Are any of the bounded types const-qualified or references?
0535         //
0536         lhs_content = *static_cast< const T* >(rhs_storage_);
0537     }
0538 
0539 };
0540 
0541 ///////////////////////////////////////////////////////////////////////////////
0542 // (detail) class move_storage
0543 //
0544 // Internal visitor that moves the given storage (which must be a
0545 // constructed value of the same type) to the value it visits.
0546 //
0547 struct move_storage
0548     : public static_visitor<>
0549 {
0550 private: // representation
0551 
0552     void* rhs_storage_;
0553 
0554 public: // structors
0555 
0556     explicit move_storage(void* rhs_storage) BOOST_NOEXCEPT
0557         : rhs_storage_(rhs_storage)
0558     {
0559     }
0560 
0561 public: // internal visitor interfaces
0562 
0563     template <typename T>
0564     void internal_visit(backup_holder<T>& lhs_content, long) const
0565     {
0566         lhs_content.get()
0567             = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
0568     }
0569 
0570     template <typename T>
0571     void internal_visit(const backup_holder<T>& lhs_content, long) const
0572     {
0573         lhs_content.get()
0574             = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
0575     }
0576 
0577     template <typename T>
0578     void internal_visit(T& lhs_content, int) const
0579     {
0580         // NOTE TO USER :
0581         // Compile error here indicates one of variant's bounded types does
0582         // not meet the requirements of the Assignable concept. Thus,
0583         // variant is not Assignable.
0584         //
0585         // Hint: Are any of the bounded types const-qualified or references?
0586         //
0587         lhs_content = ::boost::detail::variant::move(*static_cast<T* >(rhs_storage_));
0588     }
0589 
0590 };
0591 
0592 ///////////////////////////////////////////////////////////////////////////////
0593 // (detail) class direct_assigner
0594 //
0595 // Generic static visitor that: if and only if the visited value is of the
0596 // specified type, assigns the given value to the visited value and returns
0597 // true; else returns false.
0598 //
0599 template <typename T>
0600 class direct_assigner
0601     : public static_visitor<bool>
0602 {
0603 private: // representation
0604 
0605     const T& rhs_;
0606 
0607 public: // structors
0608 
0609     explicit direct_assigner(const T& rhs) BOOST_NOEXCEPT
0610         : rhs_(rhs)
0611     {
0612     }
0613 
0614 public: // visitor interface
0615 
0616     bool operator()(T& lhs)
0617     {
0618         lhs = rhs_;
0619         return true;
0620     }
0621 
0622     template <typename U>
0623     bool operator()(U&) BOOST_NOEXCEPT
0624     {
0625         return false;
0626     }
0627 
0628 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0629 private:
0630     // silence MSVC warning C4512: assignment operator could not be generated
0631     direct_assigner& operator= (direct_assigner const&);
0632 #endif
0633 };
0634 
0635 ///////////////////////////////////////////////////////////////////////////////
0636 // (detail) class direct_mover
0637 //
0638 // Generic static visitor that: if and only if the visited value is of the
0639 // specified type, move assigns the given value to the visited value and returns
0640 // true; else returns false.
0641 //
0642 template <typename T>
0643 class direct_mover
0644     : public static_visitor<bool>
0645 {
0646 private: // representation
0647 
0648     T& rhs_;
0649 
0650 public: // structors
0651 
0652     explicit direct_mover(T& rhs) BOOST_NOEXCEPT
0653         : rhs_(rhs)
0654     {
0655     }
0656 
0657 public: // visitor interface
0658 
0659     bool operator()(T& lhs)
0660     {
0661         lhs = ::boost::detail::variant::move(rhs_);
0662         return true;
0663     }
0664 
0665     template <typename U>
0666     bool operator()(U&) BOOST_NOEXCEPT
0667     {
0668         return false;
0669     }
0670 
0671 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0672 private:
0673     // silence MSVC warning C4512: assignment operator could not be generated
0674     direct_mover& operator= (direct_mover const&);
0675 #endif
0676 };
0677 
0678 
0679 ///////////////////////////////////////////////////////////////////////////////
0680 // (detail) class backup_assigner
0681 //
0682 // Internal visitor that "assigns" the given value to the visited value,
0683 // using backup to recover if the destroy-copy sequence fails.
0684 //
0685 // NOTE: This needs to be a friend of variant, as it needs access to
0686 // indicate_which, indicate_backup_which, etc.
0687 //
0688 template <typename Variant>
0689 class backup_assigner
0690     : public static_visitor<>
0691 {
0692 private: // representation
0693 
0694     Variant& lhs_;
0695     int rhs_which_;
0696     const void* rhs_content_;
0697     void (*copy_rhs_content_)(void*, const void*);
0698 
0699 public: // structors
0700 
0701     template<class RhsT>
0702     backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
0703         : lhs_(lhs)
0704         , rhs_which_(rhs_which)
0705         , rhs_content_(&rhs_content)
0706         , copy_rhs_content_(&construct_impl<RhsT>)
0707     {
0708     }
0709 
0710 private: // helpers, for visitor interface (below)
0711 
0712     template<class RhsT>
0713     static void construct_impl(void* addr, const void* obj)
0714     {
0715         new(addr) RhsT(*static_cast<const RhsT*>(obj));
0716     }
0717 
0718     template <typename LhsT>
0719     void backup_assign_impl(
0720           backup_holder<LhsT>& lhs_content
0721         , mpl::false_ // is_nothrow_move_constructible
0722         , long
0723         )
0724     {
0725         // Move lhs content to backup...
0726         backup_holder<LhsT> backup_lhs_content(0);
0727         backup_lhs_content.swap(lhs_content); // nothrow
0728 
0729         // ...destroy lhs content...
0730         lhs_content.~backup_holder<LhsT>(); // nothrow
0731 
0732         BOOST_TRY
0733         {
0734             // ...and attempt to copy rhs content into lhs storage:
0735             copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
0736         }
0737         BOOST_CATCH (...)
0738         {
0739             // In case of failure, copy backup pointer to lhs storage...
0740             new(lhs_.storage_.address())
0741                     backup_holder<LhsT>( 0 ); // nothrow
0742 
0743             static_cast<backup_holder<LhsT>* >(lhs_.storage_.address())
0744                     ->swap(backup_lhs_content); // nothrow
0745 
0746             // ...and rethrow:
0747             BOOST_RETHROW;
0748         }
0749         BOOST_CATCH_END
0750 
0751         // In case of success, indicate new content type:
0752         lhs_.indicate_which(rhs_which_); // nothrow
0753     }
0754 
0755     template <typename LhsT>
0756     void backup_assign_impl(
0757           LhsT& lhs_content
0758         , mpl::true_ // is_nothrow_move_constructible
0759         , int
0760         )
0761     {
0762         // Move lhs content to backup...
0763         LhsT backup_lhs_content(
0764               ::boost::detail::variant::move(lhs_content)
0765             ); // nothrow
0766 
0767         // ...destroy lhs content...
0768         lhs_content.~LhsT(); // nothrow
0769 
0770         BOOST_TRY
0771         {
0772             // ...and attempt to copy rhs content into lhs storage:
0773             copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
0774         }
0775         BOOST_CATCH (...)
0776         {
0777             // In case of failure, restore backup content to lhs storage...
0778             new(lhs_.storage_.address())
0779                 LhsT(
0780                       ::boost::detail::variant::move(backup_lhs_content)
0781                     ); // nothrow
0782 
0783             // ...and rethrow:
0784             BOOST_RETHROW;
0785         }
0786         BOOST_CATCH_END
0787 
0788         // In case of success, indicate new content type:
0789         lhs_.indicate_which(rhs_which_); // nothrow
0790     }
0791 
0792     template <typename LhsT>
0793     void backup_assign_impl(
0794           LhsT& lhs_content
0795         , mpl::false_ // is_nothrow_move_constructible
0796         , int
0797         )
0798     {
0799         // Backup lhs content...
0800         LhsT* backup_lhs_ptr = new LhsT(lhs_content);
0801 
0802         // ...destroy lhs content...
0803         lhs_content.~LhsT(); // nothrow
0804 
0805         BOOST_TRY
0806         {
0807             // ...and attempt to copy rhs content into lhs storage:
0808             copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
0809         }
0810         BOOST_CATCH (...)
0811         {
0812             // In case of failure, copy backup pointer to lhs storage...
0813             new(lhs_.storage_.address())
0814                 backup_holder<LhsT>( backup_lhs_ptr ); // nothrow
0815 
0816             // ...indicate now using backup...
0817             lhs_.indicate_backup_which( lhs_.which() ); // nothrow
0818 
0819             // ...and rethrow:
0820             BOOST_RETHROW;
0821         }
0822         BOOST_CATCH_END
0823 
0824         // In case of success, indicate new content type...
0825         lhs_.indicate_which(rhs_which_); // nothrow
0826 
0827         // ...and delete backup:
0828         delete backup_lhs_ptr; // nothrow
0829     }
0830 
0831 public: // visitor interface
0832 
0833     template <typename LhsT>
0834     void internal_visit(LhsT& lhs_content, int)
0835     {
0836         typedef typename is_nothrow_move_constructible<LhsT>::type
0837             nothrow_move;
0838 
0839         backup_assign_impl( lhs_content, nothrow_move(), 1L);
0840     }
0841 
0842 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0843 private:
0844     // silence MSVC warning C4512: assignment operator could not be generated
0845     backup_assigner& operator= (backup_assigner const&);
0846 #endif
0847 };
0848 
0849 ///////////////////////////////////////////////////////////////////////////////
0850 // (detail) class swap_with
0851 //
0852 // Visitor that swaps visited value with content of given variant.
0853 //
0854 // Precondition: Given variant MUST have same logical type as visited value.
0855 //
0856 template <typename Variant>
0857 struct swap_with
0858     : public static_visitor<>
0859 {
0860 private: // representation
0861 
0862     Variant& toswap_;
0863 
0864 public: // structors
0865 
0866     explicit swap_with(Variant& toswap) BOOST_NOEXCEPT
0867         : toswap_(toswap)
0868     {
0869     }
0870 
0871 public: // internal visitor interfaces
0872 
0873     template <typename T>
0874     void operator()(T& operand) const
0875     {
0876         // Since the precondition ensures types are same, get T...
0877         known_get<T> getter;
0878         T& other = toswap_.apply_visitor(getter);
0879 
0880         // ...and swap:
0881         ::boost::detail::variant::move_swap( operand, other );
0882     }
0883 
0884 private:
0885     swap_with& operator=(const swap_with&);
0886 
0887 };
0888 
0889 ///////////////////////////////////////////////////////////////////////////////
0890 // (detail) class reflect
0891 //
0892 // Generic static visitor that performs a typeid on the value it visits.
0893 //
0894 
0895 class reflect
0896     : public static_visitor<const boost::typeindex::type_info&>
0897 {
0898 public: // visitor interfaces
0899 
0900     template <typename T>
0901     const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT
0902     {
0903         return boost::typeindex::type_id<T>().type_info();
0904     }
0905 
0906 };
0907 
0908 ///////////////////////////////////////////////////////////////////////////////
0909 // (detail) class comparer
0910 //
0911 // Generic static visitor that compares the content of the given lhs variant
0912 // with the visited rhs content using Comp.
0913 //
0914 // Precondition: lhs.which() == rhs.which()
0915 //
0916 template <typename Variant, typename Comp>
0917 class comparer
0918     : public static_visitor<bool>
0919 {
0920 private: // representation
0921 
0922     const Variant& lhs_;
0923 
0924 public: // structors
0925 
0926     explicit comparer(const Variant& lhs) BOOST_NOEXCEPT
0927         : lhs_(lhs)
0928     {
0929     }
0930 
0931 public: // visitor interfaces
0932 
0933     template <typename T>
0934     bool operator()(T& rhs_content) const
0935     {
0936         // Since the precondition ensures lhs and rhs types are same, get T...
0937         known_get<T> getter;
0938         const T& lhs_content = lhs_.apply_visitor(getter);
0939 
0940         // ...and compare lhs and rhs contents:
0941         return Comp()(lhs_content, rhs_content);
0942     }
0943 
0944 private:
0945     comparer& operator=(const comparer&);
0946 
0947 };
0948 
0949 ///////////////////////////////////////////////////////////////////////////////
0950 // (detail) class equal_comp
0951 //
0952 // Generic function object compares lhs with rhs using operator==.
0953 //
0954 struct equal_comp
0955 {
0956     template <typename T>
0957     bool operator()(const T& lhs, const T& rhs) const
0958     {
0959         return lhs == rhs;
0960     }
0961 };
0962 
0963 ///////////////////////////////////////////////////////////////////////////////
0964 // (detail) class less_comp
0965 //
0966 // Generic function object compares lhs with rhs using operator<.
0967 //
0968 struct less_comp
0969 {
0970     template <typename T>
0971     bool operator()(const T& lhs, const T& rhs) const
0972     {
0973         return lhs < rhs;
0974     }
0975 };
0976 
0977 ///////////////////////////////////////////////////////////////////////////////
0978 // (detail) class template invoke_visitor
0979 //
0980 // Internal visitor that invokes the given visitor using:
0981 //  * for wrappers (e.g., recursive_wrapper), the wrapper's held value.
0982 //  * for all other values, the value itself.
0983 //
0984 template <typename Visitor, bool MoveSemantics>
0985 class invoke_visitor
0986 {
0987 private: // representation
0988 
0989     Visitor& visitor_;
0990 
0991 public: // visitor typedefs
0992 
0993     typedef typename Visitor::result_type
0994         result_type;
0995 
0996 public: // structors
0997 
0998     explicit invoke_visitor(Visitor& visitor) BOOST_NOEXCEPT
0999         : visitor_(visitor)
1000     {
1001     }
1002 
1003 public: // internal visitor interfaces
1004 
1005     //using workaround with is_same<T, T> to prenvent compilation error, because we need to use T in enable_if to make SFINAE work
1006     template <typename T>
1007     typename enable_if_c<MoveSemantics && is_same<T, T>::value, result_type>::type internal_visit(T&& operand, int)
1008     {
1009         return visitor_(std::move(operand));
1010     }
1011 
1012     //using workaround with is_same<T, T> to prenvent compilation error, because we need to use T in enable_if to make SFINAE work
1013     template <typename T>
1014     typename disable_if_c<MoveSemantics && is_same<T, T>::value, result_type>::type internal_visit(T&& operand, int)
1015     {
1016         return visitor_(operand);
1017     }
1018 
1019 public: // internal visitor interfaces, cont.
1020 
1021     template <typename T>
1022     result_type internal_visit(boost::recursive_wrapper<T>& operand, long)
1023     {
1024         return internal_visit( operand.get(), 1L );
1025     }
1026 
1027     template <typename T>
1028     result_type internal_visit(const boost::recursive_wrapper<T>& operand, long)
1029     {
1030         return internal_visit( operand.get(), 1L );
1031     }
1032 
1033     template <typename T>
1034     result_type internal_visit(boost::detail::reference_content<T>& operand, long)
1035     {
1036         return internal_visit( operand.get(), 1L );
1037     }
1038 
1039     template <typename T>
1040     result_type internal_visit(const boost::detail::reference_content<T>& operand, long)
1041     {
1042         return internal_visit( operand.get(), 1L );
1043     }
1044 
1045     template <typename T>
1046     result_type internal_visit(boost::detail::variant::backup_holder<T>& operand, long)
1047     {
1048         return internal_visit( operand.get(), 1L );
1049     }
1050 
1051     template <typename T>
1052     result_type internal_visit(const boost::detail::variant::backup_holder<T>& operand, long)
1053     {
1054         return internal_visit( operand.get(), 1L );
1055     }
1056 
1057 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
1058 private:
1059     // silence MSVC warning C4512: assignment operator could not be generated
1060     invoke_visitor& operator= (invoke_visitor const&);
1061 #endif
1062 };
1063 
1064 }} // namespace detail::variant
1065 
1066 ///////////////////////////////////////////////////////////////////////////////
1067 // class template variant (concept inspired by Andrei Alexandrescu)
1068 //
1069 // See docs and boost/variant/variant_fwd.hpp for more information.
1070 //
1071 template <
1072       typename T0_
1073     , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
1074     >
1075 class variant
1076 {
1077 private: // helpers, for typedefs (below)
1078 
1079     typedef variant wknd_self_t;
1080 
1081     struct is_recursive_
1082         : detail::variant::is_recursive_flag<T0_>
1083     {
1084     };
1085 
1086     typedef typename mpl::eval_if<
1087           is_recursive_
1088         , T0_
1089         , mpl::identity< T0_ >
1090         >::type unwrapped_T0_;
1091 
1092     struct is_sequence_based_
1093         : detail::variant::is_over_sequence<unwrapped_T0_>
1094     {
1095     };
1096 
1097 private: // helpers, for typedefs (below)
1098 
1099     typedef typename mpl::eval_if<
1100           is_sequence_based_
1101         , unwrapped_T0_ // over_sequence<...>::type
1102         , detail::variant::make_variant_list<
1103               unwrapped_T0_
1104             , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
1105             >
1106         >::type specified_types;
1107 
1108     BOOST_STATIC_ASSERT((
1109           ::boost::mpl::not_< mpl::empty<specified_types> >::value
1110         ));
1111 
1112 public: // public typedefs
1113     typedef typename mpl::eval_if<
1114           is_recursive_
1115         , mpl::transform<
1116               specified_types
1117             , mpl::protect<
1118                   detail::variant::quoted_enable_recursive<wknd_self_t>
1119                 >
1120             >
1121         , mpl::identity< specified_types >
1122         >::type recursive_enabled_types;    // used by is_variant_constructible_from<> trait
1123 
1124     typedef typename mpl::transform<
1125           recursive_enabled_types
1126         , unwrap_recursive<mpl::_1>
1127         >::type types;
1128 
1129 private: // internal typedefs
1130 
1131     typedef typename mpl::transform<
1132           recursive_enabled_types
1133         , mpl::protect< detail::make_reference_content<> >
1134         >::type internal_types;
1135 
1136     typedef typename mpl::front<
1137           internal_types
1138         >::type internal_T0;
1139 
1140 private: // helpers, for representation (below)
1141 
1142     typedef typename detail::variant::find_fallback_type<
1143           internal_types
1144         >::type fallback_type_result_;
1145 
1146     typedef typename fallback_type_result_::first
1147         fallback_type_index_;
1148     typedef typename fallback_type_result_::second
1149         fallback_type_;
1150 
1151     struct has_fallback_type_
1152         : mpl::not_<
1153               is_same< fallback_type_, detail::variant::no_fallback_type >
1154             >
1155     {
1156     };
1157 
1158     typedef has_fallback_type_
1159         never_uses_backup_flag;
1160 
1161     typedef typename detail::variant::make_storage<
1162           internal_types, never_uses_backup_flag
1163         >::type storage_t;
1164 
1165     typedef typename detail::variant::is_variant_move_noexcept_constructible<
1166         internal_types
1167     > variant_move_noexcept_constructible;
1168 
1169     typedef typename detail::variant::is_variant_move_noexcept_assignable<
1170         internal_types
1171     > variant_move_noexcept_assignable;
1172 
1173 private: // helpers, for representation (below)
1174 
1175     // which_ on:
1176     // * [0,  size<internal_types>) indicates stack content
1177     // * [-size<internal_types>, 0) indicates pointer to heap backup
1178     // if which_ >= 0:
1179     // * then which() -> which_
1180     // * else which() -> -(which_ + 1)
1181 
1182 #if !defined(BOOST_VARIANT_MINIMIZE_SIZE)
1183 
1184     typedef int which_t;
1185 
1186 #else // defined(BOOST_VARIANT_MINIMIZE_SIZE)
1187 
1188     // [if O1_size available, then attempt which_t size optimization...]
1189     // [select signed char if fewer than SCHAR_MAX types, else signed int:]
1190     typedef typename mpl::eval_if<
1191           mpl::equal_to< mpl::O1_size<internal_types>, mpl::long_<-1> >
1192         , mpl::identity< int >
1193         , mpl::if_<
1194               mpl::less< mpl::O1_size<internal_types>, mpl::int_<SCHAR_MAX> >
1195             , signed char
1196             , int
1197             >
1198         >::type which_t;
1199 
1200 #endif // BOOST_VARIANT_MINIMIZE_SIZE switch
1201 
1202 // representation -- private when possible
1203 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1204     private:
1205 #else
1206     public:
1207 #endif
1208 
1209     which_t which_;
1210     storage_t storage_;
1211 
1212     void indicate_which(int which_arg) BOOST_NOEXCEPT
1213     {
1214         which_ = static_cast<which_t>( which_arg );
1215     }
1216 
1217     void indicate_backup_which(int which_arg) BOOST_NOEXCEPT
1218     {
1219         which_ = static_cast<which_t>( -(which_arg + 1) );
1220     }
1221 
1222 private: // helpers, for queries (below)
1223 
1224     bool using_backup() const BOOST_NOEXCEPT
1225     {
1226         return which_ < 0;
1227     }
1228 
1229 public: // queries
1230 
1231     int which() const BOOST_NOEXCEPT
1232     {
1233         // If using heap backup...
1234         if (using_backup())
1235             // ...then return adjusted which_:
1236             return -(which_ + 1);
1237 
1238         // Otherwise, return which_ directly:
1239         return which_;
1240     }
1241 
1242 private: // helpers, for structors (below)
1243 
1244     struct initializer
1245         : BOOST_VARIANT_AUX_INITIALIZER_T(
1246               recursive_enabled_types, recursive_enabled_T
1247             )
1248     {
1249     };
1250 
1251     void destroy_content() BOOST_NOEXCEPT
1252     {
1253         detail::variant::destroyer visitor;
1254         this->internal_apply_visitor(visitor);
1255     }
1256 
1257 public: // structors
1258 
1259     ~variant() BOOST_NOEXCEPT
1260     {
1261         destroy_content();
1262     }
1263 
1264     variant()
1265 #if !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
1266               BOOST_NOEXCEPT_IF(boost::has_nothrow_constructor<internal_T0>::value)
1267 #endif
1268     {
1269 #ifdef _MSC_VER
1270 #pragma warning( push )
1271 // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
1272 #pragma warning( disable : 4345 )
1273 #endif
1274         // NOTE TO USER :
1275         // Compile error from here indicates that the first bound
1276         // type is not default-constructible, and so variant cannot
1277         // support its own default-construction.
1278         //
1279         new( storage_.address() ) internal_T0();
1280         indicate_which(0); // zero is the index of the first bounded type
1281 #ifdef _MSC_VER
1282 #pragma warning( pop )
1283 #endif
1284     }
1285 
1286 private: // helpers, for structors, cont. (below)
1287 
1288     class convert_copy_into
1289         : public static_visitor<int>
1290     {
1291     private: // representation
1292 
1293         void* storage_;
1294 
1295     public: // structors
1296 
1297         explicit convert_copy_into(void* storage) BOOST_NOEXCEPT
1298             : storage_(storage)
1299         {
1300         }
1301 
1302     public: // internal visitor interfaces (below)
1303 
1304         template <typename T>
1305         int internal_visit(T& operand, int) const
1306         {
1307             // NOTE TO USER :
1308             // Compile error here indicates one of the source variant's types
1309             // cannot be unambiguously converted to the destination variant's
1310             // types (or that no conversion exists).
1311             //
1312             return initializer::initialize(storage_, operand);
1313         }
1314 
1315 #   if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0564))
1316         template <typename T>
1317         result_type internal_visit(const T& operand, int) const
1318         {
1319             return initializer::initialize(storage_, operand);
1320         }
1321 #   endif
1322 
1323         template <typename T>
1324         int internal_visit(boost::detail::reference_content<T>& operand, long) const
1325         {
1326             return internal_visit( operand.get(), 1L );
1327         }
1328 
1329         template <typename T>
1330         int internal_visit(const boost::detail::reference_content<T>& operand, long) const
1331         {
1332             return internal_visit( operand.get(), 1L );
1333         }
1334 
1335         template <typename T>
1336         int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
1337         {
1338             return internal_visit( operand.get(), 1L );
1339         }
1340 
1341         template <typename T>
1342         int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
1343         {
1344             return internal_visit( operand.get(), 1L );
1345         }
1346 
1347         template <typename T>
1348         int internal_visit(boost::recursive_wrapper<T>& operand, long) const
1349         {
1350             return internal_visit( operand.get(), 1L );
1351         }
1352 
1353         template <typename T>
1354         int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
1355         {
1356             return internal_visit( operand.get(), 1L );
1357         }
1358 
1359     };
1360 
1361     friend class convert_copy_into;
1362 
1363     class convert_move_into
1364         : public static_visitor<int>
1365     {
1366     private: // representation
1367 
1368         void* storage_;
1369 
1370     public: // structors
1371 
1372         explicit convert_move_into(void* storage) BOOST_NOEXCEPT
1373             : storage_(storage)
1374         {
1375         }
1376 
1377     public: // internal visitor interfaces (below)
1378 
1379         template <typename T>
1380         int internal_visit(T& operand, int) const
1381         {
1382             // NOTE TO USER :
1383             // Compile error here indicates one of the source variant's types
1384             // cannot be unambiguously converted to the destination variant's
1385             // types (or that no conversion exists).
1386             //
1387             return initializer::initialize(storage_, detail::variant::move(operand) );
1388         }
1389 
1390         template <typename T>
1391         int internal_visit(boost::detail::reference_content<T>& operand, long) const
1392         {
1393             return internal_visit( operand.get(), 1L );
1394         }
1395 
1396         template <typename T>
1397         int internal_visit(const boost::detail::reference_content<T>& operand, long) const
1398         {
1399             return internal_visit( operand.get(), 1L );
1400         }
1401 
1402         template <typename T>
1403         int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
1404         {
1405             return internal_visit( operand.get(), 1L );
1406         }
1407 
1408         template <typename T>
1409         int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
1410         {
1411             return internal_visit( operand.get(), 1L );
1412         }
1413 
1414         template <typename T>
1415         int internal_visit(boost::recursive_wrapper<T>& operand, long) const
1416         {
1417             return internal_visit( operand.get(), 1L );
1418         }
1419 
1420         template <typename T>
1421         int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
1422         {
1423             return internal_visit( operand.get(), 1L );
1424         }
1425     };
1426 
1427     friend class convert_move_into;
1428 
1429 private: // helpers, for structors, below
1430 
1431     template <typename T>
1432     void convert_construct(
1433           T& operand
1434         , int
1435         , mpl::false_ = mpl::false_() // is_foreign_variant
1436         )
1437     {
1438         // NOTE TO USER :
1439         // Compile error here indicates that the given type is not
1440         // unambiguously convertible to one of the variant's types
1441         // (or that no conversion exists).
1442         //
1443         indicate_which(
1444               initializer::initialize(
1445                   storage_.address()
1446                 , operand
1447                 )
1448             );
1449     }
1450 
1451     template <typename T>
1452     typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type convert_construct(
1453           T&& operand
1454         , int
1455         , mpl::false_ = mpl::false_() // is_foreign_variant
1456         )
1457     {
1458         // NOTE TO USER :
1459         // Compile error here indicates that the given type is not
1460         // unambiguously convertible to one of the variant's types
1461         // (or that no conversion exists).
1462         //
1463         indicate_which(
1464               initializer::initialize(
1465                   storage_.address()
1466                 , detail::variant::move(operand)
1467                 )
1468             );
1469     }
1470 
1471     template <typename Variant>
1472     void convert_construct(
1473           Variant& operand
1474         , long
1475         , mpl::true_// is_foreign_variant
1476         )
1477     {
1478         convert_copy_into visitor(storage_.address());
1479         indicate_which(
1480               operand.internal_apply_visitor(visitor)
1481             );
1482     }
1483 
1484     template <typename Variant>
1485     typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct(
1486           Variant&& operand
1487         , long
1488         , mpl::true_// is_foreign_variant
1489         )
1490     {
1491         convert_move_into visitor(storage_.address());
1492         indicate_which(
1493               operand.internal_apply_visitor(visitor)
1494             );
1495     }
1496 
1497     template <typename Variant>
1498     void convert_construct_variant(Variant& operand)
1499     {
1500         // [Determine if the given variant is itself a bounded type, or if its
1501         //  content needs to be converted (i.e., it is a 'foreign' variant):]
1502         //
1503 
1504         typedef typename mpl::find_if<
1505               types
1506             , is_same<
1507                   add_const<mpl::_1>
1508                 , const Variant
1509                 >
1510             >::type found_it;
1511 
1512         typedef typename mpl::end<types>::type not_found;
1513         typedef typename is_same<
1514               found_it, not_found
1515             >::type is_foreign_variant;
1516 
1517         // Convert construct from operand:
1518         convert_construct(
1519               operand, 1L
1520             , is_foreign_variant()
1521             );
1522     }
1523 
1524     template <typename Variant>
1525     typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct_variant(Variant&& operand)
1526     {
1527         // [Determine if the given variant is itself a bounded type, or if its
1528         //  content needs to be converted (i.e., it is a 'foreign' variant):]
1529         //
1530 
1531         typedef typename mpl::find_if<
1532               types
1533             , is_same<
1534                   add_const<mpl::_1>
1535                 , const Variant
1536                 >
1537             >::type found_it;
1538 
1539         typedef typename mpl::end<types>::type not_found;
1540         typedef typename is_same<
1541               found_it, not_found
1542             >::type is_foreign_variant;
1543 
1544         // Convert move construct from operand:
1545         convert_construct(
1546               detail::variant::move(operand), 1L
1547             , is_foreign_variant()
1548             );
1549     }
1550 
1551     template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
1552     typename boost::enable_if<mpl::or_<
1553         boost::is_same<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>, variant>,
1554         boost::detail::variant::is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&, internal_types>
1555     > >::type convert_construct(
1556           boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
1557         , long
1558         )
1559     {
1560         convert_construct_variant(operand);
1561     }
1562 
1563     template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
1564     typename boost::enable_if<mpl::or_<
1565         boost::is_same<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>, variant>,
1566         boost::detail::variant::is_variant_constructible_from<const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&, internal_types>
1567     > >::type convert_construct(
1568           const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
1569         , long
1570         )
1571     {
1572         convert_construct_variant(operand);
1573     }
1574 
1575     template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
1576     typename boost::enable_if<mpl::or_<
1577         boost::is_same<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>, variant>,
1578         boost::detail::variant::is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&&, internal_types>
1579     > >::type convert_construct(
1580           boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&& operand
1581         , long
1582         )
1583     {
1584         convert_construct_variant( detail::variant::move(operand) );
1585     }
1586 
1587 public: // structors, cont.
1588 
1589     template <typename T>
1590     variant(const T& operand,
1591         typename boost::enable_if<mpl::or_<
1592             mpl::and_<
1593                 mpl::not_< boost::is_same<T, variant> >,
1594                 boost::detail::variant::is_variant_constructible_from<const T&, internal_types>
1595             >,
1596             boost::is_same<T, boost::recursive_variant_> >,
1597             bool >::type = true)
1598     {
1599         convert_construct(operand, 1L);
1600     }
1601 
1602     template <typename T>
1603     variant(
1604           T& operand
1605         , typename boost::enable_if<mpl::or_<
1606             mpl::and_<
1607                 mpl::not_< is_const<T> >,
1608                 mpl::not_< boost::is_same<T, variant> >,
1609                 boost::detail::variant::is_variant_constructible_from<T&, internal_types>
1610             >,
1611             boost::is_same<T, boost::recursive_variant_> >,
1612             bool >::type = true
1613         )
1614     {
1615         convert_construct(operand, 1L);
1616     }
1617 
1618     template <class T>
1619     variant(T&& operand,
1620         typename boost::enable_if<mpl::or_<
1621             mpl::and_<
1622                 boost::is_rvalue_reference<T&&>,
1623                 mpl::not_< boost::is_const<T> >,
1624                 mpl::not_< boost::is_same<T, variant> >,
1625                 boost::detail::variant::is_variant_constructible_from<T&&, internal_types>
1626             >,
1627             boost::is_same<T, boost::recursive_variant_> >,
1628             bool >::type = true)
1629     {
1630         convert_construct( detail::variant::move(operand), 1L);
1631     }
1632 
1633 public: // structors, cont.
1634 
1635     // [MSVC6 requires copy constructor appear after template constructors]
1636     variant(const variant& operand)
1637     {
1638         // Copy the value of operand into *this...
1639         detail::variant::copy_into visitor( storage_.address() );
1640         operand.internal_apply_visitor(visitor);
1641 
1642         // ...and activate the *this's primary storage on success:
1643         indicate_which(operand.which());
1644     }
1645 
1646     variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value)
1647     {
1648         // Move the value of operand into *this...
1649         detail::variant::move_into visitor( storage_.address() );
1650         operand.internal_apply_visitor(visitor);
1651 
1652         // ...and activate the *this's primary storage on success:
1653         indicate_which(operand.which());
1654     }
1655 
1656 private: // helpers, for modifiers (below)
1657 
1658     template <typename Variant>
1659     friend class detail::variant::backup_assigner;
1660 
1661     // class assigner
1662     //
1663     // Internal visitor that "assigns" the visited value to the given variant
1664     // by appropriate destruction and copy-construction.
1665     //
1666 
1667     class assigner
1668         : public static_visitor<>
1669     {
1670     protected: // representation
1671 
1672         variant& lhs_;
1673         const int rhs_which_;
1674 
1675     public: // structors
1676 
1677         assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT
1678             : lhs_(lhs)
1679             , rhs_which_(rhs_which)
1680         {
1681         }
1682 
1683     protected: // helpers, for internal visitor interface (below)
1684 
1685         template <typename RhsT, typename B1, typename B2>
1686         void assign_impl(
1687               const RhsT& rhs_content
1688             , mpl::true_ // has_nothrow_copy
1689             , B1 // is_nothrow_move_constructible
1690             , B2 // has_fallback_type
1691             ) const BOOST_NOEXCEPT
1692         {
1693             // Destroy lhs's content...
1694             lhs_.destroy_content(); // nothrow
1695 
1696             // ...copy rhs content into lhs's storage...
1697             new(lhs_.storage_.address())
1698                 RhsT( rhs_content ); // nothrow
1699 
1700             // ...and indicate new content type:
1701             lhs_.indicate_which(rhs_which_); // nothrow
1702         }
1703 
1704         template <typename RhsT, typename B>
1705         void assign_impl(
1706               const RhsT& rhs_content
1707             , mpl::false_ // has_nothrow_copy
1708             , mpl::true_ // is_nothrow_move_constructible
1709             , B // has_fallback_type
1710             ) const
1711         {
1712             // Attempt to make a temporary copy (so as to move it below)...
1713             RhsT temp(rhs_content);
1714 
1715             // ...and upon success destroy lhs's content...
1716             lhs_.destroy_content(); // nothrow
1717 
1718             // ...move the temporary copy into lhs's storage...
1719             new(lhs_.storage_.address())
1720                 RhsT( detail::variant::move(temp) ); // nothrow
1721 
1722             // ...and indicate new content type:
1723             lhs_.indicate_which(rhs_which_); // nothrow
1724         }
1725 
1726         void construct_fallback() const BOOST_NOEXCEPT {
1727             // In case of failure, default-construct fallback type in lhs's storage...
1728             new (lhs_.storage_.address())
1729                 fallback_type_; // nothrow
1730 
1731             // ...indicate construction of fallback type...
1732             lhs_.indicate_which(
1733                   BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value
1734                 ); // nothrow
1735         }
1736 
1737         template <typename RhsT>
1738         void assign_impl(
1739               const RhsT& rhs_content
1740             , mpl::false_ // has_nothrow_copy
1741             , mpl::false_ // is_nothrow_move_constructible
1742             , mpl::true_ // has_fallback_type
1743             ) const
1744         {
1745             // Destroy lhs's content...
1746             lhs_.destroy_content(); // nothrow
1747 
1748             BOOST_TRY
1749             {
1750                 // ...and attempt to copy rhs's content into lhs's storage:
1751                 new(lhs_.storage_.address())
1752                     RhsT( rhs_content );
1753             }
1754             BOOST_CATCH (...)
1755             {
1756                 construct_fallback();
1757 
1758                 // ...and rethrow:
1759                 BOOST_RETHROW;
1760             }
1761             BOOST_CATCH_END
1762 
1763             // In the event of success, indicate new content type:
1764             lhs_.indicate_which(rhs_which_); // nothrow
1765         }
1766 
1767         template <typename RhsT>
1768         void assign_impl(
1769               const RhsT& rhs_content
1770             , mpl::false_ // has_nothrow_copy
1771             , mpl::false_ // is_nothrow_move_constructible
1772             , mpl::false_ // has_fallback_type
1773             ) const
1774         {
1775             detail::variant::backup_assigner<wknd_self_t>
1776                 visitor(lhs_, rhs_which_, rhs_content);
1777             lhs_.internal_apply_visitor(visitor);
1778         }
1779 
1780     public: // internal visitor interfaces
1781 
1782         template <typename RhsT>
1783         void internal_visit(const RhsT& rhs_content, int) const
1784         {
1785             typedef typename has_nothrow_copy<RhsT>::type
1786                 nothrow_copy;
1787             typedef typename mpl::or_< // reduces compile-time
1788                   nothrow_copy
1789                 , is_nothrow_move_constructible<RhsT>
1790                 >::type nothrow_move_constructor;
1791 
1792             assign_impl(
1793                   rhs_content
1794                 , nothrow_copy()
1795                 , nothrow_move_constructor()
1796                 , has_fallback_type_()
1797                 );
1798         }
1799 
1800 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
1801     private:
1802         // silence MSVC warning C4512: assignment operator could not be generated
1803         assigner& operator= (assigner const&);
1804 #endif
1805     };
1806 
1807     friend class assigner;
1808 
1809     // class move_assigner
1810     //
1811     // Internal visitor that "move assigns" the visited value to the given variant
1812     // by appropriate destruction and move-construction.
1813     //
1814 
1815     class move_assigner
1816         : public assigner
1817     {
1818     public: // structors
1819 
1820         move_assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT
1821             : assigner(lhs, rhs_which)
1822         {
1823         }
1824 
1825     private: // helpers, for internal visitor interface (below)
1826 
1827         template <typename RhsT, typename B2>
1828         void assign_impl(
1829               RhsT& rhs_content
1830             , mpl::true_ // has_nothrow_copy
1831             , mpl::false_ // is_nothrow_move_constructible
1832             , B2 // has_fallback_type
1833             ) const BOOST_NOEXCEPT
1834         {
1835             assigner::assign_impl(rhs_content, mpl::true_(), mpl::false_(), B2());
1836         }
1837 
1838         template <typename RhsT, typename B, typename B2>
1839         void assign_impl(
1840               RhsT& rhs_content
1841             , B // has_nothrow_copy
1842             , mpl::true_ // is_nothrow_move_constructible
1843             , B2 // has_fallback_type
1844             ) const BOOST_NOEXCEPT
1845         {
1846             // ...destroy lhs's content...
1847             assigner::lhs_.destroy_content(); // nothrow
1848 
1849             // ...move the rhs_content into lhs's storage...
1850             new(assigner::lhs_.storage_.address())
1851                 RhsT( detail::variant::move(rhs_content) ); // nothrow
1852 
1853             // ...and indicate new content type:
1854             assigner::lhs_.indicate_which(assigner::rhs_which_); // nothrow
1855         }
1856 
1857         template <typename RhsT>
1858         void assign_impl(
1859               RhsT& rhs_content
1860             , mpl::false_ // has_nothrow_copy
1861             , mpl::false_ // is_nothrow_move_constructible
1862             , mpl::true_ // has_fallback_type
1863             ) const
1864         {
1865             // Destroy lhs's content...
1866             assigner::lhs_.destroy_content(); // nothrow
1867 
1868             BOOST_TRY
1869             {
1870                 // ...and attempt to copy rhs's content into lhs's storage:
1871                 new(assigner::lhs_.storage_.address())
1872                     RhsT( detail::variant::move(rhs_content) );
1873             }
1874             BOOST_CATCH (...)
1875             {
1876                 assigner::construct_fallback();
1877 
1878                 // ...and rethrow:
1879                 BOOST_RETHROW;
1880             }
1881             BOOST_CATCH_END
1882 
1883             // In the event of success, indicate new content type:
1884             assigner::lhs_.indicate_which(assigner::rhs_which_); // nothrow
1885         }
1886 
1887         template <typename RhsT>
1888         void assign_impl(
1889               RhsT& rhs_content
1890             , mpl::false_ // has_nothrow_copy
1891             , mpl::false_ // is_nothrow_move_constructible
1892             , mpl::false_ // has_fallback_type
1893             ) const
1894         {
1895             assigner::assign_impl(rhs_content, mpl::false_(), mpl::false_(), mpl::false_());
1896         }
1897 
1898     public: // internal visitor interfaces
1899 
1900         template <typename RhsT>
1901         void internal_visit(RhsT& rhs_content, int) const
1902         {
1903             typedef typename is_nothrow_move_constructible<RhsT>::type
1904                 nothrow_move_constructor;
1905             typedef typename mpl::or_< // reduces compile-time
1906                   nothrow_move_constructor
1907                 , has_nothrow_copy<RhsT>
1908                 >::type nothrow_copy;
1909 
1910             assign_impl(
1911                   rhs_content
1912                 , nothrow_copy()
1913                 , nothrow_move_constructor()
1914                 , has_fallback_type_()
1915                 );
1916         }
1917 
1918 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
1919     private:
1920         // silence MSVC warning C4512: assignment operator could not be generated
1921         move_assigner& operator= (move_assigner const&);
1922 #endif
1923     };
1924 
1925     friend class move_assigner;
1926 
1927     void variant_assign(const variant& rhs)
1928     {
1929         // If the contained types are EXACTLY the same...
1930         if (which_ == rhs.which_)
1931         {
1932             // ...then assign rhs's storage to lhs's content:
1933             detail::variant::assign_storage visitor(rhs.storage_.address());
1934             this->internal_apply_visitor(visitor);
1935         }
1936         else
1937         {
1938             // Otherwise, perform general (copy-based) variant assignment:
1939             assigner visitor(*this, rhs.which());
1940             rhs.internal_apply_visitor(visitor);
1941         }
1942     }
1943 
1944     void variant_assign(variant&& rhs)
1945     {
1946         // If the contained types are EXACTLY the same...
1947         if (which_ == rhs.which_)
1948         {
1949             // ...then move rhs's storage to lhs's content:
1950             detail::variant::move_storage visitor(rhs.storage_.address());
1951             this->internal_apply_visitor(visitor);
1952         }
1953         else
1954         {
1955             // Otherwise, perform general (move-based) variant assignment:
1956             move_assigner visitor(*this, rhs.which());
1957             rhs.internal_apply_visitor(visitor);
1958         }
1959     }
1960 
1961 private: // helpers, for modifiers (below)
1962 
1963     template <typename T>
1964     void assign(const T& rhs)
1965     {
1966         // If direct T-to-T assignment is not possible...
1967         detail::variant::direct_assigner<T> direct_assign(rhs);
1968         if (this->apply_visitor(direct_assign) == false)
1969         {
1970             // ...then convert rhs to variant and assign:
1971             //
1972             // While potentially inefficient, the following construction of a
1973             // variant allows T as any type convertible to one of the bounded
1974             // types without excessive code redundancy.
1975             //
1976             variant temp(rhs);
1977             variant_assign( detail::variant::move(temp) );
1978         }
1979     }
1980 
1981     template <typename T>
1982     void move_assign(T&& rhs)
1983     {
1984         // If direct T-to-T move assignment is not possible...
1985         detail::variant::direct_mover<T> direct_move(rhs);
1986         if (this->apply_visitor(direct_move) == false)
1987         {
1988             // ...then convert rhs to variant and assign:
1989             //
1990             // While potentially inefficient, the following construction of a
1991             // variant allows T as any type convertible to one of the bounded
1992             // types without excessive code redundancy.
1993             //
1994             variant temp( detail::variant::move(rhs) );
1995             variant_assign( detail::variant::move(temp) );
1996         }
1997     }
1998 
1999 public: // modifiers
2000 
2001 #if !BOOST_WORKAROUND(BOOST_CLANG_VERSION, BOOST_TESTED_AT(150000)) || BOOST_CXX_VERSION <= 202002L
2002     template <class T>
2003     typename boost::enable_if<
2004         boost::mpl::and_<
2005             boost::is_rvalue_reference<T&&>,
2006             mpl::not_< boost::is_const<T> >,
2007             boost::detail::variant::is_variant_constructible_from<T&&, internal_types>
2008         >,
2009         variant&
2010     >::type operator=(T&& rhs)
2011     {
2012         move_assign( detail::variant::move(rhs) );
2013         return *this;
2014     }
2015 #endif
2016 
2017     template <typename T>
2018     typename boost::enable_if<
2019         mpl::or_<
2020             boost::is_same<T, variant>,
2021             boost::detail::variant::is_variant_constructible_from<const T&, internal_types>
2022         >,
2023         variant&
2024     >::type operator=(const T& rhs)
2025     {
2026         assign(rhs);
2027         return *this;
2028     }
2029 
2030     // [MSVC6 requires copy assign appear after templated operator=]
2031     variant& operator=(const variant& rhs)
2032     {
2033         variant_assign(rhs);
2034         return *this;
2035     }
2036 
2037     variant& operator=(variant&& rhs)
2038 #if !defined(__GNUC__) || (__GNUC__ != 4) || (__GNUC_MINOR__ > 6) || defined(__clang__)
2039         BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value && variant_move_noexcept_assignable::type::value)
2040 #endif
2041     {
2042         variant_assign( detail::variant::move(rhs) );
2043         return *this;
2044     }
2045 
2046     void swap(variant& rhs)
2047     {
2048         // If the contained types are the same...
2049         if (which() == rhs.which())
2050         {
2051             // ...then swap the values directly:
2052             detail::variant::swap_with<variant> visitor(rhs);
2053             this->apply_visitor(visitor);
2054         }
2055         else
2056         {
2057             // ...otherwise, perform general variant swap:
2058             variant tmp( detail::variant::move(rhs) );
2059             rhs = detail::variant::move(*this);
2060             *this = detail::variant::move(tmp);
2061         }
2062     }
2063 
2064 public: // queries
2065 
2066     //
2067     // NOTE: member which() defined above.
2068     //
2069 
2070     bool empty() const BOOST_NOEXCEPT
2071     {
2072         return false;
2073     }
2074 
2075     const boost::typeindex::type_info& type() const
2076     {
2077         detail::variant::reflect visitor;
2078         return this->apply_visitor(visitor);
2079     }
2080 
2081 public: // prevent comparison with foreign types
2082 
2083     template <typename U>
2084     void operator==(const U&) const
2085     {
2086         BOOST_STATIC_ASSERT( false && sizeof(U) );
2087     }
2088 
2089     template <typename U>
2090     void operator<(const U&) const
2091     {
2092         BOOST_STATIC_ASSERT( false && sizeof(U) );
2093     }
2094 
2095     template <typename U>
2096     void operator!=(const U&) const
2097     {
2098         BOOST_STATIC_ASSERT( false && sizeof(U) );
2099     }
2100 
2101     template <typename U>
2102     void operator>(const U&) const
2103     {
2104         BOOST_STATIC_ASSERT( false && sizeof(U) );
2105     }
2106 
2107     template <typename U>
2108     void operator<=(const U&) const
2109     {
2110         BOOST_STATIC_ASSERT( false && sizeof(U) );
2111     }
2112 
2113     template <typename U>
2114     void operator>=(const U&) const
2115     {
2116         BOOST_STATIC_ASSERT( false && sizeof(U) );
2117     }
2118 
2119 public: // comparison operators
2120 
2121     // [MSVC6 requires these operators appear after template operators]
2122 
2123     bool operator==(const variant& rhs) const
2124     {
2125         if (this->which() != rhs.which())
2126             return false;
2127 
2128         detail::variant::comparer<
2129               variant, detail::variant::equal_comp
2130             > visitor(*this);
2131         return rhs.apply_visitor(visitor);
2132     }
2133 
2134     bool operator<(const variant& rhs) const
2135     {
2136         //
2137         // Dirk Schreib suggested this collating order.
2138         //
2139 
2140         if (this->which() != rhs.which())
2141             return this->which() < rhs.which();
2142 
2143         detail::variant::comparer<
2144               variant, detail::variant::less_comp
2145             > visitor(*this);
2146         return rhs.apply_visitor(visitor);
2147     }
2148 
2149     ///////////////////////////////////////////////////////////////////////////////
2150     // comparison operators != > <= >=
2151     inline bool operator!=(const variant& rhs) const
2152     {
2153         return !(*this == rhs);
2154     }
2155 
2156     inline bool operator>(const variant& rhs) const
2157     {
2158         return rhs < *this;
2159     }
2160 
2161     inline bool operator<=(const variant& rhs) const
2162     {
2163         return !(*this > rhs);
2164     }
2165 
2166     inline bool operator>=(const variant& rhs) const
2167     {
2168         return !(*this < rhs);
2169     }
2170 
2171 // helpers, for visitation support (below) -- private when possible
2172 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
2173 
2174     template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
2175     friend class variant;
2176 
2177 private:
2178 
2179 #else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
2180 
2181 public:
2182 
2183 #endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
2184 
2185     template <typename Visitor, typename VoidPtrCV>
2186     BOOST_FORCEINLINE static typename Visitor::result_type
2187     internal_apply_visitor_impl(
2188           int internal_which
2189         , int logical_which
2190         , Visitor& visitor
2191         , VoidPtrCV storage
2192         )
2193     {
2194         typedef mpl::int_<0> first_which;
2195         typedef typename mpl::begin<internal_types>::type first_it;
2196         typedef typename mpl::end<internal_types>::type last_it;
2197 
2198         typedef detail::variant::visitation_impl_step<
2199               first_it, last_it
2200             > first_step;
2201 
2202         return detail::variant::visitation_impl(
2203               internal_which, logical_which
2204             , visitor, storage, mpl::false_()
2205             , never_uses_backup_flag()
2206             , static_cast<first_which*>(0), static_cast<first_step*>(0)
2207             );
2208     }
2209 
2210     template <typename Visitor>
2211     BOOST_FORCEINLINE typename Visitor::result_type
2212     internal_apply_visitor(Visitor& visitor)
2213     {
2214         return internal_apply_visitor_impl(
2215               which_, which(), visitor, storage_.address()
2216             );
2217     }
2218 
2219     template <typename Visitor>
2220     BOOST_FORCEINLINE typename Visitor::result_type
2221     internal_apply_visitor(Visitor& visitor) const
2222     {
2223         return internal_apply_visitor_impl(
2224               which_, which(), visitor, storage_.address()
2225             );
2226     }
2227 
2228 public: // visitation support
2229 
2230     template <typename Visitor>
2231     typename Visitor::result_type
2232     apply_visitor(Visitor& visitor) &&
2233     {
2234         detail::variant::invoke_visitor<Visitor, true> invoker(visitor);
2235         return this->internal_apply_visitor(invoker);
2236     }
2237 
2238     template <typename Visitor>
2239     typename Visitor::result_type
2240     apply_visitor(Visitor& visitor) const&&
2241     {
2242         detail::variant::invoke_visitor<Visitor, true> invoker(visitor);
2243         return this->internal_apply_visitor(invoker);
2244     }
2245 
2246     template <typename Visitor>
2247     typename Visitor::result_type
2248     apply_visitor(Visitor& visitor) &
2249     {
2250         detail::variant::invoke_visitor<Visitor, false> invoker(visitor);
2251         return this->internal_apply_visitor(invoker);
2252     }
2253 
2254     template <typename Visitor>
2255     typename Visitor::result_type
2256     apply_visitor(Visitor& visitor) const &
2257     {
2258         detail::variant::invoke_visitor<Visitor, false> invoker(visitor);
2259         return this->internal_apply_visitor(invoker);
2260     }
2261 
2262 }; // class variant
2263 
2264 ///////////////////////////////////////////////////////////////////////////////
2265 // metafunction make_variant_over
2266 //
2267 // See docs and boost/variant/variant_fwd.hpp for more information.
2268 //
2269 template <typename Types>
2270 struct make_variant_over
2271 {
2272 private: // precondition assertions
2273 
2274     BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
2275     typedef typename boost::mpl::insert_range<
2276       boost::mpl::list<>
2277     , boost::mpl::end< boost::mpl::list<> >::type
2278     , Types
2279     >::type copied_sequence_t;
2280 
2281 public: // metafunction result
2282 
2283     typedef variant<
2284           detail::variant::over_sequence<copied_sequence_t>
2285         > type;
2286 
2287 };
2288 
2289 ///////////////////////////////////////////////////////////////////////////////
2290 // function template swap
2291 //
2292 // Swaps two variants of the same type (i.e., identical specification).
2293 //
2294 template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
2295 inline void swap(
2296       variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs
2297     , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs
2298     )
2299 {
2300     lhs.swap(rhs);
2301 }
2302 
2303 } // namespace boost
2304 
2305 // implementation additions
2306 
2307 #if !defined(BOOST_NO_IOSTREAM)
2308 #include <boost/variant/detail/variant_io.hpp>
2309 #endif // BOOST_NO_IOSTREAM
2310 
2311 #endif // BOOST_VARIANT_VARIANT_HPP