Reference documentation for deal.II version GIT 0b65fff18a 2023-09-27 19:30:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
smartpointer.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2021 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_smartpointer_h
17 #define dealii_smartpointer_h
18 
19 
20 #include <deal.II/base/config.h>
21 
23 
24 #include <atomic>
25 #include <typeinfo>
26 
28 
66 template <typename T, typename P = void>
68 {
69 public:
75 
80  template <class Q>
82 
88 
97  SmartPointer(T *t, const std::string &id);
98 
106 
111 
119  operator=(T *tt);
120 
125  template <class Q>
128 
135 
139  void
140  clear();
141 
145  operator T *() const;
146 
151  T &
152  operator*() const;
153 
158  T *
159  get() const;
160 
165  T *
166  operator->() const;
167 
177  template <class Q>
178  void
180 
189  void
190  swap(T *&tt);
191 
197  std::size_t
199 
200 private:
206  T *t;
207 
211  const std::string id;
212 
217  std::atomic<bool> pointed_to_object_is_alive;
218 };
219 
220 
221 /* --------------------- inline Template functions ------------------------- */
222 
223 
224 template <typename T, typename P>
226  : t(nullptr)
227  , id(typeid(P).name())
228  , pointed_to_object_is_alive(false)
229 {}
230 
231 
232 
233 template <typename T, typename P>
235  : t(t)
236  , id(typeid(P).name())
237  , pointed_to_object_is_alive(false)
238 {
239  if (t != nullptr)
240  t->subscribe(&pointed_to_object_is_alive, id);
241 }
242 
243 
244 
245 template <typename T, typename P>
246 inline SmartPointer<T, P>::SmartPointer(T *t, const std::string &id)
247  : t(t)
248  , id(id)
249  , pointed_to_object_is_alive(false)
250 {
251  if (t != nullptr)
252  t->subscribe(&pointed_to_object_is_alive, id);
253 }
254 
255 
256 
257 template <typename T, typename P>
258 template <class Q>
260  : t(tt.t)
261  , id(tt.id)
262  , pointed_to_object_is_alive(false)
263 {
264  if (tt.pointed_to_object_is_alive && t != nullptr)
265  t->subscribe(&pointed_to_object_is_alive, id);
266 }
267 
268 
269 
270 template <typename T, typename P>
272  : t(tt.t)
273  , id(tt.id)
274  , pointed_to_object_is_alive(false)
275 {
276  if (tt.pointed_to_object_is_alive && t != nullptr)
277  t->subscribe(&pointed_to_object_is_alive, id);
278 }
279 
280 
281 
282 template <typename T, typename P>
284 {
285  if (pointed_to_object_is_alive && t != nullptr)
286  t->unsubscribe(&pointed_to_object_is_alive, id);
287 }
288 
289 
290 
291 template <typename T, typename P>
292 inline void
294 {
295  if (pointed_to_object_is_alive && t != nullptr)
296  {
297  t->unsubscribe(&pointed_to_object_is_alive, id);
298  delete t;
299  Assert(pointed_to_object_is_alive == false, ExcInternalError());
300  }
301  t = nullptr;
302 }
303 
304 
305 
306 template <typename T, typename P>
307 inline SmartPointer<T, P> &
309 {
310  // optimize if no real action is
311  // requested
312  if (t == tt)
313  return *this;
314 
315  if (pointed_to_object_is_alive && t != nullptr)
316  t->unsubscribe(&pointed_to_object_is_alive, id);
317  t = tt;
318  if (tt != nullptr)
319  tt->subscribe(&pointed_to_object_is_alive, id);
320  return *this;
321 }
322 
323 
324 
325 template <typename T, typename P>
326 template <class Q>
327 inline SmartPointer<T, P> &
329 {
330  // if objects on the left and right
331  // hand side of the operator= are
332  // the same, then this is a no-op
333  if (&tt == this)
334  return *this;
335 
336  if (pointed_to_object_is_alive && t != nullptr)
337  t->unsubscribe(&pointed_to_object_is_alive, id);
338  t = static_cast<T *>(tt);
339  if (tt.pointed_to_object_is_alive && tt != nullptr)
340  tt->subscribe(&pointed_to_object_is_alive, id);
341  return *this;
342 }
343 
344 
345 
346 template <typename T, typename P>
347 inline SmartPointer<T, P> &
349 {
350  // if objects on the left and right
351  // hand side of the operator= are
352  // the same, then this is a no-op
353  if (&tt == this)
354  return *this;
355 
356  if (pointed_to_object_is_alive && t != nullptr)
357  t->unsubscribe(&pointed_to_object_is_alive, id);
358  t = static_cast<T *>(tt);
359  if (tt.pointed_to_object_is_alive && tt != nullptr)
360  tt->subscribe(&pointed_to_object_is_alive, id);
361  return *this;
362 }
363 
364 
365 
366 template <typename T, typename P>
368 {
369  return t;
370 }
371 
372 
373 
374 template <typename T, typename P>
375 inline T &
377 {
378  Assert(t != nullptr, ExcNotInitialized());
379  Assert(pointed_to_object_is_alive,
380  ExcMessage("The object pointed to is not valid anymore."));
381  return *t;
382 }
383 
384 
385 
386 template <typename T, typename P>
387 inline T *
389 {
390  Assert(t != nullptr, ExcNotInitialized());
391  Assert(pointed_to_object_is_alive,
392  ExcMessage("The object pointed to is not valid anymore."));
393  return t;
394 }
395 
396 
397 
398 template <typename T, typename P>
399 inline T *
401 {
402  return this->get();
403 }
404 
405 
406 
407 template <typename T, typename P>
408 template <class Q>
409 inline void
411 {
412 #ifdef DEBUG
413  SmartPointer<T, P> aux(t, id);
414  *this = tt;
415  tt = aux;
416 #else
417  std::swap(t, tt.t);
418 #endif
419 }
420 
421 
422 
423 template <typename T, typename P>
424 inline void
426 {
427  if (pointed_to_object_is_alive && t != nullptr)
428  t->unsubscribe(pointed_to_object_is_alive, id);
429 
430  std::swap(t, tt);
431 
432  if (t != nullptr)
433  t->subscribe(pointed_to_object_is_alive, id);
434 }
435 
436 
437 
438 template <typename T, typename P>
439 inline std::size_t
441 {
442  return sizeof(SmartPointer<T, P>);
443 }
444 
445 
446 
447 // The following function is not strictly necessary but is an optimization
448 // for places where you call swap(p1,p2) with SmartPointer objects p1, p2.
449 // Unfortunately, MS Visual Studio (at least up to the 2013 edition) trips
450 // over it when calling std::swap(v1,v2) where v1,v2 are std::vectors of
451 // SmartPointer objects: it can't determine whether it should call std::swap
452 // or ::swap on the individual elements (see bug #184 on our Google Code
453 // site. Consequently, just take this function out of the competition for this
454 // compiler.
455 #ifndef _MSC_VER
461 template <typename T, typename P, class Q>
462 inline void
464 {
465  t1.swap(t2);
466 }
467 #endif
468 
469 
477 template <typename T, typename P>
478 inline void
480 {
481  t1.swap(t2);
482 }
483 
484 
485 
493 template <typename T, typename P>
494 inline void
496 {
497  t2.swap(t1);
498 }
499 
501 
502 #endif
void swap(BlockIndices &u, BlockIndices &v)
SmartPointer(T *t)
Definition: smartpointer.h:234
const std::string id
Definition: smartpointer.h:211
T * operator->() const
Definition: smartpointer.h:400
void swap(SmartPointer< T, Q > &tt)
Definition: smartpointer.h:410
SmartPointer(const SmartPointer< T, P > &tt)
Definition: smartpointer.h:271
SmartPointer< T, P > & operator=(const SmartPointer< T, P > &tt)
Definition: smartpointer.h:348
std::atomic< bool > pointed_to_object_is_alive
Definition: smartpointer.h:217
SmartPointer(const SmartPointer< T, Q > &tt)
Definition: smartpointer.h:259
std::size_t memory_consumption() const
Definition: smartpointer.h:440
T * get() const
Definition: smartpointer.h:388
SmartPointer< T, P > & operator=(const SmartPointer< T, Q > &tt)
Definition: smartpointer.h:328
SmartPointer(T *t, const std::string &id)
Definition: smartpointer.h:246
void swap(T *&tt)
Definition: smartpointer.h:425
SmartPointer< T, P > & operator=(T *tt)
Definition: smartpointer.h:308
T & operator*() const
Definition: smartpointer.h:376
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNotInitialized()
#define Assert(cond, exc)
Definition: exceptions.h:1616
static ::ExceptionBase & ExcMessage(std::string arg1)
static const char T
void swap(SmartPointer< T, P > &t1, SmartPointer< T, Q > &t2)
Definition: smartpointer.h:463