epoc32/include/stdapis/boost/variant.hpp
branchSymbian3
changeset 4 837f303aceeb
parent 3 e1b950c65cb4
equal deleted inserted replaced
3:e1b950c65cb4 4:837f303aceeb
     1 //-----------------------------------------------------------------------------
     1 //-----------------------------------------------------------------------------
     2 // boost variant/variant.hpp header file
     2 // boost variant.hpp header file
     3 // See http://www.boost.org for updates, documentation, and revision history.
     3 // See http://www.boost.org for updates, documentation, and revision history.
     4 //-----------------------------------------------------------------------------
     4 //-----------------------------------------------------------------------------
     5 //
     5 //
     6 // Copyright (c) 2002-2003
     6 // Copyright (c) 2003
     7 // Eric Friedman, Itay Maman
     7 // Eric Friedman, Itay Maman
     8 //
     8 //
     9 // Distributed under the Boost Software License, Version 1.0. (See
     9 // Distributed under the Boost Software License, Version 1.0. (See
    10 // accompanying file LICENSE_1_0.txt or copy at
    10 // accompanying file LICENSE_1_0.txt or copy at
    11 // http://www.boost.org/LICENSE_1_0.txt)
    11 // http://www.boost.org/LICENSE_1_0.txt)
    12 /*
       
    13  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
       
    14 */
       
    15 #ifndef BOOST_VARIANT_VARIANT_HPP
       
    16 #define BOOST_VARIANT_VARIANT_HPP
       
    17 
    12 
    18 #include <cstddef> // for std::size_t
    13 #ifndef BOOST_VARIANT_HPP
    19 #include <new> // for placement new
    14 #define BOOST_VARIANT_HPP
    20 #ifdef __SYMBIAN32__
       
    21 #include <string>
       
    22 #endif
       
    23 #include <typeinfo> // for typeid, std::type_info
       
    24 
    15 
    25 #include "boost/variant/detail/config.hpp"
    16 // variant "main"
    26 #include "boost/mpl/aux_/config/eti.hpp"
    17 #include "boost/variant/variant.hpp"
    27 #include "boost/mpl/aux_/value_wknd.hpp"
    18 #include "boost/variant/recursive_variant.hpp"
       
    19 #include "boost/variant/recursive_wrapper.hpp"
    28 
    20 
    29 #include "boost/variant/variant_fwd.hpp"
    21 // common applications
    30 #include "boost/variant/detail/backup_holder.hpp"
    22 #include "boost/variant/get.hpp"
    31 #include "boost/variant/detail/enable_recursive_fwd.hpp"
    23 #include "boost/variant/apply_visitor.hpp"
    32 #include "boost/variant/detail/forced_return.hpp"
    24 #include "boost/variant/static_visitor.hpp"
    33 #include "boost/variant/detail/initializer.hpp"
    25 #include "boost/variant/visitor_ptr.hpp"
    34 #include "boost/variant/detail/make_variant_list.hpp"
       
    35 #include "boost/variant/detail/over_sequence.hpp"
       
    36 #include "boost/variant/detail/visitation_impl.hpp"
       
    37 
    26 
    38 #include "boost/variant/detail/generic_result_type.hpp"
    27 #endif // BOOST_VARIANT_HPP
    39 #include "boost/variant/detail/has_nothrow_move.hpp"
       
    40 #include "boost/variant/detail/move.hpp"
       
    41 
       
    42 #include "boost/detail/reference_content.hpp"
       
    43 #include "boost/aligned_storage.hpp"
       
    44 #include "boost/blank.hpp"
       
    45 #include "boost/static_assert.hpp"
       
    46 #include "boost/preprocessor/cat.hpp"
       
    47 #include "boost/preprocessor/repeat.hpp"
       
    48 #include "boost/type_traits/alignment_of.hpp"
       
    49 #include "boost/type_traits/add_const.hpp"
       
    50 #include "boost/type_traits/has_nothrow_constructor.hpp"
       
    51 #include "boost/type_traits/has_nothrow_copy.hpp"
       
    52 #include "boost/type_traits/is_const.hpp"
       
    53 #include "boost/type_traits/is_same.hpp"
       
    54 #include "boost/utility/enable_if.hpp"
       
    55 #include "boost/variant/recursive_wrapper_fwd.hpp"
       
    56 #include "boost/variant/static_visitor.hpp"
       
    57 
       
    58 #include "boost/mpl/eval_if.hpp"
       
    59 #include "boost/mpl/begin_end.hpp"
       
    60 #include "boost/mpl/bool.hpp"
       
    61 #include "boost/mpl/empty.hpp"
       
    62 #include "boost/mpl/find_if.hpp"
       
    63 #include "boost/mpl/front.hpp"
       
    64 #include "boost/mpl/identity.hpp"
       
    65 #include "boost/mpl/if.hpp"
       
    66 #include "boost/mpl/int.hpp"
       
    67 #include "boost/mpl/is_sequence.hpp"
       
    68 #include "boost/mpl/iterator_range.hpp"
       
    69 #include "boost/mpl/iter_fold_if.hpp"
       
    70 #include "boost/mpl/logical.hpp"
       
    71 #include "boost/mpl/max_element.hpp"
       
    72 #include "boost/mpl/next.hpp"
       
    73 #include "boost/mpl/deref.hpp"
       
    74 #include "boost/mpl/pair.hpp"
       
    75 #include "boost/mpl/protect.hpp"
       
    76 #include "boost/mpl/push_front.hpp"
       
    77 #include "boost/mpl/same_as.hpp"
       
    78 #include "boost/mpl/size_t.hpp"
       
    79 #include "boost/mpl/sizeof.hpp"
       
    80 #include "boost/mpl/transform.hpp"
       
    81 #include "boost/mpl/assert.hpp"
       
    82 
       
    83 ///////////////////////////////////////////////////////////////////////////////
       
    84 // Implementation Macros:
       
    85 //
       
    86 // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
       
    87 //   Defined in boost/variant/detail/visitation_impl.hpp.
       
    88 //
       
    89 // BOOST_VARIANT_MINIMIZE_SIZE
       
    90 //   When #defined, implementation employs all known means to minimize the
       
    91 //   size of variant obje   cts. However, often unsuccessful due to alignment
       
    92 //   issues, and potentially harmful to runtime speed, so not enabled by
       
    93 //   default. (TODO: Investigate further.)
       
    94 
       
    95 #if defined(BOOST_VARIANT_MINIMIZE_SIZE)
       
    96 #   include <climits> // for SCHAR_MAX
       
    97 #   include "boost/mpl/eval_if.hpp"
       
    98 #   include "boost/mpl/equal_to.hpp"
       
    99 #   include "boost/mpl/identity.hpp"
       
   100 #   include "boost/mpl/int.hpp"
       
   101 #   include "boost/mpl/if.hpp"
       
   102 #   include "boost/mpl/less.hpp"
       
   103 #   include "boost/mpl/long.hpp"
       
   104 #   include "boost/mpl/O1_size.hpp"
       
   105 #endif
       
   106 
       
   107 
       
   108 namespace boost {
       
   109 
       
   110 namespace detail { namespace variant {
       
   111 
       
   112 ///////////////////////////////////////////////////////////////////////////////
       
   113 // (detail) metafunction max_value
       
   114 //
       
   115 // Finds the maximum value of the unary metafunction F over Sequence.
       
   116 //
       
   117 template <typename Sequence, typename F>
       
   118 struct max_value
       
   119 {
       
   120 private: // helpers, for metafunction result (below)
       
   121 
       
   122     typedef typename mpl::transform1<Sequence, F>::type transformed_;
       
   123     typedef typename mpl::max_element<transformed_
       
   124           
       
   125         >::type max_it;
       
   126 
       
   127 public: // metafunction result
       
   128 
       
   129     typedef typename mpl::deref<max_it>::type
       
   130         type;
       
   131 
       
   132 };
       
   133 
       
   134 ///////////////////////////////////////////////////////////////////////////////
       
   135 // (detail) metafunction find_fallback_type
       
   136 //
       
   137 // Provides a fallback (i.e., nothrow default-constructible) type from the
       
   138 // specified sequence, or no_fallback_type if not found.
       
   139 //
       
   140 // This implementation is designed to prefer boost::blank over other potential
       
   141 // fallback types, regardless of its position in the specified sequence.
       
   142 //
       
   143 
       
   144 class no_fallback_type;
       
   145 
       
   146 struct find_fallback_type_pred
       
   147 {
       
   148     template <typename Iterator>
       
   149     struct apply
       
   150     {
       
   151     private:
       
   152         typedef typename mpl::deref<Iterator>::type t_;
       
   153 
       
   154     public:
       
   155         typedef mpl::not_< has_nothrow_constructor<t_> > type;
       
   156     };
       
   157 };
       
   158 
       
   159 template <typename Types>
       
   160 struct find_fallback_type
       
   161 {
       
   162 private: // helpers, for metafunction result (below)
       
   163 
       
   164     typedef typename mpl::end<Types>::type end_it;
       
   165 
       
   166     // [Find the first suitable fallback type...]
       
   167 
       
   168     typedef typename mpl::iter_fold_if<
       
   169           Types
       
   170         , mpl::int_<0>, mpl::protect< mpl::next<> >
       
   171         , mpl::protect< find_fallback_type_pred >
       
   172         >::type first_result_;
       
   173 
       
   174     typedef typename first_result_::first first_result_index;
       
   175     typedef typename first_result_::second first_result_it;
       
   176 
       
   177     // [...now search the rest of the sequence for boost::blank...]
       
   178 
       
   179     typedef typename mpl::iter_fold_if<
       
   180           mpl::iterator_range< first_result_it,end_it >
       
   181         , first_result_index, mpl::protect< mpl::next<> >
       
   182         , mpl::protect< mpl::not_same_as<boost::blank> >
       
   183         >::type second_result_;
       
   184 
       
   185     typedef typename second_result_::second second_result_it;
       
   186 
       
   187 public: // metafunction result
       
   188 
       
   189     // [...and return the results of the search:]
       
   190     typedef typename mpl::eval_if<
       
   191           is_same< second_result_it,end_it >
       
   192         , mpl::if_<
       
   193               is_same< first_result_it,end_it >
       
   194             , mpl::pair< no_fallback_type,no_fallback_type >
       
   195             , first_result_
       
   196             >
       
   197         , mpl::identity< second_result_ >
       
   198         >::type type;
       
   199 
       
   200 };
       
   201 
       
   202 #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
       
   203 
       
   204 template<>
       
   205 struct find_fallback_type<int>
       
   206 {
       
   207     typedef mpl::pair< no_fallback_type,no_fallback_type > type;
       
   208 };
       
   209 
       
   210 #endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
       
   211 
       
   212 ///////////////////////////////////////////////////////////////////////////////
       
   213 // (detail) metafunction make_storage
       
   214 //
       
   215 // Provides an aligned storage type capable of holding any of the types
       
   216 // specified in the given type-sequence.
       
   217 //
       
   218 
       
   219 template <typename Types, typename NeverUsesBackupFlag>
       
   220 struct make_storage
       
   221 {
       
   222 private: // helpers, for metafunction result (below)
       
   223 
       
   224     typedef typename mpl::eval_if<
       
   225           NeverUsesBackupFlag
       
   226         , mpl::identity< Types >
       
   227         , mpl::push_front<
       
   228               Types, backup_holder<void*>
       
   229             >
       
   230         >::type types;
       
   231 
       
   232     typedef typename max_value<
       
   233           types, mpl::sizeof_<mpl::_1>
       
   234         >::type max_size;
       
   235 
       
   236 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
       
   237 
       
   238     typedef typename max_value<
       
   239           types, alignment_of<mpl::_1>
       
   240         >::type max_alignment;
       
   241 
       
   242 #else // borland
       
   243 
       
   244     // temporary workaround -- use maximal alignment
       
   245     typedef mpl::size_t< -1 > max_alignment;
       
   246 
       
   247 #endif // borland workaround
       
   248 
       
   249 public: // metafunction result
       
   250 
       
   251 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
       
   252 
       
   253     typedef ::boost::aligned_storage<
       
   254           BOOST_MPL_AUX_VALUE_WKND(max_size)::value
       
   255         , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value
       
   256         > type;
       
   257 
       
   258 #else // MSVC7 and below
       
   259 
       
   260     BOOST_STATIC_CONSTANT(std::size_t, msvc_max_size_c = max_size::value);
       
   261     BOOST_STATIC_CONSTANT(std::size_t, msvc_max_alignment_c = max_alignment::value);
       
   262 
       
   263     typedef ::boost::aligned_storage<
       
   264           msvc_max_size_c
       
   265         , msvc_max_alignment_c
       
   266         > type;
       
   267 
       
   268 #endif // MSVC workaround
       
   269 
       
   270 };
       
   271 
       
   272 #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
       
   273 
       
   274 template<>
       
   275 struct make_storage<int,int>
       
   276 {
       
   277     typedef int type;
       
   278 };
       
   279 
       
   280 #endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
       
   281 
       
   282 ///////////////////////////////////////////////////////////////////////////////
       
   283 // (detail) class destroyer
       
   284 //
       
   285 // Internal visitor that destroys the value it visits.
       
   286 //
       
   287 struct destroyer
       
   288     : public static_visitor<>
       
   289 {
       
   290 public: // visitor interfaces
       
   291 
       
   292     template <typename T>
       
   293         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   294     internal_visit(T& operand, int) const
       
   295     {
       
   296         operand.~T();
       
   297 
       
   298 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
       
   299         operand; // suppresses warnings
       
   300 #endif
       
   301 
       
   302         BOOST_VARIANT_AUX_RETURN_VOID;
       
   303     }
       
   304 
       
   305 };
       
   306 
       
   307 ///////////////////////////////////////////////////////////////////////////////
       
   308 // (detail) class template known_get
       
   309 //
       
   310 // Visitor that returns a reference to content of the specified type.
       
   311 //
       
   312 // Precondition: visited variant MUST contain logical content of type T.
       
   313 //
       
   314 template <typename T>
       
   315 class known_get
       
   316     : public static_visitor<T&>
       
   317 {
       
   318 
       
   319 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
       
   320 
       
   321 public: // visitor interface
       
   322 
       
   323     T& operator()(T& operand) const
       
   324     {
       
   325         return operand;
       
   326     }
       
   327 
       
   328     template <typename U>
       
   329     T& operator()(U&) const
       
   330     {
       
   331         // logical error to be here: see precondition above
       
   332         BOOST_ASSERT(false);
       
   333         return ::boost::detail::variant::forced_return< T& >();
       
   334     }
       
   335 
       
   336 #else // MSVC6
       
   337 
       
   338 private: // helpers, for visitor interface (below)
       
   339 
       
   340     T& execute(T& operand, mpl::true_) const
       
   341     {
       
   342         return operand;
       
   343     }
       
   344 
       
   345     template <typename U>
       
   346     T& execute(U& operand, mpl::false_) const
       
   347     {
       
   348         // logical error to be here: see precondition above
       
   349         BOOST_ASSERT(false);
       
   350         return ::boost::detail::variant::forced_return< T& >();
       
   351     }
       
   352 
       
   353 public: // visitor interface
       
   354 
       
   355     template <typename U>
       
   356     T& operator()(U& operand) const
       
   357     {
       
   358         typedef typename is_same< U,T >::type
       
   359             U_is_T;
       
   360 
       
   361         return execute(operand, U_is_T());
       
   362     }
       
   363 
       
   364 #endif // MSVC6 workaround
       
   365 
       
   366 };
       
   367 
       
   368 ///////////////////////////////////////////////////////////////////////////////
       
   369 // (detail) class copy_into
       
   370 //
       
   371 // Internal visitor that copies the value it visits into the given buffer.
       
   372 //
       
   373 class copy_into
       
   374     : public static_visitor<>
       
   375 {
       
   376 private: // representation
       
   377 
       
   378     void* storage_;
       
   379 
       
   380 public: // structors
       
   381 
       
   382     explicit copy_into(void* storage)
       
   383         : storage_(storage)
       
   384     {
       
   385     }
       
   386 
       
   387 public: // internal visitor interface
       
   388 
       
   389     template <typename T>
       
   390         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   391     internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
       
   392     {
       
   393         new(storage_) T( operand.get() );
       
   394         BOOST_VARIANT_AUX_RETURN_VOID;
       
   395     }
       
   396 
       
   397     template <typename T>
       
   398         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   399     internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
       
   400     {
       
   401         new(storage_) T( operand.get() );
       
   402         BOOST_VARIANT_AUX_RETURN_VOID;
       
   403     }
       
   404 
       
   405     template <typename T>
       
   406         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   407     internal_visit(const T& operand, int) const
       
   408     {
       
   409         new(storage_) T(operand);
       
   410         BOOST_VARIANT_AUX_RETURN_VOID;
       
   411     }
       
   412 
       
   413 };
       
   414 
       
   415 ///////////////////////////////////////////////////////////////////////////////
       
   416 // (detail) class assign_storage
       
   417 //
       
   418 // Internal visitor that assigns the given storage (which must be a
       
   419 // constructed value of the same type) to the value it visits.
       
   420 //
       
   421 struct assign_storage
       
   422     : public static_visitor<>
       
   423 {
       
   424 private: // representation
       
   425 
       
   426     const void* rhs_storage_;
       
   427 
       
   428 public: // structors
       
   429 
       
   430     explicit assign_storage(const void* rhs_storage)
       
   431         : rhs_storage_(rhs_storage)
       
   432     {
       
   433     }
       
   434 
       
   435 public: // internal visitor interfaces
       
   436 
       
   437     template <typename T>
       
   438         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   439     internal_visit(backup_holder<T>& lhs_content, long) const
       
   440     {
       
   441         lhs_content.get()
       
   442             = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
       
   443         BOOST_VARIANT_AUX_RETURN_VOID;
       
   444     }
       
   445 
       
   446     template <typename T>
       
   447         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   448     internal_visit(const backup_holder<T>& lhs_content, long) const
       
   449     {
       
   450         lhs_content.get()
       
   451             = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
       
   452         BOOST_VARIANT_AUX_RETURN_VOID;
       
   453     }
       
   454 
       
   455     template <typename T>
       
   456         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   457     internal_visit(T& lhs_content, int) const
       
   458     {
       
   459         // NOTE TO USER :
       
   460         // Compile error here indicates one of variant's bounded types does
       
   461         // not meet the requirements of the Assignable concept. Thus,
       
   462         // variant is not Assignable.
       
   463         //
       
   464         // Hint: Are any of the bounded types const-qualified or references?
       
   465         //
       
   466         lhs_content = *static_cast< const T* >(rhs_storage_);
       
   467         BOOST_VARIANT_AUX_RETURN_VOID;
       
   468     }
       
   469 
       
   470 };
       
   471 
       
   472 ///////////////////////////////////////////////////////////////////////////////
       
   473 // (detail) class direct_assigner
       
   474 //
       
   475 // Generic static visitor that: if and only if the visited value is of the
       
   476 // specified type, assigns the given value to the visited value and returns
       
   477 // true; else returns false.
       
   478 //
       
   479 template <typename T>
       
   480 class direct_assigner
       
   481     : public static_visitor<bool>
       
   482 {
       
   483 private: // representation
       
   484 
       
   485     T& rhs_;
       
   486 
       
   487 public: // structors
       
   488 
       
   489     explicit direct_assigner(T& rhs)
       
   490         : rhs_(rhs)
       
   491     {
       
   492     }
       
   493 
       
   494 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
       
   495 
       
   496 public: // visitor interface
       
   497 
       
   498     bool operator()(T& lhs)
       
   499     {
       
   500         lhs = rhs_;
       
   501         return true;
       
   502     }
       
   503 
       
   504     template <typename U>
       
   505     bool operator()(U&)
       
   506     {
       
   507         return false;
       
   508     }
       
   509 
       
   510 #else // MSVC6
       
   511 
       
   512 private: // helpers, for visitor interface (below)
       
   513 
       
   514     bool execute(T& lhs, mpl::true_)
       
   515     {
       
   516         lhs = rhs_;
       
   517         return true;
       
   518     }
       
   519 
       
   520     template <typename U>
       
   521     bool execute(U&, mpl::false_)
       
   522     {
       
   523         return false;
       
   524     }
       
   525 
       
   526 public: // visitor interface
       
   527 
       
   528     template <typename U>
       
   529     bool operator()(U& lhs)
       
   530     {
       
   531         typedef typename is_same<U,T>::type U_is_T;
       
   532         return execute(lhs, U_is_T());
       
   533     }
       
   534 
       
   535 #endif // MSVC6 workaround
       
   536 
       
   537 };
       
   538 
       
   539 ///////////////////////////////////////////////////////////////////////////////
       
   540 // (detail) class backup_assigner
       
   541 //
       
   542 // Internal visitor that "assigns" the given value to the visited value,
       
   543 // using backup to recover if the destroy-copy sequence fails.
       
   544 //
       
   545 // NOTE: This needs to be a friend of variant, as it needs access to
       
   546 // indicate_which, indicate_backup_which, etc.
       
   547 //
       
   548 template <typename Variant, typename RhsT>
       
   549 class backup_assigner
       
   550     : public static_visitor<>
       
   551 {
       
   552 private: // representation
       
   553 
       
   554     Variant& lhs_;
       
   555     int rhs_which_;
       
   556     const RhsT& rhs_content_;
       
   557 
       
   558 public: // structors
       
   559 
       
   560     backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
       
   561         : lhs_(lhs)
       
   562         , rhs_which_(rhs_which)
       
   563         , rhs_content_(rhs_content)
       
   564     {
       
   565     }
       
   566 
       
   567 private: // helpers, for visitor interface (below)
       
   568 
       
   569     template <typename LhsT>
       
   570     void backup_assign_impl(
       
   571           LhsT& lhs_content
       
   572         , mpl::true_// has_nothrow_move
       
   573         )
       
   574     {
       
   575         // Move lhs content to backup...
       
   576         LhsT backup_lhs_content(
       
   577               ::boost::detail::variant::move(lhs_content)
       
   578             ); // nothrow
       
   579 
       
   580         // ...destroy lhs content...
       
   581         lhs_content.~LhsT(); // nothrow
       
   582 
       
   583         try
       
   584         {
       
   585             // ...and attempt to copy rhs content into lhs storage:
       
   586             new(lhs_.storage_.address()) RhsT(rhs_content_);
       
   587         }
       
   588         catch (...)
       
   589         {
       
   590             // In case of failure, restore backup content to lhs storage...
       
   591             new(lhs_.storage_.address())
       
   592                 LhsT(
       
   593                       ::boost::detail::variant::move(backup_lhs_content)
       
   594                     ); // nothrow
       
   595 
       
   596             // ...and rethrow:
       
   597             throw;
       
   598         }
       
   599 
       
   600         // In case of success, indicate new content type:
       
   601         lhs_.indicate_which(rhs_which_); // nothrow
       
   602     }
       
   603 
       
   604     template <typename LhsT>
       
   605     void backup_assign_impl(
       
   606           LhsT& lhs_content
       
   607         , mpl::false_// has_nothrow_move
       
   608         )
       
   609     {
       
   610         // Backup lhs content...
       
   611         LhsT* backup_lhs_ptr = new LhsT(lhs_content);
       
   612 
       
   613         // ...destroy lhs content...
       
   614         lhs_content.~LhsT(); // nothrow
       
   615 
       
   616         try
       
   617         {
       
   618             // ...and attempt to copy rhs content into lhs storage:
       
   619             new(lhs_.storage_.address()) RhsT(rhs_content_);
       
   620         }
       
   621         catch (...)
       
   622         {
       
   623             // In case of failure, copy backup pointer to lhs storage...
       
   624             new(lhs_.storage_.address())
       
   625                 backup_holder<LhsT>( backup_lhs_ptr ); // nothrow
       
   626 
       
   627             // ...indicate now using backup...
       
   628             lhs_.indicate_backup_which( lhs_.which() ); // nothrow
       
   629 
       
   630             // ...and rethrow:
       
   631             throw;
       
   632         }
       
   633 
       
   634         // In case of success, indicate new content type...
       
   635         lhs_.indicate_which(rhs_which_); // nothrow
       
   636 
       
   637         // ...and delete backup:
       
   638         delete backup_lhs_ptr; // nothrow
       
   639     }
       
   640 
       
   641 public: // visitor interface
       
   642 
       
   643     template <typename LhsT>
       
   644         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   645     internal_visit(LhsT& lhs_content, int)
       
   646     {
       
   647         typedef typename has_nothrow_move_constructor<LhsT>::type
       
   648             nothrow_move;
       
   649 
       
   650         backup_assign_impl( lhs_content, nothrow_move() );
       
   651 
       
   652         BOOST_VARIANT_AUX_RETURN_VOID;
       
   653     }
       
   654 
       
   655 };
       
   656 
       
   657 ///////////////////////////////////////////////////////////////////////////////
       
   658 // (detail) class swap_with
       
   659 //
       
   660 // Visitor that swaps visited value with content of given variant.
       
   661 //
       
   662 // Precondition: Given variant MUST have same logical type as visited value.
       
   663 //
       
   664 template <typename Variant>
       
   665 struct swap_with
       
   666     : public static_visitor<>
       
   667 {
       
   668 private: // representation
       
   669 
       
   670     Variant& toswap_;
       
   671 
       
   672 public: // structors
       
   673 
       
   674     explicit swap_with(Variant& toswap)
       
   675         : toswap_(toswap)
       
   676     {
       
   677     }
       
   678 
       
   679 public: // internal visitor interfaces
       
   680 
       
   681     template <typename T>
       
   682     void operator()(T& operand) const
       
   683     {
       
   684         // Since the precondition ensures types are same, get T...
       
   685         known_get<T> getter;
       
   686         T& other = toswap_.apply_visitor(getter);
       
   687 
       
   688         // ...and swap:
       
   689         ::boost::detail::variant::move_swap( operand, other );
       
   690     }
       
   691 
       
   692 };
       
   693 
       
   694 ///////////////////////////////////////////////////////////////////////////////
       
   695 // (detail) class reflect
       
   696 //
       
   697 // Generic static visitor that performs a typeid on the value it visits.
       
   698 //
       
   699 class reflect
       
   700     : public static_visitor<const std::type_info&>
       
   701 {
       
   702 public: // visitor interfaces
       
   703 
       
   704     template <typename T>
       
   705     const std::type_info& operator()(const T&) const
       
   706     {
       
   707         return typeid(T);
       
   708     }
       
   709 
       
   710 };
       
   711 
       
   712 ///////////////////////////////////////////////////////////////////////////////
       
   713 // (detail) class comparer
       
   714 //
       
   715 // Generic static visitor that compares the content of the given lhs variant
       
   716 // with the visited rhs content using Comp.
       
   717 //
       
   718 // Precondition: lhs.which() == rhs.which()
       
   719 //
       
   720 template <typename Variant, typename Comp>
       
   721 class comparer
       
   722     : public static_visitor<bool>
       
   723 {
       
   724 private: // representation
       
   725 
       
   726     const Variant& lhs_;
       
   727 
       
   728 public: // structors
       
   729 
       
   730     explicit comparer(const Variant& lhs)
       
   731         : lhs_(lhs)
       
   732     {
       
   733     }
       
   734 
       
   735 public: // visitor interfaces
       
   736 
       
   737     template <typename T>
       
   738     bool operator()(const T& rhs_content) const
       
   739     {
       
   740         // Since the precondition ensures lhs and rhs types are same, get T...
       
   741         known_get<const T> getter;
       
   742         const T& lhs_content = lhs_.apply_visitor(getter);
       
   743 
       
   744         // ...and compare lhs and rhs contents:
       
   745         return Comp()(lhs_content, rhs_content);
       
   746     }
       
   747 
       
   748 };
       
   749 
       
   750 ///////////////////////////////////////////////////////////////////////////////
       
   751 // (detail) class equal_comp
       
   752 //
       
   753 // Generic function object compares lhs with rhs using operator==.
       
   754 //
       
   755 struct equal_comp
       
   756 {
       
   757     template <typename T>
       
   758     bool operator()(const T& lhs, const T& rhs) const
       
   759     {
       
   760         return lhs == rhs;
       
   761     }
       
   762 };
       
   763 
       
   764 ///////////////////////////////////////////////////////////////////////////////
       
   765 // (detail) class less_comp
       
   766 //
       
   767 // Generic function object compares lhs with rhs using operator<.
       
   768 //
       
   769 struct less_comp
       
   770 {
       
   771     template <typename T>
       
   772     bool operator()(const T& lhs, const T& rhs) const
       
   773     {
       
   774         return lhs < rhs;
       
   775     }
       
   776 };
       
   777 
       
   778 ///////////////////////////////////////////////////////////////////////////////
       
   779 // (detail) class template invoke_visitor
       
   780 //
       
   781 // Internal visitor that invokes the given visitor using:
       
   782 //  * for wrappers (e.g., recursive_wrapper), the wrapper's held value.
       
   783 //  * for all other values, the value itself.
       
   784 //
       
   785 template <typename Visitor>
       
   786 class invoke_visitor
       
   787 {
       
   788 private: // representation
       
   789 
       
   790     Visitor& visitor_;
       
   791 
       
   792 public: // visitor typedefs
       
   793 
       
   794     typedef typename Visitor::result_type
       
   795         result_type;
       
   796 
       
   797 public: // structors
       
   798 
       
   799     explicit invoke_visitor(Visitor& visitor)
       
   800         : visitor_(visitor)
       
   801     {
       
   802     }
       
   803 
       
   804 #if !defined(BOOST_NO_VOID_RETURNS)
       
   805 
       
   806 public: // internal visitor interfaces
       
   807 
       
   808     template <typename T>
       
   809     result_type internal_visit(T& operand, int)
       
   810     {
       
   811         return visitor_(operand);
       
   812     }
       
   813 
       
   814 #   if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
       
   815     template <typename T>
       
   816     result_type internal_visit(const T& operand, int)
       
   817     {
       
   818         return visitor_(operand);
       
   819     }
       
   820 #   endif
       
   821 
       
   822 #else // defined(BOOST_NO_VOID_RETURNS)
       
   823 
       
   824 private: // helpers, for internal visitor interfaces (below)
       
   825 
       
   826     template <typename T>
       
   827         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   828     visit_impl(T& operand, mpl::false_)
       
   829     {
       
   830         return visitor_(operand);
       
   831     }
       
   832 
       
   833     template <typename T>
       
   834         BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
   835     visit_impl(T& operand, mpl::true_)
       
   836     {
       
   837         visitor_(operand);
       
   838         BOOST_VARIANT_AUX_RETURN_VOID;
       
   839     }
       
   840 
       
   841 public: // internal visitor interfaces
       
   842 
       
   843     template <typename T>
       
   844         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   845     internal_visit(T& operand, int)
       
   846     {
       
   847         typedef typename is_same<result_type, void>::type
       
   848             has_void_result_type;
       
   849 
       
   850         return visit_impl(operand, has_void_result_type());
       
   851     }
       
   852 
       
   853 #endif // BOOST_NO_VOID_RETURNS) workaround
       
   854 
       
   855 public: // internal visitor interfaces, cont.
       
   856 
       
   857     template <typename T>
       
   858         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   859     internal_visit(boost::recursive_wrapper<T>& operand, long)
       
   860     {
       
   861         return internal_visit( operand.get(), 1L );
       
   862     }
       
   863 
       
   864     template <typename T>
       
   865         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   866     internal_visit(const boost::recursive_wrapper<T>& operand, long)
       
   867     {
       
   868         return internal_visit( operand.get(), 1L );
       
   869     }
       
   870 
       
   871     template <typename T>
       
   872         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   873     internal_visit(boost::detail::reference_content<T>& operand, long)
       
   874     {
       
   875         return internal_visit( operand.get(), 1L );
       
   876     }
       
   877 
       
   878     template <typename T>
       
   879         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   880     internal_visit(const boost::detail::reference_content<T>& operand, long)
       
   881     {
       
   882         return internal_visit( operand.get(), 1L );
       
   883     }
       
   884 
       
   885     template <typename T>
       
   886         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   887     internal_visit(boost::detail::variant::backup_holder<T>& operand, long)
       
   888     {
       
   889         return internal_visit( operand.get(), 1L );
       
   890     }
       
   891 
       
   892     template <typename T>
       
   893         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
       
   894     internal_visit(const boost::detail::variant::backup_holder<T>& operand, long)
       
   895     {
       
   896         return internal_visit( operand.get(), 1L );
       
   897     }
       
   898 
       
   899 };
       
   900 
       
   901 }} // namespace detail::variant
       
   902 
       
   903 ///////////////////////////////////////////////////////////////////////////////
       
   904 // class template variant (concept inspired by Andrei Alexandrescu)
       
   905 //
       
   906 // See docs and boost/variant/variant_fwd.hpp for more information.
       
   907 //
       
   908 template <
       
   909       typename T0_
       
   910     , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
       
   911     >
       
   912 class variant
       
   913 {
       
   914 private: // helpers, for typedefs (below)
       
   915 
       
   916     typedef variant wknd_self_t;
       
   917 
       
   918     struct is_recursive_
       
   919         : detail::variant::is_recursive_flag<T0_>
       
   920     {
       
   921     };
       
   922 
       
   923     typedef typename mpl::eval_if<
       
   924           is_recursive_
       
   925         , T0_
       
   926         , mpl::identity< T0_ >
       
   927         >::type unwrapped_T0_;
       
   928 
       
   929     struct is_sequence_based_
       
   930         : detail::variant::is_over_sequence<unwrapped_T0_>
       
   931     {
       
   932     };
       
   933 
       
   934 #if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
       
   935 
       
   936 private: // helpers, for typedefs (below)
       
   937 
       
   938     typedef typename mpl::eval_if<
       
   939           is_sequence_based_
       
   940         , unwrapped_T0_ // over_sequence<...>::type
       
   941         , detail::variant::make_variant_list<
       
   942               unwrapped_T0_
       
   943             , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
       
   944             >
       
   945         >::type specified_types;
       
   946 
       
   947     BOOST_STATIC_ASSERT((
       
   948           ::boost::mpl::not_< mpl::empty<specified_types> >::value
       
   949         ));
       
   950 
       
   951     typedef typename mpl::eval_if<
       
   952           is_recursive_
       
   953         , mpl::transform<
       
   954               specified_types
       
   955             , mpl::protect<
       
   956                   detail::variant::quoted_enable_recursive<wknd_self_t>
       
   957                 >
       
   958             >
       
   959         , mpl::identity< specified_types >
       
   960         >::type recursive_enabled_types;
       
   961 
       
   962 public: // public typedefs
       
   963 
       
   964     typedef typename mpl::transform<
       
   965           recursive_enabled_types
       
   966         , unwrap_recursive<mpl::_1>
       
   967         >::type types;
       
   968 
       
   969 private: // internal typedefs
       
   970 
       
   971     typedef typename mpl::transform<
       
   972           recursive_enabled_types
       
   973         , mpl::protect< detail::make_reference_content<> >
       
   974         >::type internal_types;
       
   975 
       
   976     typedef typename mpl::front<
       
   977           internal_types
       
   978         >::type internal_T0;
       
   979 
       
   980 #else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
       
   981 
       
   982 private: // helpers, for typedefs (below)
       
   983 
       
   984     typedef unwrapped_T0_ T0;
       
   985 
       
   986     #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
       
   987         typedef typename mpl::eval_if< \
       
   988               is_recursive_ \
       
   989             , detail::variant::enable_recursive< \
       
   990                   BOOST_PP_CAT(T,N) \
       
   991                 , wknd_self_t \
       
   992                 > \
       
   993             , mpl::identity< BOOST_PP_CAT(T,N) > \
       
   994             >::type BOOST_PP_CAT(recursive_enabled_T,N); \
       
   995         /**/
       
   996 
       
   997     BOOST_PP_REPEAT(
       
   998           BOOST_VARIANT_LIMIT_TYPES
       
   999         , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
       
  1000         , _
       
  1001         )
       
  1002 
       
  1003     #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
       
  1004 
       
  1005     #define BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS(z,N,_) \
       
  1006         typedef typename unwrap_recursive< \
       
  1007               BOOST_PP_CAT(recursive_enabled_T,N) \
       
  1008             >::type BOOST_PP_CAT(public_T,N); \
       
  1009         /**/
       
  1010 
       
  1011     BOOST_PP_REPEAT(
       
  1012           BOOST_VARIANT_LIMIT_TYPES
       
  1013         , BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
       
  1014         , _
       
  1015         )
       
  1016 
       
  1017     #undef BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
       
  1018 
       
  1019 public: // public typedefs
       
  1020 
       
  1021     typedef typename detail::variant::make_variant_list<
       
  1022           BOOST_VARIANT_ENUM_PARAMS(public_T)
       
  1023         >::type types;
       
  1024 
       
  1025 private: // helpers, for internal typedefs (below)
       
  1026 
       
  1027     #define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \
       
  1028         typedef detail::make_reference_content< \
       
  1029               BOOST_PP_CAT(recursive_enabled_T,N) \
       
  1030             >::type BOOST_PP_CAT(internal_T,N); \
       
  1031         /**/
       
  1032 
       
  1033     BOOST_PP_REPEAT(
       
  1034           BOOST_VARIANT_LIMIT_TYPES
       
  1035         , BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
       
  1036         , _
       
  1037         )
       
  1038 
       
  1039     #undef BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
       
  1040 
       
  1041 private: // internal typedefs
       
  1042 
       
  1043     typedef typename detail::variant::make_variant_list<
       
  1044           BOOST_VARIANT_ENUM_PARAMS(internal_T)
       
  1045         >::type internal_types;
       
  1046 
       
  1047 private: // static precondition assertions
       
  1048 
       
  1049     // NOTE TO USER :
       
  1050     // variant< type-sequence > syntax is not supported on this compiler!
       
  1051     //
       
  1052     BOOST_MPL_ASSERT_NOT(( is_sequence_based_ ));
       
  1053 
       
  1054 #endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
       
  1055 
       
  1056 private: // helpers, for representation (below)
       
  1057 
       
  1058     typedef typename detail::variant::find_fallback_type<
       
  1059           internal_types
       
  1060         >::type fallback_type_result_;
       
  1061 
       
  1062     typedef typename fallback_type_result_::first
       
  1063         fallback_type_index_;
       
  1064     typedef typename fallback_type_result_::second
       
  1065         fallback_type_;
       
  1066 
       
  1067     struct has_fallback_type_
       
  1068         : mpl::not_<
       
  1069               is_same< fallback_type_, detail::variant::no_fallback_type >
       
  1070             >
       
  1071     {
       
  1072     };
       
  1073 
       
  1074     typedef has_fallback_type_
       
  1075         never_uses_backup_flag;
       
  1076 
       
  1077     typedef typename detail::variant::make_storage<
       
  1078           internal_types, never_uses_backup_flag
       
  1079         >::type storage_t;
       
  1080 
       
  1081 private: // helpers, for representation (below)
       
  1082 
       
  1083     // which_ on:
       
  1084     // * [0,  size<internal_types>) indicates stack content
       
  1085     // * [-size<internal_types>, 0) indicates pointer to heap backup
       
  1086     // if which_ >= 0:
       
  1087     // * then which() -> which_
       
  1088     // * else which() -> -(which_ + 1)
       
  1089 
       
  1090 #if !defined(BOOST_VARIANT_MINIMIZE_SIZE)
       
  1091 
       
  1092     typedef int which_t;
       
  1093 
       
  1094 #else // defined(BOOST_VARIANT_MINIMIZE_SIZE)
       
  1095 
       
  1096     // [if O1_size available, then attempt which_t size optimization...]
       
  1097     // [select signed char if fewer than SCHAR_MAX types, else signed int:]
       
  1098     typedef typename mpl::eval_if<
       
  1099           mpl::equal_to< mpl::O1_size<internal_types>, mpl::long_<-1> >
       
  1100         , mpl::identity< int >
       
  1101         , mpl::if_<
       
  1102               mpl::less< mpl::O1_size<internal_types>, mpl::int_<SCHAR_MAX> >
       
  1103             , signed char
       
  1104             , int
       
  1105             >
       
  1106         >::type which_t;
       
  1107 
       
  1108 #endif // BOOST_VARIANT_MINIMIZE_SIZE switch
       
  1109 
       
  1110 // representation -- private when possible
       
  1111 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
       
  1112     private:
       
  1113 #else
       
  1114     public:
       
  1115 #endif
       
  1116 
       
  1117     which_t which_;
       
  1118     storage_t storage_;
       
  1119 
       
  1120     void indicate_which(int which)
       
  1121     {
       
  1122         which_ = static_cast<which_t>( which );
       
  1123     }
       
  1124 
       
  1125     void indicate_backup_which(int which)
       
  1126     {
       
  1127         which_ = static_cast<which_t>( -(which + 1) );
       
  1128     }
       
  1129 
       
  1130 private: // helpers, for queries (below)
       
  1131 
       
  1132     bool using_backup() const
       
  1133     {
       
  1134         return which_ < 0;
       
  1135     }
       
  1136 
       
  1137 public: // queries
       
  1138 
       
  1139     int which() const
       
  1140     {
       
  1141         // If using heap backup...
       
  1142         if (using_backup())
       
  1143             // ...then return adjusted which_:
       
  1144             return -(which_ + 1);
       
  1145 
       
  1146         // Otherwise, return which_ directly:
       
  1147         return which_;
       
  1148     }
       
  1149 
       
  1150 private: // helpers, for structors (below)
       
  1151 
       
  1152     struct initializer
       
  1153         : BOOST_VARIANT_AUX_INITIALIZER_T(
       
  1154               recursive_enabled_types, recursive_enabled_T
       
  1155             )
       
  1156     {
       
  1157     };
       
  1158 
       
  1159     void destroy_content()
       
  1160     {
       
  1161         detail::variant::destroyer visitor;
       
  1162         this->internal_apply_visitor(visitor);
       
  1163     }
       
  1164 
       
  1165 public: // structors
       
  1166 
       
  1167     ~variant()
       
  1168     {
       
  1169         destroy_content();
       
  1170     }
       
  1171 
       
  1172     variant()
       
  1173     {
       
  1174         // NOTE TO USER :
       
  1175         // Compile error from here indicates that the first bound
       
  1176         // type is not default-constructible, and so variant cannot
       
  1177         // support its own default-construction.
       
  1178         //
       
  1179         new( storage_.address() ) internal_T0();
       
  1180         indicate_which(0); // zero is the index of the first bounded type
       
  1181     }
       
  1182 
       
  1183 private: // helpers, for structors, cont. (below)
       
  1184 
       
  1185     class convert_copy_into
       
  1186         : public static_visitor<int>
       
  1187     {
       
  1188     private: // representation
       
  1189 
       
  1190         void* storage_;
       
  1191 
       
  1192     public: // structors
       
  1193 
       
  1194         explicit convert_copy_into(void* storage)
       
  1195             : storage_(storage)
       
  1196         {
       
  1197         }
       
  1198 
       
  1199     public: // internal visitor interfaces (below)
       
  1200 
       
  1201         template <typename T>
       
  1202         int internal_visit(T& operand, int) const
       
  1203         {
       
  1204             // NOTE TO USER :
       
  1205             // Compile error here indicates one of the source variant's types 
       
  1206             // cannot be unambiguously converted to the destination variant's
       
  1207             // types (or that no conversion exists).
       
  1208             //
       
  1209             return initializer::initialize(storage_, operand);
       
  1210         }
       
  1211 
       
  1212 #   if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
       
  1213         template <typename T>
       
  1214         result_type internal_visit(const T& operand, int) const
       
  1215         {
       
  1216             return initializer::initialize(storage_, operand);
       
  1217         }
       
  1218 #   endif
       
  1219 
       
  1220         template <typename T>
       
  1221         int internal_visit(boost::detail::reference_content<T>& operand, long) const
       
  1222         {
       
  1223             return internal_visit( operand.get(), 1L );
       
  1224         }
       
  1225 
       
  1226         template <typename T>
       
  1227         int internal_visit(const boost::detail::reference_content<T>& operand, long) const
       
  1228         {
       
  1229             return internal_visit( operand.get(), 1L );
       
  1230         }
       
  1231 
       
  1232         template <typename T>
       
  1233         int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
       
  1234         {
       
  1235             return internal_visit( operand.get(), 1L );
       
  1236         }
       
  1237 
       
  1238         template <typename T>
       
  1239         int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
       
  1240         {
       
  1241             return internal_visit( operand.get(), 1L );
       
  1242         }
       
  1243 
       
  1244         template <typename T>
       
  1245         int internal_visit(boost::recursive_wrapper<T>& operand, long) const
       
  1246         {
       
  1247             return internal_visit( operand.get(), 1L );
       
  1248         }
       
  1249 
       
  1250         template <typename T>
       
  1251         int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
       
  1252         {
       
  1253             return internal_visit( operand.get(), 1L );
       
  1254         }
       
  1255 
       
  1256     };
       
  1257 
       
  1258     friend class convert_copy_into;
       
  1259 
       
  1260 private: // helpers, for structors, below 
       
  1261 
       
  1262     template <typename T>
       
  1263     void convert_construct(
       
  1264           T& operand
       
  1265         , int
       
  1266         , mpl::false_ = mpl::false_() // is_foreign_variant
       
  1267         )
       
  1268     {
       
  1269         // NOTE TO USER :
       
  1270         // Compile error here indicates that the given type is not 
       
  1271         // unambiguously convertible to one of the variant's types
       
  1272         // (or that no conversion exists).
       
  1273         //
       
  1274         indicate_which(
       
  1275               initializer::initialize(
       
  1276                   storage_.address()
       
  1277                 , operand
       
  1278                 )
       
  1279             );
       
  1280     }
       
  1281 
       
  1282     template <typename Variant>
       
  1283     void convert_construct(
       
  1284           Variant& operand
       
  1285         , long
       
  1286         , mpl::true_// is_foreign_variant
       
  1287         )
       
  1288     {
       
  1289         convert_copy_into visitor(storage_.address());
       
  1290         indicate_which(
       
  1291               operand.internal_apply_visitor(visitor)
       
  1292             );
       
  1293     }
       
  1294 
       
  1295     template <typename Variant>
       
  1296     void convert_construct_variant(Variant& operand)
       
  1297     {
       
  1298         // [Determine if the given variant is itself a bounded type, or if its
       
  1299         //  content needs to be converted (i.e., it is a 'foreign' variant):]
       
  1300         //
       
  1301 
       
  1302         typedef typename mpl::find_if<
       
  1303               types
       
  1304             , is_same<
       
  1305                   add_const<mpl::_1>
       
  1306                 , const Variant
       
  1307                 >
       
  1308             >::type found_it;
       
  1309 
       
  1310         typedef typename mpl::end<types>::type not_found;
       
  1311         typedef typename is_same<
       
  1312               found_it, not_found
       
  1313             >::type is_foreign_variant;
       
  1314 
       
  1315         // Convert construct from operand:
       
  1316         convert_construct(
       
  1317               operand, 1L
       
  1318             , is_foreign_variant()
       
  1319             );
       
  1320     }
       
  1321 
       
  1322     template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
       
  1323     void convert_construct(
       
  1324           boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
       
  1325         , long
       
  1326         )
       
  1327     {
       
  1328         convert_construct_variant(operand);
       
  1329     }
       
  1330 
       
  1331     template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
       
  1332     void convert_construct(
       
  1333           const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
       
  1334         , long
       
  1335         )
       
  1336     {
       
  1337         convert_construct_variant(operand);    
       
  1338     }
       
  1339 
       
  1340 public: // structors, cont.
       
  1341 
       
  1342 #if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
       
  1343 
       
  1344     template <typename T>
       
  1345     variant(const T& operand)
       
  1346     {
       
  1347         convert_construct(operand, 1L);
       
  1348     }
       
  1349 
       
  1350     template <typename T>
       
  1351     variant(T& operand)
       
  1352     {
       
  1353         convert_construct(operand, 1L);
       
  1354     }
       
  1355 
       
  1356 #elif defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
       
  1357 
       
  1358     // For compilers that cannot distinguish between T& and const T& in
       
  1359     // template constructors, but do fully support SFINAE, we can workaround:
       
  1360 
       
  1361     template <typename T>
       
  1362     variant(const T& operand)
       
  1363     {
       
  1364         convert_construct(operand, 1L);
       
  1365     }
       
  1366 
       
  1367     template <typename T>
       
  1368     variant(
       
  1369           T& operand
       
  1370         , typename enable_if<
       
  1371               mpl::not_< is_const<T> >
       
  1372             , void
       
  1373             >::type* = 0
       
  1374         )
       
  1375     {
       
  1376         convert_construct(operand, 1L);
       
  1377     }
       
  1378 
       
  1379 #else // !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
       
  1380 
       
  1381     // For compilers that cannot distinguish between T& and const T& in
       
  1382     // template constructors, and do NOT support SFINAE, we can't workaround:
       
  1383 
       
  1384     template <typename T>
       
  1385     variant(const T& operand)
       
  1386     {
       
  1387         convert_construct(operand, 1L);
       
  1388     }
       
  1389 
       
  1390 #endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds
       
  1391 
       
  1392 public: // structors, cont.
       
  1393 
       
  1394     // [MSVC6 requires copy constructor appear after template constructors]
       
  1395     variant(const variant& operand)
       
  1396     {
       
  1397         // Copy the value of operand into *this...
       
  1398         detail::variant::copy_into visitor( storage_.address() );
       
  1399         operand.internal_apply_visitor(visitor);
       
  1400 
       
  1401         // ...and activate the *this's primary storage on success:
       
  1402         indicate_which(operand.which());
       
  1403     }
       
  1404 
       
  1405 private: // helpers, for modifiers (below)
       
  1406 
       
  1407 #   if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
       
  1408     template <typename Variant, typename RhsT>
       
  1409     friend class detail::variant::backup_assigner;
       
  1410 #   endif
       
  1411 
       
  1412     // class assigner
       
  1413     //
       
  1414     // Internal visitor that "assigns" the visited value to the given variant
       
  1415     // by appropriate destruction and copy-construction.
       
  1416     //
       
  1417 
       
  1418     class assigner
       
  1419         : public static_visitor<>
       
  1420     {
       
  1421     private: // representation
       
  1422 
       
  1423         variant& lhs_;
       
  1424         int rhs_which_;
       
  1425 
       
  1426     public: // structors
       
  1427 
       
  1428         assigner(variant& lhs, int rhs_which)
       
  1429             : lhs_(lhs)
       
  1430             , rhs_which_(rhs_which)
       
  1431         {
       
  1432         }
       
  1433 
       
  1434     private: // helpers, for internal visitor interface (below)
       
  1435 
       
  1436         template <typename RhsT, typename B1, typename B2>
       
  1437         void assign_impl(
       
  1438               const RhsT& rhs_content
       
  1439             , mpl::true_// has_nothrow_copy
       
  1440             , B1// has_nothrow_move_constructor
       
  1441             , B2// has_fallback_type
       
  1442             )
       
  1443         {
       
  1444             // Destroy lhs's content...
       
  1445             lhs_.destroy_content(); // nothrow
       
  1446 
       
  1447             // ...copy rhs content into lhs's storage...
       
  1448             new(lhs_.storage_.address())
       
  1449                 RhsT( rhs_content ); // nothrow
       
  1450 
       
  1451             // ...and indicate new content type:
       
  1452             lhs_.indicate_which(rhs_which_); // nothrow
       
  1453         }
       
  1454 
       
  1455         template <typename RhsT, typename B>
       
  1456         void assign_impl(
       
  1457               const RhsT& rhs_content
       
  1458             , mpl::false_// has_nothrow_copy
       
  1459             , mpl::true_// has_nothrow_move_constructor
       
  1460             , B// has_fallback_type
       
  1461             )
       
  1462         {
       
  1463             // Attempt to make a temporary copy (so as to move it below)...
       
  1464             RhsT temp(rhs_content);
       
  1465 
       
  1466             // ...and upon success destroy lhs's content...
       
  1467             lhs_.destroy_content(); // nothrow
       
  1468 
       
  1469             // ...move the temporary copy into lhs's storage...
       
  1470             new(lhs_.storage_.address())
       
  1471                 RhsT( detail::variant::move(temp) ); // nothrow
       
  1472 
       
  1473             // ...and indicate new content type:
       
  1474             lhs_.indicate_which(rhs_which_); // nothrow
       
  1475         }
       
  1476 
       
  1477         template <typename RhsT>
       
  1478         void assign_impl(
       
  1479               const RhsT& rhs_content
       
  1480             , mpl::false_// has_nothrow_copy
       
  1481             , mpl::false_// has_nothrow_move_constructor
       
  1482             , mpl::true_// has_fallback_type
       
  1483             )
       
  1484         {
       
  1485             // Destroy lhs's content...
       
  1486             lhs_.destroy_content(); // nothrow
       
  1487 
       
  1488             try
       
  1489             {
       
  1490                 // ...and attempt to copy rhs's content into lhs's storage:
       
  1491                 new(lhs_.storage_.address())
       
  1492                     RhsT( rhs_content );
       
  1493             }
       
  1494             catch (...)
       
  1495             {
       
  1496                 // In case of failure, default-construct fallback type in lhs's storage...
       
  1497                 new (lhs_.storage_.address())
       
  1498                     fallback_type_; // nothrow
       
  1499 
       
  1500                 // ...indicate construction of fallback type...
       
  1501                 lhs_.indicate_which(
       
  1502                       BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value
       
  1503                     ); // nothrow
       
  1504 
       
  1505                 // ...and rethrow:
       
  1506                 throw;
       
  1507             }
       
  1508 
       
  1509             // In the event of success, indicate new content type:
       
  1510             lhs_.indicate_which(rhs_which_); // nothrow
       
  1511         }
       
  1512 
       
  1513         template <typename RhsT>
       
  1514         void assign_impl(
       
  1515               const RhsT& rhs_content
       
  1516             , mpl::false_// has_nothrow_copy
       
  1517             , mpl::false_// has_nothrow_move_constructor
       
  1518             , mpl::false_// has_fallback_type
       
  1519             )
       
  1520         {
       
  1521             detail::variant::backup_assigner<wknd_self_t, RhsT>
       
  1522                 visitor(lhs_, rhs_which_, rhs_content);
       
  1523             lhs_.internal_apply_visitor(visitor);
       
  1524         }
       
  1525 
       
  1526     public: // internal visitor interfaces
       
  1527 
       
  1528         template <typename RhsT>
       
  1529             BOOST_VARIANT_AUX_RETURN_VOID_TYPE
       
  1530         internal_visit(const RhsT& rhs_content, int)
       
  1531         {
       
  1532             typedef typename has_nothrow_copy<RhsT>::type
       
  1533                 nothrow_copy;
       
  1534             typedef typename mpl::or_< // reduces compile-time
       
  1535                   nothrow_copy
       
  1536                 , detail::variant::has_nothrow_move_constructor<RhsT>
       
  1537                 >::type nothrow_move_constructor;
       
  1538 
       
  1539             assign_impl(
       
  1540                   rhs_content
       
  1541                 , nothrow_copy()
       
  1542                 , nothrow_move_constructor()
       
  1543                 , has_fallback_type_()
       
  1544                 );
       
  1545 
       
  1546             BOOST_VARIANT_AUX_RETURN_VOID;
       
  1547         }
       
  1548 
       
  1549     };
       
  1550 
       
  1551     friend class assigner;
       
  1552 
       
  1553     void variant_assign(const variant& rhs)
       
  1554     {
       
  1555         // If the contained types are EXACTLY the same...
       
  1556         if (which_ == rhs.which_)
       
  1557         {
       
  1558             // ...then assign rhs's storage to lhs's content:
       
  1559             detail::variant::assign_storage visitor(rhs.storage_.address());
       
  1560             this->internal_apply_visitor(visitor);
       
  1561         }
       
  1562         else
       
  1563         {
       
  1564             // Otherwise, perform general (copy-based) variant assignment:
       
  1565             assigner visitor(*this, rhs.which());
       
  1566             rhs.internal_apply_visitor(visitor); 
       
  1567         }
       
  1568     }
       
  1569 
       
  1570 private: // helpers, for modifiers (below)
       
  1571 
       
  1572     template <typename T>
       
  1573     void assign(const T& rhs)
       
  1574     {
       
  1575         // If direct T-to-T assignment is not possible...
       
  1576         detail::variant::direct_assigner<const T> direct_assign(rhs);
       
  1577         if (this->apply_visitor(direct_assign) == false)
       
  1578         {
       
  1579             // ...then convert rhs to variant and assign:
       
  1580             //
       
  1581             // While potentially inefficient, the following construction of a
       
  1582             // variant allows T as any type convertible to one of the bounded
       
  1583             // types without excessive code redundancy.
       
  1584             //
       
  1585             variant temp(rhs);
       
  1586             variant_assign( detail::variant::move(temp) );
       
  1587         }
       
  1588     }
       
  1589 
       
  1590 public: // modifiers
       
  1591 
       
  1592     template <typename T>
       
  1593     variant& operator=(const T& rhs)
       
  1594     {
       
  1595         assign(rhs);
       
  1596         return *this;
       
  1597     }
       
  1598 
       
  1599     // [MSVC6 requires copy assign appear after templated operator=]
       
  1600     variant& operator=(const variant& rhs)
       
  1601     {
       
  1602         variant_assign(rhs);
       
  1603         return *this;
       
  1604     }
       
  1605 
       
  1606     void swap(variant& rhs)
       
  1607     {
       
  1608         // If the contained types are the same...
       
  1609         if (which() == rhs.which())
       
  1610         {
       
  1611             // ...then swap the values directly:
       
  1612             detail::variant::swap_with<variant> visitor(rhs);
       
  1613             this->apply_visitor(visitor);
       
  1614         }
       
  1615         else
       
  1616         {
       
  1617             // ...otherwise, perform general variant swap:
       
  1618             variant tmp( detail::variant::move(rhs) );
       
  1619             rhs = detail::variant::move(*this);
       
  1620             *this = detail::variant::move(tmp);
       
  1621         }
       
  1622     }
       
  1623 
       
  1624 public: // queries
       
  1625 
       
  1626     //
       
  1627     // NOTE: member which() defined above.
       
  1628     //
       
  1629 
       
  1630     bool empty() const
       
  1631     {
       
  1632         return false;
       
  1633     }
       
  1634 
       
  1635     const std::type_info& type() const
       
  1636     {
       
  1637         detail::variant::reflect visitor;
       
  1638         return this->apply_visitor(visitor);
       
  1639     }
       
  1640 
       
  1641 public: // prevent comparison with foreign types
       
  1642 
       
  1643 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
       
  1644 
       
  1645 #   define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \
       
  1646     void
       
  1647 
       
  1648 #else // MSVC7
       
  1649 
       
  1650     //
       
  1651     // MSVC7 gives error about return types for above being different than
       
  1652     // the true comparison operator overloads:
       
  1653     //
       
  1654 
       
  1655 #   define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \
       
  1656     bool
       
  1657 
       
  1658 #endif // MSVC7 workaround
       
  1659 
       
  1660     template <typename U>
       
  1661         BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE
       
  1662     operator==(const U&) const
       
  1663     {
       
  1664         BOOST_STATIC_ASSERT( false && sizeof(U) );
       
  1665     }
       
  1666 
       
  1667     template <typename U>
       
  1668         BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE
       
  1669     operator<(const U&) const
       
  1670     {
       
  1671         BOOST_STATIC_ASSERT( false && sizeof(U) );
       
  1672     }
       
  1673 
       
  1674 public: // comparison operators
       
  1675 
       
  1676     // [MSVC6 requires these operators appear after template operators]
       
  1677 
       
  1678     bool operator==(const variant& rhs) const
       
  1679     {
       
  1680         if (this->which() != rhs.which())
       
  1681             return false;
       
  1682 
       
  1683         detail::variant::comparer<
       
  1684               variant, detail::variant::equal_comp
       
  1685             > visitor(*this);
       
  1686         return rhs.apply_visitor(visitor);
       
  1687     }
       
  1688 
       
  1689     bool operator<(const variant& rhs) const
       
  1690     {
       
  1691         //
       
  1692         // Dirk Schreib suggested this collating order.
       
  1693         //
       
  1694 
       
  1695         if (this->which() != rhs.which())
       
  1696             return this->which() < rhs.which();
       
  1697 
       
  1698         detail::variant::comparer<
       
  1699               variant, detail::variant::less_comp
       
  1700             > visitor(*this);
       
  1701         return rhs.apply_visitor(visitor);
       
  1702     }
       
  1703 
       
  1704 // helpers, for visitation support (below) -- private when possible
       
  1705 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
       
  1706 
       
  1707     template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
       
  1708     friend class variant;
       
  1709 
       
  1710 private:
       
  1711 
       
  1712 #else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
       
  1713 
       
  1714 public:
       
  1715 
       
  1716 #endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
       
  1717 
       
  1718     template <typename Visitor, typename VoidPtrCV>
       
  1719     static
       
  1720         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
       
  1721               typename Visitor::result_type
       
  1722             )
       
  1723     internal_apply_visitor_impl(
       
  1724           int internal_which
       
  1725         , int logical_which
       
  1726         , Visitor& visitor
       
  1727         , VoidPtrCV storage
       
  1728         )
       
  1729     {
       
  1730         typedef mpl::int_<0> first_which;
       
  1731         typedef typename mpl::begin<internal_types>::type first_it;
       
  1732         typedef typename mpl::end<internal_types>::type last_it;
       
  1733 
       
  1734         typedef detail::variant::visitation_impl_step<
       
  1735               first_it, last_it
       
  1736             > first_step;
       
  1737 
       
  1738         return detail::variant::visitation_impl(
       
  1739               internal_which, logical_which
       
  1740             , visitor, storage, mpl::false_()
       
  1741             , never_uses_backup_flag()
       
  1742             , static_cast<first_which*>(0), static_cast<first_step*>(0)
       
  1743             );
       
  1744     }
       
  1745 
       
  1746     template <typename Visitor>
       
  1747         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
       
  1748               typename Visitor::result_type
       
  1749             )
       
  1750     internal_apply_visitor(Visitor& visitor)
       
  1751     {
       
  1752         return internal_apply_visitor_impl(
       
  1753               which_, which(), visitor, storage_.address()
       
  1754             );
       
  1755     }
       
  1756 
       
  1757     template <typename Visitor>
       
  1758         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
       
  1759               typename Visitor::result_type
       
  1760             )
       
  1761     internal_apply_visitor(Visitor& visitor) const
       
  1762     {
       
  1763         return internal_apply_visitor_impl(
       
  1764               which_, which(), visitor, storage_.address()
       
  1765             );
       
  1766     }
       
  1767 
       
  1768 public: // visitation support
       
  1769 
       
  1770     template <typename Visitor>
       
  1771         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
       
  1772               typename Visitor::result_type
       
  1773             )
       
  1774     apply_visitor(Visitor& visitor)
       
  1775     {
       
  1776         detail::variant::invoke_visitor<Visitor> invoker(visitor);
       
  1777         return this->internal_apply_visitor(invoker);
       
  1778     }
       
  1779 
       
  1780     template <typename Visitor>
       
  1781         BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
       
  1782               typename Visitor::result_type
       
  1783             )
       
  1784     apply_visitor(Visitor& visitor) const
       
  1785     {
       
  1786         detail::variant::invoke_visitor<Visitor> invoker(visitor);
       
  1787         return this->internal_apply_visitor(invoker);
       
  1788     }
       
  1789 
       
  1790 }; // class variant
       
  1791 
       
  1792 ///////////////////////////////////////////////////////////////////////////////
       
  1793 // metafunction make_variant_over
       
  1794 //
       
  1795 // See docs and boost/variant/variant_fwd.hpp for more information.
       
  1796 //
       
  1797 template <typename Types>
       
  1798 struct make_variant_over
       
  1799 {
       
  1800 private: // precondition assertions
       
  1801 
       
  1802 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
       
  1803     BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
       
  1804 #endif
       
  1805 
       
  1806 public: // metafunction result
       
  1807 
       
  1808     typedef variant<
       
  1809           detail::variant::over_sequence< Types >
       
  1810         > type;
       
  1811 
       
  1812 };
       
  1813 
       
  1814 ///////////////////////////////////////////////////////////////////////////////
       
  1815 // function template swap
       
  1816 //
       
  1817 // Swaps two variants of the same type (i.e., identical specification).
       
  1818 //
       
  1819 template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
       
  1820 inline void swap(
       
  1821       variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs
       
  1822     , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs
       
  1823     )
       
  1824 {
       
  1825     lhs.swap(rhs);
       
  1826 }
       
  1827 
       
  1828 } // namespace boost
       
  1829 
       
  1830 // implementation additions
       
  1831 #include "boost/variant/detail/variant_io.hpp"
       
  1832 
       
  1833 #endif // BOOST_VARIANT_VARIANT_HPP