⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variant.hpp

📁 CGAL is a collaborative effort of several sites in Europe and Israel. The goal is to make the most i
💻 HPP
📖 第 1 页 / 共 4 页
字号:
    // For compilers that cannot distinguish between T& and const T& in    // template constructors, and do NOT support SFINAE, we can't workaround:    template <typename T>    variant(const T& operand)    {        convert_construct(operand, 1L);    }#endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workaroundspublic: // structors, cont.    // [MSVC6 requires copy constructor appear after template constructors]    variant(const variant& operand)    {        // Copy the value of operand into *this...        detail::variant::copy_into visitor( storage_.address() );        operand.internal_apply_visitor(visitor);        // ...and activate the *this's primary storage on success:        indicate_which(operand.which());    }private: // helpers, for modifiers (below)#   if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)    template <typename Variant, typename RhsT>    friend class detail::variant::backup_assigner;#   endif    // class assigner    //    // Internal visitor that "assigns" the visited value to the given variant    // by appropriate destruction and copy-construction.    //    class assigner        : public static_visitor<>    {    private: // representation        variant& lhs_;        int rhs_which_;    public: // structors        assigner(variant& lhs, int rhs_which)            : lhs_(lhs)            , rhs_which_(rhs_which)        {        }    private: // helpers, for internal visitor interface (below)        template <typename RhsT, typename B1, typename B2>        void assign_impl(              const RhsT& rhs_content            , mpl::true_// has_nothrow_copy            , B1// has_nothrow_move_constructor            , B2// has_fallback_type            )        {            // Destroy lhs's content...            lhs_.destroy_content(); // nothrow            // ...copy rhs content into lhs's storage...            new(lhs_.storage_.address())                RhsT( rhs_content ); // nothrow            // ...and indicate new content type:            lhs_.indicate_which(rhs_which_); // nothrow        }        template <typename RhsT, typename B>        void assign_impl(              const RhsT& rhs_content            , mpl::false_// has_nothrow_copy            , mpl::true_// has_nothrow_move_constructor            , B// has_fallback_type            )        {            // Attempt to make a temporary copy (so as to move it below)...            RhsT temp(rhs_content);            // ...and upon success destroy lhs's content...            lhs_.destroy_content(); // nothrow            // ...move the temporary copy into lhs's storage...            new(lhs_.storage_.address())                RhsT( detail::variant::move(temp) ); // nothrow            // ...and indicate new content type:            lhs_.indicate_which(rhs_which_); // nothrow        }        template <typename RhsT>        void assign_impl(              const RhsT& rhs_content            , mpl::false_// has_nothrow_copy            , mpl::false_// has_nothrow_move_constructor            , mpl::true_// has_fallback_type            )        {            // Destroy lhs's content...            lhs_.destroy_content(); // nothrow            try            {                // ...and attempt to copy rhs's content into lhs's storage:                new(lhs_.storage_.address())                    RhsT( rhs_content );            }            catch (...)            {                // In case of failure, default-construct fallback type in lhs's storage...                new (lhs_.storage_.address())                    fallback_type_; // nothrow                // ...indicate construction of fallback type...                lhs_.indicate_which(                      BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value                    ); // nothrow                // ...and rethrow:                throw;            }            // In the event of success, indicate new content type:            lhs_.indicate_which(rhs_which_); // nothrow        }        template <typename RhsT>        void assign_impl(              const RhsT& rhs_content            , mpl::false_// has_nothrow_copy            , mpl::false_// has_nothrow_move_constructor            , mpl::false_// has_fallback_type            )        {            detail::variant::backup_assigner<wknd_self_t, RhsT>                visitor(lhs_, rhs_which_, rhs_content);            lhs_.internal_apply_visitor(visitor);        }    public: // internal visitor interfaces        template <typename RhsT>            BOOST_VARIANT_AUX_RETURN_VOID_TYPE        internal_visit(const RhsT& rhs_content, int)        {            typedef typename has_nothrow_copy<RhsT>::type                nothrow_copy;            typedef typename mpl::or_< // reduces compile-time                  nothrow_copy                , detail::variant::has_nothrow_move_constructor<RhsT>                >::type nothrow_move_constructor;            assign_impl(                  rhs_content                , nothrow_copy()                , nothrow_move_constructor()                , has_fallback_type_()                );            BOOST_VARIANT_AUX_RETURN_VOID;        }    };    friend class assigner;    void variant_assign(const variant& rhs)    {        // If the contained types are EXACTLY the same...        if (which_ == rhs.which_)        {            // ...then assign rhs's storage to lhs's content:            detail::variant::assign_storage visitor(rhs.storage_.address());            this->internal_apply_visitor(visitor);        }        else        {            // Otherwise, perform general (copy-based) variant assignment:            assigner visitor(*this, rhs.which());            rhs.internal_apply_visitor(visitor);         }    }private: // helpers, for modifiers (below)    template <typename T>    void assign(const T& rhs)    {        // If direct T-to-T assignment is not possible...        detail::variant::direct_assigner<const T> direct_assign(rhs);        if (this->apply_visitor(direct_assign) == false)        {            // ...then convert rhs to variant and assign:            //            // While potentially inefficient, the following construction of a            // variant allows T as any type convertible to one of the bounded            // types without excessive code redundancy.            //            variant temp(rhs);            variant_assign( detail::variant::move(temp) );        }    }public: // modifiers    template <typename T>    variant& operator=(const T& rhs)    {        assign(rhs);        return *this;    }    // [MSVC6 requires copy assign appear after templated operator=]    variant& operator=(const variant& rhs)    {        variant_assign(rhs);        return *this;    }    void swap(variant& rhs)    {        // If the contained types are the same...        if (which() == rhs.which())        {            // ...then swap the values directly:            detail::variant::swap_with<variant> visitor(rhs);            this->apply_visitor(visitor);        }        else        {            // ...otherwise, perform general variant swap:            variant tmp( detail::variant::move(rhs) );            rhs = detail::variant::move(*this);            *this = detail::variant::move(tmp);        }    }public: // queries    //    // NOTE: member which() defined above.    //    bool empty() const    {        return false;    }    const std::type_info& type() const    {        detail::variant::reflect visitor;        return this->apply_visitor(visitor);    }public: // prevent comparison with foreign types#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)#   define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \    void#else // MSVC7    //    // MSVC7 gives error about return types for above being different than    // the true comparison operator overloads:    //#   define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \    bool#endif // MSVC7 workaround    template <typename U>        BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE    operator==(const U&) const    {        BOOST_STATIC_ASSERT( false && sizeof(U) );    }    template <typename U>        BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE    operator<(const U&) const    {        BOOST_STATIC_ASSERT( false && sizeof(U) );    }public: // comparison operators    // [MSVC6 requires these operators appear after template operators]    bool operator==(const variant& rhs) const    {        if (this->which() != rhs.which())            return false;        detail::variant::comparer<              variant, detail::variant::equal_comp            > visitor(*this);        return rhs.apply_visitor(visitor);    }    bool operator<(const variant& rhs) const    {        //        // Dirk Schreib suggested this collating order.        //        if (this->which() != rhs.which())            return this->which() < rhs.which();        detail::variant::comparer<              variant, detail::variant::less_comp            > visitor(*this);        return rhs.apply_visitor(visitor);    }// helpers, for visitation support (below) -- private when possible#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)    template < BOOST_VARIANT_ENUM_PARAMS(typename U) >    friend class variant;private:#else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)public:#endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)    template <typename Visitor, typename VoidPtrCV>    static        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(              typename Visitor::result_type            )    internal_apply_visitor_impl(          int internal_which        , int logical_which        , Visitor& visitor        , VoidPtrCV storage        )    {        typedef mpl::int_<0> first_which;        typedef typename mpl::begin<internal_types>::type first_it;        typedef typename mpl::end<internal_types>::type last_it;        typedef detail::variant::visitation_impl_step<              first_it, last_it            > first_step;        return detail::variant::visitation_impl(              internal_which, logical_which            , visitor, storage, mpl::false_()            , never_uses_backup_flag()            , static_cast<first_which*>(0), static_cast<first_step*>(0)            );    }    template <typename Visitor>        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(              typename Visitor::result_type            )    internal_apply_visitor(Visitor& visitor)    {        return internal_apply_visitor_impl(              which_, which(), visitor, storage_.address()            );    }    template <typename Visitor>        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(              typename Visitor::result_type            )    internal_apply_visitor(Visitor& visitor) const    {        return internal_apply_visitor_impl(              which_, which(), visitor, storage_.address()            );    }public: // visitation support    template <typename Visitor>        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(              typename Visitor::result_type            )    apply_visitor(Visitor& visitor)    {        detail::variant::invoke_visitor<Visitor> invoker(visitor);        return this->internal_apply_visitor(invoker);    }    template <typename Visitor>        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(              typename Visitor::result_type            )    apply_visitor(Visitor& visitor) const    {        detail::variant::invoke_visitor<Visitor> invoker(visitor);        return this->internal_apply_visitor(invoker);    }}; // class variant///////////////////////////////////////////////////////////////////////////////// metafunction make_variant_over//// See docs and boost/variant/variant_fwd.hpp for more information.//template <typename Types>struct make_variant_over{private: // precondition assertions#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)    BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));#endifpublic: // metafunction result    typedef variant<          detail::variant::over_sequence< Types >        > type;};///////////////////////////////////////////////////////////////////////////////// function template swap//// Swaps two variants of the same type (i.e., identical specification).//template < BOOST_VARIANT_ENUM_PARAMS(typename T) >inline void swap(      variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs    , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs    ){    lhs.swap(rhs);}} // namespace boost// implementation additions#include "boost/variant/detail/variant_io.hpp"#endif // BOOST_VARIANT_VARIANT_HPP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -