From d2b0d31a49832cb5527d64659054aac2dbf02377 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 12 Oct 2026 00:22:29 +0530 Subject: [PATCH 1/2] fix: make indexed_range::accessor move constructible libc++ 21 implements std::generate with a lambda that takes the dereferenced iterator by value through an identity projection. This needs an accessible move constructor on the accessor proxy, so indexed_test failed to compile with Apple clang 21. The copy constructor stays private. Assisted-by: ClaudeCode:claude-fable-5-1 --- doc/changelog.qbk | 4 ++++ include/boost/histogram/indexed.hpp | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/changelog.qbk b/doc/changelog.qbk index f4e6fae2..42ebb9c3 100644 --- a/doc/changelog.qbk +++ b/doc/changelog.qbk @@ -7,6 +7,10 @@ [section:changelog Changelog] +[heading Boost 1.93] + +* Make `indexed_range::accessor` move constructible, which is required by `std::generate` in libc++ 21 + [heading Boost 1.89] * Update CMake minimum version and Python detection in CMake diff --git a/include/boost/histogram/indexed.hpp b/include/boost/histogram/indexed.hpp index e3ecaa94..3960ff6f 100644 --- a/include/boost/histogram/indexed.hpp +++ b/include/boost/histogram/indexed.hpp @@ -72,8 +72,8 @@ class BOOST_ATTRIBUTE_NODISCARD indexed_range { with the algorithms of the standard library, the accessor is implicitly convertible to a cell value. Assignments and comparisons are passed through to the cell. An accessor is coupled to its parent indexed_range::iterator. Moving the parent iterator - forward also updates the linked accessor. Accessors are not copyable. They cannot be - stored in containers, but indexed_range::iterator can be stored. + forward also updates the linked accessor. Accessors are movable but not copyable. + They cannot be stored in containers, but indexed_range::iterator can be stored. */ class BOOST_ATTRIBUTE_NODISCARD accessor : detail::mirrored { public: @@ -218,6 +218,9 @@ class BOOST_ATTRIBUTE_NODISCARD indexed_range { operator value_type() const noexcept { return get(); } + // libc++ 21 std::generate binds the dereferenced iterator to a by-value parameter + accessor(accessor&&) = default; + private: accessor(iterator& i) noexcept : iter_(i) {} From 11e8d0e18e4c78a02ea174613094bbe3ec22a822 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 12 Oct 2026 00:27:46 +0530 Subject: [PATCH 2/2] Apply suggestion from @henryiii --- doc/changelog.qbk | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/changelog.qbk b/doc/changelog.qbk index 42ebb9c3..f4e6fae2 100644 --- a/doc/changelog.qbk +++ b/doc/changelog.qbk @@ -7,10 +7,6 @@ [section:changelog Changelog] -[heading Boost 1.93] - -* Make `indexed_range::accessor` move constructible, which is required by `std::generate` in libc++ 21 - [heading Boost 1.89] * Update CMake minimum version and Python detection in CMake