From 77362661171c77b1a5ab27698f3c2d7c6a11c4c9 Mon Sep 17 00:00:00 2001 From: Ole Erik Peistorpet Date: Sun, 26 May 2024 12:12:05 +0200 Subject: [PATCH] transform_iterator merely input_iterator when not const callable --- unit_test/view_gtest.cpp | 2 +- view/transform_iterator.h | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/unit_test/view_gtest.cpp b/unit_test/view_gtest.cpp index e829428f..ff327c83 100644 --- a/unit_test/view_gtest.cpp +++ b/unit_test/view_gtest.cpp @@ -212,7 +212,7 @@ TEST(viewTest, viewTransformMutableLambda) auto v = view::transform(dummy, iota); using I = decltype(v.begin()); - static_assert(std::is_same_v); + static_assert(std::is_same_v); #if OEL_STD_RANGES static_assert(std::input_or_output_iterator); static_assert(std::ranges::range); diff --git a/view/transform_iterator.h b/view/transform_iterator.h index 3b34f5b5..d97dc955 100644 --- a/view/transform_iterator.h +++ b/view/transform_iterator.h @@ -26,11 +26,13 @@ class transform_iterator { _detail::TightPair< Iterator, typename _detail::AssignableWrap::Type > _m; - static constexpr bool _isBidirectional = iter_is_bidirectional; + inline static constexpr auto _isBidirectional = iter_is_bidirectional; + inline static constexpr auto _isConstCallable = std::is_invocable_v< UnaryFunc const, decltype(*_m.first) >; public: - using iterator_category = std::conditional_t< - std::is_copy_constructible_v, + using iterator_category = + std::conditional_t< + std::is_copy_constructible_v and _isConstCallable, std::conditional_t< _isBidirectional, std::bidirectional_iterator_tag, @@ -50,7 +52,7 @@ class transform_iterator constexpr const Iterator & base() const & noexcept OEL_ALWAYS_INLINE { return _m.first; } constexpr reference operator*() const - OEL_REQUIRES(std::invocable< UnaryFunc const, decltype(*_m.first) >) + OEL_REQUIRES(_isConstCallable) { const UnaryFunc & f = _m.second(); return f(*_m.first); @@ -100,7 +102,7 @@ class transform_iterator (const transform_iterator & left, sentinel_wrapper right) { return left._m.first - right._s; } constexpr bool operator==(const transform_iterator & right) const { return _m.first == right._m.first; } - + // These are not hidden friends because MSC 2017 gives error C3615 constexpr bool operator!=(const transform_iterator & right) const { return _m.first != right._m.first; } template< typename S >