1.1 --- a/epoc32/include/stdapis/boost/variant.hpp Wed Mar 31 12:27:01 2010 +0100
1.2 +++ b/epoc32/include/stdapis/boost/variant.hpp Wed Mar 31 12:33:34 2010 +0100
1.3 @@ -1,1833 +1,27 @@
1.4 //-----------------------------------------------------------------------------
1.5 -// boost variant/variant.hpp header file
1.6 +// boost variant.hpp header file
1.7 // See http://www.boost.org for updates, documentation, and revision history.
1.8 //-----------------------------------------------------------------------------
1.9 //
1.10 -// Copyright (c) 2002-2003
1.11 +// Copyright (c) 2003
1.12 // Eric Friedman, Itay Maman
1.13 //
1.14 // Distributed under the Boost Software License, Version 1.0. (See
1.15 // accompanying file LICENSE_1_0.txt or copy at
1.16 // http://www.boost.org/LICENSE_1_0.txt)
1.17 -/*
1.18 - * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved.
1.19 -*/
1.20 -#ifndef BOOST_VARIANT_VARIANT_HPP
1.21 -#define BOOST_VARIANT_VARIANT_HPP
1.22
1.23 -#include <cstddef> // for std::size_t
1.24 -#include <new> // for placement new
1.25 -#ifdef __SYMBIAN32__
1.26 -#include <string>
1.27 -#endif
1.28 -#include <typeinfo> // for typeid, std::type_info
1.29 +#ifndef BOOST_VARIANT_HPP
1.30 +#define BOOST_VARIANT_HPP
1.31
1.32 -#include "boost/variant/detail/config.hpp"
1.33 -#include "boost/mpl/aux_/config/eti.hpp"
1.34 -#include "boost/mpl/aux_/value_wknd.hpp"
1.35 +// variant "main"
1.36 +#include "boost/variant/variant.hpp"
1.37 +#include "boost/variant/recursive_variant.hpp"
1.38 +#include "boost/variant/recursive_wrapper.hpp"
1.39
1.40 -#include "boost/variant/variant_fwd.hpp"
1.41 -#include "boost/variant/detail/backup_holder.hpp"
1.42 -#include "boost/variant/detail/enable_recursive_fwd.hpp"
1.43 -#include "boost/variant/detail/forced_return.hpp"
1.44 -#include "boost/variant/detail/initializer.hpp"
1.45 -#include "boost/variant/detail/make_variant_list.hpp"
1.46 -#include "boost/variant/detail/over_sequence.hpp"
1.47 -#include "boost/variant/detail/visitation_impl.hpp"
1.48 +// common applications
1.49 +#include "boost/variant/get.hpp"
1.50 +#include "boost/variant/apply_visitor.hpp"
1.51 +#include "boost/variant/static_visitor.hpp"
1.52 +#include "boost/variant/visitor_ptr.hpp"
1.53
1.54 -#include "boost/variant/detail/generic_result_type.hpp"
1.55 -#include "boost/variant/detail/has_nothrow_move.hpp"
1.56 -#include "boost/variant/detail/move.hpp"
1.57 -
1.58 -#include "boost/detail/reference_content.hpp"
1.59 -#include "boost/aligned_storage.hpp"
1.60 -#include "boost/blank.hpp"
1.61 -#include "boost/static_assert.hpp"
1.62 -#include "boost/preprocessor/cat.hpp"
1.63 -#include "boost/preprocessor/repeat.hpp"
1.64 -#include "boost/type_traits/alignment_of.hpp"
1.65 -#include "boost/type_traits/add_const.hpp"
1.66 -#include "boost/type_traits/has_nothrow_constructor.hpp"
1.67 -#include "boost/type_traits/has_nothrow_copy.hpp"
1.68 -#include "boost/type_traits/is_const.hpp"
1.69 -#include "boost/type_traits/is_same.hpp"
1.70 -#include "boost/utility/enable_if.hpp"
1.71 -#include "boost/variant/recursive_wrapper_fwd.hpp"
1.72 -#include "boost/variant/static_visitor.hpp"
1.73 -
1.74 -#include "boost/mpl/eval_if.hpp"
1.75 -#include "boost/mpl/begin_end.hpp"
1.76 -#include "boost/mpl/bool.hpp"
1.77 -#include "boost/mpl/empty.hpp"
1.78 -#include "boost/mpl/find_if.hpp"
1.79 -#include "boost/mpl/front.hpp"
1.80 -#include "boost/mpl/identity.hpp"
1.81 -#include "boost/mpl/if.hpp"
1.82 -#include "boost/mpl/int.hpp"
1.83 -#include "boost/mpl/is_sequence.hpp"
1.84 -#include "boost/mpl/iterator_range.hpp"
1.85 -#include "boost/mpl/iter_fold_if.hpp"
1.86 -#include "boost/mpl/logical.hpp"
1.87 -#include "boost/mpl/max_element.hpp"
1.88 -#include "boost/mpl/next.hpp"
1.89 -#include "boost/mpl/deref.hpp"
1.90 -#include "boost/mpl/pair.hpp"
1.91 -#include "boost/mpl/protect.hpp"
1.92 -#include "boost/mpl/push_front.hpp"
1.93 -#include "boost/mpl/same_as.hpp"
1.94 -#include "boost/mpl/size_t.hpp"
1.95 -#include "boost/mpl/sizeof.hpp"
1.96 -#include "boost/mpl/transform.hpp"
1.97 -#include "boost/mpl/assert.hpp"
1.98 -
1.99 -///////////////////////////////////////////////////////////////////////////////
1.100 -// Implementation Macros:
1.101 -//
1.102 -// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
1.103 -// Defined in boost/variant/detail/visitation_impl.hpp.
1.104 -//
1.105 -// BOOST_VARIANT_MINIMIZE_SIZE
1.106 -// When #defined, implementation employs all known means to minimize the
1.107 -// size of variant obje cts. However, often unsuccessful due to alignment
1.108 -// issues, and potentially harmful to runtime speed, so not enabled by
1.109 -// default. (TODO: Investigate further.)
1.110 -
1.111 -#if defined(BOOST_VARIANT_MINIMIZE_SIZE)
1.112 -# include <climits> // for SCHAR_MAX
1.113 -# include "boost/mpl/eval_if.hpp"
1.114 -# include "boost/mpl/equal_to.hpp"
1.115 -# include "boost/mpl/identity.hpp"
1.116 -# include "boost/mpl/int.hpp"
1.117 -# include "boost/mpl/if.hpp"
1.118 -# include "boost/mpl/less.hpp"
1.119 -# include "boost/mpl/long.hpp"
1.120 -# include "boost/mpl/O1_size.hpp"
1.121 -#endif
1.122 -
1.123 -
1.124 -namespace boost {
1.125 -
1.126 -namespace detail { namespace variant {
1.127 -
1.128 -///////////////////////////////////////////////////////////////////////////////
1.129 -// (detail) metafunction max_value
1.130 -//
1.131 -// Finds the maximum value of the unary metafunction F over Sequence.
1.132 -//
1.133 -template <typename Sequence, typename F>
1.134 -struct max_value
1.135 -{
1.136 -private: // helpers, for metafunction result (below)
1.137 -
1.138 - typedef typename mpl::transform1<Sequence, F>::type transformed_;
1.139 - typedef typename mpl::max_element<transformed_
1.140 -
1.141 - >::type max_it;
1.142 -
1.143 -public: // metafunction result
1.144 -
1.145 - typedef typename mpl::deref<max_it>::type
1.146 - type;
1.147 -
1.148 -};
1.149 -
1.150 -///////////////////////////////////////////////////////////////////////////////
1.151 -// (detail) metafunction find_fallback_type
1.152 -//
1.153 -// Provides a fallback (i.e., nothrow default-constructible) type from the
1.154 -// specified sequence, or no_fallback_type if not found.
1.155 -//
1.156 -// This implementation is designed to prefer boost::blank over other potential
1.157 -// fallback types, regardless of its position in the specified sequence.
1.158 -//
1.159 -
1.160 -class no_fallback_type;
1.161 -
1.162 -struct find_fallback_type_pred
1.163 -{
1.164 - template <typename Iterator>
1.165 - struct apply
1.166 - {
1.167 - private:
1.168 - typedef typename mpl::deref<Iterator>::type t_;
1.169 -
1.170 - public:
1.171 - typedef mpl::not_< has_nothrow_constructor<t_> > type;
1.172 - };
1.173 -};
1.174 -
1.175 -template <typename Types>
1.176 -struct find_fallback_type
1.177 -{
1.178 -private: // helpers, for metafunction result (below)
1.179 -
1.180 - typedef typename mpl::end<Types>::type end_it;
1.181 -
1.182 - // [Find the first suitable fallback type...]
1.183 -
1.184 - typedef typename mpl::iter_fold_if<
1.185 - Types
1.186 - , mpl::int_<0>, mpl::protect< mpl::next<> >
1.187 - , mpl::protect< find_fallback_type_pred >
1.188 - >::type first_result_;
1.189 -
1.190 - typedef typename first_result_::first first_result_index;
1.191 - typedef typename first_result_::second first_result_it;
1.192 -
1.193 - // [...now search the rest of the sequence for boost::blank...]
1.194 -
1.195 - typedef typename mpl::iter_fold_if<
1.196 - mpl::iterator_range< first_result_it,end_it >
1.197 - , first_result_index, mpl::protect< mpl::next<> >
1.198 - , mpl::protect< mpl::not_same_as<boost::blank> >
1.199 - >::type second_result_;
1.200 -
1.201 - typedef typename second_result_::second second_result_it;
1.202 -
1.203 -public: // metafunction result
1.204 -
1.205 - // [...and return the results of the search:]
1.206 - typedef typename mpl::eval_if<
1.207 - is_same< second_result_it,end_it >
1.208 - , mpl::if_<
1.209 - is_same< first_result_it,end_it >
1.210 - , mpl::pair< no_fallback_type,no_fallback_type >
1.211 - , first_result_
1.212 - >
1.213 - , mpl::identity< second_result_ >
1.214 - >::type type;
1.215 -
1.216 -};
1.217 -
1.218 -#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
1.219 -
1.220 -template<>
1.221 -struct find_fallback_type<int>
1.222 -{
1.223 - typedef mpl::pair< no_fallback_type,no_fallback_type > type;
1.224 -};
1.225 -
1.226 -#endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
1.227 -
1.228 -///////////////////////////////////////////////////////////////////////////////
1.229 -// (detail) metafunction make_storage
1.230 -//
1.231 -// Provides an aligned storage type capable of holding any of the types
1.232 -// specified in the given type-sequence.
1.233 -//
1.234 -
1.235 -template <typename Types, typename NeverUsesBackupFlag>
1.236 -struct make_storage
1.237 -{
1.238 -private: // helpers, for metafunction result (below)
1.239 -
1.240 - typedef typename mpl::eval_if<
1.241 - NeverUsesBackupFlag
1.242 - , mpl::identity< Types >
1.243 - , mpl::push_front<
1.244 - Types, backup_holder<void*>
1.245 - >
1.246 - >::type types;
1.247 -
1.248 - typedef typename max_value<
1.249 - types, mpl::sizeof_<mpl::_1>
1.250 - >::type max_size;
1.251 -
1.252 -#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
1.253 -
1.254 - typedef typename max_value<
1.255 - types, alignment_of<mpl::_1>
1.256 - >::type max_alignment;
1.257 -
1.258 -#else // borland
1.259 -
1.260 - // temporary workaround -- use maximal alignment
1.261 - typedef mpl::size_t< -1 > max_alignment;
1.262 -
1.263 -#endif // borland workaround
1.264 -
1.265 -public: // metafunction result
1.266 -
1.267 -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
1.268 -
1.269 - typedef ::boost::aligned_storage<
1.270 - BOOST_MPL_AUX_VALUE_WKND(max_size)::value
1.271 - , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value
1.272 - > type;
1.273 -
1.274 -#else // MSVC7 and below
1.275 -
1.276 - BOOST_STATIC_CONSTANT(std::size_t, msvc_max_size_c = max_size::value);
1.277 - BOOST_STATIC_CONSTANT(std::size_t, msvc_max_alignment_c = max_alignment::value);
1.278 -
1.279 - typedef ::boost::aligned_storage<
1.280 - msvc_max_size_c
1.281 - , msvc_max_alignment_c
1.282 - > type;
1.283 -
1.284 -#endif // MSVC workaround
1.285 -
1.286 -};
1.287 -
1.288 -#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
1.289 -
1.290 -template<>
1.291 -struct make_storage<int,int>
1.292 -{
1.293 - typedef int type;
1.294 -};
1.295 -
1.296 -#endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
1.297 -
1.298 -///////////////////////////////////////////////////////////////////////////////
1.299 -// (detail) class destroyer
1.300 -//
1.301 -// Internal visitor that destroys the value it visits.
1.302 -//
1.303 -struct destroyer
1.304 - : public static_visitor<>
1.305 -{
1.306 -public: // visitor interfaces
1.307 -
1.308 - template <typename T>
1.309 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.310 - internal_visit(T& operand, int) const
1.311 - {
1.312 - operand.~T();
1.313 -
1.314 -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
1.315 - operand; // suppresses warnings
1.316 -#endif
1.317 -
1.318 - BOOST_VARIANT_AUX_RETURN_VOID;
1.319 - }
1.320 -
1.321 -};
1.322 -
1.323 -///////////////////////////////////////////////////////////////////////////////
1.324 -// (detail) class template known_get
1.325 -//
1.326 -// Visitor that returns a reference to content of the specified type.
1.327 -//
1.328 -// Precondition: visited variant MUST contain logical content of type T.
1.329 -//
1.330 -template <typename T>
1.331 -class known_get
1.332 - : public static_visitor<T&>
1.333 -{
1.334 -
1.335 -#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.336 -
1.337 -public: // visitor interface
1.338 -
1.339 - T& operator()(T& operand) const
1.340 - {
1.341 - return operand;
1.342 - }
1.343 -
1.344 - template <typename U>
1.345 - T& operator()(U&) const
1.346 - {
1.347 - // logical error to be here: see precondition above
1.348 - BOOST_ASSERT(false);
1.349 - return ::boost::detail::variant::forced_return< T& >();
1.350 - }
1.351 -
1.352 -#else // MSVC6
1.353 -
1.354 -private: // helpers, for visitor interface (below)
1.355 -
1.356 - T& execute(T& operand, mpl::true_) const
1.357 - {
1.358 - return operand;
1.359 - }
1.360 -
1.361 - template <typename U>
1.362 - T& execute(U& operand, mpl::false_) const
1.363 - {
1.364 - // logical error to be here: see precondition above
1.365 - BOOST_ASSERT(false);
1.366 - return ::boost::detail::variant::forced_return< T& >();
1.367 - }
1.368 -
1.369 -public: // visitor interface
1.370 -
1.371 - template <typename U>
1.372 - T& operator()(U& operand) const
1.373 - {
1.374 - typedef typename is_same< U,T >::type
1.375 - U_is_T;
1.376 -
1.377 - return execute(operand, U_is_T());
1.378 - }
1.379 -
1.380 -#endif // MSVC6 workaround
1.381 -
1.382 -};
1.383 -
1.384 -///////////////////////////////////////////////////////////////////////////////
1.385 -// (detail) class copy_into
1.386 -//
1.387 -// Internal visitor that copies the value it visits into the given buffer.
1.388 -//
1.389 -class copy_into
1.390 - : public static_visitor<>
1.391 -{
1.392 -private: // representation
1.393 -
1.394 - void* storage_;
1.395 -
1.396 -public: // structors
1.397 -
1.398 - explicit copy_into(void* storage)
1.399 - : storage_(storage)
1.400 - {
1.401 - }
1.402 -
1.403 -public: // internal visitor interface
1.404 -
1.405 - template <typename T>
1.406 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.407 - internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
1.408 - {
1.409 - new(storage_) T( operand.get() );
1.410 - BOOST_VARIANT_AUX_RETURN_VOID;
1.411 - }
1.412 -
1.413 - template <typename T>
1.414 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.415 - internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
1.416 - {
1.417 - new(storage_) T( operand.get() );
1.418 - BOOST_VARIANT_AUX_RETURN_VOID;
1.419 - }
1.420 -
1.421 - template <typename T>
1.422 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.423 - internal_visit(const T& operand, int) const
1.424 - {
1.425 - new(storage_) T(operand);
1.426 - BOOST_VARIANT_AUX_RETURN_VOID;
1.427 - }
1.428 -
1.429 -};
1.430 -
1.431 -///////////////////////////////////////////////////////////////////////////////
1.432 -// (detail) class assign_storage
1.433 -//
1.434 -// Internal visitor that assigns the given storage (which must be a
1.435 -// constructed value of the same type) to the value it visits.
1.436 -//
1.437 -struct assign_storage
1.438 - : public static_visitor<>
1.439 -{
1.440 -private: // representation
1.441 -
1.442 - const void* rhs_storage_;
1.443 -
1.444 -public: // structors
1.445 -
1.446 - explicit assign_storage(const void* rhs_storage)
1.447 - : rhs_storage_(rhs_storage)
1.448 - {
1.449 - }
1.450 -
1.451 -public: // internal visitor interfaces
1.452 -
1.453 - template <typename T>
1.454 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.455 - internal_visit(backup_holder<T>& lhs_content, long) const
1.456 - {
1.457 - lhs_content.get()
1.458 - = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
1.459 - BOOST_VARIANT_AUX_RETURN_VOID;
1.460 - }
1.461 -
1.462 - template <typename T>
1.463 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.464 - internal_visit(const backup_holder<T>& lhs_content, long) const
1.465 - {
1.466 - lhs_content.get()
1.467 - = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
1.468 - BOOST_VARIANT_AUX_RETURN_VOID;
1.469 - }
1.470 -
1.471 - template <typename T>
1.472 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.473 - internal_visit(T& lhs_content, int) const
1.474 - {
1.475 - // NOTE TO USER :
1.476 - // Compile error here indicates one of variant's bounded types does
1.477 - // not meet the requirements of the Assignable concept. Thus,
1.478 - // variant is not Assignable.
1.479 - //
1.480 - // Hint: Are any of the bounded types const-qualified or references?
1.481 - //
1.482 - lhs_content = *static_cast< const T* >(rhs_storage_);
1.483 - BOOST_VARIANT_AUX_RETURN_VOID;
1.484 - }
1.485 -
1.486 -};
1.487 -
1.488 -///////////////////////////////////////////////////////////////////////////////
1.489 -// (detail) class direct_assigner
1.490 -//
1.491 -// Generic static visitor that: if and only if the visited value is of the
1.492 -// specified type, assigns the given value to the visited value and returns
1.493 -// true; else returns false.
1.494 -//
1.495 -template <typename T>
1.496 -class direct_assigner
1.497 - : public static_visitor<bool>
1.498 -{
1.499 -private: // representation
1.500 -
1.501 - T& rhs_;
1.502 -
1.503 -public: // structors
1.504 -
1.505 - explicit direct_assigner(T& rhs)
1.506 - : rhs_(rhs)
1.507 - {
1.508 - }
1.509 -
1.510 -#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
1.511 -
1.512 -public: // visitor interface
1.513 -
1.514 - bool operator()(T& lhs)
1.515 - {
1.516 - lhs = rhs_;
1.517 - return true;
1.518 - }
1.519 -
1.520 - template <typename U>
1.521 - bool operator()(U&)
1.522 - {
1.523 - return false;
1.524 - }
1.525 -
1.526 -#else // MSVC6
1.527 -
1.528 -private: // helpers, for visitor interface (below)
1.529 -
1.530 - bool execute(T& lhs, mpl::true_)
1.531 - {
1.532 - lhs = rhs_;
1.533 - return true;
1.534 - }
1.535 -
1.536 - template <typename U>
1.537 - bool execute(U&, mpl::false_)
1.538 - {
1.539 - return false;
1.540 - }
1.541 -
1.542 -public: // visitor interface
1.543 -
1.544 - template <typename U>
1.545 - bool operator()(U& lhs)
1.546 - {
1.547 - typedef typename is_same<U,T>::type U_is_T;
1.548 - return execute(lhs, U_is_T());
1.549 - }
1.550 -
1.551 -#endif // MSVC6 workaround
1.552 -
1.553 -};
1.554 -
1.555 -///////////////////////////////////////////////////////////////////////////////
1.556 -// (detail) class backup_assigner
1.557 -//
1.558 -// Internal visitor that "assigns" the given value to the visited value,
1.559 -// using backup to recover if the destroy-copy sequence fails.
1.560 -//
1.561 -// NOTE: This needs to be a friend of variant, as it needs access to
1.562 -// indicate_which, indicate_backup_which, etc.
1.563 -//
1.564 -template <typename Variant, typename RhsT>
1.565 -class backup_assigner
1.566 - : public static_visitor<>
1.567 -{
1.568 -private: // representation
1.569 -
1.570 - Variant& lhs_;
1.571 - int rhs_which_;
1.572 - const RhsT& rhs_content_;
1.573 -
1.574 -public: // structors
1.575 -
1.576 - backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
1.577 - : lhs_(lhs)
1.578 - , rhs_which_(rhs_which)
1.579 - , rhs_content_(rhs_content)
1.580 - {
1.581 - }
1.582 -
1.583 -private: // helpers, for visitor interface (below)
1.584 -
1.585 - template <typename LhsT>
1.586 - void backup_assign_impl(
1.587 - LhsT& lhs_content
1.588 - , mpl::true_// has_nothrow_move
1.589 - )
1.590 - {
1.591 - // Move lhs content to backup...
1.592 - LhsT backup_lhs_content(
1.593 - ::boost::detail::variant::move(lhs_content)
1.594 - ); // nothrow
1.595 -
1.596 - // ...destroy lhs content...
1.597 - lhs_content.~LhsT(); // nothrow
1.598 -
1.599 - try
1.600 - {
1.601 - // ...and attempt to copy rhs content into lhs storage:
1.602 - new(lhs_.storage_.address()) RhsT(rhs_content_);
1.603 - }
1.604 - catch (...)
1.605 - {
1.606 - // In case of failure, restore backup content to lhs storage...
1.607 - new(lhs_.storage_.address())
1.608 - LhsT(
1.609 - ::boost::detail::variant::move(backup_lhs_content)
1.610 - ); // nothrow
1.611 -
1.612 - // ...and rethrow:
1.613 - throw;
1.614 - }
1.615 -
1.616 - // In case of success, indicate new content type:
1.617 - lhs_.indicate_which(rhs_which_); // nothrow
1.618 - }
1.619 -
1.620 - template <typename LhsT>
1.621 - void backup_assign_impl(
1.622 - LhsT& lhs_content
1.623 - , mpl::false_// has_nothrow_move
1.624 - )
1.625 - {
1.626 - // Backup lhs content...
1.627 - LhsT* backup_lhs_ptr = new LhsT(lhs_content);
1.628 -
1.629 - // ...destroy lhs content...
1.630 - lhs_content.~LhsT(); // nothrow
1.631 -
1.632 - try
1.633 - {
1.634 - // ...and attempt to copy rhs content into lhs storage:
1.635 - new(lhs_.storage_.address()) RhsT(rhs_content_);
1.636 - }
1.637 - catch (...)
1.638 - {
1.639 - // In case of failure, copy backup pointer to lhs storage...
1.640 - new(lhs_.storage_.address())
1.641 - backup_holder<LhsT>( backup_lhs_ptr ); // nothrow
1.642 -
1.643 - // ...indicate now using backup...
1.644 - lhs_.indicate_backup_which( lhs_.which() ); // nothrow
1.645 -
1.646 - // ...and rethrow:
1.647 - throw;
1.648 - }
1.649 -
1.650 - // In case of success, indicate new content type...
1.651 - lhs_.indicate_which(rhs_which_); // nothrow
1.652 -
1.653 - // ...and delete backup:
1.654 - delete backup_lhs_ptr; // nothrow
1.655 - }
1.656 -
1.657 -public: // visitor interface
1.658 -
1.659 - template <typename LhsT>
1.660 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.661 - internal_visit(LhsT& lhs_content, int)
1.662 - {
1.663 - typedef typename has_nothrow_move_constructor<LhsT>::type
1.664 - nothrow_move;
1.665 -
1.666 - backup_assign_impl( lhs_content, nothrow_move() );
1.667 -
1.668 - BOOST_VARIANT_AUX_RETURN_VOID;
1.669 - }
1.670 -
1.671 -};
1.672 -
1.673 -///////////////////////////////////////////////////////////////////////////////
1.674 -// (detail) class swap_with
1.675 -//
1.676 -// Visitor that swaps visited value with content of given variant.
1.677 -//
1.678 -// Precondition: Given variant MUST have same logical type as visited value.
1.679 -//
1.680 -template <typename Variant>
1.681 -struct swap_with
1.682 - : public static_visitor<>
1.683 -{
1.684 -private: // representation
1.685 -
1.686 - Variant& toswap_;
1.687 -
1.688 -public: // structors
1.689 -
1.690 - explicit swap_with(Variant& toswap)
1.691 - : toswap_(toswap)
1.692 - {
1.693 - }
1.694 -
1.695 -public: // internal visitor interfaces
1.696 -
1.697 - template <typename T>
1.698 - void operator()(T& operand) const
1.699 - {
1.700 - // Since the precondition ensures types are same, get T...
1.701 - known_get<T> getter;
1.702 - T& other = toswap_.apply_visitor(getter);
1.703 -
1.704 - // ...and swap:
1.705 - ::boost::detail::variant::move_swap( operand, other );
1.706 - }
1.707 -
1.708 -};
1.709 -
1.710 -///////////////////////////////////////////////////////////////////////////////
1.711 -// (detail) class reflect
1.712 -//
1.713 -// Generic static visitor that performs a typeid on the value it visits.
1.714 -//
1.715 -class reflect
1.716 - : public static_visitor<const std::type_info&>
1.717 -{
1.718 -public: // visitor interfaces
1.719 -
1.720 - template <typename T>
1.721 - const std::type_info& operator()(const T&) const
1.722 - {
1.723 - return typeid(T);
1.724 - }
1.725 -
1.726 -};
1.727 -
1.728 -///////////////////////////////////////////////////////////////////////////////
1.729 -// (detail) class comparer
1.730 -//
1.731 -// Generic static visitor that compares the content of the given lhs variant
1.732 -// with the visited rhs content using Comp.
1.733 -//
1.734 -// Precondition: lhs.which() == rhs.which()
1.735 -//
1.736 -template <typename Variant, typename Comp>
1.737 -class comparer
1.738 - : public static_visitor<bool>
1.739 -{
1.740 -private: // representation
1.741 -
1.742 - const Variant& lhs_;
1.743 -
1.744 -public: // structors
1.745 -
1.746 - explicit comparer(const Variant& lhs)
1.747 - : lhs_(lhs)
1.748 - {
1.749 - }
1.750 -
1.751 -public: // visitor interfaces
1.752 -
1.753 - template <typename T>
1.754 - bool operator()(const T& rhs_content) const
1.755 - {
1.756 - // Since the precondition ensures lhs and rhs types are same, get T...
1.757 - known_get<const T> getter;
1.758 - const T& lhs_content = lhs_.apply_visitor(getter);
1.759 -
1.760 - // ...and compare lhs and rhs contents:
1.761 - return Comp()(lhs_content, rhs_content);
1.762 - }
1.763 -
1.764 -};
1.765 -
1.766 -///////////////////////////////////////////////////////////////////////////////
1.767 -// (detail) class equal_comp
1.768 -//
1.769 -// Generic function object compares lhs with rhs using operator==.
1.770 -//
1.771 -struct equal_comp
1.772 -{
1.773 - template <typename T>
1.774 - bool operator()(const T& lhs, const T& rhs) const
1.775 - {
1.776 - return lhs == rhs;
1.777 - }
1.778 -};
1.779 -
1.780 -///////////////////////////////////////////////////////////////////////////////
1.781 -// (detail) class less_comp
1.782 -//
1.783 -// Generic function object compares lhs with rhs using operator<.
1.784 -//
1.785 -struct less_comp
1.786 -{
1.787 - template <typename T>
1.788 - bool operator()(const T& lhs, const T& rhs) const
1.789 - {
1.790 - return lhs < rhs;
1.791 - }
1.792 -};
1.793 -
1.794 -///////////////////////////////////////////////////////////////////////////////
1.795 -// (detail) class template invoke_visitor
1.796 -//
1.797 -// Internal visitor that invokes the given visitor using:
1.798 -// * for wrappers (e.g., recursive_wrapper), the wrapper's held value.
1.799 -// * for all other values, the value itself.
1.800 -//
1.801 -template <typename Visitor>
1.802 -class invoke_visitor
1.803 -{
1.804 -private: // representation
1.805 -
1.806 - Visitor& visitor_;
1.807 -
1.808 -public: // visitor typedefs
1.809 -
1.810 - typedef typename Visitor::result_type
1.811 - result_type;
1.812 -
1.813 -public: // structors
1.814 -
1.815 - explicit invoke_visitor(Visitor& visitor)
1.816 - : visitor_(visitor)
1.817 - {
1.818 - }
1.819 -
1.820 -#if !defined(BOOST_NO_VOID_RETURNS)
1.821 -
1.822 -public: // internal visitor interfaces
1.823 -
1.824 - template <typename T>
1.825 - result_type internal_visit(T& operand, int)
1.826 - {
1.827 - return visitor_(operand);
1.828 - }
1.829 -
1.830 -# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
1.831 - template <typename T>
1.832 - result_type internal_visit(const T& operand, int)
1.833 - {
1.834 - return visitor_(operand);
1.835 - }
1.836 -# endif
1.837 -
1.838 -#else // defined(BOOST_NO_VOID_RETURNS)
1.839 -
1.840 -private: // helpers, for internal visitor interfaces (below)
1.841 -
1.842 - template <typename T>
1.843 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.844 - visit_impl(T& operand, mpl::false_)
1.845 - {
1.846 - return visitor_(operand);
1.847 - }
1.848 -
1.849 - template <typename T>
1.850 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.851 - visit_impl(T& operand, mpl::true_)
1.852 - {
1.853 - visitor_(operand);
1.854 - BOOST_VARIANT_AUX_RETURN_VOID;
1.855 - }
1.856 -
1.857 -public: // internal visitor interfaces
1.858 -
1.859 - template <typename T>
1.860 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.861 - internal_visit(T& operand, int)
1.862 - {
1.863 - typedef typename is_same<result_type, void>::type
1.864 - has_void_result_type;
1.865 -
1.866 - return visit_impl(operand, has_void_result_type());
1.867 - }
1.868 -
1.869 -#endif // BOOST_NO_VOID_RETURNS) workaround
1.870 -
1.871 -public: // internal visitor interfaces, cont.
1.872 -
1.873 - template <typename T>
1.874 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.875 - internal_visit(boost::recursive_wrapper<T>& operand, long)
1.876 - {
1.877 - return internal_visit( operand.get(), 1L );
1.878 - }
1.879 -
1.880 - template <typename T>
1.881 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.882 - internal_visit(const boost::recursive_wrapper<T>& operand, long)
1.883 - {
1.884 - return internal_visit( operand.get(), 1L );
1.885 - }
1.886 -
1.887 - template <typename T>
1.888 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.889 - internal_visit(boost::detail::reference_content<T>& operand, long)
1.890 - {
1.891 - return internal_visit( operand.get(), 1L );
1.892 - }
1.893 -
1.894 - template <typename T>
1.895 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.896 - internal_visit(const boost::detail::reference_content<T>& operand, long)
1.897 - {
1.898 - return internal_visit( operand.get(), 1L );
1.899 - }
1.900 -
1.901 - template <typename T>
1.902 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.903 - internal_visit(boost::detail::variant::backup_holder<T>& operand, long)
1.904 - {
1.905 - return internal_visit( operand.get(), 1L );
1.906 - }
1.907 -
1.908 - template <typename T>
1.909 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
1.910 - internal_visit(const boost::detail::variant::backup_holder<T>& operand, long)
1.911 - {
1.912 - return internal_visit( operand.get(), 1L );
1.913 - }
1.914 -
1.915 -};
1.916 -
1.917 -}} // namespace detail::variant
1.918 -
1.919 -///////////////////////////////////////////////////////////////////////////////
1.920 -// class template variant (concept inspired by Andrei Alexandrescu)
1.921 -//
1.922 -// See docs and boost/variant/variant_fwd.hpp for more information.
1.923 -//
1.924 -template <
1.925 - typename T0_
1.926 - , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
1.927 - >
1.928 -class variant
1.929 -{
1.930 -private: // helpers, for typedefs (below)
1.931 -
1.932 - typedef variant wknd_self_t;
1.933 -
1.934 - struct is_recursive_
1.935 - : detail::variant::is_recursive_flag<T0_>
1.936 - {
1.937 - };
1.938 -
1.939 - typedef typename mpl::eval_if<
1.940 - is_recursive_
1.941 - , T0_
1.942 - , mpl::identity< T0_ >
1.943 - >::type unwrapped_T0_;
1.944 -
1.945 - struct is_sequence_based_
1.946 - : detail::variant::is_over_sequence<unwrapped_T0_>
1.947 - {
1.948 - };
1.949 -
1.950 -#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
1.951 -
1.952 -private: // helpers, for typedefs (below)
1.953 -
1.954 - typedef typename mpl::eval_if<
1.955 - is_sequence_based_
1.956 - , unwrapped_T0_ // over_sequence<...>::type
1.957 - , detail::variant::make_variant_list<
1.958 - unwrapped_T0_
1.959 - , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
1.960 - >
1.961 - >::type specified_types;
1.962 -
1.963 - BOOST_STATIC_ASSERT((
1.964 - ::boost::mpl::not_< mpl::empty<specified_types> >::value
1.965 - ));
1.966 -
1.967 - typedef typename mpl::eval_if<
1.968 - is_recursive_
1.969 - , mpl::transform<
1.970 - specified_types
1.971 - , mpl::protect<
1.972 - detail::variant::quoted_enable_recursive<wknd_self_t>
1.973 - >
1.974 - >
1.975 - , mpl::identity< specified_types >
1.976 - >::type recursive_enabled_types;
1.977 -
1.978 -public: // public typedefs
1.979 -
1.980 - typedef typename mpl::transform<
1.981 - recursive_enabled_types
1.982 - , unwrap_recursive<mpl::_1>
1.983 - >::type types;
1.984 -
1.985 -private: // internal typedefs
1.986 -
1.987 - typedef typename mpl::transform<
1.988 - recursive_enabled_types
1.989 - , mpl::protect< detail::make_reference_content<> >
1.990 - >::type internal_types;
1.991 -
1.992 - typedef typename mpl::front<
1.993 - internal_types
1.994 - >::type internal_T0;
1.995 -
1.996 -#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
1.997 -
1.998 -private: // helpers, for typedefs (below)
1.999 -
1.1000 - typedef unwrapped_T0_ T0;
1.1001 -
1.1002 - #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
1.1003 - typedef typename mpl::eval_if< \
1.1004 - is_recursive_ \
1.1005 - , detail::variant::enable_recursive< \
1.1006 - BOOST_PP_CAT(T,N) \
1.1007 - , wknd_self_t \
1.1008 - > \
1.1009 - , mpl::identity< BOOST_PP_CAT(T,N) > \
1.1010 - >::type BOOST_PP_CAT(recursive_enabled_T,N); \
1.1011 - /**/
1.1012 -
1.1013 - BOOST_PP_REPEAT(
1.1014 - BOOST_VARIANT_LIMIT_TYPES
1.1015 - , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
1.1016 - , _
1.1017 - )
1.1018 -
1.1019 - #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
1.1020 -
1.1021 - #define BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS(z,N,_) \
1.1022 - typedef typename unwrap_recursive< \
1.1023 - BOOST_PP_CAT(recursive_enabled_T,N) \
1.1024 - >::type BOOST_PP_CAT(public_T,N); \
1.1025 - /**/
1.1026 -
1.1027 - BOOST_PP_REPEAT(
1.1028 - BOOST_VARIANT_LIMIT_TYPES
1.1029 - , BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
1.1030 - , _
1.1031 - )
1.1032 -
1.1033 - #undef BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
1.1034 -
1.1035 -public: // public typedefs
1.1036 -
1.1037 - typedef typename detail::variant::make_variant_list<
1.1038 - BOOST_VARIANT_ENUM_PARAMS(public_T)
1.1039 - >::type types;
1.1040 -
1.1041 -private: // helpers, for internal typedefs (below)
1.1042 -
1.1043 - #define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \
1.1044 - typedef detail::make_reference_content< \
1.1045 - BOOST_PP_CAT(recursive_enabled_T,N) \
1.1046 - >::type BOOST_PP_CAT(internal_T,N); \
1.1047 - /**/
1.1048 -
1.1049 - BOOST_PP_REPEAT(
1.1050 - BOOST_VARIANT_LIMIT_TYPES
1.1051 - , BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
1.1052 - , _
1.1053 - )
1.1054 -
1.1055 - #undef BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
1.1056 -
1.1057 -private: // internal typedefs
1.1058 -
1.1059 - typedef typename detail::variant::make_variant_list<
1.1060 - BOOST_VARIANT_ENUM_PARAMS(internal_T)
1.1061 - >::type internal_types;
1.1062 -
1.1063 -private: // static precondition assertions
1.1064 -
1.1065 - // NOTE TO USER :
1.1066 - // variant< type-sequence > syntax is not supported on this compiler!
1.1067 - //
1.1068 - BOOST_MPL_ASSERT_NOT(( is_sequence_based_ ));
1.1069 -
1.1070 -#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
1.1071 -
1.1072 -private: // helpers, for representation (below)
1.1073 -
1.1074 - typedef typename detail::variant::find_fallback_type<
1.1075 - internal_types
1.1076 - >::type fallback_type_result_;
1.1077 -
1.1078 - typedef typename fallback_type_result_::first
1.1079 - fallback_type_index_;
1.1080 - typedef typename fallback_type_result_::second
1.1081 - fallback_type_;
1.1082 -
1.1083 - struct has_fallback_type_
1.1084 - : mpl::not_<
1.1085 - is_same< fallback_type_, detail::variant::no_fallback_type >
1.1086 - >
1.1087 - {
1.1088 - };
1.1089 -
1.1090 - typedef has_fallback_type_
1.1091 - never_uses_backup_flag;
1.1092 -
1.1093 - typedef typename detail::variant::make_storage<
1.1094 - internal_types, never_uses_backup_flag
1.1095 - >::type storage_t;
1.1096 -
1.1097 -private: // helpers, for representation (below)
1.1098 -
1.1099 - // which_ on:
1.1100 - // * [0, size<internal_types>) indicates stack content
1.1101 - // * [-size<internal_types>, 0) indicates pointer to heap backup
1.1102 - // if which_ >= 0:
1.1103 - // * then which() -> which_
1.1104 - // * else which() -> -(which_ + 1)
1.1105 -
1.1106 -#if !defined(BOOST_VARIANT_MINIMIZE_SIZE)
1.1107 -
1.1108 - typedef int which_t;
1.1109 -
1.1110 -#else // defined(BOOST_VARIANT_MINIMIZE_SIZE)
1.1111 -
1.1112 - // [if O1_size available, then attempt which_t size optimization...]
1.1113 - // [select signed char if fewer than SCHAR_MAX types, else signed int:]
1.1114 - typedef typename mpl::eval_if<
1.1115 - mpl::equal_to< mpl::O1_size<internal_types>, mpl::long_<-1> >
1.1116 - , mpl::identity< int >
1.1117 - , mpl::if_<
1.1118 - mpl::less< mpl::O1_size<internal_types>, mpl::int_<SCHAR_MAX> >
1.1119 - , signed char
1.1120 - , int
1.1121 - >
1.1122 - >::type which_t;
1.1123 -
1.1124 -#endif // BOOST_VARIANT_MINIMIZE_SIZE switch
1.1125 -
1.1126 -// representation -- private when possible
1.1127 -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.1128 - private:
1.1129 -#else
1.1130 - public:
1.1131 -#endif
1.1132 -
1.1133 - which_t which_;
1.1134 - storage_t storage_;
1.1135 -
1.1136 - void indicate_which(int which)
1.1137 - {
1.1138 - which_ = static_cast<which_t>( which );
1.1139 - }
1.1140 -
1.1141 - void indicate_backup_which(int which)
1.1142 - {
1.1143 - which_ = static_cast<which_t>( -(which + 1) );
1.1144 - }
1.1145 -
1.1146 -private: // helpers, for queries (below)
1.1147 -
1.1148 - bool using_backup() const
1.1149 - {
1.1150 - return which_ < 0;
1.1151 - }
1.1152 -
1.1153 -public: // queries
1.1154 -
1.1155 - int which() const
1.1156 - {
1.1157 - // If using heap backup...
1.1158 - if (using_backup())
1.1159 - // ...then return adjusted which_:
1.1160 - return -(which_ + 1);
1.1161 -
1.1162 - // Otherwise, return which_ directly:
1.1163 - return which_;
1.1164 - }
1.1165 -
1.1166 -private: // helpers, for structors (below)
1.1167 -
1.1168 - struct initializer
1.1169 - : BOOST_VARIANT_AUX_INITIALIZER_T(
1.1170 - recursive_enabled_types, recursive_enabled_T
1.1171 - )
1.1172 - {
1.1173 - };
1.1174 -
1.1175 - void destroy_content()
1.1176 - {
1.1177 - detail::variant::destroyer visitor;
1.1178 - this->internal_apply_visitor(visitor);
1.1179 - }
1.1180 -
1.1181 -public: // structors
1.1182 -
1.1183 - ~variant()
1.1184 - {
1.1185 - destroy_content();
1.1186 - }
1.1187 -
1.1188 - variant()
1.1189 - {
1.1190 - // NOTE TO USER :
1.1191 - // Compile error from here indicates that the first bound
1.1192 - // type is not default-constructible, and so variant cannot
1.1193 - // support its own default-construction.
1.1194 - //
1.1195 - new( storage_.address() ) internal_T0();
1.1196 - indicate_which(0); // zero is the index of the first bounded type
1.1197 - }
1.1198 -
1.1199 -private: // helpers, for structors, cont. (below)
1.1200 -
1.1201 - class convert_copy_into
1.1202 - : public static_visitor<int>
1.1203 - {
1.1204 - private: // representation
1.1205 -
1.1206 - void* storage_;
1.1207 -
1.1208 - public: // structors
1.1209 -
1.1210 - explicit convert_copy_into(void* storage)
1.1211 - : storage_(storage)
1.1212 - {
1.1213 - }
1.1214 -
1.1215 - public: // internal visitor interfaces (below)
1.1216 -
1.1217 - template <typename T>
1.1218 - int internal_visit(T& operand, int) const
1.1219 - {
1.1220 - // NOTE TO USER :
1.1221 - // Compile error here indicates one of the source variant's types
1.1222 - // cannot be unambiguously converted to the destination variant's
1.1223 - // types (or that no conversion exists).
1.1224 - //
1.1225 - return initializer::initialize(storage_, operand);
1.1226 - }
1.1227 -
1.1228 -# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
1.1229 - template <typename T>
1.1230 - result_type internal_visit(const T& operand, int) const
1.1231 - {
1.1232 - return initializer::initialize(storage_, operand);
1.1233 - }
1.1234 -# endif
1.1235 -
1.1236 - template <typename T>
1.1237 - int internal_visit(boost::detail::reference_content<T>& operand, long) const
1.1238 - {
1.1239 - return internal_visit( operand.get(), 1L );
1.1240 - }
1.1241 -
1.1242 - template <typename T>
1.1243 - int internal_visit(const boost::detail::reference_content<T>& operand, long) const
1.1244 - {
1.1245 - return internal_visit( operand.get(), 1L );
1.1246 - }
1.1247 -
1.1248 - template <typename T>
1.1249 - int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
1.1250 - {
1.1251 - return internal_visit( operand.get(), 1L );
1.1252 - }
1.1253 -
1.1254 - template <typename T>
1.1255 - int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
1.1256 - {
1.1257 - return internal_visit( operand.get(), 1L );
1.1258 - }
1.1259 -
1.1260 - template <typename T>
1.1261 - int internal_visit(boost::recursive_wrapper<T>& operand, long) const
1.1262 - {
1.1263 - return internal_visit( operand.get(), 1L );
1.1264 - }
1.1265 -
1.1266 - template <typename T>
1.1267 - int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
1.1268 - {
1.1269 - return internal_visit( operand.get(), 1L );
1.1270 - }
1.1271 -
1.1272 - };
1.1273 -
1.1274 - friend class convert_copy_into;
1.1275 -
1.1276 -private: // helpers, for structors, below
1.1277 -
1.1278 - template <typename T>
1.1279 - void convert_construct(
1.1280 - T& operand
1.1281 - , int
1.1282 - , mpl::false_ = mpl::false_() // is_foreign_variant
1.1283 - )
1.1284 - {
1.1285 - // NOTE TO USER :
1.1286 - // Compile error here indicates that the given type is not
1.1287 - // unambiguously convertible to one of the variant's types
1.1288 - // (or that no conversion exists).
1.1289 - //
1.1290 - indicate_which(
1.1291 - initializer::initialize(
1.1292 - storage_.address()
1.1293 - , operand
1.1294 - )
1.1295 - );
1.1296 - }
1.1297 -
1.1298 - template <typename Variant>
1.1299 - void convert_construct(
1.1300 - Variant& operand
1.1301 - , long
1.1302 - , mpl::true_// is_foreign_variant
1.1303 - )
1.1304 - {
1.1305 - convert_copy_into visitor(storage_.address());
1.1306 - indicate_which(
1.1307 - operand.internal_apply_visitor(visitor)
1.1308 - );
1.1309 - }
1.1310 -
1.1311 - template <typename Variant>
1.1312 - void convert_construct_variant(Variant& operand)
1.1313 - {
1.1314 - // [Determine if the given variant is itself a bounded type, or if its
1.1315 - // content needs to be converted (i.e., it is a 'foreign' variant):]
1.1316 - //
1.1317 -
1.1318 - typedef typename mpl::find_if<
1.1319 - types
1.1320 - , is_same<
1.1321 - add_const<mpl::_1>
1.1322 - , const Variant
1.1323 - >
1.1324 - >::type found_it;
1.1325 -
1.1326 - typedef typename mpl::end<types>::type not_found;
1.1327 - typedef typename is_same<
1.1328 - found_it, not_found
1.1329 - >::type is_foreign_variant;
1.1330 -
1.1331 - // Convert construct from operand:
1.1332 - convert_construct(
1.1333 - operand, 1L
1.1334 - , is_foreign_variant()
1.1335 - );
1.1336 - }
1.1337 -
1.1338 - template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
1.1339 - void convert_construct(
1.1340 - boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
1.1341 - , long
1.1342 - )
1.1343 - {
1.1344 - convert_construct_variant(operand);
1.1345 - }
1.1346 -
1.1347 - template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
1.1348 - void convert_construct(
1.1349 - const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
1.1350 - , long
1.1351 - )
1.1352 - {
1.1353 - convert_construct_variant(operand);
1.1354 - }
1.1355 -
1.1356 -public: // structors, cont.
1.1357 -
1.1358 -#if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
1.1359 -
1.1360 - template <typename T>
1.1361 - variant(const T& operand)
1.1362 - {
1.1363 - convert_construct(operand, 1L);
1.1364 - }
1.1365 -
1.1366 - template <typename T>
1.1367 - variant(T& operand)
1.1368 - {
1.1369 - convert_construct(operand, 1L);
1.1370 - }
1.1371 -
1.1372 -#elif defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
1.1373 -
1.1374 - // For compilers that cannot distinguish between T& and const T& in
1.1375 - // template constructors, but do fully support SFINAE, we can workaround:
1.1376 -
1.1377 - template <typename T>
1.1378 - variant(const T& operand)
1.1379 - {
1.1380 - convert_construct(operand, 1L);
1.1381 - }
1.1382 -
1.1383 - template <typename T>
1.1384 - variant(
1.1385 - T& operand
1.1386 - , typename enable_if<
1.1387 - mpl::not_< is_const<T> >
1.1388 - , void
1.1389 - >::type* = 0
1.1390 - )
1.1391 - {
1.1392 - convert_construct(operand, 1L);
1.1393 - }
1.1394 -
1.1395 -#else // !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
1.1396 -
1.1397 - // For compilers that cannot distinguish between T& and const T& in
1.1398 - // template constructors, and do NOT support SFINAE, we can't workaround:
1.1399 -
1.1400 - template <typename T>
1.1401 - variant(const T& operand)
1.1402 - {
1.1403 - convert_construct(operand, 1L);
1.1404 - }
1.1405 -
1.1406 -#endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds
1.1407 -
1.1408 -public: // structors, cont.
1.1409 -
1.1410 - // [MSVC6 requires copy constructor appear after template constructors]
1.1411 - variant(const variant& operand)
1.1412 - {
1.1413 - // Copy the value of operand into *this...
1.1414 - detail::variant::copy_into visitor( storage_.address() );
1.1415 - operand.internal_apply_visitor(visitor);
1.1416 -
1.1417 - // ...and activate the *this's primary storage on success:
1.1418 - indicate_which(operand.which());
1.1419 - }
1.1420 -
1.1421 -private: // helpers, for modifiers (below)
1.1422 -
1.1423 -# if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.1424 - template <typename Variant, typename RhsT>
1.1425 - friend class detail::variant::backup_assigner;
1.1426 -# endif
1.1427 -
1.1428 - // class assigner
1.1429 - //
1.1430 - // Internal visitor that "assigns" the visited value to the given variant
1.1431 - // by appropriate destruction and copy-construction.
1.1432 - //
1.1433 -
1.1434 - class assigner
1.1435 - : public static_visitor<>
1.1436 - {
1.1437 - private: // representation
1.1438 -
1.1439 - variant& lhs_;
1.1440 - int rhs_which_;
1.1441 -
1.1442 - public: // structors
1.1443 -
1.1444 - assigner(variant& lhs, int rhs_which)
1.1445 - : lhs_(lhs)
1.1446 - , rhs_which_(rhs_which)
1.1447 - {
1.1448 - }
1.1449 -
1.1450 - private: // helpers, for internal visitor interface (below)
1.1451 -
1.1452 - template <typename RhsT, typename B1, typename B2>
1.1453 - void assign_impl(
1.1454 - const RhsT& rhs_content
1.1455 - , mpl::true_// has_nothrow_copy
1.1456 - , B1// has_nothrow_move_constructor
1.1457 - , B2// has_fallback_type
1.1458 - )
1.1459 - {
1.1460 - // Destroy lhs's content...
1.1461 - lhs_.destroy_content(); // nothrow
1.1462 -
1.1463 - // ...copy rhs content into lhs's storage...
1.1464 - new(lhs_.storage_.address())
1.1465 - RhsT( rhs_content ); // nothrow
1.1466 -
1.1467 - // ...and indicate new content type:
1.1468 - lhs_.indicate_which(rhs_which_); // nothrow
1.1469 - }
1.1470 -
1.1471 - template <typename RhsT, typename B>
1.1472 - void assign_impl(
1.1473 - const RhsT& rhs_content
1.1474 - , mpl::false_// has_nothrow_copy
1.1475 - , mpl::true_// has_nothrow_move_constructor
1.1476 - , B// has_fallback_type
1.1477 - )
1.1478 - {
1.1479 - // Attempt to make a temporary copy (so as to move it below)...
1.1480 - RhsT temp(rhs_content);
1.1481 -
1.1482 - // ...and upon success destroy lhs's content...
1.1483 - lhs_.destroy_content(); // nothrow
1.1484 -
1.1485 - // ...move the temporary copy into lhs's storage...
1.1486 - new(lhs_.storage_.address())
1.1487 - RhsT( detail::variant::move(temp) ); // nothrow
1.1488 -
1.1489 - // ...and indicate new content type:
1.1490 - lhs_.indicate_which(rhs_which_); // nothrow
1.1491 - }
1.1492 -
1.1493 - template <typename RhsT>
1.1494 - void assign_impl(
1.1495 - const RhsT& rhs_content
1.1496 - , mpl::false_// has_nothrow_copy
1.1497 - , mpl::false_// has_nothrow_move_constructor
1.1498 - , mpl::true_// has_fallback_type
1.1499 - )
1.1500 - {
1.1501 - // Destroy lhs's content...
1.1502 - lhs_.destroy_content(); // nothrow
1.1503 -
1.1504 - try
1.1505 - {
1.1506 - // ...and attempt to copy rhs's content into lhs's storage:
1.1507 - new(lhs_.storage_.address())
1.1508 - RhsT( rhs_content );
1.1509 - }
1.1510 - catch (...)
1.1511 - {
1.1512 - // In case of failure, default-construct fallback type in lhs's storage...
1.1513 - new (lhs_.storage_.address())
1.1514 - fallback_type_; // nothrow
1.1515 -
1.1516 - // ...indicate construction of fallback type...
1.1517 - lhs_.indicate_which(
1.1518 - BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value
1.1519 - ); // nothrow
1.1520 -
1.1521 - // ...and rethrow:
1.1522 - throw;
1.1523 - }
1.1524 -
1.1525 - // In the event of success, indicate new content type:
1.1526 - lhs_.indicate_which(rhs_which_); // nothrow
1.1527 - }
1.1528 -
1.1529 - template <typename RhsT>
1.1530 - void assign_impl(
1.1531 - const RhsT& rhs_content
1.1532 - , mpl::false_// has_nothrow_copy
1.1533 - , mpl::false_// has_nothrow_move_constructor
1.1534 - , mpl::false_// has_fallback_type
1.1535 - )
1.1536 - {
1.1537 - detail::variant::backup_assigner<wknd_self_t, RhsT>
1.1538 - visitor(lhs_, rhs_which_, rhs_content);
1.1539 - lhs_.internal_apply_visitor(visitor);
1.1540 - }
1.1541 -
1.1542 - public: // internal visitor interfaces
1.1543 -
1.1544 - template <typename RhsT>
1.1545 - BOOST_VARIANT_AUX_RETURN_VOID_TYPE
1.1546 - internal_visit(const RhsT& rhs_content, int)
1.1547 - {
1.1548 - typedef typename has_nothrow_copy<RhsT>::type
1.1549 - nothrow_copy;
1.1550 - typedef typename mpl::or_< // reduces compile-time
1.1551 - nothrow_copy
1.1552 - , detail::variant::has_nothrow_move_constructor<RhsT>
1.1553 - >::type nothrow_move_constructor;
1.1554 -
1.1555 - assign_impl(
1.1556 - rhs_content
1.1557 - , nothrow_copy()
1.1558 - , nothrow_move_constructor()
1.1559 - , has_fallback_type_()
1.1560 - );
1.1561 -
1.1562 - BOOST_VARIANT_AUX_RETURN_VOID;
1.1563 - }
1.1564 -
1.1565 - };
1.1566 -
1.1567 - friend class assigner;
1.1568 -
1.1569 - void variant_assign(const variant& rhs)
1.1570 - {
1.1571 - // If the contained types are EXACTLY the same...
1.1572 - if (which_ == rhs.which_)
1.1573 - {
1.1574 - // ...then assign rhs's storage to lhs's content:
1.1575 - detail::variant::assign_storage visitor(rhs.storage_.address());
1.1576 - this->internal_apply_visitor(visitor);
1.1577 - }
1.1578 - else
1.1579 - {
1.1580 - // Otherwise, perform general (copy-based) variant assignment:
1.1581 - assigner visitor(*this, rhs.which());
1.1582 - rhs.internal_apply_visitor(visitor);
1.1583 - }
1.1584 - }
1.1585 -
1.1586 -private: // helpers, for modifiers (below)
1.1587 -
1.1588 - template <typename T>
1.1589 - void assign(const T& rhs)
1.1590 - {
1.1591 - // If direct T-to-T assignment is not possible...
1.1592 - detail::variant::direct_assigner<const T> direct_assign(rhs);
1.1593 - if (this->apply_visitor(direct_assign) == false)
1.1594 - {
1.1595 - // ...then convert rhs to variant and assign:
1.1596 - //
1.1597 - // While potentially inefficient, the following construction of a
1.1598 - // variant allows T as any type convertible to one of the bounded
1.1599 - // types without excessive code redundancy.
1.1600 - //
1.1601 - variant temp(rhs);
1.1602 - variant_assign( detail::variant::move(temp) );
1.1603 - }
1.1604 - }
1.1605 -
1.1606 -public: // modifiers
1.1607 -
1.1608 - template <typename T>
1.1609 - variant& operator=(const T& rhs)
1.1610 - {
1.1611 - assign(rhs);
1.1612 - return *this;
1.1613 - }
1.1614 -
1.1615 - // [MSVC6 requires copy assign appear after templated operator=]
1.1616 - variant& operator=(const variant& rhs)
1.1617 - {
1.1618 - variant_assign(rhs);
1.1619 - return *this;
1.1620 - }
1.1621 -
1.1622 - void swap(variant& rhs)
1.1623 - {
1.1624 - // If the contained types are the same...
1.1625 - if (which() == rhs.which())
1.1626 - {
1.1627 - // ...then swap the values directly:
1.1628 - detail::variant::swap_with<variant> visitor(rhs);
1.1629 - this->apply_visitor(visitor);
1.1630 - }
1.1631 - else
1.1632 - {
1.1633 - // ...otherwise, perform general variant swap:
1.1634 - variant tmp( detail::variant::move(rhs) );
1.1635 - rhs = detail::variant::move(*this);
1.1636 - *this = detail::variant::move(tmp);
1.1637 - }
1.1638 - }
1.1639 -
1.1640 -public: // queries
1.1641 -
1.1642 - //
1.1643 - // NOTE: member which() defined above.
1.1644 - //
1.1645 -
1.1646 - bool empty() const
1.1647 - {
1.1648 - return false;
1.1649 - }
1.1650 -
1.1651 - const std::type_info& type() const
1.1652 - {
1.1653 - detail::variant::reflect visitor;
1.1654 - return this->apply_visitor(visitor);
1.1655 - }
1.1656 -
1.1657 -public: // prevent comparison with foreign types
1.1658 -
1.1659 -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
1.1660 -
1.1661 -# define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \
1.1662 - void
1.1663 -
1.1664 -#else // MSVC7
1.1665 -
1.1666 - //
1.1667 - // MSVC7 gives error about return types for above being different than
1.1668 - // the true comparison operator overloads:
1.1669 - //
1.1670 -
1.1671 -# define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \
1.1672 - bool
1.1673 -
1.1674 -#endif // MSVC7 workaround
1.1675 -
1.1676 - template <typename U>
1.1677 - BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE
1.1678 - operator==(const U&) const
1.1679 - {
1.1680 - BOOST_STATIC_ASSERT( false && sizeof(U) );
1.1681 - }
1.1682 -
1.1683 - template <typename U>
1.1684 - BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE
1.1685 - operator<(const U&) const
1.1686 - {
1.1687 - BOOST_STATIC_ASSERT( false && sizeof(U) );
1.1688 - }
1.1689 -
1.1690 -public: // comparison operators
1.1691 -
1.1692 - // [MSVC6 requires these operators appear after template operators]
1.1693 -
1.1694 - bool operator==(const variant& rhs) const
1.1695 - {
1.1696 - if (this->which() != rhs.which())
1.1697 - return false;
1.1698 -
1.1699 - detail::variant::comparer<
1.1700 - variant, detail::variant::equal_comp
1.1701 - > visitor(*this);
1.1702 - return rhs.apply_visitor(visitor);
1.1703 - }
1.1704 -
1.1705 - bool operator<(const variant& rhs) const
1.1706 - {
1.1707 - //
1.1708 - // Dirk Schreib suggested this collating order.
1.1709 - //
1.1710 -
1.1711 - if (this->which() != rhs.which())
1.1712 - return this->which() < rhs.which();
1.1713 -
1.1714 - detail::variant::comparer<
1.1715 - variant, detail::variant::less_comp
1.1716 - > visitor(*this);
1.1717 - return rhs.apply_visitor(visitor);
1.1718 - }
1.1719 -
1.1720 -// helpers, for visitation support (below) -- private when possible
1.1721 -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.1722 -
1.1723 - template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
1.1724 - friend class variant;
1.1725 -
1.1726 -private:
1.1727 -
1.1728 -#else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.1729 -
1.1730 -public:
1.1731 -
1.1732 -#endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.1733 -
1.1734 - template <typename Visitor, typename VoidPtrCV>
1.1735 - static
1.1736 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
1.1737 - typename Visitor::result_type
1.1738 - )
1.1739 - internal_apply_visitor_impl(
1.1740 - int internal_which
1.1741 - , int logical_which
1.1742 - , Visitor& visitor
1.1743 - , VoidPtrCV storage
1.1744 - )
1.1745 - {
1.1746 - typedef mpl::int_<0> first_which;
1.1747 - typedef typename mpl::begin<internal_types>::type first_it;
1.1748 - typedef typename mpl::end<internal_types>::type last_it;
1.1749 -
1.1750 - typedef detail::variant::visitation_impl_step<
1.1751 - first_it, last_it
1.1752 - > first_step;
1.1753 -
1.1754 - return detail::variant::visitation_impl(
1.1755 - internal_which, logical_which
1.1756 - , visitor, storage, mpl::false_()
1.1757 - , never_uses_backup_flag()
1.1758 - , static_cast<first_which*>(0), static_cast<first_step*>(0)
1.1759 - );
1.1760 - }
1.1761 -
1.1762 - template <typename Visitor>
1.1763 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
1.1764 - typename Visitor::result_type
1.1765 - )
1.1766 - internal_apply_visitor(Visitor& visitor)
1.1767 - {
1.1768 - return internal_apply_visitor_impl(
1.1769 - which_, which(), visitor, storage_.address()
1.1770 - );
1.1771 - }
1.1772 -
1.1773 - template <typename Visitor>
1.1774 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
1.1775 - typename Visitor::result_type
1.1776 - )
1.1777 - internal_apply_visitor(Visitor& visitor) const
1.1778 - {
1.1779 - return internal_apply_visitor_impl(
1.1780 - which_, which(), visitor, storage_.address()
1.1781 - );
1.1782 - }
1.1783 -
1.1784 -public: // visitation support
1.1785 -
1.1786 - template <typename Visitor>
1.1787 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
1.1788 - typename Visitor::result_type
1.1789 - )
1.1790 - apply_visitor(Visitor& visitor)
1.1791 - {
1.1792 - detail::variant::invoke_visitor<Visitor> invoker(visitor);
1.1793 - return this->internal_apply_visitor(invoker);
1.1794 - }
1.1795 -
1.1796 - template <typename Visitor>
1.1797 - BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
1.1798 - typename Visitor::result_type
1.1799 - )
1.1800 - apply_visitor(Visitor& visitor) const
1.1801 - {
1.1802 - detail::variant::invoke_visitor<Visitor> invoker(visitor);
1.1803 - return this->internal_apply_visitor(invoker);
1.1804 - }
1.1805 -
1.1806 -}; // class variant
1.1807 -
1.1808 -///////////////////////////////////////////////////////////////////////////////
1.1809 -// metafunction make_variant_over
1.1810 -//
1.1811 -// See docs and boost/variant/variant_fwd.hpp for more information.
1.1812 -//
1.1813 -template <typename Types>
1.1814 -struct make_variant_over
1.1815 -{
1.1816 -private: // precondition assertions
1.1817 -
1.1818 -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
1.1819 - BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
1.1820 -#endif
1.1821 -
1.1822 -public: // metafunction result
1.1823 -
1.1824 - typedef variant<
1.1825 - detail::variant::over_sequence< Types >
1.1826 - > type;
1.1827 -
1.1828 -};
1.1829 -
1.1830 -///////////////////////////////////////////////////////////////////////////////
1.1831 -// function template swap
1.1832 -//
1.1833 -// Swaps two variants of the same type (i.e., identical specification).
1.1834 -//
1.1835 -template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
1.1836 -inline void swap(
1.1837 - variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs
1.1838 - , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs
1.1839 - )
1.1840 -{
1.1841 - lhs.swap(rhs);
1.1842 -}
1.1843 -
1.1844 -} // namespace boost
1.1845 -
1.1846 -// implementation additions
1.1847 -#include "boost/variant/detail/variant_io.hpp"
1.1848 -
1.1849 -#endif // BOOST_VARIANT_VARIANT_HPP
1.1850 +#endif // BOOST_VARIANT_HPP