📄 classtype_tmpl.hpp
字号:
/******************************************************************************\
* *
* ClassType_tmpl.hpp *
* *
* <Purpose of this file> *
* *
\******************************************************************************/
// $Id: ClassType_tmpl.hpp,v 1.1 2007/10/25 14:05:24 tdevadit Exp $
#ifndef REFLCPP_CLASS_TYPE_TMPL_H
#define REFLCPP_CLASS_TYPE_TMPL_H
#include <reflcpp/Type.hpp>
#include <reflcpp/ClassType.hpp>
#include <reflcpp/FundamentalType.hpp>
#include <reflcpp/BoundClassType_tmpl.hpp>
#include <reflcpp/TypeInfoCmp.hpp>
#include <reflcpp/check.hpp>
#include <reflcpp/Exceptions.hpp>
namespace reflcpp {
/*------------------------------------------------------------------------------
Forwards (within namespace) */
template <typename Bottom_TP, typename Der_TP, typename Class_TP, int N>
class Bases;
template <typename Bottom_TP> class BaseList_base;
template <class Obj_TP> class ClassType_body_tmpl;
template <typename Obj_TP> class Members;
template <typename Obj_TP> class MemberFunction_body_tmpl1;
/*-----------------------------------------------------------------------------\
|------------------------------------------------------------------------------|
| |
| ObjHolder |
| |
|------------------------------------------------------------------------------|
\------------------------------------------------------------------------------/
This is the base class for an object holder.
ObjHolders are used to allow pointers to different object types to be
passed through virtual functions.
The reason we need both the castTo() and castFrom() is because sometimes
we need to cast B to A, and sometimes A to B. I have not been able to
discover any way to refactor this to eliminate the need for both directions
explicitly.
Note that the information about all directions is always in the derived
type. A base class A does not know about the classes that are derived
from it.
- */
class ObjHolder {
protected:
ObjHolder(const std::type_info &ti) : typeInfo(ti) {}
public:
virtual ~ObjHolder() {}
virtual void castTo(ObjHolder *oh) const = 0;
virtual void castFrom(const ObjHolder &) = 0;
const std::type_info &typeInfo;
};
/*-----------------------------------------------------------------------------\
|------------------------------------------------------------------------------|
| |
| ObjHolder_tmpl |
| |
|------------------------------------------------------------------------------|
\------------------------------------------------------------------------------/
This is the templated class that contains a typed pointer. Each
instantiation of this class will specialize the castTo() and castFrom().
- */
template <typename T>
class ObjHolder_tmpl : public ObjHolder {
public:
explicit ObjHolder_tmpl(T *p)
: ObjHolder(typeid(T)), ptr(p) { ixcr_assert(p != NULL); }
// XXX - For non-debug, don't set ptr to zero, for speed.
ObjHolder_tmpl() : ObjHolder(typeid(T)), ptr(0) { }
virtual ~ObjHolder_tmpl() {}
virtual void castTo(ObjHolder *ph) const;
virtual void castFrom(const ObjHolder &ph);
T *ptr;
};
/*-----------------------------------------------------------------------------\
|------------------------------------------------------------------------------|
| |
| DataMember_body_tmpl1 |
| |
|------------------------------------------------------------------------------|
\------------------------------------------------------------------------------/
DataMember body class. This one is templated just on the object type (and
not also on the member type).
- */
template <typename Obj_TP>
class DataMember_body_tmpl1 : public DataMember_body {
/*--------------------------------------------------------------------------
Types and Constants */
typedef std::map<std::string, const DataMember_body_tmpl1<Obj_TP> *>
dataMember_map_t;
typedef std::map<std::string, const MemberFunction_body_tmpl1<Obj_TP> *>
memberFunction_map_t;
typedef std::vector<DataMember> dataMember_vector_t;
typedef std::vector<MemberFunction> memberFunction_vector_t;
/*--------------------------------------------------------------------------
Constructors, Initters, Assignments, and Destructors */
public:
inline DataMember_body_tmpl1(const std::string &name,
const std::string &type_name);
virtual ~DataMember_body_tmpl1() {}
private:
// Disallow these unless specifically allowed.
DataMember_body_tmpl1(const DataMember_body_tmpl1 &);
DataMember_body_tmpl1 &operator=(const DataMember_body_tmpl1 &);
/*--------------------------------------------------------------------------
Methods */
public:
// This declaration is just to avoid warning messages about virtual
// function hiding.
virtual BoundDataMember_body *bind(const ObjHolder &oh) const = 0;
virtual BoundDataMember_body *bind(Obj_TP *) const = 0;
void registerMember(dataMember_map_t *fm, dataMember_vector_t *fv,
memberFunction_map_t *mm, memberFunction_vector_t *mv) {
fm->insert(typename dataMember_map_t::value_type(name(), this));
fv->push_back(DataMember(this));
}
};
/*-----------------------------------------------------------------------------\
|------------------------------------------------------------------------------|
| |
| DataMember_body_tmpl2 |
| |
|------------------------------------------------------------------------------|
\------------------------------------------------------------------------------/
DataMember body class. This one is templated on both the object type and the
member type. The member type is a synthetic type class, and not a native
type.
- */
template <typename Obj_TP, typename MemType_TP>
class DataMember_body_tmpl2 : public DataMember_body_tmpl1<Obj_TP> {
/*--------------------------------------------------------------------------
Constructors, Initters, Assignments, and Destructors */
public:
DataMember_body_tmpl2(const std::string &member_name);
private:
// Disallow these unless specifically allowed.
DataMember_body_tmpl2(const DataMember_body_tmpl2 &);
DataMember_body_tmpl2 &operator=(const DataMember_body_tmpl2 &);
/*--------------------------------------------------------------------------
Accessors and Convertors */
public:
virtual const Type &type() const { return m_type; }
/*--------------------------------------------------------------------------
Methods */
public:
// This needs to be inline to workaround a MIPSpro 7.4 bug in RTTI.
virtual void getPtr(const ObjHolder &oh, PtrHolder *vh) const {
// Convert the object holder.
ObjHolder_tmpl<Obj_TP> oh_t;
oh.castTo(&oh_t);
assert(oh_t.ptr != NULL);
// Cast the value holder to the correct type.
PtrHolder_tmpl<typename MemType_TP::type> *vh_t
= dynamic_cast<PtrHolder_tmpl<typename MemType_TP::type> *>(vh);
assert(vh_t != NULL);
vh_t->ptr = ptr(oh_t.ptr);
}
virtual typename MemType_TP::type *ptr(Obj_TP *) const = 0;
// The first version is for creating a BoundDataMember from a DataMember. The
// second is for creating a BoundDataMember from a BoundClass. These two
// versions of bind could be converted into one, but at a slight cost
// in performance. The ObjHolder in the first version would have to be
// converted to the actual object in a separate method.
virtual BoundDataMember_body *bind(const ObjHolder &oh) const {
// Convert the object holder.
ObjHolder_tmpl<Obj_TP> oh_t;
using namespace std;
oh.castTo(&oh_t);
assert(oh_t.ptr != NULL);
// XXX - Memleak.
return new BoundDataMember_body_tmpl2<Obj_TP, MemType_TP>(oh_t.ptr, this);
}
virtual BoundDataMember_body *bind(Obj_TP *) const;
/*--------------------------------------------------------------------------
Data */
private:
const MemType_TP m_type;
};
/*-----------------------------------------------------------------------------\
|------------------------------------------------------------------------------|
| |
| DataMemberFunction_body_tmpl1 |
| |
|------------------------------------------------------------------------------|
\------------------------------------------------------------------------------/
MemberFunction body class. This one is templated only on the object type.
- */
template <typename Obj_TP>
class MemberFunction_body_tmpl1 : public MemberFunction_body {
/*--------------------------------------------------------------------------
Types and Constants */
typedef std::map<std::string, const DataMember_body_tmpl1<Obj_TP> *>
dataMember_map_t;
typedef std::map<std::string, const MemberFunction_body_tmpl1<Obj_TP> *>
memberFunction_map_t;
typedef std::vector<DataMember> dataMember_vector_t;
typedef std::vector<MemberFunction> memberFunction_vector_t;
/*--------------------------------------------------------------------------
Constructors, Initters, Assignments, and Destructors */
public:
inline MemberFunction_body_tmpl1(const std::string &name);
virtual ~MemberFunction_body_tmpl1() {}
private:
// Disallow these unless specifically allowed.
MemberFunction_body_tmpl1(const MemberFunction_body_tmpl1 &);
MemberFunction_body_tmpl1 &operator=(const MemberFunction_body_tmpl1 &);
/*--------------------------------------------------------------------------
Methods */
public:
// Extract the object pointer. This is done here to minimize what has
// to be done in the duplicated code in sub classes.
// This method is overloaded for ObjHolder and PtrHolder.
virtual void invoke1(const ObjHolder &oh, RetValHolder &rvh,
const int n, Arguments &args) const {
ObjHolder_tmpl<Obj_TP> oh_t;
oh.castTo(&oh_t);
assert(oh_t.ptr != NULL);
invoke2(oh_t.ptr, rvh, n, args);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -