15#ifndef dealii_observer_pointer_h
16#define dealii_observer_pointer_h
103template <
typename T,
typename P =
void>
201 operator T *()
const;
265 const std::string
id;
281template <
typename T,
typename P =
void>
289template <
typename T,
typename P>
292 , id(typeid(P).name())
293 , pointed_to_object_is_alive(false)
295 static_assert(std::is_base_of_v<Subscriptor, T>,
296 "This class can only be used if the first template argument "
297 "is a class derived from 'Subscriptor'.");
302template <
typename T,
typename P>
305 , id(typeid(P).name())
306 , pointed_to_object_is_alive(false)
308 static_assert(std::is_base_of_v<Subscriptor, T>,
309 "This class can only be used if the first template argument "
310 "is a class derived from 'Subscriptor'.");
318template <
typename T,
typename P>
322 , pointed_to_object_is_alive(false)
324 static_assert(std::is_base_of_v<Subscriptor, T>,
325 "This class can only be used if the first template argument "
326 "is a class derived from 'Subscriptor'.");
334template <
typename T,
typename P>
338 : pointer(other.pointer)
340 , pointed_to_object_is_alive(false)
342 static_assert(std::is_base_of_v<Subscriptor, T>,
343 "This class can only be used if the first template argument "
344 "is a class derived from 'Subscriptor'.");
346 if (other !=
nullptr)
349 ExcMessage(
"You can't copy a smart pointer object that "
350 "is pointing to an object that is no longer alive."));
357template <
typename T,
typename P>
360 : pointer(other.pointer)
362 , pointed_to_object_is_alive(false)
364 static_assert(std::is_base_of_v<Subscriptor, T>,
365 "This class can only be used if the first template argument "
366 "is a class derived from 'Subscriptor'.");
368 if (other !=
nullptr)
371 ExcMessage(
"You can't copy a smart pointer object that "
372 "is pointing to an object that is no longer alive."));
379template <
typename T,
typename P>
382 : pointer(other.pointer)
384 , pointed_to_object_is_alive(
false)
386 static_assert(std::is_base_of_v<Subscriptor, T>,
387 "This class can only be used if the first template argument "
388 "is a class derived from 'Subscriptor'.");
390 if (other !=
nullptr)
392 Assert(other.pointed_to_object_is_alive,
393 ExcMessage(
"You can't move a smart pointer object that "
394 "is pointing to an object that is no longer alive."));
398 pointer->subscribe(&pointed_to_object_is_alive,
id);
404 "Calling subscribe() failed with an exception, but we "
405 "are in a function that cannot throw exceptions. "
406 "Aborting the program here."));
417template <
typename T,
typename P>
420 static_assert(std::is_base_of_v<Subscriptor, T>,
421 "This class can only be used if the first template argument "
422 "is a class derived from 'Subscriptor'.");
424 if (pointed_to_object_is_alive && pointer !=
nullptr)
425 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
430template <
typename T,
typename P>
434 if (pointed_to_object_is_alive && pointer !=
nullptr)
436 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
445template <
typename T,
typename P>
454 if (pointed_to_object_is_alive && pointer !=
nullptr)
455 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
460 pointer->subscribe(&pointed_to_object_is_alive,
id);
467template <
typename T,
typename P>
479 if (pointed_to_object_is_alive && pointer !=
nullptr)
480 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
483 pointer = (other !=
nullptr ? other.
get() :
nullptr);
484 if (other !=
nullptr)
487 ExcMessage(
"You can't copy a smart pointer object that "
488 "is pointing to an object that is no longer alive."));
489 pointer->subscribe(&pointed_to_object_is_alive,
id);
496template <
typename T,
typename P>
507 if (pointed_to_object_is_alive && pointer !=
nullptr)
508 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
511 pointer = (other !=
nullptr ? other.
get() :
nullptr);
512 if (other !=
nullptr)
515 ExcMessage(
"You can't copy a smart pointer object that "
516 "is pointing to an object that is no longer alive."));
517 pointer->subscribe(&pointed_to_object_is_alive,
id);
524template <
typename T,
typename P>
528 if (other ==
nullptr)
534 else if (&other !=
this)
537 if (pointer !=
nullptr && pointed_to_object_is_alive)
538 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
541 Assert(other.pointed_to_object_is_alive,
542 ExcMessage(
"You can't move a smart pointer object that "
543 "is pointing to an object that is no longer alive."));
544 pointer = other.get();
547 pointer->subscribe(&pointed_to_object_is_alive,
id);
553 "Calling subscribe() failed with an exception, but we "
554 "are in a function that cannot throw exceptions. "
555 "Aborting the program here."));
566template <
typename T,
typename P>
574template <
typename T,
typename P>
579 Assert(pointed_to_object_is_alive,
580 ExcMessage(
"The object pointed to is not valid anymore."));
586template <
typename T,
typename P>
591 Assert(pointed_to_object_is_alive,
592 ExcMessage(
"The object pointed to is not valid anymore."));
598template <
typename T,
typename P>
607template <
typename T,
typename P>
617 std::swap(pointer, other.
pointer);
623template <
typename T,
typename P>
627 if (pointed_to_object_is_alive && pointer !=
nullptr)
628 pointer->unsubscribe(pointed_to_object_is_alive,
id);
630 std::swap(pointer, ptr);
632 if (pointer !=
nullptr)
633 pointer->subscribe(pointed_to_object_is_alive,
id);
638template <
typename T,
typename P>
661template <
typename T,
typename P,
class Q>
677template <
typename T,
typename P>
693template <
typename T,
typename P>
std::size_t memory_consumption() const
void swap(ObserverPointer< T, Q > &tt)
std::atomic< bool > pointed_to_object_is_alive
ObserverPointer< T, P > & operator=(const ObserverPointer< T, P > &other)
ObserverPointer< T, P > & operator=(const ObserverPointer< T, Q > &other)
ObserverPointer(const ObserverPointer< T, P > &other)
ObserverPointer< T, P > & operator=(T *tt)
ObserverPointer< T, P > & operator=(ObserverPointer< T, P > &&other) noexcept
ObserverPointer(const ObserverPointer< T, Q > &other)
ObserverPointer(ObserverPointer< T, P > &&other) noexcept
ObserverPointer(T *t, const std::string &id)
#define DEAL_II_DEPRECATED
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
void swap(ObserverPointer< T, P > &t1, ObserverPointer< T, Q > &t2)