Skip to content

Commit b2255e6

Browse files
committed
Address iterator_category failing to compile for input iterators
The wording of P2727R4 states, with respect to the iterator_category type alias: "The nested type iterator_category is defined if and only if IteratorConcept is derived from forward_iterator_tag." Previously, this implementation had attempted to implement this using a class template detail::iter_cat, which had a specialization that contained an iterator_category member type alias which was only enabled if IteratorConcept was derived from std::forward_iterator_tag. However, the iter_category member type alias of iterator_interface itself was specified as detail::iter_cat</* ... */>>::iterator_category, which caused iterator_interface to simply fail to compile if IteratorConcept was not derived from forward_iterator_tag as detail::iter_cat's iterator_category was not found. This commit addresses the issue by removing the iterator_category member type alias from iterator_interface itself and making iterator_interface provide the member type alias by inheriting from detail::iter_cat, which satisfies the requirement in the wording. It also adds a reproducing unit test.
1 parent fed466b commit b2255e6

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

include/beman/iterator_interface/iterator_interface.hpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,17 @@ struct iter_cat<IteratorConcept, ReferenceType, true> {
154154
}
155155
}
156156

157-
using TagType = std::invoke_result_t<decltype(compute_category_tag)>;
158-
using iterator_category = TagType;
157+
using iterator_category = std::invoke_result_t<decltype(compute_category_tag)>;
159158
};
160159

161160
} // namespace detail
162161

163162
template <class IteratorConcept, class ValueType, class Reference, class Pointer, class DifferenceType>
164-
class iterator_interface {
163+
class iterator_interface
164+
: detail::iter_cat<IteratorConcept, Reference, std::derived_from<IteratorConcept, std::forward_iterator_tag>>
165+
{
165166
public:
166167
using iterator_concept = IteratorConcept;
167-
using iterator_category =
168-
detail::iter_cat<IteratorConcept, Reference, std::derived_from<IteratorConcept, std::forward_iterator_tag>>::
169-
iterator_category;
170168
using value_type = remove_const_t<ValueType>;
171169
using reference = Reference;
172170
using pointer = conditional_t<is_same_v<iterator_concept, output_iterator_tag>, void, Pointer>;

tests/beman/iterator_interface/iterator_interface.test.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <gtest/gtest.h>
88

99
#include <algorithm>
10+
#include <iterator>
1011
#include <ranges>
1112

1213
namespace beman {
@@ -119,5 +120,38 @@ TEST(IteratorTest, OperatorArrow) {
119120
ASSERT_EQ(ai->f(), 3);
120121
}
121122

123+
#ifdef __cpp_explicit_this_parameter
124+
125+
struct dummy_input_iterator :
126+
public iterator_interface<
127+
std::input_iterator_tag, int, int const&, void, std::ptrdiff_t> {
128+
constexpr dummy_input_iterator() { }
129+
dummy_input_iterator(dummy_input_iterator const&) = delete;
130+
dummy_input_iterator& operator=(dummy_input_iterator const&) = delete;
131+
dummy_input_iterator(dummy_input_iterator&&) = default;
132+
dummy_input_iterator& operator=(dummy_input_iterator&&) = default;
133+
constexpr reference operator*() const {
134+
return foo;
135+
}
136+
constexpr dummy_input_iterator& operator++() {
137+
return *this;
138+
}
139+
constexpr void operator++(int) {}
140+
141+
friend constexpr bool operator==(std::default_sentinel_t const&,
142+
dummy_input_iterator const&) {
143+
return true;
144+
}
145+
146+
friend beman::iterator_interface::iterator_interface_access;
147+
148+
int foo = 0;
149+
};
150+
151+
static_assert(std::input_iterator<dummy_input_iterator>);
152+
static_assert(!std::forward_iterator<dummy_input_iterator>);
153+
154+
#endif
155+
122156
} // namespace iterator_interface
123157
} // namespace beman

0 commit comments

Comments
 (0)