Skip to content

Commit acfdce9

Browse files
authored
[support] ParentIndexIterator: Add subscript and friend plus operators (#8916)
`ParentIndexIterator` declares `using iterator_category =` `std::random_access_iterator_tag;`, but did not provide the subscript operator (`operator[]`) or friend commutative addition (`friend operator+(difference_type, const ParentIndexIterator&)`). When #8912 introduced `std::sort(begin(), end())` on `AndedConstraintSet` (which inherits from `inplace_vector`), building `binaryen` failed on the Chromium `emscripten-releases` macOS builders with: ``` error: type 'wasm::inplace_vector<...>::Iterator' does not provide a subscript operator ``` This failure did not show up on Binaryen's CI because `libstdc++` implements `std::sort` using pointer/iterator addition and dereferencing (`*(first + child)`). In contrast, on macOS with `-stdlib=libc++`, `libc++` implements `std::sort` (`std::__sift_down`) using `__first[__child]` and `__first[__start]`, which requires `operator[]`. This commit adds `decltype(auto) operator[]` and `friend operator+` to `ParentIndexIterator` to satisfy `RandomAccessIterator` requirements.
1 parent 17ed400 commit acfdce9

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

src/support/parent_index_iterator.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ namespace wasm {
2424

2525
// A helper for defining iterators that contain references to some parent object
2626
// and indices into that parent object. Provides operator implementations for
27-
// equality, inequality, index updates, and index differences, but not for
28-
// dereferencing.
27+
// equality, inequality, index updates, index differences, and subscripting,
28+
// but not for dereferencing (`operator*` or `operator->`).
2929
//
3030
// Users of this utility should subclass ParentIndexIterator<...> and define the
3131
// following members in the subclass:
@@ -96,6 +96,10 @@ template<typename Parent, typename Iterator> struct ParentIndexIterator {
9696
Iterator operator+(difference_type off) const {
9797
return Iterator(self()) += off;
9898
}
99+
friend Iterator operator+(difference_type off,
100+
const ParentIndexIterator& it) {
101+
return it + off;
102+
}
99103
Iterator& operator-=(difference_type off) {
100104
index -= off;
101105
return self();
@@ -107,6 +111,9 @@ template<typename Parent, typename Iterator> struct ParentIndexIterator {
107111
assert(parent == other.parent);
108112
return index - other.index;
109113
}
114+
decltype(auto) operator[](difference_type off) const {
115+
return *(self() + off);
116+
}
110117
};
111118

112119
} // namespace wasm

test/gtest/inplace_vector.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,15 @@ TEST_F(InplaceVectorTest, Insert) {
110110
EXPECT_EQ(vec.size(), 6u);
111111
EXPECT_EQ(vec[5], 50);
112112
}
113+
114+
TEST_F(InplaceVectorTest, SortAndIteratorOps) {
115+
inplace_vector<int, 5> vec{40, 10, 50, 20, 30};
116+
117+
// Test iterator subscripting and friend operator+
118+
EXPECT_EQ(vec.begin()[1], 10);
119+
EXPECT_EQ(*(2 + vec.begin()), 50);
120+
121+
// Test std::sort on inplace_vector iterators
122+
std::sort(vec.begin(), vec.end());
123+
EXPECT_EQ(vec, (inplace_vector<int, 5>{10, 20, 30, 40, 50}));
124+
}

0 commit comments

Comments
 (0)