Runtime Concept 的模拟(4)

Runtime Concept 的模拟(4)
简化使用方法!
支持auto concept和non-auto concept。
支持引用类型concept和值类型concept。
已测试支持的编译器:
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. 没考虑异常安全。
4. 继承自两个有相同约束的concept的时候,产生调用不明确的问题。
   可用重新声明约束的方法来解决。

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

// main.cpp

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

CONCEPT_MEMBER_FUNCTION(c_set_value, concept_base, set_value, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value1, concept_base, set_value1, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value2, concept_base, set_value2, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value3, concept_base, set_value3, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_set_value4, concept_base, set_value4, 
void , ( int  Value), (Value));
CONCEPT_MEMBER_FUNCTION(c_draw, concept_base, draw, 
void , (monitor device)  const , (device));
CONCEPT_FUNCTION(g_set_value, concept_base, set_value, 
void , (ObjectType  & t,  int  Value), (t, Value));
CONCEPT_FUNCTION(g_drawShape, concept_base, drawShape, 
void , ( const  ObjectType  & t, monitor device), (t, device));
typedef concept_list
< g_drawShape, c_draw, c_set_value, c_set_value1, c_set_value2, c_set_value3 >  Shape;

template 
<>   struct  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);
}


int  main( int  argc,  char *  argv[])
{
    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
<c_set_value>(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
#ifdef _MSC_VER
#define  MEMFUNCCAST(A)          reinterpret_cast<A>
#else
#define  MEMFUNCCAST(A)
#endif

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

    template 
<bool isvtable, class ObjectType> 
    
struct table : public BASE::template table<isvtable, ObjectType> 
    

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

    template 
<class ObjectType> 
    
struct table<false, ObjectType> : public BASE::template table<false, ObjectType> 
    

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

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

}
;

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

    template 
<bool isvtable, class ObjectType> 
    
struct table : public BASE::template table<isvtable, ObjectType> 
    

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

    template 
<class ObjectType> 
    
struct table<false, ObjectType> : public BASE::template table<false, ObjectType> 
    

        
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 
< class  T >   struct  get_type  {typedef T type;} ;

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

struct  concept_base
{
    template 
<bool isvtable, class ObjectType>
    
struct table
    
{
    }
;
}
;

template 
< class  First  =  concept_base,  class  Second  =  concept_base >
struct  concept_pair
{
    typedef concept_pair type;
    template 
<bool isvtable = trueclass ObjectType = concept_object>
    
struct table : public First::template table<isvtable, ObjectType>
                          Second::template table
<isvtable, ObjectType>
    
{
    }
;
}
;

template 
< class  SameType >
struct  concept_pair < SameType, SameType >
{
    typedef concept_pair type;
    template 
<bool isvtable = trueclass ObjectType = concept_object>
    
struct table : public SameType::template table<isvtable, ObjectType>
    
{
    }
;
}
;

template 
< class  First >
struct  concept_pair < First, concept_base >
{
    typedef First type;
}
;

template 
< class  Second >
struct  concept_pair < concept_base, Second >
{
    typedef Second type;
}
;

template 
<>
struct  concept_pair < concept_base, concept_base >
{
    typedef concept_base type;
}
;

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
{
    template 
<bool isvtable = trueclass ObjectType = concept_object>
    
struct table : public
                 concept_pair
< C0, typename concept_pair< C1, typename concept_pair< C2, typename concept_pair< C3, typename concept_pair< C4,
        typename concept_pair
< C5, typename concept_pair< C6, typename concept_pair< C7, typename concept_pair< C8, typename concept_pair< C9,
        typename concept_pair
<C10, typename concept_pair<C11, typename concept_pair<C12, typename concept_pair<C13, typename concept_pair<C14,
        typename concept_pair
<C15, typename concept_pair<C16, typename concept_pair<C17, typename concept_pair<C18, C19>
        ::type
>::type>::type>::type>::type>::type>::type>::type>::type>::type>
        ::type
>::type>::type>::type>::type>::type>::type>::type>::type
        ::template table
<isvtable, ObjectType>
    
{
    }
;
}
;

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  T  =  concept_object >
struct  concept_table :  public  conceptT::template table < true , T >
{
    typedef conceptT conceptType;

    typedef T
* (*tcloneT)(const T *p);
    typedef 
void (*tdeleteT)(T *p);
    tcloneT pcloneT;
    tdeleteT pdeleteT;
    concept_table() : 
        pcloneT(reinterpret_cast
<tcloneT>(&concept_table::cloneT)), 
        pdeleteT(reinterpret_cast
<tdeleteT>(&concept_table::deleteT)){}

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

    
static T *cloneT(const T *p)
    
{
        
return new T(*p);
    }

    
static void deleteT(T *p)
    
{
        delete p;
    }

}
;

template 
< class  conceptT >
class  auto_concept;
template 
< class  conceptT >
class  ref_concept;
template 
< class  conceptT >
class  ref_auto_concept;

template 
< class  conceptT,  bool  isauto  =   false bool  isref  =   false >
class  concept : 
    
public  concept_class_base < concept_table < conceptT >   >
    
public  conceptT::template table < false , concept_class_base < concept_table < conceptT >   >   >
{
public:
    
using concept_class_base<concept_table<conceptT> >::ptable;
    
using concept_class_base<concept_table<conceptT> >::object_pointer;
    typedef concept_table
<conceptT> TableType;
private:
    
void init_with(concept_object* p, TableType* pTable)
    
{
        ptable 
= pTable;
        
if (isref)
        
{
            object_pointer 
= p;
        }

        
else
        
{
            object_pointer 
= (*ptable->pcloneT)(p);
        }

    }

    concept_object 
*cloneT() const
    
{
        
return (*ptable->pcloneT)(object_pointer);
    }

    
void deleteT()
    
{
        (
*ptable->pdeleteT)(object_pointer);
    }

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, 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>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, !isauto, isref>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const concept<conceptT, !isauto, !isref>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const auto_concept<conceptT>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const ref_concept<conceptT>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }
    concept(
const ref_auto_concept<conceptT>& rhs) { init_with(rhs.object_pointer, rhs.ptable); }

    
~concept()
    
{
        
if (!isref) deleteT();
    }


    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  auto_concept :  public  concept < conceptT,  true false >
{
public:
    template 
<class T>
    auto_concept(
const T& t) : concept<conceptT, truefalse>(t) {}
}
;

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

template 
< class  conceptT >
class  ref_auto_concept :  public  concept < conceptT,  true true >
{
public:
    template 
<class T>
    ref_auto_concept(
const T& t) : concept<conceptT, truetrue>(t) {}
}
;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值