1
//---------------------------------------------------------------------------
2
// $Id: subscriptor.h 15292 2007-10-11 16:28:49Z kanschat $
5
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
7
// This file is subject to QPL and may not be distributed
8
// without copyright and license information. Please refer
9
// to the file deal.II/doc/license.html for the text and
10
// further information on this license.
12
//---------------------------------------------------------------------------
13
#ifndef __deal2__subscriptor_h
14
#define __deal2__subscriptor_h
17
#include <base/config.h>
18
#include <base/exceptions.h>
24
DEAL_II_NAMESPACE_OPEN
27
* Handling of subscriptions.
29
* This class, as a base class, allows to keep track of other objects
30
* using a specific object. It is used, when an object, given to a
31
* constructor by reference, is stored. Then, the original object may
32
* not be deleted before the dependent object is deleted. You can assert
33
* this constraint by letting the object passed be derived from this class
34
* and let the user subscribe() to this object. The destructor the used
35
* object inherits from the Subscriptor class then will lead to an error
36
* when destruction is attempted while there are still subscriptions.
38
* The utility of this class is even enhanced by providing identifying
39
* strings to the functions subscribe() and unsubscribe(). In case of
40
* a hanging subscription during destruction, this string will be
41
* listed in the exception's message. For reasons of efficiency, these
42
* strings are handled as <tt>const char*</tt>. Therefore, the
43
* pointers provided to subscribe() and to unsubscribe() must be the
44
* same. Strings with equal contents will not be recognized to be the
45
* same. The handling in SmartPointer will take care of this.
47
* @note Due to a problem with <tt>volatile</tt> declarations, this
48
* additional feature is switched of if multithreading is used.
51
* @author Guido Kanschat, 1998 - 2005
57
* Constructor setting the counter to zero.
64
* The counter of the copy is zero,
65
* since references point to the
68
Subscriptor(const Subscriptor&);
71
* Destructor, asserting that the counter
74
virtual ~Subscriptor();
77
* Assignment operator.
79
* This has to be handled with
80
* care, too, because the counter
81
* has to remain the same. It therefore
82
* does nothing more than returning
85
Subscriptor& operator = (const Subscriptor&);
88
* Subscribes a user of the
89
* object. The subscriber may be
90
* identified by text supplied as
91
* <tt>identifier</tt>.
93
void subscribe (const char* identifier = 0) const;
96
* Unsubscribes a user from the
99
* @note The <tt>identifier</tt>
100
* must be the <b>same
101
* pointer</b> as the one
102
* supplied to subscribe(), not
103
* just the same text.
105
void unsubscribe (const char* identifier = 0) const;
108
* Return the present number of
109
* subscriptions to this object.
110
* This allows to use this class
111
* for reference counted lifetime
112
* determination where the last one
113
* to unsubscribe also deletes the
116
unsigned int n_subscriptions () const;
119
* List the subscribers to #deallog.
121
void list_subscribers () const;
123
/** @addtogroup Exceptions
128
* Object may not be deleted, since
131
DeclException3(ExcInUse,
132
int, char*, std::string&,
133
<< "Object of class " << arg2
134
<< " is still used by " << arg1 << " other objects."
138
* A subscriber with the
139
* identification string given to
140
* Subscriptor::unsubscribe() did
141
* not subscribe to the object.
143
DeclException2(ExcNoSubscriber, char*, char*,
144
<< "No subscriber with identifier \"" << arg2
145
<< "\" did subscribe to this object of class " << arg1);
148
* Exception: object should be
150
* Subscriptor::unsubscribe() is
153
DeclException0(ExcNotUsed);
158
* Register a subscriber for
159
* debugging purposes. Called by
160
* subscribe() in debug mode.
162
void do_subscribe(const char* id) const;
165
* Deregister a subscriber for
166
* debugging purposes. Called by
167
* unsubscribe() in debug mode.
169
void do_unsubscribe(const char* id) const;
172
* The data type used in
175
typedef std::map<const char*, unsigned int>::value_type
179
* The iterator type used in
182
typedef std::map<const char*, unsigned int>::iterator
186
* Store the number of objects
187
* which subscribed to this
188
* object. Initialally, this
189
* number is zero, and upon
190
* destruction it shall be zero
191
* again (i.e. all objects which
192
* subscribed should have
193
* unsubscribed again).
195
* The creator (and owner) of an
196
* object is counted in the map
197
* below if HE manages to supply
200
* We use the <tt>mutable</tt> keyword
201
* in order to allow subscription
202
* to constant objects also.
204
* In multithreaded mode, this
205
* counter may be modified by
206
* different threads. We thus
208
* <tt>volatile</tt>. However, this is
209
* counter-productive in non-MT
210
* mode since it may pessimize
211
* code. So use the macro
212
* defined above to selectively
215
mutable DEAL_VOLATILE unsigned int counter;
218
* In this map, we count
219
* subscriptions for each
220
* different identification strig
221
* supplied to subscribe().
223
mutable std::map<const char*, unsigned int> counter_map;
226
* Pointer to the typeinfo object
227
* of this object, from which we
228
* can later deduce the class
229
* name. Since this information
230
* on the derived class is
231
* neither available in the
232
* destructor, nor in the
233
* constructor, we obtain it in
234
* between and store it here.
236
mutable const std::type_info * object_info;
239
//---------------------------------------------------------------------------
241
// If we are in optimized mode, the subscription checking is turned
242
// off. Therefore, we provide inline definitions of subscribe and
243
// unsubscribe here. The definitions for debug mode are in
249
Subscriptor::subscribe(const char* id) const
256
Subscriptor::unsubscribe(const char* id) const
264
Subscriptor::subscribe(const char*) const
269
Subscriptor::unsubscribe(const char*) const
273
DEAL_II_NAMESPACE_CLOSE