summaryrefslogtreecommitdiff
path: root/utils/metaclass.h
blob: df896d61e5d52b72440061f15c3aea5cc852193f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 *	CENA C++ Utilities
 *
 *	by Stephane Chatty
 *
 *	Copyright 1991, 1992
 *	Laboratoire de Recherche en Informatique (LRI)
 *	Centre d'Etudes de la Navigation Aerienne (CENA)
 *
 *	metaclasses, originally by Michel Beaudouin-Lafon
 *
 *	$Id$
 *	$CurLog$
 */

#ifndef _MetaClass_H_
#define _MetaClass_H_

#include "List.h"

class MetaClass {
protected:
	const char*		Name;
	IvlListOf <MetaClass>		BaseClasses;
	
public:
	MetaClass (const char*, MetaClass&);
	MetaClass (const char*);
inline	MetaClass*	GetBaseClass () const		{ return BaseClass; }
inline	const char*	GetName () const			{ return Name; }
inline	operator		const char* () const		{ return Name; }
inline	int		IsBase () const 			{ return (BaseClass == 0); }
inline	int		IsDerived () const 			{ return (BaseClass != 0); }
	int		IsSubClassOf (const MetaClass&) const;
	int		IsSubClassOf (const char*) const;
inline	int		operator <= (const MetaClass& c) const	{ return IsSubClassOf (c); }
inline	int		operator >= (const MetaClass& c) const	{ return c.IsSubClassOf (*this); }
inline	int		operator < (const MetaClass& c) const		{ return (this != &c) && IsSubClassOf (c);}
inline	int		operator > (const MetaClass& c) const		{ return (this != &c)  && c.IsSubClassOf (*this); }
inline	int		operator == (const MetaClass& c) const	{ return (this == &c); }
inline	int		operator != (const MetaClass& c) const		{ return (this != &c); }
inline	const MetaClass&	operator = (const MetaClass&) const		{ return *this; }
};

#ifdef __GNUG__
#define _nameCLASS(a)	#a
#else
#define _nameCLASS(a)	"a"
#endif

/*** should we have two macros for headers (with/without virtual) ***/

#define MetaclassHeader						\
public:								\
static	MetaClass	TheClass;					\
virtual	MetaClass&	Class () const;				\
private:

#define BaseMetaclassBody(name)				\
MetaClass	name::CLASS (_nameCLASS(name));		\
								\
MetaClass&							\
name :: Class () const						\
{								\
	return CLASS;						\
}

#define DerivedMetaclassBody(name,base)			\
MetaClass	name::CLASS (_nameCLASS(name),&base::CLASS);\
								\
MetaClass&							\
name :: Class () const						\
{								\
	return CLASS;						\
}

#define NarrowMembers(derived,base)				\
static	inline	derived*		Narrow (base* p)		{ if (p && p->Class () <= CLASS) return (derived*) p; else return 0; }	\
static	inline	const derived*	Narrow (const base* p)	{ if (p && p->Class () <= CLASS) return (const derived*) p; else return 0; }	\
static	inline	derived&		Narrow (base& p)		{ return * Narrow (&p); }	\
static	inline	const derived&	Narrow (const base& p)	{ return * Narrow (&p); }

#endif