From b75d8e0b18a64fb0ce11743dc5b4ec28e07a7ce8 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 17 Jul 2026 14:04:27 -0700 Subject: [PATCH] [support] ParentIndexIterator: Add subscript and friend plus operators `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 `ConstraintAnalysis: Remove older redundant constraints` (#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. Are we missing CI testing for stdlib=libc++? --- src/support/parent_index_iterator.h | 11 +++++++++-- test/gtest/inplace_vector.cpp | 12 ++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/support/parent_index_iterator.h b/src/support/parent_index_iterator.h index 8495356eed7..7a4fdb75f99 100644 --- a/src/support/parent_index_iterator.h +++ b/src/support/parent_index_iterator.h @@ -24,8 +24,8 @@ 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. +// equality, inequality, index updates, index differences, and subscripting, +// but not for dereferencing (`operator*` or `operator->`). // // Users of this utility should subclass ParentIndexIterator<...> and define the // following members in the subclass: @@ -96,6 +96,10 @@ template struct ParentIndexIterator { Iterator operator+(difference_type off) const { return Iterator(self()) += off; } + friend Iterator operator+(difference_type off, + const ParentIndexIterator& it) { + return it + off; + } Iterator& operator-=(difference_type off) { index -= off; return self(); @@ -107,6 +111,9 @@ template struct ParentIndexIterator { assert(parent == other.parent); return index - other.index; } + decltype(auto) operator[](difference_type off) const { + return *(self() + off); + } }; } // namespace wasm diff --git a/test/gtest/inplace_vector.cpp b/test/gtest/inplace_vector.cpp index 0f477f0f624..925f439fac1 100644 --- a/test/gtest/inplace_vector.cpp +++ b/test/gtest/inplace_vector.cpp @@ -110,3 +110,15 @@ TEST_F(InplaceVectorTest, Insert) { EXPECT_EQ(vec.size(), 6u); EXPECT_EQ(vec[5], 50); } + +TEST_F(InplaceVectorTest, SortAndIteratorOps) { + inplace_vector vec{40, 10, 50, 20, 30}; + + // Test iterator subscripting and friend operator+ + EXPECT_EQ(vec.begin()[1], 10); + EXPECT_EQ(*(2 + vec.begin()), 50); + + // Test std::sort on inplace_vector iterators + std::sort(vec.begin(), vec.end()); + EXPECT_EQ(vec, (inplace_vector{10, 20, 30, 40, 50})); +}