6.5 KiB
[common.iterator]
24 Iterators library [iterators]
24.5 Iterator adaptors [predef.iterators]
24.5.5 Common iterators [iterators.common]
24.5.5.1 Class template common_iterator [common.iterator]
Class template common_iterator is an iterator/sentinel adaptor that is capable of representing a non-common range of elements (where the types of the iterator and sentinel differ) as a common range (where they are the same).
It does this by holding either an iterator or a sentinel, and implementing the equality comparison operators appropriately.
[Note 1:
The common_iterator type is useful for interfacing with legacy code that expects the begin and end of a range to have the same type.
â end note]
[Example 1: templatevoid fun(ForwardIterator begin, ForwardIterator end);
list s;// populate the list susing CI = common_iterator<counted_iterator<list::iterator>, default_sentinel_t>;// call fun on a range of 10 ints fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel)); â end example]
namespace std {template<input_or_output_iterator I, sentinel_for S>requires (<I, S> && copyable)class common_iterator {public:constexpr common_iterator() requires default_initializable = 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&>constexpr common_iterator& operator=(const common_iterator<I2, S2>& x); constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() constrequires dereferenceable; constexpr auto operator->() constrequires see below; constexpr common_iterator& operator++(); constexpr decltype(auto) operator++(int); template<class I2, sentinel_for S2>requires sentinel_for<S, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<class I2, sentinel_for S2>requires sentinel_for<S, I2> && equality_comparable_with<I, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<sized_sentinel_for I2, sized_sentinel_for S2>requires sized_sentinel_for<S, I2>friend constexpr iter_difference_t operator-(const common_iterator& x, const common_iterator<I2, S2>& y); friend constexpr decltype(auto) iter_move(const common_iterator& i)noexcept(noexcept(ranges::iter_move(declval<const I&>())))requires input_iterator; template<indirectly_swappable I2, class S2>friend constexpr 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_; // exposition only}; template<class I, class S>struct incrementable_traits<common_iterator<I, S>> {using difference_type = iter_difference_t; }; template<input_iterator I, class S>struct iterator_traits<common_iterator<I, S>> {using iterator_concept = see below; using iterator_category = see below; // not always presentusing value_type = iter_value_t; using difference_type = iter_difference_t; using pointer = see below; using reference = iter_reference_t; };}