Revision control

Copy as Markdown

// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QITERATORFACADE_P_H
#define QITERATORFACADE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qtconfigmacros.h>
#include <QtCore/qxptype_traits.h>
#include <iterator>
#include <type_traits>
QT_BEGIN_NAMESPACE
namespace QtMultimediaPrivate {
namespace impl {
#if defined(__cpp_concepts)
template <typename T>
concept has_increment = requires(T & t)
{
t.increment();
};
template <typename T>
concept has_decrement = requires(T & t)
{
t.decrement();
};
template <typename T>
concept has_equals = requires(const T &t1, const T &t2)
{
t1.equals(t2);
};
#else
template <typename T>
using increment_expr = decltype(std::declval<T &>().increment());
template <typename T>
using decrement_expr = decltype(std::declval<T &>().decrement());
template <typename T>
using equals_expr = decltype(std::declval<const T &>().equals(std::declval<const T &>()));
template <typename T>
constexpr bool has_increment = qxp::is_detected<increment_expr, T>::value;
template <typename T>
constexpr bool has_decrement = qxp::is_detected<decrement_expr, T>::value;
template <typename T>
constexpr bool has_equals = qxp::is_detected<equals_expr, T>::value;
#endif
} // namespace impl
// CRTP helper that turns a minimal iterator implementation into a full one.
//
// Derived must always implement:
// <value> dereference() const - access the current element
//
// and, for single-pass/forward/bidirectional iteration:
// void increment() - move one step forward
// bool equals(const Derived &o) const - compare iterator positions
// void decrement() - move one step backward (optional; enables operator--)
//
// For random access iteration, Derived may instead (or additionally) implement:
// void advance_by(difference_type n) - move n steps forward (n may be negative)
// difference_type distance_to(const Derived &o) const
// - signed number of steps from *this to o
template <typename Derived, typename ValueType, typename IteratorCategory = std::input_iterator_tag,
typename Reference = ValueType &, typename DifferenceType = std::ptrdiff_t>
class IteratorFacade
{
public:
using iterator_category = IteratorCategory;
using value_type = ValueType;
using reference = Reference;
using difference_type = DifferenceType;
using pointer = std::conditional_t<std::is_reference_v<Reference>,
std::remove_reference_t<Reference> *, void>;
constexpr decltype(auto) operator*() const { return derived().dereference(); }
constexpr Derived &operator++()
{
stepForward();
return derived();
}
constexpr Derived operator++(int)
{
Derived result = derived();
stepForward();
return result;
}
constexpr Derived &operator--()
{
stepBackward();
return derived();
}
constexpr Derived operator--(int)
{
Derived result = derived();
stepBackward();
return result;
}
template <typename N>
#if defined(__cpp_concepts)
requires requires(Derived &d, N n)
{
d.advance_by(n);
}
#endif
constexpr Derived &operator+=(N n)
{
derived().advance_by(n);
return derived();
}
template <typename N>
#if defined(__cpp_concepts)
requires requires(Derived &d, N n)
{
d.advance_by(n);
}
#endif
constexpr Derived &operator-=(N n)
{
derived().advance_by(-n);
return derived();
}
template <typename N>
#if defined(__cpp_concepts)
requires requires(Derived &d, N n)
{
d.advance_by(n);
}
#endif
friend constexpr Derived operator+(Derived it, N n)
{
it.advance_by(n);
return it;
}
template <typename N>
#if defined(__cpp_concepts)
requires requires(Derived &d, N n)
{
d.advance_by(n);
}
#endif
friend constexpr Derived operator+(N n, Derived it)
{
it.advance_by(n);
return it;
}
template <typename N>
#if defined(__cpp_concepts)
requires requires(Derived &d, N n)
{
d.advance_by(n);
}
#endif
friend constexpr Derived operator-(Derived it, N n)
{
it.advance_by(-n);
return it;
}
template <typename N>
#if defined(__cpp_concepts)
requires requires(Derived &d, N n)
{
d.advance_by(n);
}
#endif
friend constexpr Derived operator-(N n, Derived it)
{
it.advance_by(-n);
return it;
}
template <typename N>
#if defined(__cpp_concepts)
requires requires(Derived &d, N n)
{
d.advance_by(n);
}
#endif
constexpr decltype(auto) operator[](N n) const
{
Derived tmp = derived();
tmp.advance_by(n);
return tmp.dereference();
}
friend constexpr auto operator-(const Derived &lhs, const Derived &rhs)
#if defined(__cpp_concepts)
requires requires(const Derived &d)
{
d.distance_to(d);
}
#endif
{
return rhs.distance_to(lhs);
}
friend constexpr bool operator<(const Derived &lhs, const Derived &rhs)
#if defined(__cpp_concepts)
requires requires(const Derived &d)
{
d.distance_to(d);
}
#endif
{
return lhs.distance_to(rhs) > 0;
}
friend constexpr bool operator<=(const Derived &lhs, const Derived &rhs)
#if defined(__cpp_concepts)
requires requires(const Derived &d)
{
d.distance_to(d);
}
#endif
{
return lhs.distance_to(rhs) >= 0;
}
friend constexpr bool operator>(const Derived &lhs, const Derived &rhs)
#if defined(__cpp_concepts)
requires requires(const Derived &d)
{
d.distance_to(d);
}
#endif
{
return lhs.distance_to(rhs) < 0;
}
friend constexpr bool operator>=(const Derived &lhs, const Derived &rhs)
#if defined(__cpp_concepts)
requires requires(const Derived &d)
{
d.distance_to(d);
}
#endif
{
return lhs.distance_to(rhs) <= 0;
}
friend constexpr bool operator==(const Derived &lhs, const Derived &rhs)
{
return lhs.equalsImpl(rhs);
}
friend constexpr bool operator!=(const Derived &lhs, const Derived &rhs)
{
return !lhs.equalsImpl(rhs);
}
private:
constexpr Derived &derived() { return static_cast<Derived &>(*this); }
constexpr const Derived &derived() const { return static_cast<const Derived &>(*this); }
constexpr void stepForward() { stepForwardDispatch<impl::has_increment<Derived>>(); }
template <bool HasIncrement>
constexpr void stepForwardDispatch()
{
if constexpr (HasIncrement)
derived().increment();
else
derived().advance_by(1);
}
constexpr void stepBackward() { stepBackwardDispatch<impl::has_decrement<Derived>>(); }
template <bool HasDecrement>
constexpr void stepBackwardDispatch()
{
if constexpr (HasDecrement)
derived().decrement();
else
derived().advance_by(-1);
}
constexpr bool equalsImpl(const Derived &other) const
{
return equalsDispatch<impl::has_equals<Derived>>(other);
}
template <bool HasEquals>
constexpr bool equalsDispatch(const Derived &other) const
{
if constexpr (HasEquals)
return derived().equals(other);
else
return derived().distance_to(other) == 0;
}
};
} // namespace QtMultimediaPrivate
QT_END_NAMESPACE
#endif // QITERATORFACADE_P_H