diff options
Diffstat (limited to 'utils/metaclass.h')
-rw-r--r-- | utils/metaclass.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/utils/metaclass.h b/utils/metaclass.h new file mode 100644 index 0000000..b036603 --- /dev/null +++ b/utils/metaclass.h @@ -0,0 +1,86 @@ +/* + * 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; + CcuListOf <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 |