📄 variant.hpp
字号:
typedef typename mpl::eval_if<
is_recursive_
, T0_
, mpl::identity< T0_ >
>::type unwrapped_T0_;
struct is_sequence_based_
: detail::variant::is_over_sequence<unwrapped_T0_>
{
};
#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
private: // helpers, for typedefs (below)
typedef typename mpl::eval_if<
is_sequence_based_
, unwrapped_T0_ // over_sequence<...>::type
, detail::variant::make_variant_list<
unwrapped_T0_
, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
>
>::type specified_types;
BOOST_STATIC_ASSERT((
::boost::mpl::not_< mpl::empty<specified_types> >::value
));
typedef typename mpl::eval_if<
is_recursive_
, mpl::transform<
specified_types
, mpl::protect<
detail::variant::quoted_enable_recursive<wknd_self_t>
>
>
, mpl::identity< specified_types >
>::type recursive_enabled_types;
public: // public typedefs
typedef typename mpl::transform<
recursive_enabled_types
, unwrap_recursive<mpl::_1>
>::type types;
private: // internal typedefs
typedef typename mpl::transform<
recursive_enabled_types
, mpl::protect< detail::make_reference_content<> >
>::type internal_types;
typedef typename mpl::front<
internal_types
>::type internal_T0;
#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
private: // helpers, for typedefs (below)
typedef unwrapped_T0_ T0;
#define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
typedef typename mpl::eval_if< \
is_recursive_ \
, detail::variant::enable_recursive< \
BOOST_PP_CAT(T,N) \
, wknd_self_t \
> \
, mpl::identity< BOOST_PP_CAT(T,N) > \
>::type BOOST_PP_CAT(recursive_enabled_T,N); \
/**/
BOOST_PP_REPEAT(
BOOST_VARIANT_LIMIT_TYPES
, BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
, _
)
#undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
#define BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS(z,N,_) \
typedef typename unwrap_recursive< \
BOOST_PP_CAT(recursive_enabled_T,N) \
>::type BOOST_PP_CAT(public_T,N); \
/**/
BOOST_PP_REPEAT(
BOOST_VARIANT_LIMIT_TYPES
, BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
, _
)
#undef BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
public: // public typedefs
typedef typename detail::variant::make_variant_list<
BOOST_VARIANT_ENUM_PARAMS(public_T)
>::type types;
private: // helpers, for internal typedefs (below)
#define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \
typedef detail::make_reference_content< \
BOOST_PP_CAT(recursive_enabled_T,N) \
>::type BOOST_PP_CAT(internal_T,N); \
/**/
BOOST_PP_REPEAT(
BOOST_VARIANT_LIMIT_TYPES
, BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
, _
)
#undef BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
private: // internal typedefs
typedef typename detail::variant::make_variant_list<
BOOST_VARIANT_ENUM_PARAMS(internal_T)
>::type internal_types;
private: // static precondition assertions
// NOTE TO USER :
// variant< type-sequence > syntax is not supported on this compiler!
//
BOOST_MPL_ASSERT_NOT(( is_sequence_based_ ));
#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
private: // helpers, for representation (below)
typedef typename detail::variant::find_fallback_type<
internal_types
>::type fallback_type_result_;
typedef typename fallback_type_result_::first
fallback_type_index_;
typedef typename fallback_type_result_::second
fallback_type_;
struct has_fallback_type_
: mpl::not_<
is_same< fallback_type_, detail::variant::no_fallback_type >
>
{
};
typedef has_fallback_type_
never_uses_backup_flag;
typedef typename detail::variant::make_storage<
internal_types, never_uses_backup_flag
>::type storage_t;
private: // helpers, for representation (below)
// which_ on:
// * [0, size<internal_types>) indicates stack content
// * [-size<internal_types>, 0) indicates pointer to heap backup
// if which_ >= 0:
// * then which() -> which_
// * else which() -> -(which_ + 1)
#if !defined(BOOST_VARIANT_MINIMIZE_SIZE)
typedef int which_t;
#else // defined(BOOST_VARIANT_MINIMIZE_SIZE)
// [if O1_size available, then attempt which_t size optimization...]
// [select signed char if fewer than SCHAR_MAX types, else signed int:]
typedef typename mpl::eval_if<
mpl::equal_to< mpl::O1_size<internal_types>, mpl::long_<-1> >
, mpl::identity< int >
, mpl::if_<
mpl::less< mpl::O1_size<internal_types>, mpl::int_<SCHAR_MAX> >
, signed char
, int
>
>::type which_t;
#endif // BOOST_VARIANT_MINIMIZE_SIZE switch
// representation -- private when possible
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
private:
#else
public:
#endif
which_t which_;
storage_t storage_;
void indicate_which(int which)
{
which_ = static_cast<which_t>( which );
}
void indicate_backup_which(int which)
{
which_ = static_cast<which_t>( -(which + 1) );
}
private: // helpers, for queries (below)
bool using_backup() const
{
return which_ < 0;
}
public: // queries
int which() const
{
// If using heap backup...
if (using_backup())
// ...then return adjusted which_:
return -(which_ + 1);
// Otherwise, return which_ directly:
return which_;
}
private: // helpers, for structors (below)
struct initializer
: BOOST_VARIANT_AUX_INITIALIZER_T(
recursive_enabled_types, recursive_enabled_T
)
{
};
void destroy_content()
{
detail::variant::destroyer visitor;
this->internal_apply_visitor(visitor);
}
public: // structors
~variant()
{
destroy_content();
}
variant()
{
// NOTE TO USER :
// Compile error from here indicates that the first bound
// type is not default-constructible, and so variant cannot
// support its own default-construction.
//
new( storage_.address() ) internal_T0();
indicate_which(0); // zero is the index of the first bounded type
}
private: // helpers, for structors, cont. (below)
class convert_copy_into
: public static_visitor<int>
{
private: // representation
void* storage_;
public: // structors
explicit convert_copy_into(void* storage)
: storage_(storage)
{
}
public: // internal visitor interfaces (below)
template <typename T>
int internal_visit(T& operand, int) const
{
// NOTE TO USER :
// Compile error here indicates one of the source variant's types
// cannot be unambiguously converted to the destination variant's
// types (or that no conversion exists).
//
return initializer::initialize(storage_, operand);
}
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
template <typename T>
result_type internal_visit(const T& operand, int) const
{
return initializer::initialize(storage_, operand);
}
# endif
template <typename T>
int internal_visit(boost::detail::reference_content<T>& operand, long) const
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
int internal_visit(const boost::detail::reference_content<T>& operand, long) const
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
int internal_visit(boost::recursive_wrapper<T>& operand, long) const
{
return internal_visit( operand.get(), 1L );
}
template <typename T>
int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
{
return internal_visit( operand.get(), 1L );
}
};
friend class convert_copy_into;
private: // helpers, for structors, below
template <typename T>
void convert_construct(
T& operand
, int
, mpl::false_ = mpl::false_() // is_foreign_variant
)
{
// NOTE TO USER :
// Compile error here indicates that the given type is not
// unambiguously convertible to one of the variant's types
// (or that no conversion exists).
//
indicate_which(
initializer::initialize(
storage_.address()
, operand
)
);
}
template <typename Variant>
void convert_construct(
Variant& operand
, long
, mpl::true_// is_foreign_variant
)
{
convert_copy_into visitor(storage_.address());
indicate_which(
operand.internal_apply_visitor(visitor)
);
}
template <typename Variant>
void convert_construct_variant(Variant& operand)
{
// [Determine if the given variant is itself a bounded type, or if its
// content needs to be converted (i.e., it is a 'foreign' variant):]
//
typedef typename mpl::find_if<
types
, is_same<
add_const<mpl::_1>
, const Variant
>
>::type found_it;
typedef typename mpl::end<types>::type not_found;
typedef typename is_same<
found_it, not_found
>::type is_foreign_variant;
// Convert construct from operand:
convert_construct(
operand, 1L
, is_foreign_variant()
);
}
template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
void convert_construct(
boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
, long
)
{
convert_construct_variant(operand);
}
template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
void convert_construct(
const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
, long
)
{
convert_construct_variant(operand);
}
public: // structors, cont.
#if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
template <typename T>
variant(const T& operand)
{
convert_construct(operand, 1L);
}
template <typename T>
variant(T& operand)
{
convert_construct(operand, 1L);
}
#elif defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
// For compilers that cannot distinguish between T& and const T& in
// template constructors, but do fully support SFINAE, we can workaround:
template <typename T>
variant(const T& operand)
{
convert_construct(operand, 1L);
}
template <typename T>
variant(
T& operand
, typename enable_if<
mpl::not_< is_const<T> >
, void
>::type* = 0
)
{
convert_construct(operand, 1L);
}
#else // !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -