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

📄 variant.hpp

📁 support vector clustering for vc++
💻 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 workarounds

public: // 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 ));
#endif

public: // 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 + -