[move.iterators] (original) (raw)
24 Iterators library [iterators]
24.5 Iterator adaptors [predef.iterators]
24.5.4 Move iterators and sentinels [move.iterators]
24.5.4.1 General [move.iterators.general]
Class template move_iterator is an iterator adaptor with the same behavior as the underlying iterator except that its indirection operator implicitly converts the value returned by the underlying iterator's indirection operator to an rvalue.
Some generic algorithms can be called with move iterators to replace copying with moving.
[Example 1: list<string> s; vector<string> v1(s.begin(), s.end()); vector<string> v2(make_move_iterator(s.begin()), make_move_iterator(s.end())); — _end example_]
24.5.4.2 Class template move_iterator [move.iterator]
namespace std { template<class Iterator> class move_iterator { public: using iterator_type = Iterator;using iterator_concept = see below;using iterator_category = see below; using value_type = iter_value_t<Iterator>;using difference_type = iter_difference_t<Iterator>;using pointer = Iterator;using reference = iter_rvalue_reference_t<Iterator>;constexpr move_iterator();constexpr explicit move_iterator(Iterator i);template<class U> constexpr move_iterator(const move_iterator<U>& u);template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);constexpr const Iterator& base() const & noexcept;constexpr Iterator base() &&;constexpr reference operator*() const;constexpr move_iterator& operator++();constexpr auto operator++(int);constexpr move_iterator& operator--();constexpr move_iterator operator--(int);constexpr move_iterator operator+(difference_type n) const;constexpr move_iterator& operator+=(difference_type n);constexpr move_iterator operator-(difference_type n) const;constexpr move_iterator& operator-=(difference_type n);constexpr reference operator[](difference_type n) const;template<sentinel_for<Iterator> S> friend constexpr bool operator==(const move_iterator& x, const move_sentinel<S>& y);template<sized_sentinel_for<Iterator> S> friend constexpr iter_difference_t<Iterator> operator-(const move_sentinel<S>& x, const move_iterator& y);template<sized_sentinel_for<Iterator> S> friend constexpr iter_difference_t<Iterator> operator-(const move_iterator& x, const move_sentinel<S>& y);friend constexpr iter_rvalue_reference_t<Iterator> iter_move(const move_iterator& i) noexcept(noexcept(ranges::iter_move(i.current)));template<indirectly_swappable<Iterator> Iterator2> friend constexpr void iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y) noexcept(noexcept(ranges::iter_swap(x.current, y.current)));private: Iterator current; };}
The member typedef-name iterator_concept is defined as follows:
- Otherwise, if Iterator models forward_iterator, then iterator_concept denotes forward_iterator_tag.
- Otherwise, iterator_concept denotes input_iterator_tag.
The member typedef-name iterator_category is defined if and only if the qualified-id iterator_traits<Iterator>::iterator_categoryis valid and denotes a type.
In that case, iterator_category denotes
- random_access_iterator_tag if the typeiterator_traits<Iterator>::iterator_category modelsderived_from<random_access_iterator_tag>, and
- iterator_traits<Iterator>::iterator_category otherwise.
24.5.4.4 Construction and assignment [move.iter.cons]
constexpr move_iterator();
Effects: Value-initializes current.
constexpr explicit move_iterator(Iterator i);
Effects: Initializes current with std::move(i).
template<class U> constexpr move_iterator(const move_iterator<U>& u);
Constraints: is_same_v<U, Iterator> is false andconst U& models convertible_to<Iterator>.
Effects: Initializes current with u.current.
template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
Effects: Assigns u.current tocurrent.
24.5.4.5 Conversion [move.iter.op.conv]
constexpr const Iterator& base() const & noexcept;
constexpr Iterator base() &&;
Returns: std::move(current).
24.5.4.6 Element access [move.iter.elem]
constexpr reference operator*() const;
Effects: Equivalent to: return ranges::iter_move(current);
constexpr reference operator[](difference_type n) const;
Effects: Equivalent to: return ranges::iter_move(current + n);
24.5.4.7 Navigation [move.iter.nav]
constexpr move_iterator& operator++();
Effects: As if by ++current.
constexpr auto operator++(int);
Effects: If Iterator models forward_iterator, equivalent to:move_iterator tmp = *this;++current;return tmp;
Otherwise, equivalent to ++current.
constexpr move_iterator& operator--();
Effects: As if by --current.
constexpr move_iterator operator--(int);
Effects: As if by:move_iterator tmp = *this;--current;return tmp;
constexpr move_iterator operator+(difference_type n) const;
Returns: move_iterator(current + n).
constexpr move_iterator& operator+=(difference_type n);
Effects: As if by: current += n;
constexpr move_iterator operator-(difference_type n) const;
Returns: move_iterator(current - n).
constexpr move_iterator& operator-=(difference_type n);
Effects: As if by: current -= n;
24.5.4.8 Comparisons [move.iter.op.comp]
template<class Iterator1, class Iterator2> constexpr bool operator==(const move_iterator<Iterator1>& x,const move_iterator<Iterator2>& y);template<[sentinel_for](iterator.concept.sentinel#concept:sentinel%5Ffor "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<Iterator> S> friend constexpr bool operator==(const move_iterator& x,const move_sentinel<S>& y);
Constraints: x.base() == y.base() is well-formed and convertible to bool.
Returns: x.base() == y.base().
template<class Iterator1, class Iterator2> constexpr bool operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Constraints: x.base() < y.base() is well-formed and convertible to bool.
Returns: x.base() < y.base().
template<class Iterator1, class Iterator2> constexpr bool operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Constraints: y.base() < x.base() is well-formed and convertible to bool.
template<class Iterator1, class Iterator2> constexpr bool operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Constraints: y.base() < x.base() is well-formed and convertible to bool.
template<class Iterator1, class Iterator2> constexpr bool operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Constraints: x.base() < y.base() is well-formed and convertible to bool.
template<class Iterator1, [three_way_comparable_with](cmp.concept#concept:three%5Fway%5Fcomparable%5Fwith "17.12.4 Concept three_way_comparable [cmp.concept]")<Iterator1> Iterator2> constexpr compare_three_way_result_t<Iterator1, Iterator2> operator<=>(const move_iterator<Iterator1>& x,const move_iterator<Iterator2>& y);
Returns: x.base() <=> y.base().
24.5.4.9 Non-member functions [move.iter.nonmember]
template<class Iterator1, class Iterator2> constexpr auto operator-( const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized%5Fsentinel%5Ffor "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<Iterator> S> friend constexpr iter_difference_t<Iterator> operator-(const move_sentinel<S>& x, const move_iterator& y);template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized%5Fsentinel%5Ffor "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<Iterator> S> friend constexpr iter_difference_t<Iterator> operator-(const move_iterator& x, const move_sentinel<S>& y);
Returns: x.base() - y.base().
template<class Iterator> constexpr move_iterator<Iterator> operator+(iter_difference_t<Iterator> n, const move_iterator<Iterator>& x);
Constraints: x.base() + n is well-formed and has type Iterator.
friend constexpr iter_rvalue_reference_t<Iterator> iter_move(const move_iterator& i) noexcept(noexcept(ranges::iter_move(i.current)));
Effects: Equivalent to: return ranges::iter_move(i.current);
template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly%5Fswappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<Iterator> Iterator2> friend constexpr void iter_swap(const move_iterator& x, const move_iterator<Iterator2>& y) noexcept(noexcept(ranges::iter_swap(x.current, y.current)));
Effects: Equivalent to: ranges::iter_swap(x.current, y.current).
template<class Iterator> constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
Returns: move_iterator<Iterator>(std::move(i)).
24.5.4.10 Class template move_sentinel [move.sentinel]
Class template move_sentinel is a sentinel adaptor useful for denoting ranges together with move_iterator.
When an input iterator typeI and sentinel type S model sentinel_for<S, I>,move_sentinel<S> and move_iterator<I> modelsentinel_for<move_sentinel<S>, move_iterator<I>> as well.
[Example 1:
A move_if algorithm is easily implemented withcopy_if using move_iterator and move_sentinel:template<input_iterator I, sentinel_for<I> S, weakly_incrementable O,indirect_unary_predicate<I> Pred> requires indirectly_movable<I, O> void move_if(I first, S last, O out, Pred pred) { ranges::copy_if(move_iterator<I>{std::move(first)}, move_sentinel<S>{last}, std::move(out), pred);}
— _end example_]
namespace std { template<semiregular S> class move_sentinel { public: constexpr move_sentinel();constexpr explicit move_sentinel(S s);template<class S2> requires convertible_to<const S2&, S> constexpr move_sentinel(const move_sentinel<S2>& s);template<class S2> requires assignable_from<S&, const S2&> constexpr move_sentinel& operator=(const move_sentinel<S2>& s);constexpr S base() const;private: S last; };}
24.5.4.11 Operations [move.sent.ops]
constexpr move_sentinel();
Effects: Value-initializes last.
If is_trivially_default_constructible_v<S> is true, then this constructor is a constexpr constructor.
constexpr explicit move_sentinel(S s);
Effects: Initializes last with std::move(s).
template<class S2> requires [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_to [concept.convertible]")<const S2&, S> constexpr move_sentinel(const move_sentinel<S2>& s);
Effects: Initializes last with s.last.
template<class S2> requires [assignable_from](concept.assignable#concept:assignable%5Ffrom "18.4.8 Concept assignable_from [concept.assignable]")<S&, const S2&> constexpr move_sentinel& operator=(const move_sentinel<S2>& s);
Effects: Equivalent to: last = s.last; return *this;
constexpr S base() const;