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 = true, class 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 = true, class 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 = int, class 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 = true, class 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 = true, class 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 = true, class 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 = false, bool isref = false, class 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 (0) char 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, true, false, Alloc>

...{
public:
template <class T>

auto_concept(const T& t) : concept<conceptT, true, false, Alloc>(t) ...{}
};

template <class conceptT, class Alloc>
class ref_concept : public concept<conceptT, false, true, Alloc>

...{
public:
template <class T>

ref_concept(const T& t) : concept<conceptT, false, true, Alloc>(t) ...{}
};

template <class conceptT, class Alloc>
class ref_auto_concept : public concept<conceptT, true, true, Alloc>

...{
public:
template <class T>

ref_auto_concept(const T& t) : concept<conceptT, true, true, Alloc>(t) ...{}
};

}
//
namespace Concept