📄 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_TYPEDEFSpublic: // 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_TYPEDEFSprivate: // 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 workaroundprivate: // 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 + -