Reference documentation for deal.II version 9.0.0
smartpointer.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2017 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_smartpointer_h
17 #define dealii_smartpointer_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/subscriptor.h>
22 
23 DEAL_II_NAMESPACE_OPEN
24 
62 template <typename T, typename P = void>
64 {
65 public:
70  SmartPointer ();
71 
76  template <class Q>
77  SmartPointer (const SmartPointer<T,Q> &tt);
78 
83  SmartPointer (const SmartPointer<T,P> &tt);
84 
93  SmartPointer (T *t, const char *id);
94 
101  SmartPointer (T *t);
102 
103 
107  ~SmartPointer();
108 
116 
121  template <class Q>
123 
129 
133  void clear ();
134 
138  operator T *() const;
139 
144  T &operator * () const;
145 
150  T *operator -> () const;
151 
161  template <class Q>
162  void swap (SmartPointer<T,Q> &tt);
163 
172  void swap (T *&tt);
173 
179  std::size_t memory_consumption () const;
180 
181 private:
187  T *t;
188 
192  const char *const id;
193 };
194 
195 
196 /* --------------------------- inline Template functions ------------------------------*/
197 
198 
199 template <typename T, typename P>
200 inline
202  :
203  t (nullptr), id(typeid(P).name())
204 {}
205 
206 
207 
208 template <typename T, typename P>
209 inline
211  :
212  t (t), id(typeid(P).name())
213 {
214  if (t != nullptr)
215  t->subscribe(id);
216 }
217 
218 
219 
220 template <typename T, typename P>
221 inline
222 SmartPointer<T,P>::SmartPointer (T *t, const char *id)
223  :
224  t (t), id(id)
225 {
226  if (t != nullptr)
227  t->subscribe(id);
228 }
229 
230 
231 
232 template <typename T, typename P>
233 template <class Q>
234 inline
236  :
237  t (tt.t), id(tt.id)
238 {
239  if (t != nullptr)
240  t->subscribe(id);
241 }
242 
243 
244 
245 template <typename T, typename P>
246 inline
248  :
249  t (tt.t), id(tt.id)
250 {
251  if (t != nullptr)
252  t->subscribe(id);
253 }
254 
255 
256 
257 template <typename T, typename P>
258 inline
260 {
261  if (t != nullptr)
262  t->unsubscribe(id);
263 }
264 
265 
266 
267 template <typename T, typename P>
268 inline
269 void
271 {
272  if (t != nullptr)
273  {
274  t->unsubscribe(id);
275  delete t;
276  t = nullptr;
277  }
278 }
279 
280 
281 
282 template <typename T, typename P>
283 inline
285 {
286  // optimize if no real action is
287  // requested
288  if (t == tt)
289  return *this;
290 
291  if (t != nullptr)
292  t->unsubscribe(id);
293  t = tt;
294  if (tt != nullptr)
295  tt->subscribe(id);
296  return *this;
297 }
298 
299 
300 
301 template <typename T, typename P>
302 template <class Q>
303 inline
306 {
307  // if objects on the left and right
308  // hand side of the operator= are
309  // the same, then this is a no-op
310  if (&tt == this)
311  return *this;
312 
313  if (t != nullptr)
314  t->unsubscribe(id);
315  t = static_cast<T *>(tt);
316  if (tt != nullptr)
317  tt->subscribe(id);
318  return *this;
319 }
320 
321 
322 
323 template <typename T, typename P>
324 inline
327 {
328  // if objects on the left and right
329  // hand side of the operator= are
330  // the same, then this is a no-op
331  if (&tt == this)
332  return *this;
333 
334  if (t != nullptr)
335  t->unsubscribe(id);
336  t = static_cast<T *>(tt);
337  if (tt != nullptr)
338  tt->subscribe(id);
339  return *this;
340 }
341 
342 
343 
344 template <typename T, typename P>
345 inline
347 {
348  return t;
349 }
350 
351 
352 
353 template <typename T, typename P>
354 inline
356 {
357  Assert(t != nullptr, ExcNotInitialized());
358  return *t;
359 }
360 
361 
362 
363 template <typename T, typename P>
364 inline
366 {
367  Assert(t != nullptr, ExcNotInitialized());
368  return t;
369 }
370 
371 
372 
373 template <typename T, typename P>
374 template <class Q>
375 inline
377 {
378 #ifdef DEBUG
379  SmartPointer<T,P> aux(t,id);
380  *this = tt;
381  tt = aux;
382 #else
383  std::swap (t, tt.t);
384 #endif
385 }
386 
387 
388 
389 template <typename T, typename P>
390 inline
392 {
393  if (t != nullptr)
394  t->unsubscribe (id);
395 
396  std::swap (t, tt);
397 
398  if (t != nullptr)
399  t->subscribe (id);
400 }
401 
402 
403 
404 template <typename T, typename P>
405 inline
406 std::size_t
408 {
409  return sizeof(SmartPointer<T,P>);
410 }
411 
412 
413 
414 // The following function is not strictly necessary but is an optimization
415 // for places where you call swap(p1,p2) with SmartPointer objects p1, p2.
416 // Unfortunately, MS Visual Studio (at least up to the 2013 edition) trips
417 // over it when calling std::swap(v1,v2) where v1,v2 are std::vectors of
418 // SmartPointer objects: it can't determine whether it should call std::swap
419 // or ::swap on the individual elements (see bug #184 on our Google Code
420 // site. Consequently, just take this function out of the competition for this
421 // compiler.
422 #ifndef _MSC_VER
423 
428 template <typename T, typename P, class Q>
429 inline
431 {
432  t1.swap (t2);
433 }
434 #endif
435 
436 
444 template <typename T, typename P>
445 inline
446 void swap (SmartPointer<T,P> &t1, T *&t2)
447 {
448  t1.swap (t2);
449 }
450 
451 
452 
460 template <typename T, typename P>
461 inline
462 void swap (T *&t1, SmartPointer<T,P> &t2)
463 {
464  t2.swap (t1);
465 }
466 
467 DEAL_II_NAMESPACE_CLOSE
468 
469 #endif
const char *const id
Definition: smartpointer.h:192
T * operator->() const
Definition: smartpointer.h:365
static ::ExceptionBase & ExcNotInitialized()
void swap(BlockIndices &u, BlockIndices &v)
#define Assert(cond, exc)
Definition: exceptions.h:1142
T & operator*() const
Definition: smartpointer.h:355
void swap(SmartPointer< T, Q > &tt)
Definition: smartpointer.h:376
SmartPointer< T, P > & operator=(T *tt)
Definition: smartpointer.h:284
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1312
std::size_t memory_consumption() const
Definition: smartpointer.h:407