15#ifndef dealii_observer_pointer_h
16#define dealii_observer_pointer_h
104template <
typename T,
typename P =
void>
203 operator T *()
const;
267 const std::string
id;
283template <
typename T,
typename P =
void>
291template <
typename T,
typename P>
294 , id(typeid(P).name())
295 , pointed_to_object_is_alive(false)
297 static_assert(std::is_base_of_v<EnableObserverPointer, T>,
298 "This class can only be used if the first template argument "
299 "is a class derived from 'EnableObserverPointer'.");
304template <
typename T,
typename P>
307 , id(typeid(P).name())
308 , pointed_to_object_is_alive(false)
310 static_assert(std::is_base_of_v<EnableObserverPointer, T>,
311 "This class can only be used if the first template argument "
312 "is a class derived from 'EnableObserverPointer'.");
320template <
typename T,
typename P>
324 , pointed_to_object_is_alive(false)
326 static_assert(std::is_base_of_v<EnableObserverPointer, T>,
327 "This class can only be used if the first template argument "
328 "is a class derived from 'EnableObserverPointer'.");
336template <
typename T,
typename P>
340 : pointer(other.pointer)
342 , pointed_to_object_is_alive(false)
344 static_assert(std::is_base_of_v<EnableObserverPointer, T>,
345 "This class can only be used if the first template argument "
346 "is a class derived from 'EnableObserverPointer'.");
348 if (other !=
nullptr)
351 ExcMessage(
"You can't copy a smart pointer object that "
352 "is pointing to an object that is no longer alive."));
359template <
typename T,
typename P>
362 : pointer(other.pointer)
364 , pointed_to_object_is_alive(false)
366 static_assert(std::is_base_of_v<EnableObserverPointer, T>,
367 "This class can only be used if the first template argument "
368 "is a class derived from 'EnableObserverPointer'.");
370 if (other !=
nullptr)
373 ExcMessage(
"You can't copy a smart pointer object that "
374 "is pointing to an object that is no longer alive."));
381template <
typename T,
typename P>
384 : pointer(other.pointer)
386 , pointed_to_object_is_alive(
false)
388 static_assert(std::is_base_of_v<EnableObserverPointer, T>,
389 "This class can only be used if the first template argument "
390 "is a class derived from 'EnableObserverPointer'.");
392 if (other !=
nullptr)
394 Assert(other.pointed_to_object_is_alive,
395 ExcMessage(
"You can't move a smart pointer object that "
396 "is pointing to an object that is no longer alive."));
400 pointer->subscribe(&pointed_to_object_is_alive,
id);
406 "Calling subscribe() failed with an exception, but we "
407 "are in a function that cannot throw exceptions. "
408 "Aborting the program here."));
419template <
typename T,
typename P>
422 static_assert(std::is_base_of_v<EnableObserverPointer, T>,
423 "This class can only be used if the first template argument "
424 "is a class derived from 'EnableObserverPointer'.");
426 if (pointed_to_object_is_alive && pointer !=
nullptr)
427 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
432template <
typename T,
typename P>
436 if (pointed_to_object_is_alive && pointer !=
nullptr)
438 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
447template <
typename T,
typename P>
456 if (pointed_to_object_is_alive && pointer !=
nullptr)
457 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
462 pointer->subscribe(&pointed_to_object_is_alive,
id);
469template <
typename T,
typename P>
481 if (pointed_to_object_is_alive && pointer !=
nullptr)
482 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
485 pointer = (other !=
nullptr ? other.
get() :
nullptr);
486 if (other !=
nullptr)
489 ExcMessage(
"You can't copy a smart pointer object that "
490 "is pointing to an object that is no longer alive."));
491 pointer->subscribe(&pointed_to_object_is_alive,
id);
498template <
typename T,
typename P>
509 if (pointed_to_object_is_alive && pointer !=
nullptr)
510 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
513 pointer = (other !=
nullptr ? other.
get() :
nullptr);
514 if (other !=
nullptr)
517 ExcMessage(
"You can't copy a smart pointer object that "
518 "is pointing to an object that is no longer alive."));
519 pointer->subscribe(&pointed_to_object_is_alive,
id);
526template <
typename T,
typename P>
530 if (other ==
nullptr)
536 else if (&other !=
this)
539 if (pointer !=
nullptr && pointed_to_object_is_alive)
540 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
543 Assert(other.pointed_to_object_is_alive,
544 ExcMessage(
"You can't move a smart pointer object that "
545 "is pointing to an object that is no longer alive."));
546 pointer = other.get();
549 pointer->subscribe(&pointed_to_object_is_alive,
id);
555 "Calling subscribe() failed with an exception, but we "
556 "are in a function that cannot throw exceptions. "
557 "Aborting the program here."));
568template <
typename T,
typename P>
576template <
typename T,
typename P>
581 Assert(pointed_to_object_is_alive,
582 ExcMessage(
"The object pointed to is not valid anymore."));
588template <
typename T,
typename P>
593 Assert(pointed_to_object_is_alive,
594 ExcMessage(
"The object pointed to is not valid anymore."));
600template <
typename T,
typename P>
609template <
typename T,
typename P>
619 std::swap(pointer, other.
pointer);
625template <
typename T,
typename P>
629 if (pointed_to_object_is_alive && pointer !=
nullptr)
630 pointer->unsubscribe(pointed_to_object_is_alive,
id);
632 std::swap(pointer, ptr);
634 if (pointer !=
nullptr)
635 pointer->subscribe(pointed_to_object_is_alive,
id);
640template <
typename T,
typename P>
663template <
typename T,
typename P,
class Q>
679template <
typename T,
typename P>
695template <
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)