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

📄 variant.h

📁 loki库的源代码。loki库是以模板技术和面向对象技术为基础的c++类库。
💻 H
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001, 2002 by Andrei Alexandrescu
// Permission to use, copy, modify, distribute and sell this software for any 
//     purpose is hereby granted without fee, provided that the above copyright 
//     notice appear in all copies and that both that copyright notice and this 
//     permission notice appear in supporting documentation.
// The author makes no representations about the suitability of this software 
//     for any purpose. It is provided "as is" 
//     without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////

#ifndef VARIANT_INC_
#define VARIANT_INC_

#include <cstddef>
#include <memory>
#include <typeinfo>
#include "Visitor.h"
#include "Typelist.h"
#include "static_check.h"

//
// At the moment there is no namespace for Variant
//

#ifdef _MSC_VER
# include "VC_Alignment.h"
#endif

////////////////////////////////////////////////////////////////////////////////
// class template ConfigurableUnion
// Builds a union that contains each type in a typelist
// Usage: ConfigurableUnion<TList> is the very type
////////////////////////////////////////////////////////////////////////////////

template <class U> union ConfigurableUnion;

template <> union ConfigurableUnion< ::Loki::NullType >
{
};

template <class TList> 
union ConfigurableUnion
{
private:
    ASSERT_TYPELIST(TList);

    typedef typename TList::Head Head;
    typedef typename TList::Tail Tail;

public:
   Head head_;
   ConfigurableUnion<Tail> tail_;
};


////////////////////////////////////////////////////////////////////////////////
// class template MaxSize
// Computes the maximum sizeof for all types in a typelist
// Usage: MaxSize<TList>::result
////////////////////////////////////////////////////////////////////////////////

template <class TList> struct MaxSize;

template <> 
struct MaxSize< ::Loki::NullType >
{
    enum { result = 0 };
};

template <class TList>
struct MaxSize
{
private:
    ASSERT_TYPELIST(TList);

    typedef typename TList::Head Head;
    typedef typename TList::Tail Tail;

private:
    enum { headResult = sizeof(Head)          };
    enum { tailResult = MaxSize<Tail>::result };

public:
    enum { result = headResult > tailResult ? 
           headResult : tailResult };
};


////////////////////////////////////////////////////////////////////////////////
// class AlignedPODBase
// Defines a host of protected types used by AlignedPOD (defined later)
// Could be just part of AlignedPOD itself, but making it separate ought to 
// reduce compile times 
////////////////////////////////////////////////////////////////////////////////

class AlignedPODBase
{
protected:
    template <class TList, std::size_t size> 
    struct ComputeAlignBound
    {
    private:
        ASSERT_TYPELIST(TList);
    
        typedef typename TList::Head Head;
        typedef typename TList::Tail Tail;
    
    private:
        template<class TList1>
        struct In
        {
        private:
            typedef typename TList1::Head Head1;
            typedef typename TList1::Tail Tail1;
    
            typedef typename ComputeAlignBound<Tail1, size>::Result TailResult;
    
        public:
            typedef typename ::Loki::Select
            <
                sizeof(Head1) <= size,
                ::Loki::Typelist<Head1, TailResult>,
                TailResult
            >
            ::Result Result;
        };

        template<>
        struct In< ::Loki::NullType >
        {
            typedef ::Loki::NullType Result;
        };

    public:
        typedef typename In<TList>::Result Result;
    };

    template <typename U> struct Structify
    { U dummy_; };
    
    class Unknown;

    // VC7: fatal error C1067: compiler limit :
    // debug information module size exceeded
    // Therfore I decreased the list to 26 without 
    // changing the rage of detectable alignment
    typedef TYPELIST_26(
            char,
            wchar_t,
            short int,
            int,
            long int,
            float,
            double,
            long double,
            char*,
            void*,
            Unknown (*)(Unknown),
            Unknown* Unknown::*,
            Unknown (Unknown::*)(Unknown),
            Structify<char>, 
            Structify<wchar_t>, 
            Structify<short int>, 
            Structify<int>,
            Structify<long int>,
            Structify<float>,
            Structify<double>,
            Structify<long double>,
            Structify<char*>,
            Structify<void*>,
            Structify<Unknown (*)(Unknown)>,
            Structify<Unknown* Unknown::*>,
            Structify<Unknown (Unknown::*)(Unknown)>
            )
        TypesOfAllAlignments;
};

////////////////////////////////////////////////////////////////////////////////
// class template AlignedPOD
// Computes the alignment of all types in a typelist
// Usage: ConfigurableUnion<TList> is the very type
////////////////////////////////////////////////////////////////////////////////

template <typename TList>
class AlignedPOD : private AlignedPODBase
{
    enum { maxSize = MaxSize<TList>::result };

    typedef typename ComputeAlignBound
    <
        TypesOfAllAlignments, 
        maxSize
    >
    ::Result AlignTypes;

public:
    typedef ConfigurableUnion<AlignTypes> Result;
};

////////////////////////////////////////////////////////////////////////////////
// class template MakeConst
// Given a typelist TList, returns a typelist that contains the types in TList 
// adding a const qualifier to each.
// Usage: MakeConst<TList>::Result 
////////////////////////////////////////////////////////////////////////////////

template <class TList> struct MakeConst;

template <> struct MakeConst< ::Loki::NullType >
{
    typedef ::Loki::NullType Result; // terminator is not const
};

template <class TList>
struct MakeConst
{
private:
    ASSERT_TYPELIST(TList);

    typedef typename TList::Head Head;
    typedef typename TList::Tail Tail;
    
private:
    typedef typename MakeConst<Tail>::Result NewTail;

public:
    typedef ::Loki::Typelist<const Head, NewTail> Result; 
};

////////////////////////////////////////////////////////////////////////////////
// class template Converter
// Supports the Variant-to-Variant conversion constructor
// Guaranteed to issue an internal compiler error on:
//      1. Metrowerks CodeWarrior 7.0 (internal compiler error: File: 
//          'CTemplateTools.c' Line: 1477 
//          Variant.h line 244           UnitBase > VisitorBase;)
//      2. Microsoft Visual C++ 7.1 alpha release (Assertion failed: 
//          ( name - nameBuf ) < LIMIT_ID_LENGTH, 
//          file f:\vs70builds\2108\vc\Compiler\CxxFE\sl\P1\C\outdname.c, 
//          line 4583)
//      3. GNU gcc 2.95.3-6 (Internal compiler error 980422)
////////////////////////////////////////////////////////////////////////////////

template <class VariantFrom, class VariantTo>
struct Converter
{
//private: VC7 complains
    struct UnitBase : public VariantFrom::ConstStrictVisitor
    {
    protected:
        VariantTo* storageForDestination;
    };

    template <class Type, class Base> 
    struct Unit : public Base
    {
    private:
        void DoVisit(const Type& obj, ::Loki::Int2Type<true>)
        {
            new(this->storageForDestination) VariantTo(obj);
        }
        void DoVisit(const Type&, ::Loki::Int2Type<false>)
        {
            throw std::runtime_error("Cannot convert");
        }
        virtual void Visit(const Type& obj)
        {
            using namespace Loki;
            typedef typename VariantTo::Types TList;
            enum { dispatch = TL::IndexOf<TList, Type>::value > -1 };
            this->DoVisit(obj, Int2Type<dispatch>());
        }
    };
    
private:
    typedef ::Loki::GenLinearHierarchy
    <
        typename VariantFrom::Types,
        Unit,
        UnitBase 
    > 
    VisitorBase;

public:
    struct Visitor : public VisitorBase
    {
        explicit Visitor(VariantTo& dest)
        {
            // Initialize the pointer to destination
            this->storageForDestination = &dest;
        }
    };
};


////////////////////////////////////////////////////////////////////////////////
// class template ConverterTo
// Supports Variant-to-T conversion
////////////////////////////////////////////////////////////////////////////////
#if 0
template <class VariantFrom, class T>
struct ConverterTo
{
private:
    struct DestHolder 
        : VariantFrom::ConstStrictVisitor
    {
    protected:
        DestHolder() {}
        DestHolder(const T& dest) : destination_(dest) {}
        T destination_;
    };

    template <class TList> 
    struct VisitorBase
        : VisitorBase<typename TList::Tail>
    {
    private:
        ASSERT_TYPELIST(TList);
    
        typedef typename TList::Head Type;
        typedef typename TList::Tail Tail;
    
    protected:
        VisitorBase<TList>() {}
        VisitorBase<TList>(const T& dest) 
            : VisitorBase<Tail>(dest) {}
    
    private:
        void DoVisit(const Type& obj, ::Loki::Int2Type<true>)
        {   //
            // T temp(obj)
            // swap(destination_, temp) or destination_ = temp
            //
            this->destination_ = obj;
        }
        void DoVisit(const Type&, ::Loki::Int2Type<false>)
        {
            throw std::runtime_error("Cannot convert");
        }

        virtual void Visit(const Type& obj)
        {
            using namespace Loki;
            enum { dispatch = Conversion<Type, T>::exists != 0 };
            this->DoVisit(obj, Int2Type<dispatch>());
        }
    };
    
    template <> 
    struct VisitorBase< ::Loki::NullType > 
        : DestHolder
    {
    protected:
        VisitorBase< ::Loki::NullType >() {}
        VisitorBase< ::Loki::NullType >(const T& dest) 
            : DestHolder(dest) {}
    };

    
    typedef VisitorBase
    <
        typename VariantFrom::Types
    >
    VisitorBaseType;
    
public:
    struct Visitor : public VisitorBaseType
    {
        Visitor() {}

        explicit Visitor(const T& dest) 
            : VisitorBaseType(dest) {}

        const T &GetDestination() const 
        { return this->destination_; }
    };
};

#else

template <class VariantFrom, class T>
struct ConverterTo
{
//private:
    struct UnitBase : public VariantFrom::ConstStrictVisitor
    {
    protected:
        T destination_;
    };

    template <class Type, class Base> 
    struct Unit : public Base
    {
    private:
        void DoVisit(const Type& obj, ::Loki::Int2Type<true>)
        {
            this->destination_ = obj;
        }
        void DoVisit(const Type&, ::Loki::Int2Type<false>)
        {
            throw std::runtime_error("Cannot convert");
        }
        virtual void Visit(const Type& obj)
        {
            using namespace Loki;
            enum { dispatch = Conversion<Type, T>::exists != 0 };
            this->DoVisit(obj, Int2Type<dispatch>());
        }
    };
    
    typedef ::Loki::GenLinearHierarchy<
        typename VariantFrom::Types,
        Unit,
        UnitBase > VisitorBase;

public:
    struct Visitor : public VisitorBase
    {
        const T &GetDestination() const 
        { return this->destination_; }
    };
};

#endif

namespace Private 
{
    template<typename T>
    struct RawDataKeeper
    {        
    private:        

⌨️ 快捷键说明

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