#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <algorithm>
#include <any>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <boost/core/demangle.hpp>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/vector_memory.h>
--- /dev/null
+// ------------------------------------------------------------------------
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (C) 1998 - 2023 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// Part of the source code is dual licensed under Apache-2.0 WITH
+// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
+// governing the source code and code contributions can be found in
+// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
+//
+// ------------------------------------------------------------------------
+
+#ifndef dealii_enable_ref_counting_by_observer_h
+#define dealii_enable_ref_counting_by_observer_h
+
+
+#include <deal.II/base/config.h>
+
+#include <deal.II/base/exceptions.h>
+
+#include <atomic>
+#include <map>
+#include <mutex>
+#include <string>
+#include <typeinfo>
+#include <vector>
+
+DEAL_II_NAMESPACE_OPEN
+
+/**
+ * Handling of subscriptions.
+ *
+ * This class, as a base class, allows to keep track of other objects using a
+ * specific object. It is used to avoid that pointers that point to an object of
+ * a class derived from EnableRefCountingByObserverPointer are referenced after
+ * that object has been invalidated. Here, invalidation is assumed to happen
+ * when the object is moved from or destroyed. The mechanism works as follows:
+ * The member function subscribe() accepts a pointer to a boolean that is
+ * modified on invalidation. The object that owns this pointer (usually an
+ * object of class type ObserverPointer) is then expected to check the state of
+ * the boolean before trying to access this class.
+ *
+ * The utility of this class is even enhanced by providing identifying strings
+ * to the functions subscribe() and unsubscribe(). These strings are represented
+ * as <code>const char</code> pointers since the underlying buffer comes from
+ * (and is managed by) the run-time type information system: more exactly, these
+ * pointers are the result the function call <code>typeid(x).name()</code> where
+ * <code>x</code> is some object. Therefore, the pointers provided to
+ * subscribe() and to unsubscribe() must be the same. Strings with equal
+ * contents will not be recognized to be the same. The handling in
+ * ObserverPointer will take care of this.
+ * The current subscribers to this class can be obtained by calling
+ * list_subscribers().
+ *
+ * @ingroup memory
+ */
+class EnableRefCountingByObserverPointer
+{
+public:
+ /**
+ * Constructor setting the counter to zero.
+ */
+ EnableRefCountingByObserverPointer();
+
+ /**
+ * Copy-constructor.
+ *
+ * The counter of the copy is zero, since references point to the original
+ * object.
+ */
+ EnableRefCountingByObserverPointer(
+ const EnableRefCountingByObserverPointer &);
+
+ /**
+ * Move constructor.
+ *
+ * An object inheriting from EnableRefCountingByObserverPointer can only be
+ * moved if no other objects are subscribing to it.
+ */
+ EnableRefCountingByObserverPointer(
+ EnableRefCountingByObserverPointer &&) noexcept;
+
+ /**
+ * Destructor, asserting that the counter is zero.
+ */
+ virtual ~EnableRefCountingByObserverPointer();
+
+ /**
+ * Assignment operator.
+ *
+ * This has to be handled with care, too, because the counter has to remain
+ * the same. It therefore does nothing more than returning <tt>*this</tt>.
+ */
+ EnableRefCountingByObserverPointer &
+ operator=(const EnableRefCountingByObserverPointer &);
+
+ /**
+ * Move assignment operator. Only invalidates the object moved from.
+ */
+ EnableRefCountingByObserverPointer &
+ operator=(EnableRefCountingByObserverPointer &&) noexcept;
+
+ /**
+ * @name EnableRefCountingByObserverPointer functionality
+ *
+ * Classes derived from EnableRefCountingByObserverPointer provide a facility
+ * to subscribe to this object. This is mostly used by the ObserverPointer
+ * class.
+ * @{
+ */
+
+ /**
+ * Subscribes a user of the object by storing the pointer @p validity. The
+ * subscriber may be identified by text supplied as @p identifier.
+ */
+ void
+ subscribe(std::atomic<bool> *const validity,
+ const std::string &identifier = "") const;
+
+ /**
+ * Unsubscribes a user from the object.
+ *
+ * @note The @p identifier and the @p validity pointer must be the same as
+ * the one supplied to subscribe().
+ */
+ void
+ unsubscribe(std::atomic<bool> *const validity,
+ const std::string &identifier = "") const;
+
+ /**
+ * Return the present number of subscriptions to this object. This allows to
+ * use this class for reference counted lifetime determination where the
+ * last one to unsubscribe also deletes the object.
+ */
+ unsigned int
+ n_subscriptions() const;
+
+ /**
+ * List the subscribers to the input @p stream.
+ */
+ template <typename StreamType>
+ void
+ list_subscribers(StreamType &stream) const;
+
+ /**
+ * List the subscribers to @p deallog.
+ */
+ void
+ list_subscribers() const;
+
+ /** @} */
+
+ /**
+ * @addtogroup Exceptions
+ * @{
+ */
+
+ /**
+ * Exception: Object may not be deleted, since it is used.
+ */
+ DeclException3(ExcInUse,
+ int,
+ std::string,
+ std::string,
+ << "Object of class " << arg2 << " is still used by " << arg1
+ << " other objects."
+ << "\n\n"
+ << "(Additional information: " << arg3 << ")\n\n"
+ << "See the entry in the Frequently Asked Questions of "
+ << "deal.II (linked to from http://www.dealii.org/) for "
+ << "a lot more information on what this error means and "
+ << "how to fix programs in which it happens.");
+
+ /**
+ * A subscriber with the identification string given to
+ * EnableRefCountingByObserverPointer::unsubscribe() did not subscribe to the
+ * object.
+ */
+ DeclException2(ExcNoSubscriber,
+ std::string,
+ std::string,
+ << "No subscriber with identifier <" << arg2
+ << "> subscribes to this object of class " << arg1
+ << ". Consequently, it cannot be unsubscribed.");
+ /** @} */
+
+ /**
+ * Read or write the data of this object to or from a stream for the purpose
+ * of serialization using the [BOOST serialization
+ * library](https://www.boost.org/doc/libs/1_74_0/libs/serialization/doc/index.html).
+ *
+ * This function does not actually serialize any of the member variables of
+ * this class. The reason is that what this class stores is only who
+ * subscribes to this object, but who does so at the time of storing the
+ * contents of this object does not necessarily have anything to do with who
+ * subscribes to the object when it is restored. Consequently, we do not
+ * want to overwrite the subscribers at the time of restoring, and then
+ * there is no reason to write the subscribers out in the first place.
+ */
+ template <class Archive>
+ void
+ serialize(Archive &ar, const unsigned int version);
+
+private:
+ /**
+ * Store the number of objects which subscribed to this object. Initially,
+ * this number is zero, and upon destruction it shall be zero again (i.e.
+ * all objects which subscribed should have unsubscribed again).
+ *
+ * The creator (and owner) of an object is counted in the map below if HE
+ * manages to supply identification.
+ *
+ * We use the <tt>mutable</tt> keyword in order to allow subscription to
+ * constant objects also.
+ *
+ * This counter may be read from and written to concurrently in
+ * multithreaded code: hence we use the <code>std::atomic</code> class
+ * template.
+ */
+ mutable std::atomic<unsigned int> counter;
+
+ /**
+ * In this map, we count subscriptions for each different identification
+ * string supplied to subscribe().
+ */
+ mutable std::map<std::string, unsigned int> counter_map;
+
+ /**
+ * The data type used in #counter_map.
+ */
+ using map_value_type = decltype(counter_map)::value_type;
+
+ /**
+ * The iterator type used in #counter_map.
+ */
+ using map_iterator = decltype(counter_map)::iterator;
+
+ /**
+ * In this vector, we store pointers to the validity bool in the
+ * ObserverPointer objects that subscribe to this class.
+ */
+ mutable std::vector<std::atomic<bool> *> validity_pointers;
+
+ /**
+ * Pointer to the typeinfo object of this object, from which we can later
+ * deduce the class name. Since this information on the derived class is
+ * neither available in the destructor, nor in the constructor, we obtain it
+ * in between and store it here.
+ */
+ mutable const std::type_info *object_info;
+
+ /**
+ * Check that there are no objects subscribing to this object. If this check
+ * passes then it is safe to destroy the current object. It this check fails
+ * then this function will either abort or print an error message to deallog
+ * (by using the AssertNothrow mechanism), but will not throw an exception.
+ *
+ * @note Since this function is just a consistency check it does nothing in
+ * release mode.
+ *
+ * @note If this function is called when there is an uncaught exception
+ * then, rather than aborting, this function prints an error message to the
+ * standard error stream and returns.
+ */
+ void
+ check_no_subscribers() const noexcept;
+
+ /**
+ * A mutex used to ensure data consistency when accessing the `mutable`
+ * members of this class. This lock is used in the subscribe() and
+ * unsubscribe() functions, as well as in `list_subscribers()`.
+ */
+ static std::mutex mutex;
+};
+
+//---------------------------------------------------------------------------
+
+inline EnableRefCountingByObserverPointer::EnableRefCountingByObserverPointer()
+ : counter(0)
+ , object_info(nullptr)
+{}
+
+
+
+inline EnableRefCountingByObserverPointer::EnableRefCountingByObserverPointer(
+ const EnableRefCountingByObserverPointer &)
+ : counter(0)
+ , object_info(nullptr)
+{}
+
+
+
+inline EnableRefCountingByObserverPointer &
+EnableRefCountingByObserverPointer::operator=(
+ const EnableRefCountingByObserverPointer &s)
+{
+ object_info = s.object_info;
+ return *this;
+}
+
+
+
+inline unsigned int
+EnableRefCountingByObserverPointer::n_subscriptions() const
+{
+ return counter;
+}
+
+
+
+template <class Archive>
+inline void
+EnableRefCountingByObserverPointer::serialize(Archive &, const unsigned int)
+{
+ // do nothing, as explained in the
+ // documentation of this function
+}
+
+template <typename StreamType>
+inline void
+EnableRefCountingByObserverPointer::list_subscribers(StreamType &stream) const
+{
+ std::lock_guard<std::mutex> lock(mutex);
+
+ for (const auto &it : counter_map)
+ stream << it.second << '/' << counter << " subscriptions from \""
+ << it.first << '\"' << std::endl;
+}
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/function_time.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/symmetric_tensor.h>
#include <deal.II/base/tensor.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/thread_local_storage.h>
#include <cmath>
#include <deal.II/base/config.h>
-#include <deal.II/base/subscriptor.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <memory>
#include <vector>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <atomic>
#include <typeinfo>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/patterns.h>
-#include <deal.II/base/subscriptor.h>
#include <boost/archive/basic_archive.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/base/utilities.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <array>
#include <limits>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/point.h>
#include <deal.II/base/polynomial.h>
-#include <deal.II/base/subscriptor.h>
#include <vector>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/point.h>
#include <deal.II/base/polynomial.h>
-#include <deal.II/base/subscriptor.h>
#include <vector>
#include <deal.II/base/config.h>
#include <deal.II/base/array_view.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <array>
#include <memory>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/quadrature.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/distributed/tria.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/function.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/symmetric_tensor.h>
#include <deal.II/base/tensor.h>
#include <deal.II/base/config.h>
#include <deal.II/base/aligned_vector.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/linear_index_iterator.h>
#include <deal.II/base/memory_consumption.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/table_indices.h>
#include <algorithm>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/function.h>
#include <deal.II/base/function_time.h>
#include <deal.II/base/observer_pointer.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <vector>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/mpi_stub.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/distributed/tria_base.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/mpi_stub.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/distributed/p4est_wrappers.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/mpi_stub.h>
#include <deal.II/base/observer_pointer.h>
#include <deal.II/base/partitioner.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/grid/tria.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/memory_consumption.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/block_indices.h>
#include <deal.II/algorithms/general_data_storage.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/std_cxx20/iota_view.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/thread_local_storage.h>
#include <deal.II/base/utilities.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/table.h>
#include <deal.II/base/table_indices.h>
#include <deal.II/base/tensor.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/geometry_info.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/symmetric_tensor.h>
#include <deal.II/base/tensor.h>
#include <deal.II/base/config.h>
#include <deal.II/base/derivative_form.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/point.h>
#include <deal.II/base/quadrature.h>
#include <deal.II/base/std_cxx20/iota_view.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/symmetric_tensor.h>
#include <deal.II/dofs/dof_accessor.h>
#include <deal.II/base/config.h>
#include <deal.II/base/derivative_form.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/point.h>
#include <deal.II/base/quadrature.h>
#include <deal.II/base/std_cxx20/iota_view.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/symmetric_tensor.h>
#include <deal.II/dofs/dof_accessor.h>
#include <deal.II/base/config.h>
#include <deal.II/base/derivative_form.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/point.h>
#include <deal.II/base/quadrature_lib.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/grid/manifold.h>
#include <deal.II/grid/tria.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/fe/mapping.h>
#include <deal.II/base/array_view.h>
#include <deal.II/base/derivative_form.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/point.h>
#include <deal.II/base/quadrature_lib.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/grid/tria.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/utilities.h>
#include <deal.II/grid/manifold.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/geometry_info.h>
#include <deal.II/base/iterator_range.h>
#include <deal.II/base/observer_pointer.h>
#include <deal.II/base/partitioner.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/grid/cell_id.h>
#include <deal.II/grid/cell_status.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/memory_consumption.h>
-#include <deal.II/base/subscriptor.h>
#include <iterator>
#include <memory>
#include <deal.II/base/config.h>
-#include <deal.II/base/subscriptor.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/fe/fe.h>
#include <deal.II/fe/mapping.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/memory_consumption.h>
#include <deal.II/base/quadrature.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/hp/collection.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/index_set.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/table.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/base/thread_local_storage.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/logstream.h>
-#include <deal.II/base/subscriptor.h>
#include <algorithm>
#include <cstddef>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/table.h>
#include <deal.II/lac/block_indices.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/table.h>
#include <deal.II/lac/block_indices.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/memory_consumption.h>
#include <deal.II/base/numbers.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/block_indices.h>
#include <deal.II/lac/exceptions.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/chunk_sparsity_pattern.h>
#include <deal.II/lac/exceptions.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/sparsity_pattern.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/index_set.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/utilities.h>
#include <deal.II/lac/exceptions.h>
#include <deal.II/base/config.h>
#include <deal.II/base/communication_pattern_base.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/memory_space.h>
#include <deal.II/base/memory_space_data.h>
#include <deal.II/base/mpi_stub.h>
#include <deal.II/base/numbers.h>
#include <deal.II/base/parallel.h>
#include <deal.II/base/partitioner.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/read_vector.h>
#include <deal.II/lac/vector_operation.h>
#ifdef DEAL_II_WITH_PETSC
-# include <deal.II/base/subscriptor.h>
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/lac/exceptions.h>
# include <deal.II/lac/full_matrix.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#ifdef DEAL_II_WITH_PETSC
#ifdef DEAL_II_WITH_PETSC
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
# include <deal.II/base/partitioner.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/lac/exceptions.h>
# include <deal.II/lac/petsc_vector_base.h>
#ifdef DEAL_II_WITH_PETSC
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/lac/exceptions.h>
# include <deal.II/lac/vector.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/precondition_block_base.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/memory_consumption.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/householder.h>
#include <deal.II/lac/lapack_full_matrix.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <string>
#include <deal.II/base/aligned_vector.h>
#include <deal.II/base/communication_pattern_base.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/index_set.h>
#include <deal.II/base/memory_consumption.h>
#include <deal.II/base/mpi_stub.h>
#include <deal.II/base/parallel.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/base/types.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/precondition_block_base.h>
#include <deal.II/lac/sparsity_pattern.h>
#include <deal.II/base/config.h>
-#include <deal.II/base/subscriptor.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/solver_control.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/signaling_nan.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/solver.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/logstream.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/base/vectorization.h>
#include <deal.II/base/config.h>
-#include <deal.II/base/subscriptor.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <vector>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/logstream.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/block_vector_base.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/signaling_nan.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/block_vector_base.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/signaling_nan.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/solver.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/logstream.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/solver.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/logstream.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/lac/solver.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/block_sparse_matrix.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/mpi_stub.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/exceptions.h>
#include <deal.II/lac/identity_matrix.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/exceptions.h>
#include <deal.II/base/config.h>
#include <deal.II/base/array_view.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/linear_index_iterator.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/sparsity_pattern_base.h>
#include <deal.II/base/config.h>
#include <deal.II/base/array_view.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <utility>
#include <deal.II/base/config.h>
-#include <deal.II/base/subscriptor.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/lac/lapack_support.h>
#ifdef DEAL_II_WITH_TRILINOS
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
# include <deal.II/base/mpi_stub.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/lac/read_vector.h>
# include <deal.II/lac/trilinos_epetra_communication_pattern.h>
#ifdef DEAL_II_WITH_TRILINOS
-# include <deal.II/base/subscriptor.h>
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/lac/la_parallel_vector.h>
# include <deal.II/lac/trilinos_vector.h>
# ifdef DEAL_II_WITH_TRILINOS
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
# include <deal.II/base/mpi_stub.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/lac/exceptions.h>
# include <deal.II/lac/full_matrix.h>
#ifdef DEAL_II_WITH_TRILINOS
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
# include <deal.II/base/mpi_stub.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/base/utilities.h>
# include <deal.II/lac/exceptions.h>
#ifdef DEAL_II_TRILINOS_WITH_TPETRA
-# include <deal.II/base/subscriptor.h>
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/lac/la_parallel_vector.h>
# include <deal.II/lac/trilinos_tpetra_sparse_matrix.h>
#ifdef DEAL_II_TRILINOS_WITH_TPETRA
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/base/trilinos_utilities.h>
# include <deal.II/lac/sparse_matrix.h>
#ifdef DEAL_II_TRILINOS_WITH_TPETRA
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
# include <deal.II/base/mpi_stub.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/lac/exceptions.h>
# include <deal.II/lac/sparsity_pattern_base.h>
#ifdef DEAL_II_TRILINOS_WITH_TPETRA
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
# include <deal.II/base/mpi_stub.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/lac/read_vector.h>
# include <deal.II/lac/trilinos_tpetra_communication_pattern.h>
#include <deal.II/base/config.h>
#ifdef DEAL_II_WITH_TRILINOS
+# include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
# include <deal.II/base/index_set.h>
# include <deal.II/base/mpi_stub.h>
# include <deal.II/base/partitioner.h>
-# include <deal.II/base/subscriptor.h>
# include <deal.II/lac/exceptions.h>
# include <deal.II/lac/read_vector.h>
#include <deal.II/base/config.h>
#include <deal.II/base/aligned_vector.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/index_set.h>
#include <deal.II/base/numbers.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/read_vector.h>
#include <deal.II/lac/vector_operation.h>
#include <deal.II/base/config.h>
#include <deal.II/base/aligned_vector.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/vectorization.h>
#include <deal.II/fe/fe_nothing.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/vectorization.h>
#include <deal.II/lac/diagonal_matrix.h>
#include <deal.II/base/config.h>
-#include <deal.II/base/subscriptor.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <functional>
#include <string>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/vector.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/mg_level_object.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/lac/affine_constraints.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/mg_level_object.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/distributed/tria.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/point.h>
#include <deal.II/base/quadrature.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/tensor.h>
#include <vector>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/point.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/tensor.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/base/config.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/exceptions.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/base/template_constraints.h>
#include <utility>
#include <deal.II/base/array_view.h>
#include <deal.II/base/bounding_box.h>
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/function.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <deal.II/distributed/tria.h>
//
// ------------------------------------------------------------------------
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/logstream.h>
-#include <deal.II/base/subscriptor.h>
#include <algorithm>
#include <iostream>
// pair for copy and move semantics.
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <iostream>
#include <vector>
// other tests.
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <iostream>
#include <vector>
// std::any object.
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <any>
#include <iostream>
// available after the renaming to ObserverPointer.
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
#include <deal.II/base/smartpointer.h>
-#include <deal.II/base/subscriptor.h>
#include <any>
#include <iostream>
// check that unsubscribing with a wrong id is handled correctly
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <iostream>
#include <vector>
// works as well
+#include <deal.II/base/enable_ref_counting_by_observer_pointer.h>
#include <deal.II/base/observer_pointer.h>
-#include <deal.II/base/subscriptor.h>
#include <iostream>
#include <vector>