[
Example:
template<class ForwardIterator>
void fun(ForwardIterator begin, ForwardIterator end);
list<int> s;
using CI = common_iterator<counted_iterator<list<int>::iterator>, default_sentinel_t>;
fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel));
—
end example ]
namespace std {
template<input_or_output_iterator I, sentinel_for<I> S>
requires (!same_as<I, S> && copyable<I>)
class common_iterator {
public:
constexpr common_iterator() = default;
constexpr common_iterator(I i);
constexpr common_iterator(S s);
template<class I2, class S2>
requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
constexpr common_iterator(const common_iterator<I2, S2>& x);
template<class I2, class S2>
requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
common_iterator& operator=(const common_iterator<I2, S2>& x);
decltype(auto) operator*();
decltype(auto) operator*() const
requires dereferenceable<const I>;
decltype(auto) operator->() const
requires see below;
common_iterator& operator++();
decltype(auto) operator++(int);
template<class I2, sentinel_for<I> S2>
requires sentinel_for<S, I2>
friend bool operator==(
const common_iterator& x, const common_iterator<I2, S2>& y);
template<class I2, sentinel_for<I> S2>
requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
friend bool operator==(
const common_iterator& x, const common_iterator<I2, S2>& y);
template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
requires sized_sentinel_for<S, I2>
friend iter_difference_t<I2> operator-(
const common_iterator& x, const common_iterator<I2, S2>& y);
friend iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
noexcept(noexcept(ranges::iter_move(declval<const I&>())))
requires input_iterator<I>;
template<indirectly_swappable<I> I2, class S2>
friend void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
private:
variant<I, S> v_;
};
template<class I, class S>
struct incrementable_traits<common_iterator<I, S>> {
using difference_type = iter_difference_t<I>;
};
template<input_iterator I, class S>
struct iterator_traits<common_iterator<I, S>> {
using iterator_concept = see below;
using iterator_category = see below;
using value_type = iter_value_t<I>;
using difference_type = iter_difference_t<I>;
using pointer = see below;
using reference = iter_reference_t<I>;
};
}