LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/variant - variant.hpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 74 75 98.7 %
Date: 2026-06-25 07:23:43 Functions: 55 70 78.6 %

          Line data    Source code
       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 Eric Friedman, Itay Maman
       7             : // Copyright (c) 2012-2025 Antony Polukhin
       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             : // Thanks to Adam Romanek for providing patches for exception-disabled env.
      14             : 
      15             : #ifndef BOOST_VARIANT_VARIANT_HPP
      16             : #define BOOST_VARIANT_VARIANT_HPP
      17             : 
      18             : #include <cstddef> // for std::size_t
      19             : #include <new> // for placement new
      20             : 
      21             : #include <boost/type_index.hpp>
      22             : 
      23             : #include <boost/variant/detail/config.hpp>
      24             : #include <boost/mpl/aux_/value_wknd.hpp>
      25             : 
      26             : #include <boost/variant/variant_fwd.hpp>
      27             : #include <boost/variant/detail/backup_holder.hpp>
      28             : #include <boost/variant/detail/enable_recursive_fwd.hpp>
      29             : #include <boost/variant/detail/forced_return.hpp>
      30             : #include <boost/variant/detail/initializer.hpp>
      31             : #include <boost/variant/detail/make_variant_list.hpp>
      32             : #include <boost/variant/detail/over_sequence.hpp>
      33             : #include <boost/variant/detail/visitation_impl.hpp>
      34             : #include <boost/variant/detail/hash_variant.hpp>
      35             : #include <boost/variant/detail/std_hash.hpp>
      36             : 
      37             : #include <boost/variant/detail/move.hpp>
      38             : 
      39             : #include <boost/detail/reference_content.hpp>
      40             : #include <boost/blank.hpp>
      41             : #include <boost/integer/common_factor_ct.hpp>
      42             : #include <boost/static_assert.hpp>
      43             : #include <boost/type_traits/aligned_storage.hpp>
      44             : #include <boost/type_traits/alignment_of.hpp>
      45             : #include <boost/type_traits/add_const.hpp>
      46             : #include <boost/type_traits/has_nothrow_constructor.hpp>
      47             : #include <boost/type_traits/has_nothrow_copy.hpp>
      48             : #include <boost/type_traits/is_nothrow_move_assignable.hpp>
      49             : #include <boost/type_traits/is_nothrow_move_constructible.hpp>
      50             : #include <boost/type_traits/is_const.hpp>
      51             : #include <boost/type_traits/is_same.hpp>
      52             : #include <boost/type_traits/is_rvalue_reference.hpp>
      53             : #include <boost/type_traits/is_constructible.hpp>
      54             : #include <boost/type_traits/add_lvalue_reference.hpp>
      55             : #include <boost/type_traits/declval.hpp>
      56             : #include <boost/core/no_exceptions_support.hpp>
      57             : #include <boost/core/enable_if.hpp>
      58             : #include <boost/variant/recursive_wrapper_fwd.hpp>
      59             : #include <boost/variant/static_visitor.hpp>
      60             : 
      61             : #include <boost/mpl/assert.hpp>
      62             : #include <boost/mpl/begin_end.hpp>
      63             : #include <boost/mpl/bool.hpp>
      64             : #include <boost/mpl/deref.hpp>
      65             : #include <boost/mpl/empty.hpp>
      66             : #include <boost/mpl/eval_if.hpp>
      67             : #include <boost/mpl/find_if.hpp>
      68             : #include <boost/mpl/fold.hpp>
      69             : #include <boost/mpl/front.hpp>
      70             : #include <boost/mpl/identity.hpp>
      71             : #include <boost/mpl/if.hpp>
      72             : #include <boost/mpl/insert_range.hpp>
      73             : #include <boost/mpl/int.hpp>
      74             : #include <boost/mpl/is_sequence.hpp>
      75             : #include <boost/mpl/iterator_range.hpp>
      76             : #include <boost/mpl/iter_fold_if.hpp>
      77             : #include <boost/mpl/list.hpp>
      78             : #include <boost/mpl/logical.hpp>
      79             : #include <boost/mpl/max_element.hpp>
      80             : #include <boost/mpl/next.hpp>
      81             : #include <boost/mpl/not.hpp>
      82             : #include <boost/mpl/pair.hpp>
      83             : #include <boost/mpl/protect.hpp>
      84             : #include <boost/mpl/push_front.hpp>
      85             : #include <boost/mpl/same_as.hpp>
      86             : #include <boost/mpl/size_t.hpp>
      87             : #include <boost/mpl/sizeof.hpp>
      88             : #include <boost/mpl/transform.hpp>
      89             : 
      90             : ///////////////////////////////////////////////////////////////////////////////
      91             : // Implementation Macros:
      92             : //
      93             : // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
      94             : //   Defined in boost/variant/detail/visitation_impl.hpp.
      95             : //
      96             : // BOOST_VARIANT_MINIMIZE_SIZE
      97             : //   When #defined, implementation employs all known means to minimize the
      98             : //   size of variant obje   cts. However, often unsuccessful due to alignment
      99             : //   issues, and potentially harmful to runtime speed, so not enabled by
     100             : //   default. (TODO: Investigate further.)
     101             : 
     102             : #if defined(BOOST_VARIANT_MINIMIZE_SIZE)
     103             : #   include <climits> // for SCHAR_MAX
     104             : #   include <boost/mpl/eval_if.hpp>
     105             : #   include <boost/mpl/equal_to.hpp>
     106             : #   include <boost/mpl/identity.hpp>
     107             : #   include <boost/mpl/int.hpp>
     108             : #   include <boost/mpl/if.hpp>
     109             : #   include <boost/mpl/less.hpp>
     110             : #   include <boost/mpl/long.hpp>
     111             : #   include <boost/mpl/O1_size.hpp>
     112             : #endif
     113             : 
     114             : 
     115             : namespace boost {
     116             : 
     117             : namespace detail { namespace variant {
     118             : 
     119             : ///////////////////////////////////////////////////////////////////////////////
     120             : // (detail) metafunction max_value
     121             : //
     122             : // Finds the maximum value of the unary metafunction F over Sequence.
     123             : //
     124             : template <typename Sequence, typename F>
     125             : struct max_value
     126             : {
     127             : private: // helpers, for metafunction result (below)
     128             : 
     129             :     typedef typename mpl::transform1<Sequence, F>::type transformed_;
     130             :     typedef typename mpl::max_element<transformed_
     131             : 
     132             :         >::type max_it;
     133             : 
     134             : public: // metafunction result
     135             : 
     136             :     typedef typename mpl::deref<max_it>::type
     137             :         type;
     138             : 
     139             : };
     140             : 
     141             : struct add_alignment
     142             : {
     143             :     template <typename State, typename Item>
     144             :     struct apply
     145             :         : mpl::size_t<
     146             :               ::boost::integer::static_lcm<
     147             :                   BOOST_MPL_AUX_VALUE_WKND(State)::value
     148             :                 , ::boost::alignment_of<Item>::value
     149             :                 >::value
     150             :             >
     151             :     {};
     152             : };
     153             : 
     154             : ///////////////////////////////////////////////////////////////////////////////
     155             : // (detail) metafunction find_fallback_type
     156             : //
     157             : // Provides a fallback (i.e., nothrow default-constructible) type from the
     158             : // specified sequence, or no_fallback_type if not found.
     159             : //
     160             : // This implementation is designed to prefer boost::blank over other potential
     161             : // fallback types, regardless of its position in the specified sequence.
     162             : //
     163             : 
     164             : class no_fallback_type;
     165             : 
     166             : struct find_fallback_type_pred
     167             : {
     168             :     template <typename Iterator>
     169             :     struct apply
     170             :     {
     171             :     private:
     172             :         typedef typename mpl::deref<Iterator>::type t_;
     173             : 
     174             :     public:
     175             :         typedef mpl::not_< has_nothrow_constructor<t_> > type;
     176             :     };
     177             : };
     178             : 
     179             : template <typename Types>
     180             : struct find_fallback_type
     181             : {
     182             : private: // helpers, for metafunction result (below)
     183             : 
     184             :     typedef typename mpl::end<Types>::type end_it;
     185             : 
     186             :     // [Find the first suitable fallback type...]
     187             : 
     188             :     typedef typename mpl::iter_fold_if<
     189             :           Types
     190             :         , mpl::int_<0>, mpl::protect< mpl::next<> >
     191             :         , mpl::protect< find_fallback_type_pred >
     192             :         >::type first_result_;
     193             : 
     194             :     typedef typename first_result_::first first_result_index;
     195             :     typedef typename first_result_::second first_result_it;
     196             : 
     197             :     // [...now search the rest of the sequence for boost::blank...]
     198             : 
     199             :     typedef typename mpl::iter_fold_if<
     200             :           mpl::iterator_range< first_result_it,end_it >
     201             :         , first_result_index, mpl::protect< mpl::next<> >
     202             :         , mpl::protect< mpl::not_same_as<boost::blank> >
     203             :         >::type second_result_;
     204             : 
     205             :     typedef typename second_result_::second second_result_it;
     206             : 
     207             : public: // metafunction result
     208             : 
     209             :     // [...and return the results of the search:]
     210             :     typedef typename mpl::eval_if<
     211             :           is_same< second_result_it,end_it >
     212             :         , mpl::if_<
     213             :               is_same< first_result_it,end_it >
     214             :             , mpl::pair< no_fallback_type,no_fallback_type >
     215             :             , first_result_
     216             :             >
     217             :         , mpl::identity< second_result_ >
     218             :         >::type type;
     219             : 
     220             : };
     221             : 
     222             : ///////////////////////////////////////////////////////////////////////////////
     223             : // (detail) metafunction is_variant_move_noexcept_constructible
     224             : //
     225             : // Returns true_type if all the types are nothrow move constructible.
     226             : //
     227             : template <class Types>
     228             : struct is_variant_move_noexcept_constructible {
     229             :     typedef typename boost::mpl::find_if<
     230             :         Types, mpl::not_<boost::is_nothrow_move_constructible<boost::mpl::_1> >
     231             :     >::type iterator_t;
     232             : 
     233             :     typedef typename boost::mpl::end<Types>::type end_t;
     234             :     typedef typename boost::is_same<
     235             :         iterator_t, end_t
     236             :     >::type type;
     237             : };
     238             : 
     239             : ///////////////////////////////////////////////////////////////////////////////
     240             : // (detail) metafunction is_variant_move_noexcept_assignable
     241             : //
     242             : // Returns true_type if all the types are nothrow move constructible.
     243             : //
     244             : template <class Types>
     245             : struct is_variant_move_noexcept_assignable {
     246             :     typedef typename boost::mpl::find_if<
     247             :         Types, mpl::not_<boost::is_nothrow_move_assignable<boost::mpl::_1> >
     248             :     >::type iterator_t;
     249             : 
     250             :     typedef typename boost::mpl::end<Types>::type end_t;
     251             :     typedef typename boost::is_same<
     252             :         iterator_t, end_t
     253             :     >::type type;
     254             : };
     255             : 
     256             : ///////////////////////////////////////////////////////////////////////////////
     257             : // (detail) metafunction is_variant_constructible_from
     258             : //
     259             : // Derives from true_type if at least one variant's type is constructible from T.
     260             : //
     261             : template <class T1, class T2>
     262             : struct is_constructible_ext:
     263             :     boost::mpl::or_<
     264             :         boost::is_constructible<
     265             :             T1,
     266             :             T2
     267             :         >,
     268             :         boost::is_constructible<
     269             :             T1,
     270             :             typename boost::add_lvalue_reference<T2>::type
     271             :         >
     272             :     >
     273             : {};
     274             : 
     275             : template <class T, class Types>
     276             : struct is_variant_constructible_from:
     277             :     boost::mpl::not_< boost::is_same<
     278             :         typename boost::mpl::find_if<
     279             :             Types,
     280             :             is_constructible_ext<boost::mpl::_1, T>
     281             :         >::type,
     282             :         typename boost::mpl::end<Types>::type
     283             :     > >
     284             : {};
     285             : 
     286             : template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
     287             : struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >:
     288             :     boost::is_same<
     289             :         typename boost::mpl::find_if<
     290             :             typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::recursive_enabled_types,
     291             :             mpl::not_< is_variant_constructible_from< boost::mpl::_1, Types> >
     292             :         >::type,
     293             :         typename boost::mpl::end< typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::recursive_enabled_types >::type
     294             :     >
     295             : {};
     296             : 
     297             : template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
     298             : struct is_variant_constructible_from< const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& , Types >:
     299             :     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
     300             : {};
     301             : 
     302             : template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
     303             : struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& , Types >:
     304             :     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
     305             : {};
     306             : 
     307             : template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
     308             : struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>&& , Types >:
     309             :     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
     310             : {};
     311             : 
     312             : template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types>
     313             : struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const && , Types >:
     314             :     is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >
     315             : {};
     316             : 
     317             : 
     318             : ///////////////////////////////////////////////////////////////////////////////
     319             : // (detail) metafunction make_storage
     320             : //
     321             : // Provides an aligned storage type capable of holding any of the types
     322             : // specified in the given type-sequence.
     323             : //
     324             : 
     325             : template <typename Types, typename NeverUsesBackupFlag>
     326             : struct make_storage
     327             : {
     328             : private: // helpers, for metafunction result (below)
     329             : 
     330             :     typedef typename mpl::eval_if<
     331             :           NeverUsesBackupFlag
     332             :         , mpl::identity< Types >
     333             :         , mpl::push_front<
     334             :               Types, backup_holder<void*>
     335             :             >
     336             :         >::type types;
     337             : 
     338             :     typedef typename max_value<
     339             :           types, mpl::sizeof_<mpl::_1>
     340             :         >::type max_size;
     341             : 
     342             : #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
     343             : 
     344             :     typedef typename mpl::fold<
     345             :           types
     346             :         , mpl::size_t<1>
     347             :         , add_alignment
     348             :         >::type max_alignment;
     349             : 
     350             : #else // borland
     351             : 
     352             :     // temporary workaround -- use maximal alignment
     353             :     typedef mpl::size_t< -1 > max_alignment;
     354             : 
     355             : #endif // borland workaround
     356             : 
     357             : public: // metafunction result
     358             : 
     359             :     typedef ::boost::aligned_storage<
     360             :           BOOST_MPL_AUX_VALUE_WKND(max_size)::value
     361             :         , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value
     362             :         > type;
     363             : };
     364             : 
     365             : ///////////////////////////////////////////////////////////////////////////////
     366             : // (detail) class destroyer
     367             : //
     368             : // Internal visitor that destroys the value it visits.
     369             : //
     370             : struct destroyer
     371             :     : public static_visitor<>
     372             : {
     373             : public: // visitor interfaces
     374             : 
     375             :     template <typename T>
     376      229090 :     void internal_visit(T& operand, int) const BOOST_NOEXCEPT
     377             :     {
     378      229090 :         operand.~T(); // must be noexcept
     379             : 
     380             : #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551)) || \
     381             :     BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
     382             :         (void)operand; // suppresses warnings
     383             : #endif
     384      229090 :     }
     385             : 
     386             : };
     387             : 
     388             : ///////////////////////////////////////////////////////////////////////////////
     389             : // (detail) class template known_get
     390             : //
     391             : // Visitor that returns a reference to content of the specified type.
     392             : //
     393             : // Precondition: visited variant MUST contain logical content of type T.
     394             : //
     395             : template <typename T>
     396             : class known_get
     397             :     : public static_visitor<T&>
     398             : {
     399             : 
     400             : public: // visitor interface
     401             : 
     402             :     T& operator()(T& operand) const BOOST_NOEXCEPT
     403             :     {
     404             :         return operand;
     405             :     }
     406             : 
     407             :     template <typename U>
     408             :     T& operator()(U&) const
     409             :     {
     410             :         // logical error to be here: see precondition above
     411             :         return ::boost::detail::variant::forced_return< T& >();
     412             :     }
     413             : };
     414             : 
     415             : ///////////////////////////////////////////////////////////////////////////////
     416             : // (detail) class copy_into
     417             : //
     418             : // Internal visitor that copies the value it visits into the given buffer.
     419             : //
     420             : class copy_into
     421             :     : public static_visitor<>
     422             : {
     423             : private: // representation
     424             : 
     425             :     void* storage_;
     426             : 
     427             : public: // structors
     428             : 
     429      222462 :     explicit copy_into(void* storage) BOOST_NOEXCEPT
     430      111231 :         : storage_(storage)
     431      111231 :     {
     432      222462 :     }
     433             : 
     434             : public: // internal visitor interface
     435             : 
     436             :     template <typename T>
     437             :     void internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
     438             :     {
     439             :         new(storage_) T( operand.get() );
     440             :     }
     441             : 
     442             :     template <typename T>
     443             :     void internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
     444             :     {
     445             :         new(storage_) T( operand.get() );
     446             :     }
     447             : 
     448             :     template <typename T>
     449      111231 :     void internal_visit(const T& operand, int) const
     450             :     {
     451      111231 :         new(storage_) T(operand);
     452      111231 :     }
     453             : 
     454             : };
     455             : 
     456             : ///////////////////////////////////////////////////////////////////////////////
     457             : // (detail) class move_into
     458             : //
     459             : // Internal visitor that moves the value it visits into the given buffer.
     460             : //
     461             : class move_into
     462             :     : public static_visitor<>
     463             : {
     464             : private: // representation
     465             : 
     466             :     void* storage_;
     467             : 
     468             : public: // structors
     469             : 
     470       13256 :     explicit move_into(void* storage) BOOST_NOEXCEPT
     471        6628 :         : storage_(storage)
     472        6628 :     {
     473       13256 :     }
     474             : 
     475             : public: // internal visitor interface
     476             : 
     477             :     template <typename T>
     478             :     void internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
     479             :     {
     480             :         new(storage_) T( ::boost::detail::variant::move(operand.get()) );
     481             :     }
     482             : 
     483             :     template <typename T>
     484        6628 :     void internal_visit(T& operand, int) const BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(boost::declval<T>())))
     485             :     {
     486        6628 :         new(storage_) T(::boost::detail::variant::move(operand));
     487        6628 :     }
     488             : };
     489             : 
     490             : ///////////////////////////////////////////////////////////////////////////////
     491             : // (detail) class assign_storage
     492             : //
     493             : // Internal visitor that assigns the given storage (which must be a
     494             : // constructed value of the same type) to the value it visits.
     495             : //
     496             : struct assign_storage
     497             :     : public static_visitor<>
     498             : {
     499             : private: // representation
     500             : 
     501             :     const void* rhs_storage_;
     502             : 
     503             : public: // structors
     504             : 
     505             :     explicit assign_storage(const void* rhs_storage) BOOST_NOEXCEPT
     506             :         : rhs_storage_(rhs_storage)
     507             :     {
     508             :     }
     509             : 
     510             : public: // internal visitor interfaces
     511             : 
     512             :     template <typename T>
     513             :     void internal_visit(backup_holder<T>& lhs_content, long) const
     514             :     {
     515             :         lhs_content.get()
     516             :             = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
     517             :     }
     518             : 
     519             :     template <typename T>
     520             :     void internal_visit(const backup_holder<T>& lhs_content, long) const
     521             :     {
     522             :         lhs_content.get()
     523             :             = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
     524             :     }
     525             : 
     526             :     template <typename T>
     527             :     void internal_visit(T& lhs_content, int) const
     528             :     {
     529             :         // NOTE TO USER :
     530             :         // Compile error here indicates one of variant's bounded types does
     531             :         // not meet the requirements of the Assignable concept. Thus,
     532             :         // variant is not Assignable.
     533             :         //
     534             :         // Hint: Are any of the bounded types const-qualified or references?
     535             :         //
     536             :         lhs_content = *static_cast< const T* >(rhs_storage_);
     537             :     }
     538             : 
     539             : };
     540             : 
     541             : ///////////////////////////////////////////////////////////////////////////////
     542             : // (detail) class move_storage
     543             : //
     544             : // Internal visitor that moves the given storage (which must be a
     545             : // constructed value of the same type) to the value it visits.
     546             : //
     547             : struct move_storage
     548             :     : public static_visitor<>
     549             : {
     550             : private: // representation
     551             : 
     552             :     void* rhs_storage_;
     553             : 
     554             : public: // structors
     555             : 
     556             :     explicit move_storage(void* rhs_storage) BOOST_NOEXCEPT
     557             :         : rhs_storage_(rhs_storage)
     558             :     {
     559             :     }
     560             : 
     561             : public: // internal visitor interfaces
     562             : 
     563             :     template <typename T>
     564             :     void internal_visit(backup_holder<T>& lhs_content, long) const
     565             :     {
     566             :         lhs_content.get()
     567             :             = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
     568             :     }
     569             : 
     570             :     template <typename T>
     571             :     void internal_visit(const backup_holder<T>& lhs_content, long) const
     572             :     {
     573             :         lhs_content.get()
     574             :             = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
     575             :     }
     576             : 
     577             :     template <typename T>
     578             :     void internal_visit(T& lhs_content, int) const
     579             :     {
     580             :         // NOTE TO USER :
     581             :         // Compile error here indicates one of variant's bounded types does
     582             :         // not meet the requirements of the Assignable concept. Thus,
     583             :         // variant is not Assignable.
     584             :         //
     585             :         // Hint: Are any of the bounded types const-qualified or references?
     586             :         //
     587             :         lhs_content = ::boost::detail::variant::move(*static_cast<T* >(rhs_storage_));
     588             :     }
     589             : 
     590             : };
     591             : 
     592             : ///////////////////////////////////////////////////////////////////////////////
     593             : // (detail) class direct_assigner
     594             : //
     595             : // Generic static visitor that: if and only if the visited value is of the
     596             : // specified type, assigns the given value to the visited value and returns
     597             : // true; else returns false.
     598             : //
     599             : template <typename T>
     600             : class direct_assigner
     601             :     : public static_visitor<bool>
     602             : {
     603             : private: // representation
     604             : 
     605             :     const T& rhs_;
     606             : 
     607             : public: // structors
     608             : 
     609             :     explicit direct_assigner(const T& rhs) BOOST_NOEXCEPT
     610             :         : rhs_(rhs)
     611             :     {
     612             :     }
     613             : 
     614             : public: // visitor interface
     615             : 
     616             :     bool operator()(T& lhs)
     617             :     {
     618             :         lhs = rhs_;
     619             :         return true;
     620             :     }
     621             : 
     622             :     template <typename U>
     623             :     bool operator()(U&) BOOST_NOEXCEPT
     624             :     {
     625             :         return false;
     626             :     }
     627             : 
     628             : #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
     629             : private:
     630             :     // silence MSVC warning C4512: assignment operator could not be generated
     631             :     direct_assigner& operator= (direct_assigner const&);
     632             : #endif
     633             : };
     634             : 
     635             : ///////////////////////////////////////////////////////////////////////////////
     636             : // (detail) class direct_mover
     637             : //
     638             : // Generic static visitor that: if and only if the visited value is of the
     639             : // specified type, move assigns the given value to the visited value and returns
     640             : // true; else returns false.
     641             : //
     642             : template <typename T>
     643             : class direct_mover
     644             :     : public static_visitor<bool>
     645             : {
     646             : private: // representation
     647             : 
     648             :     T& rhs_;
     649             : 
     650             : public: // structors
     651             : 
     652             :     explicit direct_mover(T& rhs) BOOST_NOEXCEPT
     653             :         : rhs_(rhs)
     654             :     {
     655             :     }
     656             : 
     657             : public: // visitor interface
     658             : 
     659             :     bool operator()(T& lhs)
     660             :     {
     661             :         lhs = ::boost::detail::variant::move(rhs_);
     662             :         return true;
     663             :     }
     664             : 
     665             :     template <typename U>
     666             :     bool operator()(U&) BOOST_NOEXCEPT
     667             :     {
     668             :         return false;
     669             :     }
     670             : 
     671             : #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
     672             : private:
     673             :     // silence MSVC warning C4512: assignment operator could not be generated
     674             :     direct_mover& operator= (direct_mover const&);
     675             : #endif
     676             : };
     677             : 
     678             : 
     679             : ///////////////////////////////////////////////////////////////////////////////
     680             : // (detail) class backup_assigner
     681             : //
     682             : // Internal visitor that "assigns" the given value to the visited value,
     683             : // using backup to recover if the destroy-copy sequence fails.
     684             : //
     685             : // NOTE: This needs to be a friend of variant, as it needs access to
     686             : // indicate_which, indicate_backup_which, etc.
     687             : //
     688             : template <typename Variant>
     689             : class backup_assigner
     690             :     : public static_visitor<>
     691             : {
     692             : private: // representation
     693             : 
     694             :     Variant& lhs_;
     695             :     int rhs_which_;
     696             :     const void* rhs_content_;
     697             :     void (*copy_rhs_content_)(void*, const void*);
     698             : 
     699             : public: // structors
     700             : 
     701             :     template<class RhsT>
     702             :     backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
     703             :         : lhs_(lhs)
     704             :         , rhs_which_(rhs_which)
     705             :         , rhs_content_(&rhs_content)
     706             :         , copy_rhs_content_(&construct_impl<RhsT>)
     707             :     {
     708             :     }
     709             : 
     710             : private: // helpers, for visitor interface (below)
     711             : 
     712             :     template<class RhsT>
     713             :     static void construct_impl(void* addr, const void* obj)
     714             :     {
     715             :         new(addr) RhsT(*static_cast<const RhsT*>(obj));
     716             :     }
     717             : 
     718             :     template <typename LhsT>
     719             :     void backup_assign_impl(
     720             :           backup_holder<LhsT>& lhs_content
     721             :         , mpl::false_ // is_nothrow_move_constructible
     722             :         , long
     723             :         )
     724             :     {
     725             :         // Move lhs content to backup...
     726             :         backup_holder<LhsT> backup_lhs_content(0);
     727             :         backup_lhs_content.swap(lhs_content); // nothrow
     728             : 
     729             :         // ...destroy lhs content...
     730             :         lhs_content.~backup_holder<LhsT>(); // nothrow
     731             : 
     732             :         BOOST_TRY
     733             :         {
     734             :             // ...and attempt to copy rhs content into lhs storage:
     735             :             copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
     736             :         }
     737             :         BOOST_CATCH (...)
     738             :         {
     739             :             // In case of failure, copy backup pointer to lhs storage...
     740             :             new(lhs_.storage_.address())
     741             :                     backup_holder<LhsT>( 0 ); // nothrow
     742             : 
     743             :             static_cast<backup_holder<LhsT>* >(lhs_.storage_.address())
     744             :                     ->swap(backup_lhs_content); // nothrow
     745             : 
     746             :             // ...and rethrow:
     747             :             BOOST_RETHROW;
     748             :         }
     749             :         BOOST_CATCH_END
     750             : 
     751             :         // In case of success, indicate new content type:
     752             :         lhs_.indicate_which(rhs_which_); // nothrow
     753             :     }
     754             : 
     755             :     template <typename LhsT>
     756             :     void backup_assign_impl(
     757             :           LhsT& lhs_content
     758             :         , mpl::true_ // is_nothrow_move_constructible
     759             :         , int
     760             :         )
     761             :     {
     762             :         // Move lhs content to backup...
     763             :         LhsT backup_lhs_content(
     764             :               ::boost::detail::variant::move(lhs_content)
     765             :             ); // nothrow
     766             : 
     767             :         // ...destroy lhs content...
     768             :         lhs_content.~LhsT(); // nothrow
     769             : 
     770             :         BOOST_TRY
     771             :         {
     772             :             // ...and attempt to copy rhs content into lhs storage:
     773             :             copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
     774             :         }
     775             :         BOOST_CATCH (...)
     776             :         {
     777             :             // In case of failure, restore backup content to lhs storage...
     778             :             new(lhs_.storage_.address())
     779             :                 LhsT(
     780             :                       ::boost::detail::variant::move(backup_lhs_content)
     781             :                     ); // nothrow
     782             : 
     783             :             // ...and rethrow:
     784             :             BOOST_RETHROW;
     785             :         }
     786             :         BOOST_CATCH_END
     787             : 
     788             :         // In case of success, indicate new content type:
     789             :         lhs_.indicate_which(rhs_which_); // nothrow
     790             :     }
     791             : 
     792             :     template <typename LhsT>
     793             :     void backup_assign_impl(
     794             :           LhsT& lhs_content
     795             :         , mpl::false_ // is_nothrow_move_constructible
     796             :         , int
     797             :         )
     798             :     {
     799             :         // Backup lhs content...
     800             :         LhsT* backup_lhs_ptr = new LhsT(lhs_content);
     801             : 
     802             :         // ...destroy lhs content...
     803             :         lhs_content.~LhsT(); // nothrow
     804             : 
     805             :         BOOST_TRY
     806             :         {
     807             :             // ...and attempt to copy rhs content into lhs storage:
     808             :             copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
     809             :         }
     810             :         BOOST_CATCH (...)
     811             :         {
     812             :             // In case of failure, copy backup pointer to lhs storage...
     813             :             new(lhs_.storage_.address())
     814             :                 backup_holder<LhsT>( backup_lhs_ptr ); // nothrow
     815             : 
     816             :             // ...indicate now using backup...
     817             :             lhs_.indicate_backup_which( lhs_.which() ); // nothrow
     818             : 
     819             :             // ...and rethrow:
     820             :             BOOST_RETHROW;
     821             :         }
     822             :         BOOST_CATCH_END
     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             : 
     831             : public: // visitor interface
     832             : 
     833             :     template <typename LhsT>
     834             :     void internal_visit(LhsT& lhs_content, int)
     835             :     {
     836             :         typedef typename is_nothrow_move_constructible<LhsT>::type
     837             :             nothrow_move;
     838             : 
     839             :         backup_assign_impl( lhs_content, nothrow_move(), 1L);
     840             :     }
     841             : 
     842             : #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
     843             : private:
     844             :     // silence MSVC warning C4512: assignment operator could not be generated
     845             :     backup_assigner& operator= (backup_assigner const&);
     846             : #endif
     847             : };
     848             : 
     849             : ///////////////////////////////////////////////////////////////////////////////
     850             : // (detail) class swap_with
     851             : //
     852             : // Visitor that swaps visited value with content of given variant.
     853             : //
     854             : // Precondition: Given variant MUST have same logical type as visited value.
     855             : //
     856             : template <typename Variant>
     857             : struct swap_with
     858             :     : public static_visitor<>
     859             : {
     860             : private: // representation
     861             : 
     862             :     Variant& toswap_;
     863             : 
     864             : public: // structors
     865             : 
     866             :     explicit swap_with(Variant& toswap) BOOST_NOEXCEPT
     867             :         : toswap_(toswap)
     868             :     {
     869             :     }
     870             : 
     871             : public: // internal visitor interfaces
     872             : 
     873             :     template <typename T>
     874             :     void operator()(T& operand) const
     875             :     {
     876             :         // Since the precondition ensures types are same, get T...
     877             :         known_get<T> getter;
     878             :         T& other = toswap_.apply_visitor(getter);
     879             : 
     880             :         // ...and swap:
     881             :         ::boost::detail::variant::move_swap( operand, other );
     882             :     }
     883             : 
     884             : private:
     885             :     swap_with& operator=(const swap_with&);
     886             : 
     887             : };
     888             : 
     889             : ///////////////////////////////////////////////////////////////////////////////
     890             : // (detail) class reflect
     891             : //
     892             : // Generic static visitor that performs a typeid on the value it visits.
     893             : //
     894             : 
     895             : class reflect
     896             :     : public static_visitor<const boost::typeindex::type_info&>
     897             : {
     898             : public: // visitor interfaces
     899             : 
     900             :     template <typename T>
     901             :     const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT
     902             :     {
     903             :         return boost::typeindex::type_id<T>().type_info();
     904             :     }
     905             : 
     906             : };
     907             : 
     908             : ///////////////////////////////////////////////////////////////////////////////
     909             : // (detail) class comparer
     910             : //
     911             : // Generic static visitor that compares the content of the given lhs variant
     912             : // with the visited rhs content using Comp.
     913             : //
     914             : // Precondition: lhs.which() == rhs.which()
     915             : //
     916             : template <typename Variant, typename Comp>
     917             : class comparer
     918             :     : public static_visitor<bool>
     919             : {
     920             : private: // representation
     921             : 
     922             :     const Variant& lhs_;
     923             : 
     924             : public: // structors
     925             : 
     926             :     explicit comparer(const Variant& lhs) BOOST_NOEXCEPT
     927             :         : lhs_(lhs)
     928             :     {
     929             :     }
     930             : 
     931             : public: // visitor interfaces
     932             : 
     933             :     template <typename T>
     934             :     bool operator()(T& rhs_content) const
     935             :     {
     936             :         // Since the precondition ensures lhs and rhs types are same, get T...
     937             :         known_get<T> getter;
     938             :         const T& lhs_content = lhs_.apply_visitor(getter);
     939             : 
     940             :         // ...and compare lhs and rhs contents:
     941             :         return Comp()(lhs_content, rhs_content);
     942             :     }
     943             : 
     944             : private:
     945             :     comparer& operator=(const comparer&);
     946             : 
     947             : };
     948             : 
     949             : ///////////////////////////////////////////////////////////////////////////////
     950             : // (detail) class equal_comp
     951             : //
     952             : // Generic function object compares lhs with rhs using operator==.
     953             : //
     954             : struct equal_comp
     955             : {
     956             :     template <typename T>
     957             :     bool operator()(const T& lhs, const T& rhs) const
     958             :     {
     959             :         return lhs == rhs;
     960             :     }
     961             : };
     962             : 
     963             : ///////////////////////////////////////////////////////////////////////////////
     964             : // (detail) class less_comp
     965             : //
     966             : // Generic function object compares lhs with rhs using operator<.
     967             : //
     968             : struct less_comp
     969             : {
     970             :     template <typename T>
     971             :     bool operator()(const T& lhs, const T& rhs) const
     972             :     {
     973             :         return lhs < rhs;
     974             :     }
     975             : };
     976             : 
     977             : ///////////////////////////////////////////////////////////////////////////////
     978             : // (detail) class template invoke_visitor
     979             : //
     980             : // Internal visitor that invokes the given visitor using:
     981             : //  * for wrappers (e.g., recursive_wrapper), the wrapper's held value.
     982             : //  * for all other values, the value itself.
     983             : //
     984             : template <typename Visitor, bool MoveSemantics>
     985             : class invoke_visitor
     986             : {
     987             : private: // representation
     988             : 
     989             :     Visitor& visitor_;
     990             : 
     991             : public: // visitor typedefs
     992             : 
     993             :     typedef typename Visitor::result_type
     994             :         result_type;
     995             : 
     996             : public: // structors
     997             : 
     998      420730 :     explicit invoke_visitor(Visitor& visitor) BOOST_NOEXCEPT
     999      210365 :         : visitor_(visitor)
    1000      210365 :     {
    1001      420730 :     }
    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      210365 :     typename disable_if_c<MoveSemantics && is_same<T, T>::value, result_type>::type internal_visit(T&& operand, int)
    1015             :     {
    1016      210365 :         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      229089 :     void indicate_which(int which_arg) BOOST_NOEXCEPT
    1213             :     {
    1214      229089 :         which_ = static_cast<which_t>( which_arg );
    1215      229089 :     }
    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      675171 :     bool using_backup() const BOOST_NOEXCEPT
    1225             :     {
    1226      675171 :         return which_ < 0;
    1227             :     }
    1228             : 
    1229             : public: // queries
    1230             : 
    1231      675172 :     int which() const BOOST_NOEXCEPT
    1232             :     {
    1233             :         // If using heap backup...
    1234      675172 :         if (using_backup())
    1235             :             // ...then return adjusted which_:
    1236           0 :             return -(which_ + 1);
    1237             : 
    1238             :         // Otherwise, return which_ directly:
    1239      675172 :         return which_;
    1240      675172 :     }
    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      229090 :     void destroy_content() BOOST_NOEXCEPT
    1252             :     {
    1253             :         detail::variant::destroyer visitor;
    1254      229090 :         this->internal_apply_visitor(visitor);
    1255      229090 :     }
    1256             : 
    1257             : public: // structors
    1258             : 
    1259      458180 :     ~variant() BOOST_NOEXCEPT
    1260      229090 :     {
    1261      229090 :         destroy_content();
    1262      458180 :     }
    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      111230 :     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      111230 :         indicate_which(
    1464      111230 :               initializer::initialize(
    1465      111230 :                   storage_.address()
    1466      111230 :                 , detail::variant::move(operand)
    1467             :                 )
    1468             :             );
    1469      111230 :     }
    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      222461 :     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      111231 :     {
    1630      111230 :         convert_construct( detail::variant::move(operand), 1L);
    1631      222461 :     }
    1632             : 
    1633             : public: // structors, cont.
    1634             : 
    1635             :     // [MSVC6 requires copy constructor appear after template constructors]
    1636      222462 :     variant(const variant& operand)
    1637      111231 :     {
    1638             :         // Copy the value of operand into *this...
    1639      111231 :         detail::variant::copy_into visitor( storage_.address() );
    1640      111231 :         operand.internal_apply_visitor(visitor);
    1641             : 
    1642             :         // ...and activate the *this's primary storage on success:
    1643      111231 :         indicate_which(operand.which());
    1644      222462 :     }
    1645             : 
    1646       13256 :     variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value)
    1647        6628 :     {
    1648             :         // Move the value of operand into *this...
    1649        6628 :         detail::variant::move_into visitor( storage_.address() );
    1650        6628 :         operand.internal_apply_visitor(visitor);
    1651             : 
    1652             :         // ...and activate the *this's primary storage on success:
    1653        6628 :         indicate_which(operand.which());
    1654       13256 :     }
    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      557313 :     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      557313 :         return detail::variant::visitation_impl(
    2203      557313 :               internal_which, logical_which
    2204      557313 :             , 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      235718 :     internal_apply_visitor(Visitor& visitor)
    2213             :     {
    2214      235718 :         return internal_apply_visitor_impl(
    2215      235718 :               which_, which(), visitor, storage_.address()
    2216             :             );
    2217             :     }
    2218             : 
    2219             :     template <typename Visitor>
    2220             :     BOOST_FORCEINLINE typename Visitor::result_type
    2221      321596 :     internal_apply_visitor(Visitor& visitor) const
    2222             :     {
    2223      321596 :         return internal_apply_visitor_impl(
    2224      321596 :               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      210365 :     apply_visitor(Visitor& visitor) const &
    2257             :     {
    2258      210365 :         detail::variant::invoke_visitor<Visitor, false> invoker(visitor);
    2259      210365 :         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

Generated by: LCOV version 1.16