Skip to content

Commit

Permalink
transform_iterator merely input_iterator when not const callable
Browse files Browse the repository at this point in the history
  • Loading branch information
OleErikPeistorpet committed May 26, 2024
1 parent def2962 commit 7736266
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 6 deletions.
2 changes: 1 addition & 1 deletion unit_test/view_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ TEST(viewTest, viewTransformMutableLambda)
auto v = view::transform(dummy, iota);
using I = decltype(v.begin());

static_assert(std::is_same_v<I::iterator_category, std::bidirectional_iterator_tag>);
static_assert(std::is_same_v<I::iterator_category, std::input_iterator_tag>);
#if OEL_STD_RANGES
static_assert(std::input_or_output_iterator<I>);
static_assert(std::ranges::range<decltype(v)>);
Expand Down
12 changes: 7 additions & 5 deletions view/transform_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ class transform_iterator
{
_detail::TightPair< Iterator, typename _detail::AssignableWrap<UnaryFunc>::Type > _m;

static constexpr bool _isBidirectional = iter_is_bidirectional<Iterator>;
inline static constexpr auto _isBidirectional = iter_is_bidirectional<Iterator>;
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<UnaryFunc>,
using iterator_category =
std::conditional_t<
std::is_copy_constructible_v<UnaryFunc> and _isConstCallable,
std::conditional_t<
_isBidirectional,
std::bidirectional_iterator_tag,
Expand All @@ -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);
Expand Down Expand Up @@ -100,7 +102,7 @@ class transform_iterator
(const transform_iterator & left, sentinel_wrapper<S> 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 >
Expand Down

0 comments on commit 7736266

Please sign in to comment.