From 872aae6d691b4f6885f3bd9abd3901fe41ccebf2 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 18 Jul 2024 10:14:22 +0200 Subject: [PATCH 01/17] TODO is deprecated --- src/t8_forest/t8_forest.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index c65c2dc14d..1f39894fd4 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -1443,7 +1443,6 @@ t8_forest_copy_trees (t8_forest_t forest, t8_forest_t from, int copy_elements) * such that the element at position i has a smaller id than the given one. * If no such i exists, return -1. */ -/* TODO: should return t8_locidx_t */ static t8_locidx_t t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_linearidx_t element_id, const int maxlevel) { From 3894a690000145668534cc4d5a5a8cf86ba3b257 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 18 Jul 2024 10:32:38 +0200 Subject: [PATCH 02/17] Implemented a bidirectional iterator wrapper for a t8_element_array_t --- src/Makefile.am | 3 +- src/t8_data/t8_element_array_iterator.hxx | 191 ++++++++++++++++++++++ 2 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 src/t8_data/t8_element_array_iterator.hxx diff --git a/src/Makefile.am b/src/Makefile.am index e26283ad46..be80d7d16e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,7 +45,8 @@ libt8_installed_headers_cmesh = \ src/t8_cmesh/t8_cmesh_types.h \ src/t8_cmesh/t8_cmesh_stash.h libt8_installed_headers_data = \ - src/t8_data/t8_shmem.h src/t8_data/t8_containers.h + src/t8_data/t8_shmem.h src/t8_data/t8_containers.h \ + src/t8_data/t8_element_array_iterator.hxx libt8_installed_headers_forest = \ src/t8_forest/t8_forest.h \ src/t8_forest/t8_forest_general.h \ diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx new file mode 100644 index 0000000000..48a6a83a49 --- /dev/null +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -0,0 +1,191 @@ +/* + This file is part of t8code. + t8code is a C library to manage a collection (a forest) of multiple + connected adaptive space-trees of general element classes in parallel. + + Copyright (C) 2015 the developers + + t8code is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + t8code is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with t8code; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/** \file t8_element_array_iterator.hxx + * We define a pseudo-bidirectional-iterator for the t8_element_array that stores elements of a given + * eclass scheme. + */ + +#ifndef T8_ELEMENT_ARRAY_ITERATOR_HXX +#define T8_ELEMENT_ARRAY_ITERATOR_HXX + +#include +#include +#include + +#include +#include + +T8_EXTERN_C_BEGIN (); + +/** + * @brief This struct resembles a bidirectional-iterator wrapper for the content of an \a t8_element_array_t. + * The iterators can be dereferenced in order to receive an \a t8_element_t pointer to the corresponding index. + * These iterators may be used in algorithms of the standard library (e.g. std::lower_bound,...) or to iterate + * through an \a t8_element_array_t. + * Since the actual data is serialized to char-bytes in the underlying array, we have to store an element pointer + * \a dref_element_ resembling the actual (serialized) element withint the iterator class and cannot return a real + * reference of the element pointer residing in the underlying array. Therefore, read-only operations are possible. + */ +class t8_element_array_iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using pointer = t8_element_t**; + using value_type = t8_element_t*; + using reference = t8_element_t*&; + + /* Constructors */ + t8_element_array_iterator () = delete; + t8_element_array_iterator (const t8_element_array_t* element_array, const t8_locidx_t position) + : scheme_ { t8_element_array_get_scheme (element_array) }, array_ { t8_element_array_get_array (element_array) }, + index_ { position } {}; + + /* Copy/Move Constructors/Assignment-Operators */ + t8_element_array_iterator (const t8_element_array_iterator& other) = default; + t8_element_array_iterator& + operator= (const t8_element_array_iterator& other) + = default; + t8_element_array_iterator (t8_element_array_iterator&& other) = default; + t8_element_array_iterator& + operator= (t8_element_array_iterator&& other) + = default; + + /* Destructor */ + ~t8_element_array_iterator () = default; + + /* Dereferencing operator of the iterator wrapper, returning a reference to const of the t8_element_t-pointer to the serialized bytes representing the actual serialized t8_element_t pointer */ + const reference + operator* () + { + T8_ASSERT (index_ >= 0 && static_cast (index_) < array_->elem_count); + dref_element_ = static_cast (t8_sc_array_index_locidx (array_, index_)); + return dref_element_; + }; + + /* Pre- and Postfix increment */ + t8_element_array_iterator& + operator++ () + { + ++index_; + return *this; + }; + t8_element_array_iterator + operator++ (int) + { + t8_element_array_iterator tmp_iterator (*this); + ++(*this); + return tmp_iterator; + }; + + /* Pre- and Postfix decrement */ + t8_element_array_iterator& + operator-- () + { + --index_; + return *this; + }; + t8_element_array_iterator + operator-- (int) + { + t8_element_array_iterator tmp_iterator (*this); + --(*this); + return tmp_iterator; + }; + + /* Return the index within the array the iterator currently points to [0,...,size] */ + t8_locidx_t + GetArrayIndex () const + { + return index_; + }; + + /* Compute the linear id at a given level for the element the iterator points to */ + t8_linearidx_t + GetLinearIDAtLevel (const int level) + { + T8_ASSERT (index_ >= 0 && static_cast (index_) < array_->elem_count); + dref_element_ = static_cast (t8_sc_array_index_locidx (array_, index_)); + return scheme_->t8_element_get_linear_id (dref_element_, level); + }; + + /* Comparison operators */ + friend bool + operator== (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) + { + return (iter1.array_->array == iter2.array_->array && iter1.index_ == iter2.index_); + }; + friend bool + operator!= (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) + { + return (iter1.array_->array != iter2.array_->array || iter1.index_ != iter2.index_); + }; + + /* Arithmetic assignment operators */ + t8_element_array_iterator& + operator+= (const difference_type n) + { + index_ += n; + return *this; + } + t8_element_array_iterator& + operator-= (const difference_type n) + { + index_ -= n; + T8_ASSERT (index_ < 0); + return *this; + } + + private: + const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array */ + const sc_array_t* array_; /*!< A pointer to the actual serialized array of element pointers */ + t8_locidx_t index_ { 0 }; /*!< The index the iterator currently points to */ + t8_element_t* dref_element_; /*!< A helper variable for de-serializing the actual element pointers in the array */ +}; + +/** + * \brief Get an bidirectional iterator to the first element pointer within an element array. + * + * \param[in] element_array The element array from which the begin-bidirectional-iterator should be taken. + * \return t8_element_array_iterator The iterator to the start of the element array. + */ +inline t8_element_array_iterator +t8_element_array_begin (const t8_element_array_t* element_array) +{ + return t8_element_array_iterator (element_array, 0); +} + +/** + * \brief Get an bidirectional iterator to the one after the last element pointer within the array. + * + * \param[in] element_array The element array from which the end-bidirectional-iterator should be taken. + * \return t8_element_array_iterator The iterator to the end of the element array. + */ +inline t8_element_array_iterator +t8_element_array_end (const t8_element_array_t* element_array) +{ + return t8_element_array_iterator (element_array, t8_element_array_get_count (element_array)); +} + +T8_EXTERN_C_END (); + +#endif /* !T8_ELEMENT_ARRAY_ITERATOR_HXX */ From 2beed554b386a0978869de9522b1a1e6ce232a72 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 18 Jul 2024 10:43:03 +0200 Subject: [PATCH 03/17] Replaced the implemented binary search in t8_forest_bin_search_lower by a std::upper_bound search with t8_element_array iterators --- src/t8_forest/t8_forest.cxx | 47 +++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index 1f39894fd4..abb3075c4a 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -43,6 +43,9 @@ #include #include #endif +#include + +#include /* We want to export the whole implementation to be callable from "C" */ T8_EXTERN_C_BEGIN (); @@ -1446,41 +1449,33 @@ t8_forest_copy_trees (t8_forest_t forest, t8_forest_t from, int copy_elements) static t8_locidx_t t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_linearidx_t element_id, const int maxlevel) { - t8_linearidx_t query_id; - t8_locidx_t low, high, guess; - const t8_eclass_scheme_c *ts = t8_element_array_get_scheme (elements); /* At first, we check whether any element has smaller id than the * given one. */ const t8_element_t *query = t8_element_array_index_int (elements, 0); - query_id = ts->t8_element_get_linear_id (query, maxlevel); + const t8_linearidx_t query_id = ts->t8_element_get_linear_id (query, maxlevel); if (query_id > element_id) { /* No element has id smaller than the given one */ return -1; } - /* We now perform the binary search */ - low = 0; - high = t8_element_array_get_count (elements) - 1; - while (low < high) { - guess = (low + high + 1) / 2; - query = t8_element_array_index_int (elements, guess); - query_id = ts->t8_element_get_linear_id (query, maxlevel); - if (query_id == element_id) { - /* we are done */ - return guess; - } - else if (query_id > element_id) { - /* look further left */ - high = guess - 1; - } - else { - /* look further right, but keep guess in the search range */ - low = guess; - } - } - T8_ASSERT (low == high); - return low; + /* A typedef for the value type of the t8_element_array_t iterator */ + using element_ptr_t = t8_element_t *; + + /* We search for the first element in the array that is greater than the given element id */ + auto elem_iter + = std::upper_bound (t8_element_array_begin (elements), t8_element_array_end (elements), element_id, + [&maxlevel, &ts] (const t8_linearidx_t element_id_, const element_ptr_t &elem_ptr) { + const t8_linearidx_t elem_id = ts->t8_element_get_linear_id (elem_ptr, maxlevel); + return (element_id_ < elem_id); + }); + + /* After we found the element with an id greater than the given one, we are able to jump one index back. + * This guarantees us that the element at (index - 1) is smaller or equal to the given element id. + * In case we do not find an element that is greater than the given element_id, we binary search returns + * the end-iterator of the element array. In that case, we want to return the last index from the element + * array. */ + return elem_iter.GetArrayIndex () - 1; } t8_eclass_t From 1c098d207cdf81f5fc8a2c873388a743f238b44c Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 18 Jul 2024 11:43:11 +0200 Subject: [PATCH 04/17] Corrected some comments --- src/t8_data/t8_element_array_iterator.hxx | 14 +++++++------- src/t8_forest/t8_forest.cxx | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 48a6a83a49..31d81a43ef 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -73,7 +73,7 @@ class t8_element_array_iterator { /* Destructor */ ~t8_element_array_iterator () = default; - /* Dereferencing operator of the iterator wrapper, returning a reference to const of the t8_element_t-pointer to the serialized bytes representing the actual serialized t8_element_t pointer */ + /* Dereferencing operator of the iterator wrapper, returning a reference to const of the t8_element_t-pointer to the serialized bytes representing the actual serialized t8_element_t pointer. */ const reference operator* () { @@ -112,14 +112,14 @@ class t8_element_array_iterator { return tmp_iterator; }; - /* Return the index within the array the iterator currently points to [0,...,size] */ + /* Return the index within the array the iterator currently points to [0,...,size]. */ t8_locidx_t GetArrayIndex () const { return index_; }; - /* Compute the linear id at a given level for the element the iterator points to */ + /* Compute the linear id at a given level for the element the iterator points to. */ t8_linearidx_t GetLinearIDAtLevel (const int level) { @@ -156,10 +156,10 @@ class t8_element_array_iterator { } private: - const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array */ - const sc_array_t* array_; /*!< A pointer to the actual serialized array of element pointers */ - t8_locidx_t index_ { 0 }; /*!< The index the iterator currently points to */ - t8_element_t* dref_element_; /*!< A helper variable for de-serializing the actual element pointers in the array */ + const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array. */ + const sc_array_t* array_; /*!< A pointer to the actual serialized array of element pointers. */ + t8_locidx_t index_ { 0 }; /*!< The index the iterator currently points to. */ + t8_element_t* dref_element_; /*!< A helper variable for de-serializing the actual element pointers in the array. */ }; /** diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index abb3075c4a..4a196a3583 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -1441,7 +1441,7 @@ t8_forest_copy_trees (t8_forest_t forest, t8_forest_t from, int copy_elements) } } -/* Search for a linear element id (at forest->maxlevel) in a sorted array of +/** \brief Search for a linear element id (at forest->maxlevel) in a sorted array of * elements. If the element does not exist, return the largest index i * such that the element at position i has a smaller id than the given one. * If no such i exists, return -1. @@ -1455,14 +1455,14 @@ t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_lineari const t8_element_t *query = t8_element_array_index_int (elements, 0); const t8_linearidx_t query_id = ts->t8_element_get_linear_id (query, maxlevel); if (query_id > element_id) { - /* No element has id smaller than the given one */ + /* No element has id smaller than the given one. */ return -1; } - /* A typedef for the value type of the t8_element_array_t iterator */ + /* A typedef for the value type of the t8_element_array_t iterator. */ using element_ptr_t = t8_element_t *; - /* We search for the first element in the array that is greater than the given element id */ + /* We search for the first element in the array that is greater than the given element id. */ auto elem_iter = std::upper_bound (t8_element_array_begin (elements), t8_element_array_end (elements), element_id, [&maxlevel, &ts] (const t8_linearidx_t element_id_, const element_ptr_t &elem_ptr) { @@ -1472,7 +1472,7 @@ t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_lineari /* After we found the element with an id greater than the given one, we are able to jump one index back. * This guarantees us that the element at (index - 1) is smaller or equal to the given element id. - * In case we do not find an element that is greater than the given element_id, we binary search returns + * In case we do not find an element that is greater than the given element_id, the binary search returns * the end-iterator of the element array. In that case, we want to return the last index from the element * array. */ return elem_iter.GetArrayIndex () - 1; From ad4574e1e51f57d73a7ec8a2029b5819aa65e696 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 19 Jul 2024 07:12:50 +0200 Subject: [PATCH 05/17] Removed the t8_element_t* member from the iterator class and let the dereference operator return a value_type instead of a reference type --- src/t8_data/t8_element_array_iterator.hxx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 31d81a43ef..496740ace8 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -74,12 +74,11 @@ class t8_element_array_iterator { ~t8_element_array_iterator () = default; /* Dereferencing operator of the iterator wrapper, returning a reference to const of the t8_element_t-pointer to the serialized bytes representing the actual serialized t8_element_t pointer. */ - const reference + value_type operator* () { T8_ASSERT (index_ >= 0 && static_cast (index_) < array_->elem_count); - dref_element_ = static_cast (t8_sc_array_index_locidx (array_, index_)); - return dref_element_; + return static_cast (t8_sc_array_index_locidx (array_, index_)); }; /* Pre- and Postfix increment */ @@ -124,8 +123,7 @@ class t8_element_array_iterator { GetLinearIDAtLevel (const int level) { T8_ASSERT (index_ >= 0 && static_cast (index_) < array_->elem_count); - dref_element_ = static_cast (t8_sc_array_index_locidx (array_, index_)); - return scheme_->t8_element_get_linear_id (dref_element_, level); + return scheme_->t8_element_get_linear_id (*(*this), level); }; /* Comparison operators */ @@ -159,7 +157,6 @@ class t8_element_array_iterator { const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array. */ const sc_array_t* array_; /*!< A pointer to the actual serialized array of element pointers. */ t8_locidx_t index_ { 0 }; /*!< The index the iterator currently points to. */ - t8_element_t* dref_element_; /*!< A helper variable for de-serializing the actual element pointers in the array. */ }; /** From e462b5157fa71110be4a3cb17ba07df114278609 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 19 Jul 2024 07:17:19 +0200 Subject: [PATCH 06/17] Renamed the array_ member of the iterator class to elements --- src/t8_data/t8_element_array_iterator.hxx | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 496740ace8..97984e2884 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -47,6 +47,12 @@ T8_EXTERN_C_BEGIN (); * reference of the element pointer residing in the underlying array. Therefore, read-only operations are possible. */ class t8_element_array_iterator { + + private: + const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array. */ + const sc_array_t* elements; /*!< A pointer to the actual serialized array of element pointers. */ + t8_locidx_t index_ { 0 }; /*!< The index the iterator currently points to. */ + public: using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; @@ -57,7 +63,7 @@ class t8_element_array_iterator { /* Constructors */ t8_element_array_iterator () = delete; t8_element_array_iterator (const t8_element_array_t* element_array, const t8_locidx_t position) - : scheme_ { t8_element_array_get_scheme (element_array) }, array_ { t8_element_array_get_array (element_array) }, + : scheme_ { t8_element_array_get_scheme (element_array) }, elements { t8_element_array_get_array (element_array) }, index_ { position } {}; /* Copy/Move Constructors/Assignment-Operators */ @@ -77,8 +83,8 @@ class t8_element_array_iterator { value_type operator* () { - T8_ASSERT (index_ >= 0 && static_cast (index_) < array_->elem_count); - return static_cast (t8_sc_array_index_locidx (array_, index_)); + T8_ASSERT (index_ >= 0 && static_cast (index_) < elements->elem_count); + return static_cast (t8_sc_array_index_locidx (elements, index_)); }; /* Pre- and Postfix increment */ @@ -122,7 +128,7 @@ class t8_element_array_iterator { t8_linearidx_t GetLinearIDAtLevel (const int level) { - T8_ASSERT (index_ >= 0 && static_cast (index_) < array_->elem_count); + T8_ASSERT (index_ >= 0 && static_cast (index_) < elements->elem_count); return scheme_->t8_element_get_linear_id (*(*this), level); }; @@ -130,12 +136,12 @@ class t8_element_array_iterator { friend bool operator== (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) { - return (iter1.array_->array == iter2.array_->array && iter1.index_ == iter2.index_); + return (iter1.elements->array == iter2.elements->array && iter1.index_ == iter2.index_); }; friend bool operator!= (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) { - return (iter1.array_->array != iter2.array_->array || iter1.index_ != iter2.index_); + return (iter1.elements->array != iter2.elements->array || iter1.index_ != iter2.index_); }; /* Arithmetic assignment operators */ @@ -152,11 +158,6 @@ class t8_element_array_iterator { T8_ASSERT (index_ < 0); return *this; } - - private: - const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array. */ - const sc_array_t* array_; /*!< A pointer to the actual serialized array of element pointers. */ - t8_locidx_t index_ { 0 }; /*!< The index the iterator currently points to. */ }; /** From 69fdd74c0771733234a3617c476b0411eadeae33 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 19 Jul 2024 07:21:40 +0200 Subject: [PATCH 07/17] Renamed the index_ member of the iterator class to current_index --- src/t8_data/t8_element_array_iterator.hxx | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 97984e2884..c497b9e7f3 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -51,7 +51,7 @@ class t8_element_array_iterator { private: const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array. */ const sc_array_t* elements; /*!< A pointer to the actual serialized array of element pointers. */ - t8_locidx_t index_ { 0 }; /*!< The index the iterator currently points to. */ + t8_locidx_t current_index { 0 }; /*!< The index the iterator currently points to. */ public: using iterator_category = std::bidirectional_iterator_tag; @@ -64,7 +64,7 @@ class t8_element_array_iterator { t8_element_array_iterator () = delete; t8_element_array_iterator (const t8_element_array_t* element_array, const t8_locidx_t position) : scheme_ { t8_element_array_get_scheme (element_array) }, elements { t8_element_array_get_array (element_array) }, - index_ { position } {}; + current_index { position } {}; /* Copy/Move Constructors/Assignment-Operators */ t8_element_array_iterator (const t8_element_array_iterator& other) = default; @@ -83,15 +83,15 @@ class t8_element_array_iterator { value_type operator* () { - T8_ASSERT (index_ >= 0 && static_cast (index_) < elements->elem_count); - return static_cast (t8_sc_array_index_locidx (elements, index_)); + T8_ASSERT (current_index >= 0 && static_cast (current_index) < elements->elem_count); + return static_cast (t8_sc_array_index_locidx (elements, current_index)); }; /* Pre- and Postfix increment */ t8_element_array_iterator& operator++ () { - ++index_; + ++current_index; return *this; }; t8_element_array_iterator @@ -106,7 +106,7 @@ class t8_element_array_iterator { t8_element_array_iterator& operator-- () { - --index_; + --current_index; return *this; }; t8_element_array_iterator @@ -121,14 +121,14 @@ class t8_element_array_iterator { t8_locidx_t GetArrayIndex () const { - return index_; + return current_index; }; /* Compute the linear id at a given level for the element the iterator points to. */ t8_linearidx_t GetLinearIDAtLevel (const int level) { - T8_ASSERT (index_ >= 0 && static_cast (index_) < elements->elem_count); + T8_ASSERT (current_index >= 0 && static_cast (current_index) < elements->elem_count); return scheme_->t8_element_get_linear_id (*(*this), level); }; @@ -136,26 +136,26 @@ class t8_element_array_iterator { friend bool operator== (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) { - return (iter1.elements->array == iter2.elements->array && iter1.index_ == iter2.index_); + return (iter1.elements->array == iter2.elements->array && iter1.current_index == iter2.current_index); }; friend bool operator!= (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) { - return (iter1.elements->array != iter2.elements->array || iter1.index_ != iter2.index_); + return (iter1.elements->array != iter2.elements->array || iter1.current_index != iter2.current_index); }; /* Arithmetic assignment operators */ t8_element_array_iterator& operator+= (const difference_type n) { - index_ += n; + current_index += n; return *this; } t8_element_array_iterator& operator-= (const difference_type n) { - index_ -= n; - T8_ASSERT (index_ < 0); + current_index -= n; + T8_ASSERT (current_index < 0); return *this; } }; From 36cd6a6d3d8baa77b2b023a0297b55b725158ad8 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 19 Jul 2024 07:23:39 +0200 Subject: [PATCH 08/17] Renamed the scheme_ member of the iterator class to scheme --- src/t8_data/t8_element_array_iterator.hxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index c497b9e7f3..81744dc51c 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -49,7 +49,7 @@ T8_EXTERN_C_BEGIN (); class t8_element_array_iterator { private: - const t8_eclass_scheme_c* scheme_; /*!< The scheme of the elements residing within the array. */ + const t8_eclass_scheme_c* scheme; /*!< The scheme of the elements residing within the array. */ const sc_array_t* elements; /*!< A pointer to the actual serialized array of element pointers. */ t8_locidx_t current_index { 0 }; /*!< The index the iterator currently points to. */ @@ -63,7 +63,7 @@ class t8_element_array_iterator { /* Constructors */ t8_element_array_iterator () = delete; t8_element_array_iterator (const t8_element_array_t* element_array, const t8_locidx_t position) - : scheme_ { t8_element_array_get_scheme (element_array) }, elements { t8_element_array_get_array (element_array) }, + : scheme { t8_element_array_get_scheme (element_array) }, elements { t8_element_array_get_array (element_array) }, current_index { position } {}; /* Copy/Move Constructors/Assignment-Operators */ @@ -129,7 +129,7 @@ class t8_element_array_iterator { GetLinearIDAtLevel (const int level) { T8_ASSERT (current_index >= 0 && static_cast (current_index) < elements->elem_count); - return scheme_->t8_element_get_linear_id (*(*this), level); + return scheme->t8_element_get_linear_id (*(*this), level); }; /* Comparison operators */ From cfcafc5c2d4095a299e3d565889f46031e004722 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 19 Jul 2024 07:46:56 +0200 Subject: [PATCH 09/17] Corrected some comments --- src/t8_data/t8_element_array_iterator.hxx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 81744dc51c..fe99f51596 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -38,21 +38,21 @@ T8_EXTERN_C_BEGIN (); /** - * @brief This struct resembles a bidirectional-iterator wrapper for the content of an \a t8_element_array_t. + * \brief This class resembles a bidirectional-iterator wrapper for the content of a \a t8_element_array_t. * The iterators can be dereferenced in order to receive an \a t8_element_t pointer to the corresponding index. * These iterators may be used in algorithms of the standard library (e.g. std::lower_bound,...) or to iterate * through an \a t8_element_array_t. - * Since the actual data is serialized to char-bytes in the underlying array, we have to store an element pointer - * \a dref_element_ resembling the actual (serialized) element withint the iterator class and cannot return a real - * reference of the element pointer residing in the underlying array. Therefore, read-only operations are possible. + * Since the actual data is serialized to char-bytes in the underlying array, we reconstruct a \a t8_element_t pointer + * and let the dereference operator return it as a value_type. Therefore, read-only operations on the + * \a t8_element_array_t are possible. */ class t8_element_array_iterator { - + private: const t8_eclass_scheme_c* scheme; /*!< The scheme of the elements residing within the array. */ - const sc_array_t* elements; /*!< A pointer to the actual serialized array of element pointers. */ - t8_locidx_t current_index { 0 }; /*!< The index the iterator currently points to. */ - + const sc_array_t* elements; /*!< A pointer to the actual serialized array of element pointers. */ + t8_locidx_t current_index { 0 }; /*!< The index the iterator currently points to. */ + public: using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; @@ -79,7 +79,8 @@ class t8_element_array_iterator { /* Destructor */ ~t8_element_array_iterator () = default; - /* Dereferencing operator of the iterator wrapper, returning a reference to const of the t8_element_t-pointer to the serialized bytes representing the actual serialized t8_element_t pointer. */ + /* Dereferencing operator of the iterator wrapper returning a value_type (a t8_element_t-pointer + * casted from the serialized char-bytes in the underlying sc_array_t). */ value_type operator* () { @@ -173,7 +174,7 @@ t8_element_array_begin (const t8_element_array_t* element_array) } /** - * \brief Get an bidirectional iterator to the one after the last element pointer within the array. + * \brief Get an bidirectional iterator to the one after the last element pointer within an element array. * * \param[in] element_array The element array from which the end-bidirectional-iterator should be taken. * \return t8_element_array_iterator The iterator to the end of the element array. From 101f0f6e5cced2eed1e67d2296001e22fcc98270 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 19 Jul 2024 07:49:34 +0200 Subject: [PATCH 10/17] Corrected file description --- src/t8_data/t8_element_array_iterator.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index fe99f51596..53706591cf 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -21,7 +21,7 @@ */ /** \file t8_element_array_iterator.hxx - * We define a pseudo-bidirectional-iterator for the t8_element_array that stores elements of a given + * We define a bidirectional-iterator for a \a t8_element_array_t that stores pointers to elements of a given * eclass scheme. */ From c5803a9c5ebf835048338614fe74cbe1740c0239 Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 22 Jul 2024 08:57:31 +0200 Subject: [PATCH 11/17] Renamed GetArrayIndex function of the element array iterator to GetCurrentIndex --- src/t8_data/t8_element_array_iterator.hxx | 2 +- src/t8_forest/t8_forest.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 53706591cf..a90cae84bf 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -120,7 +120,7 @@ class t8_element_array_iterator { /* Return the index within the array the iterator currently points to [0,...,size]. */ t8_locidx_t - GetArrayIndex () const + GetCurrentIndex () const { return current_index; }; diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index 4a196a3583..b634011fd6 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -1475,7 +1475,7 @@ t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_lineari * In case we do not find an element that is greater than the given element_id, the binary search returns * the end-iterator of the element array. In that case, we want to return the last index from the element * array. */ - return elem_iter.GetArrayIndex () - 1; + return elem_iter.GetCurrentIndex () - 1; } t8_eclass_t From 1487f09505df332ea2a65cad3518d3cea5157140 Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 22 Jul 2024 09:06:40 +0200 Subject: [PATCH 12/17] Reordered functions wihtin the iterator class --- src/t8_data/t8_element_array_iterator.hxx | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index a90cae84bf..386a2ff04d 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -118,21 +118,6 @@ class t8_element_array_iterator { return tmp_iterator; }; - /* Return the index within the array the iterator currently points to [0,...,size]. */ - t8_locidx_t - GetCurrentIndex () const - { - return current_index; - }; - - /* Compute the linear id at a given level for the element the iterator points to. */ - t8_linearidx_t - GetLinearIDAtLevel (const int level) - { - T8_ASSERT (current_index >= 0 && static_cast (current_index) < elements->elem_count); - return scheme->t8_element_get_linear_id (*(*this), level); - }; - /* Comparison operators */ friend bool operator== (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) @@ -159,6 +144,22 @@ class t8_element_array_iterator { T8_ASSERT (current_index < 0); return *this; } + + /* Return the index within the array the iterator currently points to [0,...,size]. */ + t8_locidx_t + GetCurrentIndex () const + { + return current_index; + }; + + /* Compute the linear id at a given level for the element the iterator points to. */ + t8_linearidx_t + GetLinearIDAtLevel (const int level) + { + T8_ASSERT (current_index >= 0 && static_cast (current_index) < elements->elem_count); + return scheme->t8_element_get_linear_id (*(*this), level); + }; + }; /** From c9fb20b4de7411db499e16b872d026dbc64e9fcb Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 22 Jul 2024 09:08:22 +0200 Subject: [PATCH 13/17] Updated comment --- src/t8_data/t8_element_array_iterator.hxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 386a2ff04d..d6de2c0b71 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -21,7 +21,7 @@ */ /** \file t8_element_array_iterator.hxx - * We define a bidirectional-iterator for a \a t8_element_array_t that stores pointers to elements of a given + * We define a bidirectional-iterator wrapping around a \a t8_element_array_t that stores pointers to elements of a given * eclass scheme. */ @@ -159,7 +159,7 @@ class t8_element_array_iterator { T8_ASSERT (current_index >= 0 && static_cast (current_index) < elements->elem_count); return scheme->t8_element_get_linear_id (*(*this), level); }; - + }; /** From 1ae96622a64d1c3a3bb63f2f3c5e8d6317302769 Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 22 Jul 2024 09:08:47 +0200 Subject: [PATCH 14/17] Updated year in copyright notice --- src/t8_data/t8_element_array_iterator.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index d6de2c0b71..12a526be64 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -3,7 +3,7 @@ t8code is a C library to manage a collection (a forest) of multiple connected adaptive space-trees of general element classes in parallel. - Copyright (C) 2015 the developers + Copyright (C) 2024 the developers t8code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 1f11fd4098b39df631c07303c7b0edd214344a67 Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 22 Jul 2024 09:39:14 +0200 Subject: [PATCH 15/17] Switched to a random access iterator --- src/t8_data/t8_element_array_iterator.hxx | 83 ++++++++++++++++++----- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 12a526be64..86ca50ac43 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -35,8 +35,6 @@ #include #include -T8_EXTERN_C_BEGIN (); - /** * \brief This class resembles a bidirectional-iterator wrapper for the content of a \a t8_element_array_t. * The iterators can be dereferenced in order to receive an \a t8_element_t pointer to the corresponding index. @@ -54,7 +52,7 @@ class t8_element_array_iterator { t8_locidx_t current_index { 0 }; /*!< The index the iterator currently points to. */ public: - using iterator_category = std::bidirectional_iterator_tag; + using iterator_category = std::random_access_iterator_tag; using difference_type = std::ptrdiff_t; using pointer = t8_element_t**; using value_type = t8_element_t*; @@ -88,6 +86,13 @@ class t8_element_array_iterator { return static_cast (t8_sc_array_index_locidx (elements, current_index)); }; + value_type + operator[] (const difference_type n) const + { + T8_ASSERT (n >= 0 && static_cast (n) < elements->elem_count); + return static_cast (t8_sc_array_index_locidx (elements, n)); + }; + /* Pre- and Postfix increment */ t8_element_array_iterator& operator++ () @@ -118,6 +123,21 @@ class t8_element_array_iterator { return tmp_iterator; }; + /* Arithmetic assignment operators */ + t8_element_array_iterator& + operator+= (const difference_type n) + { + current_index += n; + return *this; + } + t8_element_array_iterator& + operator-= (const difference_type n) + { + current_index -= n; + T8_ASSERT (current_index < 0); + return *this; + } + /* Comparison operators */ friend bool operator== (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) @@ -129,20 +149,54 @@ class t8_element_array_iterator { { return (iter1.elements->array != iter2.elements->array || iter1.current_index != iter2.current_index); }; + friend bool + operator< (const t8_element_array_iterator& lhs, const t8_element_array_iterator& rhs) + { + T8_ASSERT (lhs.elements->array == rhs.elements->array); + return lhs.current_index < rhs.current_index; + } + friend bool + operator> (const t8_element_array_iterator& lhs, const t8_element_array_iterator& rhs) + { + T8_ASSERT (rhs.elements->array == lhs.elements->array); + return rhs.current_index < lhs.current_index; + } + friend bool + operator<= (const t8_element_array_iterator& lhs, const t8_element_array_iterator& rhs) + { + return !(rhs < lhs); + } + friend bool + operator>= (const t8_element_array_iterator& lhs, const t8_element_array_iterator& rhs) + { + return !(lhs < rhs); + } - /* Arithmetic assignment operators */ - t8_element_array_iterator& - operator+= (const difference_type n) + /* Arithmetic operators */ + friend t8_element_array_iterator + operator+ (const t8_element_array_iterator& iter, const difference_type n) { - current_index += n; - return *this; + t8_element_array_iterator tmp_iterator (iter); + tmp_iterator += n; + return tmp_iterator; } - t8_element_array_iterator& - operator-= (const difference_type n) + friend t8_element_array_iterator + operator+ (const difference_type n, const t8_element_array_iterator& iter) { - current_index -= n; - T8_ASSERT (current_index < 0); - return *this; + return iter + n; + } + friend t8_element_array_iterator + operator- (const t8_element_array_iterator& iter, const difference_type n) + { + t8_element_array_iterator tmp_iterator (iter); + tmp_iterator -= n; + return tmp_iterator; + } + friend difference_type + operator- (const t8_element_array_iterator& lhs, const t8_element_array_iterator& rhs) + { + T8_ASSERT (lhs.elements->array == rhs.elements->array); + return lhs.current_index - rhs.current_index; } /* Return the index within the array the iterator currently points to [0,...,size]. */ @@ -159,7 +213,6 @@ class t8_element_array_iterator { T8_ASSERT (current_index >= 0 && static_cast (current_index) < elements->elem_count); return scheme->t8_element_get_linear_id (*(*this), level); }; - }; /** @@ -186,6 +239,4 @@ t8_element_array_end (const t8_element_array_t* element_array) return t8_element_array_iterator (element_array, t8_element_array_get_count (element_array)); } -T8_EXTERN_C_END (); - #endif /* !T8_ELEMENT_ARRAY_ITERATOR_HXX */ From c3aa8a7c01d35fe26c83b38395272e19c3ddb40c Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 22 Jul 2024 11:16:01 +0200 Subject: [PATCH 16/17] Updated the comments due to the switch to a random access iterator --- src/t8_data/t8_element_array_iterator.hxx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/t8_data/t8_element_array_iterator.hxx b/src/t8_data/t8_element_array_iterator.hxx index 86ca50ac43..269f77a3af 100644 --- a/src/t8_data/t8_element_array_iterator.hxx +++ b/src/t8_data/t8_element_array_iterator.hxx @@ -21,7 +21,7 @@ */ /** \file t8_element_array_iterator.hxx - * We define a bidirectional-iterator wrapping around a \a t8_element_array_t that stores pointers to elements of a given + * We define a Random-Access-Iterator wrapping around a \a t8_element_array_t that stores pointers to elements of a given * eclass scheme. */ @@ -36,10 +36,10 @@ #include /** - * \brief This class resembles a bidirectional-iterator wrapper for the content of a \a t8_element_array_t. - * The iterators can be dereferenced in order to receive an \a t8_element_t pointer to the corresponding index. + * \brief This class resembles a Random-Access-Iterator wrapper for the content of a \a t8_element_array_t. + * The iterator can be dereferenced in order to receive a \a t8_element_t pointer to the corresponding index. * These iterators may be used in algorithms of the standard library (e.g. std::lower_bound,...) or to iterate - * through an \a t8_element_array_t. + * through a \a t8_element_array_t. * Since the actual data is serialized to char-bytes in the underlying array, we reconstruct a \a t8_element_t pointer * and let the dereference operator return it as a value_type. Therefore, read-only operations on the * \a t8_element_array_t are possible. @@ -137,7 +137,6 @@ class t8_element_array_iterator { T8_ASSERT (current_index < 0); return *this; } - /* Comparison operators */ friend bool operator== (const t8_element_array_iterator& iter1, const t8_element_array_iterator& iter2) @@ -216,9 +215,9 @@ class t8_element_array_iterator { }; /** - * \brief Get an bidirectional iterator to the first element pointer within an element array. + * \brief Get an Random-Access-Iterator to the first element pointer within an element array. * - * \param[in] element_array The element array from which the begin-bidirectional-iterator should be taken. + * \param[in] element_array The element array from which the begin()-Random-Access-Iterator should be taken. * \return t8_element_array_iterator The iterator to the start of the element array. */ inline t8_element_array_iterator @@ -228,9 +227,9 @@ t8_element_array_begin (const t8_element_array_t* element_array) } /** - * \brief Get an bidirectional iterator to the one after the last element pointer within an element array. + * \brief Get an Random-Access-Iterator to the one after the last element pointer within an element array. * - * \param[in] element_array The element array from which the end-bidirectional-iterator should be taken. + * \param[in] element_array The element array from which the end()-Random-Access-Iterator should be taken. * \return t8_element_array_iterator The iterator to the end of the element array. */ inline t8_element_array_iterator From 35c05309a7e00aac6e01dcfe582a558e3237c0c2 Mon Sep 17 00:00:00 2001 From: Niklas Date: Mon, 22 Jul 2024 11:18:14 +0200 Subject: [PATCH 17/17] Removed const variable before comparison in upper_bound search --- src/t8_forest/t8_forest.cxx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/t8_forest/t8_forest.cxx b/src/t8_forest/t8_forest.cxx index b634011fd6..00a8747d8c 100644 --- a/src/t8_forest/t8_forest.cxx +++ b/src/t8_forest/t8_forest.cxx @@ -1466,8 +1466,7 @@ t8_forest_bin_search_lower (const t8_element_array_t *elements, const t8_lineari auto elem_iter = std::upper_bound (t8_element_array_begin (elements), t8_element_array_end (elements), element_id, [&maxlevel, &ts] (const t8_linearidx_t element_id_, const element_ptr_t &elem_ptr) { - const t8_linearidx_t elem_id = ts->t8_element_get_linear_id (elem_ptr, maxlevel); - return (element_id_ < elem_id); + return (element_id_ < ts->t8_element_get_linear_id (elem_ptr, maxlevel)); }); /* After we found the element with an id greater than the given one, we are able to jump one index back.