C++ Runtime Concept 的模拟(6)

来源:互联网 发布:香港电视剧大全软件 编辑:程序博客网 时间:2024/05/17 17:39

C++ Runtime Concept 的模拟(6)
C++0x 新特性 Concept 提前用。
支持allocator。
简化使用方法!
用链式的单继承解决多继承方法的调用不明确的问题。
支持auto concept和non-auto concept。
支持引用类型concept和值类型concept。
已测试支持的编译器:
VC 6.0 (VC 98)
VC 7.1 (VC 2003)
VC 8.0 (VC 2005)
VC 9.0 (VC 2008)
GCC 3.4.2
GCC 4.2.3

基本原理:
1. 用类继承的方法生成vtable。
2. 用链式的单继承来组合concept。

缺陷:
1. 成员函数的调用方法不知道是不是符合标准,不过估计移植性没什么问题。
2. static应该改为多线程安全的Singleton。
3. 没考虑异常安全。

另:
1. 关于非虚成员函数指针可以指向虚函数并正常调用的问题:
   i) VC 如果指向的是没有基类的类的虚函数就可以。
   ii) GCC 总是可以调用的。
2. VC6 不支持偏特化,不支持类模板参数的成员类模板。
   为了支持 VC6 ... 唉!不提了

使用方法:
1. 全局函数约束: CONCEPT_FUNCTION
CONCEPT_FUNCTION(g_drawShape, drawShape, void, (const ObjectType &t, monitor device), (t, device));
表示声明名称为g_drawShape的约束:
对于约束对象(ObjectType)必须有对应全局函数 void drawShape(const ObjectType &t, monitor device);
VC6 注意事项: CONCEPT_FUNCTION 必须在全局域声明。

2. 成员函数约束: CONCEPT_MEMBER_FUNCTION
CONCEPT_MEMBER_FUNCTION(c_draw, draw, void, (monitor device) const, (device));
表示声明名称为c_draw的约束:
对于约束对象必须有对应成员函数 void ObjectType::draw(monitor device) const;
VC6 注意事项: CONCEPT_MEMBER_FUNCTION 必须在全局域声明。

3. 约束组合: concept_list
typedef concept_list<g_drawShape, c_draw> Shape;
表示组合约束g_drawShape和c_draw。

4. 非auto concept的concept_map: CONCEPT_MAP
CONCEPT_MAP(Shape, Rectangle);
表示Rectangle符合Shape。
注意事项: CONCEPT_MAP 必须在全局域声明。

5. concept 使用: concept
concept<Shape> v;
ref_concept<Shape> v;
auto_concept<Shape> v;
ref_auto_concept<Shape> v;
表示传递给v的对象必须满足Shape(4种concept类型)。

6. allocator 使用
concept<Shape, user_define_allocator<void> > v;
auto_concept<Shape, user_define_allocator<void> > v;
表示值类型concept用user_define_allocator管理对象。
VC6 注意事项:
必须在全局域声明
CONCEPT_ALLOCATOR_REBIND(user_define_allocator<void>);

7. 如果不想VC6出现很多警告就用
#pragma warning(disable:4786)
#pragma warning(disable:4530)
#pragma warning(disable:4503)

// main.cpp

// main.cpp
#include <stdio.h>
#include 
<vector>
#include 
<string>
#include 
"shape.hpp"
#include 
"concept.hpp"

using namespace Concept;

CONCEPT_MEMBER_FUNCTION(cShape0, set_value, 
void, (int Value), (Value));
CONCEPT_MEMBER_FUNCTION(cShape1, set_value1, 
void, (int Value), (Value));
CONCEPT_MEMBER_FUNCTION(cShape2, set_value2, 
void, (int Value), (Value));
CONCEPT_MEMBER_FUNCTION(cShape3, set_value3, 
void, (int Value), (Value));
CONCEPT_MEMBER_FUNCTION(cShape4, set_value4, 
void, (int Value), (Value));
CONCEPT_FUNCTION(g_set_value, set_value, 
void, (ObjectType &t, int Value), (t, Value));
CONCEPT_FUNCTION(g_drawShape, drawShape, 
void, (const ObjectType &t, monitor device), (t, device));
CONCEPT_MEMBER_FUNCTION(c_draw, draw, 
void, (monitor device) const, (device));
typedef concept_list
<g_drawShape, c_draw, cShape0, cShape1, cShape2, cShape3, cShape4> Shape;

CONCEPT_MAP(Shape, Rectangle);

////////////////////////////////////////////////////////////////////////////////

typedef auto_concept
<Shape> auto_Shape;

void DrawShapes(monitor device, std::vector<auto_Shape> const& g)
{
    std::vector
<auto_Shape>::const_iterator b(g.begin()), e(g.end());
    
for(; b != e; ++b)
    
{
        b
->draw(device);
        auto_Shape::drawShape(
*b, device);
    }

}


template 
<class T>
void DrawShape(monitor device, const T& t)
{
    
if (0) concept<Shape> tmp = t;         //static non-auto concept
    t.draw(device);
}


template 
<class allocator_name, class T = int>
struct myallocator : public std::allocator<T>
{
    typedef std::allocator
<T> base_allocator;
    typedef typename base_allocator::pointer pointer;
    typedef typename base_allocator::size_type size_type;
    pointer allocate(size_type n, 
const void *hint)
    
{
        printf(
"myallocator::allocate ");
        
return base_allocator::allocate(n, hint);
    }

    
void deallocate(pointer p, size_type n)
    
{
        printf(
"myallocator::deallocate ");
        base_allocator::deallocate(p, n);
    }

    
void construct(pointer p, const T& val)
    
{
        printf(
"myallocator::construct ");
        base_allocator::construct(p, val);
    }

    
void destroy(pointer p)
    
{
        printf(
"myallocator::destroy ");
        base_allocator::destroy(p);
    }

    template
<class U>
    
struct rebind
    
{
        typedef myallocator
<allocator_name, U> other;
    }
;
}
;

struct temp_allocator;

CONCEPT_ALLOCATOR_REBIND(myallocator
<temp_allocator>);

int main(int argc, char* argv[])
{
    auto_concept
<Shape, myallocator<temp_allocator> > test_for_allocator = Rectangle();

    auto_Shape 
as = Rectangle();
    
int sizeofShape = sizeof(Shape), sizeofconceptShape = sizeof(auto_Shape);
    
as.draw(stdout);
    
as.set_value(1);
    
as.draw(stdout);
    
as.set_value1(sizeofShape);
    
as.draw(stdout);
    
as.set_value2(sizeofconceptShape);
    
as.draw(stdout);
    
as.set_value3(1);
    
as.draw(stdout);

    std::vector
<auto_Shape> vg;
    vg.push_back(Rectangle());
    vg.push_back(Ellipse());
    vg.push_back(vg[
0]);
    vg.push_back(vg[
2]);
    vg[
2= vg[0];
    vg[
3= vg[1];
    
//vg.push_back(Triangle());            //错误,不符合Shape concept // OK in GCC
    
//vg.push_back(std::string("xxx"));    //错误,不符合Shape concept
    DrawShapes(stdout, vg);

    Rectangle rect;
    Ellipse elli;
    EllipseChild ellichild;
    DrawShape(stdout, rect);
    
//DrawShape(stdout, elli);             //错误,不符合Shape static concept
    
//DrawShape(stdout, ellichild);        //错误,不符合Shape static concept
    ref_concept<Shape> ref_non_auto_Shape = rect;
    ref_non_auto_Shape 
= rect;
    
//ref_non_auto_Shape = elli;           //错误,不符合Shape non-auto concept
    printf("rect.value = %d ", rect.value);
    ref_non_auto_Shape.set_value(
1);
    printf(
"rect.value = %d ", rect.value);
    ref_auto_concept
<cShape0>(rect).set_value(2);
    ref_auto_concept
<g_set_value> x(rect);
    ref_auto_concept
<g_set_value>::set_value(x, 2);
    printf(
"rect.value = %d ", rect.value);

    
return 0;
}


// shape.hpp
// shape.hpp
#include <stdio.h>
typedef FILE
* monitor;

struct ShapeBase
{
    
int value;
    ShapeBase() : value(
0{}
    
void set_value(int Value)
    
{
        value 
= Value;
    }

    
void set_value1(int Value)
    
{
        value 
= Value;
    }

    
void set_value2(int Value)
    
{
        value 
= Value;
    }

    
void set_value3(int Value)
    
{
        value 
= Value;
    }

    
void set_value4(int Value)
    
{
        value 
= Value;
    }

}
;

struct Rectangle : public ShapeBase
{
    
void draw(monitor device) const
    
{
        fprintf(device, 
"Rectangle.draw: %d ", value);
    }

    
void draw() const
    
{
        printf(
"Rectangle.draw ?: %d ", value);
    }

}
;

struct Ellipse
{
    
int value;
    Ellipse() : value(
0{}
    
void set_value(int Value)
    
{
        value 
= Value;
    }

    
void set_value1(int Value)
    
{
        value 
= Value;
    }

    
void set_value2(int Value)
    
{
        value 
= Value;
    }

    
void set_value3(int Value)
    
{
        value 
= Value;
    }

    
void set_value4(int Value)
    
{
        value 
= Value;
    }

    
virtual void draw(monitor device) const
    
{
        fprintf(device, 
"Ellipse.draw: %d ", value);
    }

}
;

struct EllipseChild : public Ellipse
{
    
virtual void draw(monitor device) const
    
{
        fprintf(device, 
"EllipseChild.draw?: %d ", value);
    }

}
;

struct Triangle : public ShapeBase
{
    
virtual void draw(monitor device) const
    
{
        fprintf(device, 
"Triangle.draw virtual: %d ", value);
    }

}
;

void drawShape(const Rectangle &refShape, monitor device)
{
    refShape.draw(device);
}


void drawShape(const Ellipse &refShape, monitor device)
{
    refShape.draw(device);
}


void drawShape(const Triangle &refShape, monitor device)
{
    refShape.draw(device);
}


template 
<class T>
void set_value(T &refShape, int Value)
{
    refShape.value 
= Value;
}


// concept.hpp
// concept.hpp
#include <memory>

#ifdef __GNUC__
#define TEMPLATE_SPEC_DECL      , typename TEMPLATE_SPEC_T = int
#define TEMPLATE_SPEC_PART      typename TEMPLATE_SPEC_T
#define TEMPLATE_SPEC           , TEMPLATE_SPEC_T
#define TEMPLATE_SPEC_DECL1     , typename TEMPLATE_SPEC_T1 = int
#define TEMPLATE_SPEC_PART1     typename TEMPLATE_SPEC_T1
#define TEMPLATE_SPEC1          , TEMPLATE_SPEC_T1
#else
#define TEMPLATE_SPEC_DECL
#define TEMPLATE_SPEC_PART
#define TEMPLATE_SPEC
#define TEMPLATE_SPEC_DECL1
#define TEMPLATE_SPEC_PART1
#define TEMPLATE_SPEC1
#endif

#ifdef _MSC_VER
#define MEMFUNCCAST(A)          reinterpret_cast<A>
#else
#define MEMFUNCCAST(A)
#endif

#if !defined(_MSC_VER) || _MSC_VER >= 1300
#define CONCEPT_IF_NOT_VC6_3(A, B, C)   A, B, C
#define CONCEPT_IF_VC6_ELSE(A, B)       B
#define CONCEPT_ALLOCATOR_REBIND(CONCEPTNAME)
#define CONCEPT_BIND(CONCEPTNAME)
#else
#define CONCEPT_IF_NOT_VC6_3(A, B, C)
#define CONCEPT_IF_VC6_ELSE(A, B)       A
#define CONCEPT_ALLOCATOR_REBIND(ALLOCATORNAME) 
namespace Concept 

template 
<> 
struct concept_rebind_allocator<ALLOCATORNAME > 

    template 
<class T> 
    
struct with 
    

        typedef ALLOCATORNAME::rebind
<T>::other other; 
    }

}

}

#define CONCEPT_BIND(CONCEPTNAME) 
namespace Concept 

template 
<> 
struct concept_bind<CONCEPTNAME > 

    typedef CONCEPTNAME ConceptName; 
    template 
<class BaseType, class BaseFrom, bool isvtable, class ObjectType> 
    
struct with : public CONCEPTNAME::template table<BaseFrom, isvtable, ObjectType> 
    

        typedef BaseType Base; 
        typedef BaseFrom DeriveFrom; 
    }

}

}
 // namespace Concept
#endif

#define CONCEPT_MAP(CONCEPTNAME, TYPE) 
namespace Concept 

template 
<> struct concept_map<CONCEPTNAME, TYPE> {}
}


#define CONCEPT_FUNCTION(CONCEPTNAME, FNAME, RTYPE, FTYPE, PARA) 
struct CONCEPTNAME 

    typedef CONCEPTNAME ConceptName; 
    template 
<bool isvtable TEMPLATE_SPEC_DECL> 
    
struct ifvtable 
    

        template 
<class ReturnType> 
        
struct rt 
        

            template 
<class ObjectType, class BaseFrom> 
            
struct table : public Concept::concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, isvtable, ObjectType>::type 
            

                typedef typename Concept::get_type
<RTYPE (*)FTYPE>::type function_type; 
                function_type p##FNAME; 
                table() : p##FNAME(
&::FNAME) {} 
            }

        }

    }

    template 
<TEMPLATE_SPEC_PART> 
    
struct ifvtable<false TEMPLATE_SPEC> 
    

        template 
<class ReturnType TEMPLATE_SPEC_DECL1> 
        
struct rt 
        

            template 
<class ObjectType, class BaseFrom> 
            
struct table : public Concept::concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, false, ObjectType>::type 
            

                
const void* CONCEPTNAME##_index() const {return this;} 
                
static RTYPE FNAME FTYPE 
                

                    
return (*t.ptable->p##FNAME)PARA; 
                }
 
            }

        }

        template 
<TEMPLATE_SPEC_PART1> 
        
struct rt<void TEMPLATE_SPEC1> 
        

            template 
<class ObjectType, class BaseFrom> 
            
struct table : public Concept::concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, false, ObjectType>::type 
            

                
const void* CONCEPTNAME##_index() const {return this;} 
                
static RTYPE FNAME FTYPE 
                

                    (
*t.ptable->p##FNAME)PARA; 
                }
 
            }

        }

    }

    template 
<class BaseFrom = concept_base, bool isvtable = trueclass ObjectType = concept_object> 
    
struct table : public ifvtable<isvtable>::template rt<RTYPE>::template table<ObjectType, BaseFrom> 
    

        typedef CONCEPTNAME Base; 
        typedef BaseFrom DeriveFrom; 
    }

}

CONCEPT_BIND(CONCEPTNAME);

#define CONCEPT_MEMBER_FUNCTION(CONCEPTNAME, FNAME, RTYPE, FTYPE, PARA) 
struct CONCEPTNAME 

    typedef CONCEPTNAME ConceptName; 
    template 
<bool isvtable TEMPLATE_SPEC_DECL> 
    
struct ifvtable 
    

        template 
<class ReturnType> 
        
struct rt 
        

            template 
<class ObjectType, class BaseFrom> 
            
struct table : public Concept::concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, isvtable, ObjectType>::type 
            

                typedef typename Concept::get_type
<RTYPE (ObjectType::*)FTYPE>::type function_type; 
                function_type p##FNAME; 
                table() : p##FNAME(MEMFUNCCAST(function_type)(
&ObjectType::FNAME)) {} 
            }

        }

    }

    template 
<TEMPLATE_SPEC_PART> 
    
struct ifvtable<false TEMPLATE_SPEC> 
    

        template 
<class ReturnType TEMPLATE_SPEC_DECL1> 
        
struct rt 
        

            template 
<class ObjectType, class BaseFrom> 
            
struct table : public Concept::concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, false, ObjectType>::type 
            

                
const void* CONCEPTNAME##_index() const {return this;} 
                RTYPE FNAME FTYPE 
                

                    typedef typename ObjectType::TableType TableType; 
                    typedef typename TableType::conceptType conceptType; 
                    typedef concept
<conceptType> concept_Type; 
                    ObjectType
* This = reinterpret_cast<ObjectType*>
                        reinterpret_cast
<size_t>(this- 
                        reinterpret_cast
<size_t>
                            reinterpret_cast
<concept_Type*>(0)->CONCEPTNAME##_index())); 
                    
return (This->object_pointer->*This->ptable->p##FNAME)PARA; 
                }
 
            }

        }

        template 
<TEMPLATE_SPEC_PART1> 
        
struct rt<void TEMPLATE_SPEC1> 
        

            template 
<class ObjectType, class BaseFrom> 
            
struct table : public Concept::concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, false, ObjectType>::type 
            

                
const void* CONCEPTNAME##_index() const {return this;} 
                RTYPE FNAME FTYPE 
                

                    typedef typename ObjectType::TableType TableType; 
                    typedef typename TableType::conceptType conceptType; 
                    typedef concept
<conceptType> concept_Type; 
                    ObjectType
* This = reinterpret_cast<ObjectType*>
                        reinterpret_cast
<size_t>(this- 
                        reinterpret_cast
<size_t>
                            reinterpret_cast
<concept_Type*>(0)->CONCEPTNAME##_index())); 
                    (This
->object_pointer->*This->ptable->p##FNAME)PARA; 
                }
 
            }

        }

    }

    template 
<class BaseFrom = concept_base, bool isvtable = trueclass ObjectType = concept_object> 
    
struct table : public ifvtable<isvtable>::template rt<RTYPE>::template table<ObjectType, BaseFrom> 
    

        typedef CONCEPTNAME Base; 
        typedef BaseFrom DeriveFrom; 
    }

}

CONCEPT_BIND(CONCEPTNAME);

namespace Concept
{

template 
<class T> struct get_type {typedef T type;};

struct concept_base;
struct concept_object{};
template 
<class conceptT = intclass T = int> struct concept_map {int t[2];};

template 
<class conceptT>
struct concept_bind
{
    typedef conceptT ConceptName;
    template 
<class BaseType, class BaseFrom, bool isvtable, class ObjectType>
    
struct with CONCEPT_IF_NOT_VC6_3(: public conceptT::template table<BaseFrom, isvtable, ObjectType>)
    
{
        typedef conceptT Base;
        typedef BaseFrom DeriveFrom;
    }
;
}
;

template 
<class conceptT, class BaseFrom = concept_base, bool isvtable = trueclass ObjectType = concept_object>
struct concept_bind_with
{
    typedef typename concept_bind
<typename conceptT::ConceptName>::template with<conceptT, BaseFrom, isvtable, ObjectType> type;
}
;

template 
<class Alloc>
struct concept_rebind_allocator
{
    template 
<class T>
    
struct with
    
{
        typedef std::allocator
<T> other;
    }
;
}
;

template 
<class Alloc, class T>
struct concept_rebind_allocator_with
{
    typedef typename CONCEPT_IF_VC6_ELSE(
        concept_rebind_allocator
<Alloc>::template with<T>::other, 
        Alloc::template rebind
<T>::other) other;
}
;

struct concept_base
{
    typedef concept_base ConceptName;
    typedef concept_base Base;
    typedef concept_base DeriveFrom;
    template 
<class BaseFrom TEMPLATE_SPEC_DECL>
    
struct from
    
{
        template 
<bool isvtable, class ObjectType>
        
struct table : public concept_bind_with<typename BaseFrom::Base, typename BaseFrom::DeriveFrom, isvtable, ObjectType>::type {};
    }
;
    template 
<TEMPLATE_SPEC_PART>
    
struct from<concept_base TEMPLATE_SPEC>
    
{
        template 
<bool isvtable, class ObjectType>
        
struct table {};
    }
;
    template 
<class BaseFrom = concept_base, bool isvtable = trueclass ObjectType = concept_object>
    
struct table : public from<BaseFrom>::template table<isvtable, ObjectType>
    
{
        typedef concept_base Base;
        typedef BaseFrom DeriveFrom;
    }
;
}
;

template 
<class C0 = concept_base,  class C1 = concept_base,  class C2 = concept_base,  class C3 = concept_base,  class C4 = concept_base,  
          
class C5 = concept_base,  class C6 = concept_base,  class C7 = concept_base,  class C8 = concept_base,  class C9 = concept_base,  
          
class C10 = concept_base, class C11 = concept_base, class C12 = concept_base, class C13 = concept_base, class C14 = concept_base, 
          
class C15 = concept_base, class C16 = concept_base, class C17 = concept_base, class C18 = concept_base, class C19 = concept_base >
struct concept_list
{
    typedef concept_list
<> ConceptName;
    typedef  C0  P0; typedef  C1  P1; typedef  C2  P2; typedef  C3  P3; typedef  C4  P4; typedef  C5  P5; typedef  C6  P6; typedef  C7  P7; typedef  C8  P8; typedef  C9  P9;
    typedef C10 P10; typedef C11 P11; typedef C12 P12; typedef C13 P13; typedef C14 P14; typedef C15 P15; typedef C16 P16; typedef C17 P17; typedef C18 P18; typedef C19 P19;
    typedef concept_list
<P0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19> concept_list_type;
    template 
<class BaseFrom = concept_base, bool isvtable = trueclass T = concept_object>
    
struct table : public
                 concept_bind_with
< C0,typename concept_bind_with< C1,typename concept_bind_with< C2,typename concept_bind_with< C3,typename concept_bind_with< C4,
        typename concept_bind_with
< C5,typename concept_bind_with< C6,typename concept_bind_with< C7,typename concept_bind_with< C8,typename concept_bind_with< C9,
        typename concept_bind_with
<C10,typename concept_bind_with<C11,typename concept_bind_with<C12,typename concept_bind_with<C13,typename concept_bind_with<C14,
        typename concept_bind_with
<C15,typename concept_bind_with<C16,typename concept_bind_with<C17,typename concept_bind_with<C18,typename concept_bind_with<C19,
        BaseFrom
        
>::type>::type>::type>::type>::type>::type>::type>::type>::type>::type
        
>::type>::type>::type>::type>::type>::type>::type>::type>::type, isvtable, T>::type
    
{
        typedef concept_list Base;
        typedef BaseFrom DeriveFrom;
    }
;
}
;

template 
<>
struct concept_bind<concept_list<> >
{
    typedef concept_list
<> ConceptName;
    template 
<class BaseType, class BaseFrom, bool isvtable, class ObjectType>
    
struct with_type
    
{
        typedef  typename BaseType::P0  P0; typedef  typename BaseType::P1  P1; typedef  typename BaseType::P2  P2; typedef  typename BaseType::P3  P3; typedef  typename BaseType::P4  P4;
        typedef  typename BaseType::P5  P5; typedef  typename BaseType::P6  P6; typedef  typename BaseType::P7  P7; typedef  typename BaseType::P8  P8; typedef  typename BaseType::P9  P9;
        typedef typename BaseType::P10 P10; typedef typename BaseType::P11 P11; typedef typename BaseType::P12 P12; typedef typename BaseType::P13 P13; typedef typename BaseType::P14 P14;
        typedef typename BaseType::P15 P15; typedef typename BaseType::P16 P16; typedef typename BaseType::P17 P17; typedef typename BaseType::P18 P18; typedef typename BaseType::P19 P19;
        typedef concept_list
<P0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19> concept_list_type;
        typedef typename concept_list_type::template table
<BaseFrom, isvtable, ObjectType> type;
    }
;
    template 
<class BaseType, class BaseFrom, bool isvtable, class ObjectType>
    
struct with : public with_type<BaseType, BaseFrom, isvtable, ObjectType>::type
    
{
        typedef BaseType Base;
        typedef BaseFrom DeriveFrom;
    }
;
}
;

template 
<class TableT>
struct concept_class_base
{
    typedef TableT TableType;

    concept_object 
*object_pointer;
    TableT 
*ptable;

    
operator const concept_object&() const return *object_pointer; }
    
operator concept_object&() return *object_pointer; }
}
;

template 
<class conceptT, class Alloc = std::allocator<void>class T = concept_object>
struct concept_table : public concept_bind_with<conceptT, concept_base, true, T>::type
{
    typedef conceptT conceptType;
    typedef typename concept_rebind_allocator_with
<Alloc, T>::other allocatorT;

    template 
<class _Alloc>
    
struct allocator_function_type
    
{
        typedef typename _Alloc::pointer pointer;
        typedef typename _Alloc::size_type size_type;
        typedef pointer (_Alloc::
*type_allocate)(size_type n, const void *hint);
        typedef 
void (_Alloc::*type_deallocate)(pointer p, size_type n);
        typedef 
void (_Alloc::*type_construct)(pointer p, const T& val);
        typedef 
void (_Alloc::*type_destroy)(pointer p);
    }
;
    typedef typename allocator_function_type
<allocatorT>::type_allocate type_allocate;
    typedef typename allocator_function_type
<allocatorT>::type_deallocate type_deallocate;
    typedef typename allocator_function_type
<allocatorT>::type_construct type_construct;
    typedef typename allocator_function_type
<allocatorT>::type_destroy type_destroy;

    type_allocate allocate;
    type_deallocate deallocate;
    type_construct construct;
    type_destroy destroy;
    allocatorT 
*allocator;

    concept_table() : 
        allocator(
new allocatorT), 
        allocate(
&allocatorT::allocate), 
        deallocate(reinterpret_cast
<type_deallocate>(&allocatorT::deallocate)), 
        construct(
&allocatorT::construct), 
        destroy(
&allocatorT::destroy) {}

    
static concept_table* vtable()
    
{
        
static concept_table static_table;
        
return &static_table;
    }

}
;

template 
<class conceptT, class Alloc = std::allocator<void> >
class auto_concept;
template 
<class conceptT, class Alloc = std::allocator<void> >
class ref_concept;
template 
<class conceptT, class Alloc = std::allocator<void> >
class ref_auto_concept;

template 
<class conceptT, bool isauto = falsebool isref = falseclass Alloc = std::allocator<void> >
class concept : 
    
public concept_class_base<concept_table<conceptT, Alloc> >
    
public concept_bind_with<conceptT, concept_base, false, concept_class_base<concept_table<conceptT, Alloc> > >::type
{
public:
    
using concept_class_base<concept_table<conceptT, Alloc> >::ptable;
    
using concept_class_base<concept_table<conceptT, Alloc> >::object_pointer;
    typedef concept_table
<conceptT, Alloc> TableType;
private:
    
void init_with(concept_object* p, TableType* pTable)
    
{
        ptable 
= pTable;
        
if (isref)
        
{
            object_pointer 
= p;
        }

        
else
        
{
            object_pointer 
= (ptable->allocator->*ptable->allocate)(1, p);
            (ptable
->allocator->*ptable->construct)(object_pointer, *p);
        }

    }

public:
    template 
<class T>
    concept(
const T& t)
    
{
        
if (0char static_assert[isauto || sizeof(concept_map<>!= sizeof(concept_map<conceptT, T>? 1 : -1];
        typedef concept_table
<conceptT, Alloc, T> cTable;
        init_with(const_cast
<concept_object *>(reinterpret_cast<const concept_object *>(&t)), 
                  (reinterpret_cast
<TableType*>(cTable::vtable())));
    }


    concept(
const concept& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, isauto, !isref, Alloc>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, !isauto, isref, Alloc>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, !isauto, !isref, Alloc>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const auto_concept<conceptT, Alloc>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const ref_concept<conceptT, Alloc>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const ref_auto_concept<conceptT, Alloc>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }

    
~concept()
    
{
        
if (!isref)
        
{
            (ptable
->allocator->*ptable->destroy)(object_pointer);
            (ptable
->allocator->*ptable->deallocate)(object_pointer, 1);
        }

    }


    concept
& operator = (const concept& rhs)
    
{
        concept(rhs).swap(
*this);
        
return *this;
    }


    
void swap(concept& rhs)
    
{
        concept_object 
*pointer0 = object_pointer;
        TableType 
*ptable0 = ptable;
        object_pointer 
= rhs.object_pointer;
        ptable 
= rhs.ptable;
        rhs.object_pointer 
= pointer0;
        rhs.ptable 
= ptable0;
    }

}
;

template 
<class conceptT, class Alloc>
class auto_concept : public concept<conceptT, truefalse, Alloc>
{
public:
    template 
<class T>
    auto_concept(
const T& t) : concept<conceptT, truefalse, Alloc>(t) {}
}
;

template 
<class conceptT, class Alloc>
class ref_concept : public concept<conceptT, falsetrue, Alloc>
{
public:
    template 
<class T>
    ref_concept(
const T& t) : concept<conceptT, falsetrue, Alloc>(t) {}
}
;

template 
<class conceptT, class Alloc>
class ref_auto_concept : public concept<conceptT, truetrue, Alloc>
{
public:
    template 
<class T>
    ref_auto_concept(
const T& t) : concept<conceptT, truetrue, Alloc>(t) {}
}
;

}
 // namespace Concept
原创粉丝点击