15#ifndef dealii_smartpointer_h
16#define dealii_smartpointer_h
102template <
typename T,
typename P =
void>
200 operator T *()
const;
264 const std::string
id;
277template <
typename T,
typename P>
280 , id(typeid(P).name())
281 , pointed_to_object_is_alive(false)
283 static_assert(std::is_base_of_v<Subscriptor, T>,
284 "This class can only be used if the first template argument "
285 "is a class derived from 'Subscriptor'.");
290template <
typename T,
typename P>
293 , id(typeid(P).name())
294 , pointed_to_object_is_alive(false)
296 static_assert(std::is_base_of_v<Subscriptor, T>,
297 "This class can only be used if the first template argument "
298 "is a class derived from 'Subscriptor'.");
306template <
typename T,
typename P>
310 , pointed_to_object_is_alive(false)
312 static_assert(std::is_base_of_v<Subscriptor, T>,
313 "This class can only be used if the first template argument "
314 "is a class derived from 'Subscriptor'.");
322template <
typename T,
typename P>
325 : pointer(other.pointer)
327 , pointed_to_object_is_alive(false)
329 static_assert(std::is_base_of_v<Subscriptor, T>,
330 "This class can only be used if the first template argument "
331 "is a class derived from 'Subscriptor'.");
333 if (other !=
nullptr)
336 ExcMessage(
"You can't copy a smart pointer object that "
337 "is pointing to an object that is no longer alive."));
344template <
typename T,
typename P>
346 : pointer(other.pointer)
348 , pointed_to_object_is_alive(false)
350 static_assert(std::is_base_of_v<Subscriptor, T>,
351 "This class can only be used if the first template argument "
352 "is a class derived from 'Subscriptor'.");
354 if (other !=
nullptr)
357 ExcMessage(
"You can't copy a smart pointer object that "
358 "is pointing to an object that is no longer alive."));
365template <
typename T,
typename P>
367 : pointer(other.pointer)
369 , pointed_to_object_is_alive(
false)
371 static_assert(std::is_base_of_v<Subscriptor, T>,
372 "This class can only be used if the first template argument "
373 "is a class derived from 'Subscriptor'.");
375 if (other !=
nullptr)
377 Assert(other.pointed_to_object_is_alive,
378 ExcMessage(
"You can't move a smart pointer object that "
379 "is pointing to an object that is no longer alive."));
383 pointer->subscribe(&pointed_to_object_is_alive,
id);
389 "Calling subscribe() failed with an exception, but we "
390 "are in a function that cannot throw exceptions. "
391 "Aborting the program here."));
402template <
typename T,
typename P>
405 static_assert(std::is_base_of_v<Subscriptor, T>,
406 "This class can only be used if the first template argument "
407 "is a class derived from 'Subscriptor'.");
409 if (pointed_to_object_is_alive && pointer !=
nullptr)
410 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
415template <
typename T,
typename P>
419 if (pointed_to_object_is_alive && pointer !=
nullptr)
421 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
430template <
typename T,
typename P>
439 if (pointed_to_object_is_alive && pointer !=
nullptr)
440 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
445 pointer->subscribe(&pointed_to_object_is_alive,
id);
452template <
typename T,
typename P>
464 if (pointed_to_object_is_alive && pointer !=
nullptr)
465 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
468 pointer = (other !=
nullptr ? other.
get() :
nullptr);
469 if (other !=
nullptr)
472 ExcMessage(
"You can't copy a smart pointer object that "
473 "is pointing to an object that is no longer alive."));
474 pointer->subscribe(&pointed_to_object_is_alive,
id);
481template <
typename T,
typename P>
492 if (pointed_to_object_is_alive && pointer !=
nullptr)
493 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
496 pointer = (other !=
nullptr ? other.
get() :
nullptr);
497 if (other !=
nullptr)
500 ExcMessage(
"You can't copy a smart pointer object that "
501 "is pointing to an object that is no longer alive."));
502 pointer->subscribe(&pointed_to_object_is_alive,
id);
509template <
typename T,
typename P>
513 if (other ==
nullptr)
519 else if (&other !=
this)
522 if (pointer !=
nullptr && pointed_to_object_is_alive)
523 pointer->unsubscribe(&pointed_to_object_is_alive,
id);
526 Assert(other.pointed_to_object_is_alive,
527 ExcMessage(
"You can't move a smart pointer object that "
528 "is pointing to an object that is no longer alive."));
529 pointer = other.get();
532 pointer->subscribe(&pointed_to_object_is_alive,
id);
538 "Calling subscribe() failed with an exception, but we "
539 "are in a function that cannot throw exceptions. "
540 "Aborting the program here."));
551template <
typename T,
typename P>
559template <
typename T,
typename P>
564 Assert(pointed_to_object_is_alive,
565 ExcMessage(
"The object pointed to is not valid anymore."));
571template <
typename T,
typename P>
576 Assert(pointed_to_object_is_alive,
577 ExcMessage(
"The object pointed to is not valid anymore."));
583template <
typename T,
typename P>
592template <
typename T,
typename P>
602 std::swap(pointer, other.
pointer);
608template <
typename T,
typename P>
612 if (pointed_to_object_is_alive && pointer !=
nullptr)
613 pointer->unsubscribe(pointed_to_object_is_alive,
id);
615 std::swap(pointer, ptr);
617 if (pointer !=
nullptr)
618 pointer->subscribe(pointed_to_object_is_alive,
id);
623template <
typename T,
typename P>
646template <
typename T,
typename P,
class Q>
662template <
typename T,
typename P>
678template <
typename T,
typename P>
void swap(SmartPointer< T, Q > &tt)
SmartPointer(const SmartPointer< T, Q > &other)
SmartPointer< T, P > & operator=(const SmartPointer< T, P > &other)
std::atomic< bool > pointed_to_object_is_alive
SmartPointer(const SmartPointer< T, P > &other)
std::size_t memory_consumption() const
SmartPointer< T, P > & operator=(SmartPointer< T, P > &&other) noexcept
SmartPointer< T, P > & operator=(const SmartPointer< T, Q > &other)
SmartPointer(T *t, const std::string &id)
SmartPointer< T, P > & operator=(T *tt)
SmartPointer(SmartPointer< T, P > &&other) noexcept
#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(SmartPointer< T, P > &t1, SmartPointer< T, Q > &t2)