Salome HOME
Fix compilation pb.
[modules/kernel.git] / src / Basics / BasicsGenericDestructor.hxx
1 //  SALOME Basics : general SALOME definitions and tools (C++ part - no CORBA)
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : BasicGenericDestructor.hxx
25 //  Author : Antoine YESSAYAN, Paul RASCLE, EDF
26 //  Module : SALOME
27 //  $Header$
28
29 #ifndef _BASICGENERICDESTRUCTOR_HXX_
30 #define _BASICGENERICDESTRUCTOR_HXX_
31
32 #ifdef WNT
33  #if defined BASICS_EXPORTS
34   #if defined WIN32
35    #define BASICS_EXPORT __declspec( dllexport )
36   #else
37    #define BASICS_EXPORT
38   #endif
39  #else
40   #if defined WIN32
41    #define BASICS_EXPORT __declspec( dllimport )
42   #else
43    #define BASICS_EXPORT
44   #endif
45  #endif
46 #else
47  #define BASICS_EXPORT
48 #endif
49
50 #include <list>
51 #include <algorithm>
52 #include <cassert>
53 #include <typeinfo>
54 #include <iostream>
55 #include <cstdlib>
56 #include <pthread.h>
57
58 //#define _DEVDEBUG_
59
60 #ifdef _DEVDEBUG_
61 #define MYDEVTRACE {std::cerr << __FILE__ << " [" << __LINE__ << "] : ";}
62 #define DEVTRACE(msg) {MYDEVTRACE; std::cerr<<msg<<std::endl<<std::flush;}
63 #else
64 #define MYDEVTRACE
65 #define DEVTRACE(msg)
66 #endif
67
68 // ============================================================================
69 /*!
70  * The PROTECTED_DELETE base class provides a protected destructor. 
71  * The only way to use PROTECTED_DELETE is inheritance:
72  *   example: class LocalTraceBufferPool : public PROTECTED_DELETE
73  * Herited class destructor must stay protected.
74  * Normal use is:
75  * - create an instance of herited class on the heap (new),
76  * - use addObj(instance) to store the instance on the static list _objList,
77  * - delete instance with deleteInstance(instance)
78  *
79  * This class is utilised with GENERIC_DESTRUCTOR and DESTRUCTOR_OF, 
80  * to program automatic deletion of objects at the end of the process, while
81  * keeping the possibility of an early destruction, if required. This is used
82  * for unit testing and trace mecanism.
83  */ 
84 // ============================================================================
85
86 class BASICS_EXPORT PROTECTED_DELETE
87 {
88 public:
89   static void deleteInstance(PROTECTED_DELETE *anObject);
90   static void addObj(PROTECTED_DELETE *anObject);
91
92 protected:
93   virtual ~PROTECTED_DELETE();
94   static std::list<PROTECTED_DELETE*> _objList;
95
96 private:
97   static pthread_mutex_t _listMutex;
98 };
99
100 // ============================================================================
101 /*!
102  * The GENERIC_DESTRUCTOR abstract class describes the comportement of any
103  * destruction object. This type is used to create a list of miscellaneous
104  * destruction objects.
105  *
106  * The only way to use the GENERIC_DESTRUCTOR class is inheritance:
107  *   class SPECIFIC_DESTRUCTOR : public GENERIC_DESTRUCTOR
108  * 
109  * A generic destructor provides two methods:
110  * -# a static method to add a destruction (object) to be performed:
111  *    GENERIC_DESTRUCTOR::Add(GENERIC_DESTRUCTOR &anObject);
112  *    The Destruction object is stored in a list of pointer to
113  *    GENERIC_DESTRUCTOR objects.
114  * -# an object method to execute the destruction : operator()().
115  */ 
116 // ============================================================================
117
118 class BASICS_EXPORT GENERIC_DESTRUCTOR
119 {
120 public :
121   static std::list<GENERIC_DESTRUCTOR*> *Destructors;
122
123   virtual ~GENERIC_DESTRUCTOR() {};
124   static const int Add(GENERIC_DESTRUCTOR &anObject);
125   virtual void operator()(void) = 0;
126 };
127
128 // ============================================================================
129 /*! 
130  * The DESTRUCTOR_OF class allows the user to program - at any moment - the
131  * destruction of an object at the end of the process.
132  *
133  * Example: the POINT ptrPoint will be destroyed at the end of the process
134  * (atexit).
135  *
136  * POINT *ptrPoint = new POINT ;
137  *
138  * DESTRUCTOR_OF<POINT> *ptrDestruct = new DESTRUCTOR_OF<POINT>(*ptrPoint);
139  * 
140  * Note that neither ptrPoint, nor ptrDestruct should be destroyed by the user.
141  * 
142  * The destruction object must be created dynamically because it suscribes
143  * itself in the list of destruction to be performed at the end of the process.
144  */ 
145 // ============================================================================
146
147 template <class TYPE> class DESTRUCTOR_OF : public GENERIC_DESTRUCTOR
148 {
149 public:
150   /*!
151     Programs the destruction at the end of the process, of the object anObject.
152     This method records in _objectPtr the address of an object to be destroyed 
153     at the end of the process
154   */
155   DESTRUCTOR_OF(TYPE &anObject):
156     _objectPtr(&anObject)
157   {
158     DEVTRACE(" DESTRUCTOR_OF " << typeid(anObject).name() 
159              << " " << _objectPtr << " " << this );
160     PROTECTED_DELETE::addObj(_objectPtr);
161     assert(GENERIC_DESTRUCTOR::Add(*this) >= 0);
162   }
163
164   /*!
165     Performs the destruction of the object.
166     This method really destroys the object pointed by _objectPtr. 
167     It should be called at the end of the process (i.e. at exit).
168   */
169   virtual void operator()(void)
170   {
171     if (_objectPtr)
172       {
173         DEVTRACE("DESTRUCTOR_OF<>::operator() " << _objectPtr);
174         if (_objectPtr) PROTECTED_DELETE::deleteInstance(_objectPtr);
175         _objectPtr = NULL;
176       }
177   }
178
179   virtual ~DESTRUCTOR_OF()
180   {
181     DEVTRACE("~DESTRUCTOR_OF() " << this);
182     assert(!_objectPtr);
183   }
184
185 private:
186   TYPE *_objectPtr;
187 };
188
189 # endif