From 3e4d41ca57de475f4b769320308e80a103c8f5d6 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Tue, 14 Apr 2026 11:56:05 +0200 Subject: [PATCH] Fix operator| conflict with std::ranges (#1395) --- include/etl/ranges.h | 48 ++++++++++++++++++++++++++------------------ test/test_ranges.cpp | 8 ++++++++ 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/include/etl/ranges.h b/include/etl/ranges.h index fe62e06d..4e1ba4b1 100644 --- a/include/etl/ranges.h +++ b/include/etl/ranges.h @@ -735,8 +735,23 @@ namespace etl inline constexpr private_views::repeat repeat; } // namespace views - template - class range_adapter_closure + // Non-template base so ADL finds exactly one operator| definition. + class range_adapter_closure_base + { + // Found via ADL on the RHS (any type that derives from + // range_adapter_closure_base). Placing the operator here instead of at + // global/namespace scope avoids conflicts with std::ranges::operator|. + template > + && etl::is_invocable_v, Range>>> + friend auto operator|(Range&& r, Closure&& c) + { + return etl::forward(c)(etl::forward(r)); + } + }; + + template + class range_adapter_closure : public range_adapter_closure_base { }; @@ -932,7 +947,7 @@ namespace etl { namespace private_views { - struct all + struct all : public range_adapter_closure_base { template < class Range, etl::enable_if_t>, etl::decay_t>, int> = 0> @@ -1422,7 +1437,7 @@ namespace etl { namespace private_views { - struct as_rvalue + struct as_rvalue : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -1501,7 +1516,7 @@ namespace etl { namespace private_views { - struct as_const + struct as_const : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -1726,7 +1741,7 @@ namespace etl { namespace private_views { - struct cache_latest + struct cache_latest : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -1802,7 +1817,7 @@ namespace etl { namespace private_views { - struct reverse + struct reverse : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -2397,7 +2412,7 @@ namespace etl { namespace private_views { - struct join + struct join : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -4244,7 +4259,7 @@ namespace etl { namespace private_views { - struct common + struct common : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -4404,7 +4419,7 @@ namespace etl { namespace private_views { - struct enumerate + struct enumerate : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -4569,7 +4584,7 @@ namespace etl namespace private_views { template - struct elements_fn + struct elements_fn : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -4797,7 +4812,7 @@ namespace etl namespace private_views { template - struct adjacent_fn + struct adjacent_fn : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -6064,7 +6079,7 @@ namespace etl { namespace private_views { - struct to_input + struct to_input : public range_adapter_closure_base { template constexpr auto operator()(Range&& r) const @@ -6152,13 +6167,6 @@ namespace etl namespace views = ranges::views; } // namespace etl -template < class Range, typename RangeAdaptorClosure, typename = etl::enable_if_t>> - -auto operator|(Range&& r, RangeAdaptorClosure rac) -{ - return rac(etl::forward(r)); -} - #endif #endif diff --git a/test/test_ranges.cpp b/test/test_ranges.cpp index fff3d9bc..0fe4c41b 100644 --- a/test/test_ranges.cpp +++ b/test/test_ranges.cpp @@ -37,6 +37,14 @@ SOFTWARE. #include #include +// Issue #1391: include when available to verify etl::operator| +// does not conflict with std::ranges::operator|. +#if ETL_USING_STL && ETL_USING_CPP20 && defined(__has_include) + #if __has_include() + #include + #endif +#endif + #if ETL_USING_CPP17 // C++03 does not support move semantics as used in the ranges library