/* * CENA C++ Utilities * * by Stephane Chatty * * Copyright 1990, 1991, 1992 * Laboratoire de Recherche en Informatique (LRI) * Centre d'Etudes de la Navigation Aerienne (CENA) * * smart pointers, originally by Michel Beaudouin-Lafon * * $Id$ * $CurLog$ */ #ifndef SmartPointer_H_ #define SmartPointer_H_ #include "cplus_bugs.h" class CcuSmartData { public: enum check_type { NoCheck, OnlyDynamic, Warn, Abort }; private: static check_type check; int State; inline int IsDynamic () const { return !(State & 1); } protected: static int NextCreatedIsDynamic; public: void* operator new (unsigned long); inline void operator delete (void* that) { ::delete (that); } CcuSmartData (); CcuSmartData (const CcuSmartData&); virtual ~CcuSmartData (); static check_type SetCheck (check_type); void DecrRef (); inline void IncrRef () { State += 2; } }; #ifndef CPLUS_BUG19 template class CcuSmartPointerTo { protected: DATA* Data; inline void DecrDataRef () const { if (Data) Data->DecrRef (); } inline void IncrDataRef () const { if (Data) Data->IncrRef (); } public: inline CcuSmartPointerTo () : Data (0) { } inline CcuSmartPointerTo (DATA* d) : Data (d) { IncrDataRef (); } inline CcuSmartPointerTo (const CcuSmartPointerTo& p) : Data (p.Data) { IncrDataRef (); } inline ~CcuSmartPointerTo () { DecrDataRef (); Data = 0; } inline CcuSmartPointerTo& operator = (DATA* d) { if (d != Data) { DecrDataRef (); Data = d; IncrDataRef (); } return *this;} inline int operator == (const DATA* d) const { return Data == d;} inline int operator != (const DATA* d) const { return Data != d;} inline int operator == (const CcuSmartPointerTo& p) const { return Data == p.Data;} inline int operator != (const CcuSmartPointerTo& p) const { return Data != p.Data;} inline DATA* operator -> () const { return Data; } inline DATA& operator * () const { return *Data; } inline operator DATA* () const { return Data; } }; #define PointerClass(SmartClass, DataClass) typedef CcuSmartPointerTo SmartClass; #else /* CPLUS_BUG19 */ #define PointerClass(SmartClass, DataClass) \ class SmartClass { \ protected: \ DataClass* Data; \ inline void DecrDataRef () const { if (Data) Data->DecrRef (); } \ inline void IncrDataRef () const { if (Data) Data->IncrRef (); } \ \ public: \ inline SmartClass () : Data (0) { } \ inline SmartClass (DataClass* d) : Data (d) { IncrDataRef (); } \ inline SmartClass (const SmartClass& p) : Data (p.Data) { IncrDataRef (); } \ inline ~SmartClass () { DecrDataRef (); Data = 0; } \ inline SmartClass& operator = (DataClass* d) { if (d != Data) { DecrDataRef (); Data = d; IncrDataRef (); } return *this;} \ inline int operator == (const DataClass* d) const { return Data == d;} \ inline int operator != (const DataClass* d) const { return Data != d;} \ inline int operator == (const SmartClass& p) const { return Data == p.Data;} \ inline int operator != (const SmartClass& p) const { return Data != p.Data;} \ inline DataClass* operator -> () const { return Data; } \ inline DataClass& operator * () const { return *Data; } \ inline operator DataClass* () const { return Data; } \ }; #endif /* CPLUS_BUG19 */ #define DerivedPointerClass(SmartClass, BaseSmartClass, DataClass) \ class SmartClass : public BaseSmartClass { \ public: \ inline SmartClass () : BaseSmartClass () { } \ inline SmartClass (const SmartClass& p) : BaseSmartClass (p) { } \ inline SmartClass (DataClass* d) : BaseSmartClass (d) { } \ inline SmartClass& operator = (DataClass* d) { if (d != Data) { DecrDataRef (); Data = d; IncrDataRef (); } return *this; } \ inline DataClass* operator -> () const { return (DataClass*) Data; } \ inline DataClass& operator * () const { return * ((DataClass*) Data); } \ inline operator DataClass* () const { return (DataClass*) Data; } \ }; #ifdef DOC global macro PointerClass (SmartClass, DataClass); global macro DerivedPointerClass (SmartClass, BaseSmartClass, DataClass); #endif #endif /* SmartPointer_H_ */