namespace hp
{
+ /**
+ * An iterator for hp::Collection.
+ */
+ template <typename T>
+ class CollectionIterator
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param data The actual data of hp::Collection.
+ * @param index The current index.
+ */
+ CollectionIterator(const std::vector<std::shared_ptr<const T>> &data,
+ const std::size_t index)
+ : data(&data)
+ , index(index)
+ {}
+
+ /**
+ * Compare for equality.
+ */
+ bool
+ operator==(const CollectionIterator<T> &other) const
+ {
+ Assert(
+ this->data == other.data,
+ ExcMessage(
+ "You are trying to compare iterators into different hp::Collection objects."));
+ return this->index == other.index;
+ }
+
+ /**
+ * Compare for inequality.
+ */
+ bool
+ operator!=(const CollectionIterator<T> &other) const
+ {
+ Assert(
+ this->data == other.data,
+ ExcMessage(
+ "You are trying to compare iterators into different hp::Collection objects."));
+ return this->index != other.index;
+ }
+
+ /**
+ * Copy assignment.
+ */
+ CollectionIterator<T> &
+ operator=(const CollectionIterator<T> &other) = default;
+
+ /**
+ * Dereferencing operator: returns the value of the current index.
+ */
+ const T &
+ operator*() const
+ {
+ AssertIndexRange(index, data->size());
+ return *(*data)[index];
+ }
+
+ /**
+ * Prefix <tt>++</tt> operator: <tt>++iterator</tt>. This operator advances
+ * the iterator to the next index and returns a reference to
+ * <tt>*this</tt>.
+ */
+ CollectionIterator<T> &
+ operator++()
+ {
+ AssertIndexRange(index + 1, data->size() + 1);
+ index++;
+ return *this;
+ }
+
+ /**
+ * This operator advances the iterator by @p offset and returns a
+ * reference to <tt>*this</tt>.
+ */
+ CollectionIterator<T> &
+ operator+=(const std::size_t offset)
+ {
+ AssertIndexRange(index + offset, data->size() + 1);
+ index += offset;
+ return *this;
+ }
+
+ /**
+ * Prefix <tt>--</tt> operator: <tt>--iterator</tt>. This operator advances
+ * the iterator to the previous index and returns a reference to
+ * <tt>*this</tt>.
+ */
+ CollectionIterator<T> &
+ operator--()
+ {
+ Assert(
+ index > 0,
+ ExcMessage(
+ "You can't decrement an iterator that is already at the beginning of the range."));
+ --index;
+ return *this;
+ }
+
+ /**
+ * Create new iterator, which is shifted by @p offset.
+ */
+ CollectionIterator<T>
+ operator+(const std::size_t &offset) const
+ {
+ AssertIndexRange(index + offset, T::size() + 1);
+ return CollectionIterator<T>(*data, index + offset);
+ }
+
+ /**
+ * Compute distance between this iterator and iterator @p other.
+ */
+ std::ptrdiff_t
+ operator-(const CollectionIterator<T> &other) const
+ {
+ return static_cast<std::ptrdiff_t>(index) -
+ static_cast<ptrdiff_t>(other.index);
+ }
+
+ private:
+ /**
+ * Pointer to the actual data of hp::Collection.
+ */
+ const std::vector<std::shared_ptr<const T>> *data;
+
+ /**
+ * Current index.
+ */
+ std::size_t index;
+ };
+
/**
* This class implements a collection of objects.
*
std::size_t
memory_consumption() const;
+ /**
+ * @return An iterator pointing to the beginning of the underlying data (`const`
+ * version).
+ */
+ CollectionIterator<T>
+ begin() const;
+
+ /**
+ * @return An iterator pointing to the end of the underlying data (`const`
+ * version).
+ */
+ CollectionIterator<T>
+ end() const;
+
private:
/**
* The real container, which stores pointers to the different objects.
return *entries[index];
}
+
+
+ template <typename T>
+ CollectionIterator<T>
+ Collection<T>::begin() const
+ {
+ return CollectionIterator<T>(entries, 0);
+ }
+
+
+
+ template <typename T>
+ CollectionIterator<T>
+ Collection<T>::end() const
+ {
+ return CollectionIterator<T>(entries, entries.size());
+ }
+
} // namespace hp
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2021 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// Loop over entries of FECollection.
+
+#include <deal.II/fe/fe_q.h>
+
+#include <deal.II/hp/fe_collection.h>
+
+#include "../tests.h"
+
+int
+main()
+{
+ initlog();
+
+ const unsigned int dim = 2;
+
+ hp::FECollection<dim> collection(FE_Q<dim>(1), FE_Q<dim>(2), FE_Q<dim>(3));
+
+ for (const auto &fe : collection)
+ deallog << fe.n_dofs_per_cell() << std::endl;
+
+ return 0;
+}