From 02ef6b11d740f5a3aa2071b53b35c306d6ddfa7a Mon Sep 17 00:00:00 2001 From: Thomas Lively <7121787+tlively@users.noreply.github.com> Date: Fri, 21 Jan 2022 11:09:34 -0800 Subject: Create `ParentIndexIterator` to reduce iterator boilerplate (#4469) Add a utility class for defining all the common operations like pre- and post- increment and decrement, addition and subtraction, and assigning addition and subtraction for iterators that are comprised of a parent object and an index into that parent object. Use the new utility to reduce the boilerplate in wasm-type.h. Add a new test of the iterator behavior. --- src/support/parent_index_iterator.h | 96 +++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/support/parent_index_iterator.h (limited to 'src/support') diff --git a/src/support/parent_index_iterator.h b/src/support/parent_index_iterator.h new file mode 100644 index 000000000..1375ab204 --- /dev/null +++ b/src/support/parent_index_iterator.h @@ -0,0 +1,96 @@ +/* + * Copyright 2022 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_support_parent_index_iterator_h +#define wasm_support_parent_index_iterator_h + +#include +#include + +namespace wasm { + +// A helper for defining iterators that contain references to some parent object +// and indices into that parent object. Provides operator implementations for +// equality, inequality, index updates, and index differences, but not for +// dereferencing. +// +// Users of this utility should subclass ParentIndexIterator<...> and define the +// following members in the subclass: +// +// - using value_type = ... +// - using pointer = ... +// - using reference = ... +// - reference operator*() const +// +// `Parent` is the parent type that the iterator contains and is being indexed +// into and `Iterator` is the subclass of ParentIndexIterator<...> that is being +// defined. +template struct ParentIndexIterator { + using iterator_category = std::random_access_iterator_tag; + using difference_type = std::ptrdiff_t; + + Parent parent; + size_t index; + + const Iterator& self() const { return *static_cast(this); } + + Iterator& self() { return *static_cast(this); } + + bool operator==(const Iterator& other) const { + return index == other.index && parent == other.parent; + } + bool operator!=(const Iterator& other) const { return !(*this == other); } + Iterator& operator++() { + ++index; + return self(); + } + Iterator& operator--() { + --index; + return self(); + } + Iterator operator++(int) { + auto it = self(); + index++; + return it; + } + Iterator operator--(int) { + auto it = self(); + index--; + return it; + } + Iterator& operator+=(difference_type off) { + index += off; + return self(); + } + Iterator operator+(difference_type off) const { + return Iterator(self()) += off; + } + Iterator& operator-=(difference_type off) { + index -= off; + return self(); + } + Iterator operator-(difference_type off) const { + return Iterator(self()) -= off; + } + difference_type operator-(const Iterator& other) const { + assert(parent == other.parent); + return index - other.index; + } +}; + +} // namespace wasm + +#endif // wasm_support_parent_index_iterator_h -- cgit v1.2.3