From 52f463e97f52b9635431cdb10f5a0036a2d74437 Mon Sep 17 00:00:00 2001 From: chatty Date: Wed, 22 Dec 1993 12:25:01 +0000 Subject: Initial revision --- utils/metaclass.cc | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++ utils/metaclass.h | 86 ++++++++++++++++++++++++ 2 files changed, 279 insertions(+) create mode 100644 utils/metaclass.cc create mode 100644 utils/metaclass.h diff --git a/utils/metaclass.cc b/utils/metaclass.cc new file mode 100644 index 0000000..c07755c --- /dev/null +++ b/utils/metaclass.cc @@ -0,0 +1,193 @@ +/* + * 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$ + */ + + +#include "MetaClass.h" +#include + +/*?class MetaClass +This class provides minimal support for metaclasses in C++. +A \typ{MetaClass} object represents a C++ class. +It contains a name (a string holding the name of the C++ class), and the inheritance information. +Multiple inheritance is not supported in this version. +?*/ + +/* +a discuter : + autres fonctions dans MetaClass, notamment pour le transport d'objet + stocker dans l'objet MetaClass la fonction de chargement/ecriture + mettre les MetaClass dans une h-table indexee par le nom + persistance: la description des classes pour la sauvegarde/chargement pourrait etre + non pas dans le code, mais dans un fichier (par exemple le .h !!!) + faut-il conserver la liste des classes filles ? + */ + + +/*? +Create a metaclass for the base class named \var{n}. +?*/ +MetaClass :: MetaClass (const char* n) +: Name (n), + BaseClasses () +{ +} + +/*? +Create a metaclass for the derived class named \var{n}. +\var{s} is the metaclass of the base class of the class named \var{n}. +?*/ +MetaClass :: MetaClass (const char* n, MetaClass& s) +: Name (n), + BaseClasses () +{ + BaseClasses->Append (s); +} + +/*? +Return true if this metaclass is a derived class of the metaclass s. +?*/ +int +MetaClass :: IsDerivedClass (const MetaClass& s) const +{ + register const MetaClass* m = this; + do { + if (m == &s) + return 1; + } while (m = m->BaseClass); + return 0; +} + +/*? +Return 1 if this metaclass is a derived class of the metaclass named \var{n}. +This form is less efficient than the previous one. +It may be useful to avoid including the definition of the class named \var{n}. +?*/ +int +MetaClass :: IsSubClass (const char* n) const +{ + register const MetaClass* m = this; + do { + if (strcmp (m->name, n) == 0) + return 1; + } while (m = m->BaseClass); + return 0; +} + +#ifdef DOC +// fake entries for documentation + +/*? +Return the superClass of this metaclass. +Note that base classe have MetaClass::ROOT as superClass. +MetaClass::ROOT is its own metaclass +(there is a loop at the root of the inheritance tree). +?*/ +MetaClass& +MetaClass :: SuperClass () const +{ +} + +/*? +Return the name of this metaclass. +By convention, it is identical to the identifier for the class represented by this metaclass. +?*/ +const char* +MetaClass :: Name () const +{ +} + +/*? +This conversion operator returns the name of this metaclass. +See the member function Name. +?*/ +MetaClass :: operator const char* () const +{ +} + +/*?nextdoc?*/ +int +MetaClass :: Base () const +{ +} + +/*? +Return true if the class represented by this metaclass +is a base class (resp. a derived class). +?*/ +int +MetaClass :: Derived () const +{ +} + +/*? +Return 0 if this metaclass is MetaClass::ROOT, else return 1. +This makes it easy to walk up the hierarchy of metaclasses:\\ +\hspace*{1cm}\com{while (mc = mc.SuperClass ()) ...}. +?*/ +MetaClass :: operator int () const +{ +} + + +/*?nextdoc?*/ +int +MetaClass :: operator <= (const MetaClass& c) const +{ +} + +/*?nextdoc?*/ +int +MetaClass :: operator >= (const MetaClass& c) const +{ +} + +/*?nextdoc?*/ +int +MetaClass :: operator < (const MetaClass& c) const +{ +} + +/*?nextdoc?*/ +int +MetaClass :: operator > (const MetaClass& c) const +{ +} +/*?nextdoc?*/ +int +MetaClass :: operator == (const MetaClass& c) const +{ +} +/*? +Relational operations between metaclasses. +The metaclass of class A is $<$ to the metaclass of class B +if A is a derived class of B. +The definitions of the other operators derive from this one. +Note however that the order between metaclasses is not total : +two metaclasses A and B can be uncomparable, that is +neither A $<$ B or B $<$ A is true. +This is the case when A does not derive from B and B does not derive from A. +?*/ +int +MetaClass :: operator != (const MetaClass& c) const +{ +} + +/*?nodoc?*/ +const MetaClass& +MetaClass :: operator = (const MetaClass&) +{ +} + +#endif 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 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 -- cgit v1.1