@@ -45,7 +45,6 @@ class proxy_arrow_result {
4545 constexpr T* operator ->() noexcept { return &value_; }
4646};
4747
48-
4948// [iterator.interface.tmpl], class template iterator_interface
5049template <class IteratorConcept ,
5150 class ValueType ,
@@ -141,7 +140,7 @@ struct iter_cat<IteratorConcept, ReferenceType, false> {};
141140
142141template <typename IteratorConcept, typename ReferenceType>
143142struct iter_cat <IteratorConcept, ReferenceType, true > {
144- constexpr static auto compute_category_tag () {
143+ static constexpr auto compute_category_tag () {
145144 if constexpr (!std::is_reference_v<ReferenceType>) {
146145 return std::input_iterator_tag{};
147146 } else if constexpr (std::is_base_of_v<std::random_access_iterator_tag, IteratorConcept>) {
@@ -153,7 +152,7 @@ struct iter_cat<IteratorConcept, ReferenceType, true> {
153152 }
154153 }
155154
156- using TagType = std::invoke_result_t <decltype (compute_category_tag)>;
155+ using TagType = std::invoke_result_t <decltype (compute_category_tag)>;
157156 using iterator_category = TagType;
158157};
159158
@@ -162,13 +161,14 @@ struct iter_cat<IteratorConcept, ReferenceType, true> {
162161template <class IteratorConcept , class ValueType , class Reference , class Pointer , class DifferenceType >
163162class iterator_interface {
164163 public:
165- using iterator_concept = IteratorConcept;
166- using iterator_category = detail::iter_cat < IteratorConcept, Reference,
167- std::derived_from<IteratorConcept, std::forward_iterator_tag>>::iterator_category;
168- using value_type = remove_const_t <ValueType>;
169- using reference = Reference;
170- using pointer = conditional_t <is_same_v<iterator_concept, output_iterator_tag>, void , Pointer>;
171- using difference_type = DifferenceType;
164+ using iterator_concept = IteratorConcept;
165+ using iterator_category =
166+ detail::iter_cat<IteratorConcept, Reference, std::derived_from<IteratorConcept, std::forward_iterator_tag>>::
167+ iterator_category;
168+ using value_type = remove_const_t <ValueType>;
169+ using reference = Reference;
170+ using pointer = conditional_t <is_same_v<iterator_concept, output_iterator_tag>, void , Pointer>;
171+ using difference_type = DifferenceType;
172172
173173 constexpr decltype (auto ) operator*(this auto && self)
174174 requires requires { *iterator_interface_access::base (self); }
@@ -332,9 +332,43 @@ constexpr bool operator==(D1 lhs, D2 rhs)
332332 }
333333}
334334
335+ template <typename Derived,
336+ typename IteratorConcept,
337+ typename ValueType,
338+ typename Reference = ValueType&,
339+ typename Pointer = ValueType*,
340+ typename DifferenceType = std::ptrdiff_t >
341+ using ext_iterator_interface_compat =
342+ iterator_interface<IteratorConcept, ValueType, Reference, Pointer, DifferenceType>;
343+
335344#else
336345
337- using detail::stl_interfaces::iterator_interface;
346+ namespace detail {
347+ template <class >
348+ constexpr bool dependent_false = false ; // workaround before CWG2518/P2593R1
349+ }
350+
351+ template <class IteratorConcept ,
352+ class ValueType ,
353+ class Reference = ValueType&,
354+ class Pointer = ValueType*,
355+ class DifferenceType = std::ptrdiff_t >
356+ class iterator_interface {
357+ static_assert (detail::dependent_false<IteratorConcept>,
358+ " beman.iterator_interface was compiled with "
359+ " BEMAN_ITERATOR_INTERFACE26_USE_DEDUCING_THIS set to FALSE so "
360+ " beman::iterator_interface26::iterator_interface is not available. See "
361+ " beman::iterator_interface26::ext_iterator_interface_compat for a portable alternative." );
362+ };
363+
364+ template <typename Derived,
365+ typename IteratorConcept,
366+ typename ValueType,
367+ typename Reference = ValueType&,
368+ typename Pointer = ValueType*,
369+ typename DifferenceType = std::ptrdiff_t >
370+ using ext_iterator_interface_compat = detail::stl_interfaces::
371+ iterator_interface<Derived, IteratorConcept, ValueType, Reference, Pointer, DifferenceType>;
338372
339373#endif
340374
0 commit comments