Salome HOME
Typo-fix by Kunda
[modules/kernel.git] / src / Basics / BasicsGenericDestructor.hxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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 //  SALOME Basics : general SALOME definitions and tools (C++ part - no CORBA)
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 #include "SALOME_Basics.hxx"
33
34 #include <list>
35 #include <algorithm>
36 #include <cassert>
37 #include <typeinfo>
38 #include <iostream>
39 #include <cstdlib>
40 #include <pthread.h>
41
42 //#define _DEVDEBUG_
43
44 #ifdef _DEVDEBUG_
45 #define MYDEVTRACE {std::cerr << __FILE__ << " [" << __LINE__ << "] : ";}
46 #define DEVTRACE(msg) {MYDEVTRACE; std::cerr<<msg<<std::endl<<std::flush;}
47 #else
48 #define MYDEVTRACE
49 #define DEVTRACE(msg)
50 #endif
51
52 #ifdef WIN32
53 #pragma warning(disable:4251) // Warning DLL Interface ...
54 #endif
55
56 // ============================================================================
57 /*!
58  * The PROTECTED_DELETE base class provides a protected destructor. 
59  * The only way to use PROTECTED_DELETE is inheritance:
60  *   example: class LocalTraceBufferPool : public PROTECTED_DELETE
61  * Herited class destructor must stay protected.
62  * Normal use is:
63  * - create an instance of herited class on the heap (new),
64  * - use addObj(instance) to store the instance on the static list _objList,
65  * - delete instance with deleteInstance(instance)
66  *
67  * This class is utilised with GENERIC_DESTRUCTOR and DESTRUCTOR_OF, 
68  * to program automatic deletion of objects at the end of the process, while
69  * keeping the possibility of an early destruction, if required. This is used
70  * for unit testing and trace mechanism.
71  */ 
72 // ============================================================================
73
74 class BASICS_EXPORT PROTECTED_DELETE
75 {
76 public:
77   static void deleteInstance(PROTECTED_DELETE *anObject);
78   static void addObj(PROTECTED_DELETE *anObject);
79
80 protected:
81   virtual ~PROTECTED_DELETE();
82   static std::list<PROTECTED_DELETE*> _objList;
83
84 private:
85   static pthread_mutex_t _listMutex;
86 };
87
88 // ============================================================================
89 /*!
90  * The GENERIC_DESTRUCTOR abstract class describes the comportement of any
91  * destruction object. This type is used to create a list of miscellaneous
92  * destruction objects.
93  *
94  * The only way to use the GENERIC_DESTRUCTOR class is inheritance:
95  *   class SPECIFIC_DESTRUCTOR : public GENERIC_DESTRUCTOR
96  * 
97  * A generic destructor provides two methods:
98  * -# a static method to add a destruction (object) to be performed:
99  *    GENERIC_DESTRUCTOR::Add(GENERIC_DESTRUCTOR &anObject);
100  *    The Destruction object is stored in a list of pointer to
101  *    GENERIC_DESTRUCTOR objects.
102  * -# an object method to execute the destruction : operator()().
103  */ 
104 // ============================================================================
105
106 class BASICS_EXPORT GENERIC_DESTRUCTOR
107 {
108 public :
109   static std::list<GENERIC_DESTRUCTOR*> *Destructors;
110
111   virtual ~GENERIC_DESTRUCTOR() {};
112   static const int Add(GENERIC_DESTRUCTOR &anObject);
113   virtual void operator()(void) = 0;
114 };
115
116 // ============================================================================
117 /*! 
118  * The DESTRUCTOR_OF class allows the user to program - at any moment - the
119  * destruction of an object at the end of the process.
120  *
121  * Example: the POINT ptrPoint will be destroyed at the end of the process
122  * (atexit).
123  *
124  * POINT *ptrPoint = new POINT ;
125  *
126  * DESTRUCTOR_OF<POINT> *ptrDestruct = new DESTRUCTOR_OF<POINT>(*ptrPoint);
127  * 
128  * Note that neither ptrPoint, nor ptrDestruct should be destroyed by the user.
129  * 
130  * The destruction object must be created dynamically because it subscribes
131  * itself in the list of destruction to be performed at the end of the process.
132  */ 
133 // ============================================================================
134
135 template <class TYPE> class DESTRUCTOR_OF : public GENERIC_DESTRUCTOR
136 {
137 public:
138   /*!
139     Programs the destruction at the end of the process, of the object anObject.
140     This method records in _objectPtr the address of an object to be destroyed 
141     at the end of the process
142   */
143   DESTRUCTOR_OF(TYPE &anObject):
144     _objectPtr(&anObject)
145   {
146     DEVTRACE(" DESTRUCTOR_OF " << typeid(anObject).name() 
147              << " " << _objectPtr << " " << this );
148     PROTECTED_DELETE::addObj(_objectPtr);
149     assert(GENERIC_DESTRUCTOR::Add(*this) >= 0);
150   }
151
152   /*!
153     Performs the destruction of the object.
154     This method really destroys the object pointed by _objectPtr. 
155     It should be called at the end of the process (i.e. at exit).
156   */
157   virtual void operator()(void)
158   {
159     if (_objectPtr)
160       {
161         DEVTRACE("DESTRUCTOR_OF<>::operator() " << _objectPtr);
162         if (_objectPtr) PROTECTED_DELETE::deleteInstance(_objectPtr);
163         _objectPtr = NULL;
164       }
165   }
166
167   virtual ~DESTRUCTOR_OF()
168   {
169     DEVTRACE("~DESTRUCTOR_OF() " << this);
170     assert(!_objectPtr);
171   }
172
173 private:
174   TYPE *_objectPtr;
175 };
176
177 # endif