epoc32/include/stdapis/boost/variant/variant.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 //-----------------------------------------------------------------------------
     2 // boost variant/variant.hpp header file
     3 // See http://www.boost.org for updates, documentation, and revision history.
     4 //-----------------------------------------------------------------------------
     5 //
     6 // Copyright (c) 2002-2003
     7 // Eric Friedman, Itay Maman
     8 //
     9 // Distributed under the Boost Software License, Version 1.0. (See
    10 // accompanying file LICENSE_1_0.txt or copy at
    11 // http://www.boost.org/LICENSE_1_0.txt)
    12 /*
    13  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
    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 #ifdef __SYMBIAN32__
    21 #include <string>
    22 #endif
    23 #include <typeinfo> // for typeid, std::type_info
    24 
    25 #include "boost/variant/detail/config.hpp"
    26 #include "boost/mpl/aux_/config/eti.hpp"
    27 #include "boost/mpl/aux_/value_wknd.hpp"
    28 
    29 #include "boost/variant/variant_fwd.hpp"
    30 #include "boost/variant/detail/backup_holder.hpp"
    31 #include "boost/variant/detail/enable_recursive_fwd.hpp"
    32 #include "boost/variant/detail/forced_return.hpp"
    33 #include "boost/variant/detail/initializer.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 
    38 #include "boost/variant/detail/generic_result_type.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