24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.14 Reverse view [range.reverse]

24.7.14.1 Overview [range.reverse.overview]

reverse_­view takes a bidirectional view and produces another view that iterates the same elements in reverse order.
Example
:
vector<int> is {0,1,2,3,4};
reverse_view rv {is};
for (int i : rv)
  cout << i << ' '; // prints: 4 3 2 1 0
— end example
 ]

24.7.14.2 Class template reverse_­view [range.reverse.view]

namespace std::ranges {
  template<view V>
    requires bidirectional_range<V>
  class reverse_view : public view_interface<reverse_view<V>> {
  private:
    V base_ = V();  // exposition only
  public:
    reverse_view() = default;

    constexpr explicit reverse_view(V r);

    template<viewable_range R>
      requires bidirectional_range<R> && constructible_from<V, all_view<R>>
    constexpr explicit reverse_view(R&& r);

    constexpr V base() const& requires copy_constructible<V> { return base_; }
    constexpr V base() && { return std::move(base_); }

    constexpr reverse_iterator<iterator_t<V>> begin();
    constexpr reverse_iterator<iterator_t<V>> begin() requires common_range<V>;
    constexpr reverse_iterator<iterator_t<const V>> begin() const
      requires common_range<const V>;

    constexpr reverse_iterator<iterator_t<V>> end();
    constexpr reverse_iterator<iterator_t<const V>> end() const
      requires common_range<const V>;

    constexpr auto size() requires sized_range<V> {
      return ranges::size(base_);
    }
    constexpr auto size() const requires sized_range<const V> {
      return ranges::size(base_);
    }
  };

  template<class R>
    reverse_view(R&&) -> reverse_view<all_view<R>>;
}
constexpr explicit reverse_view(V base);
Effects: Initializes base_­ with std​::​move(base).
template<viewable_range R> requires bidirectional_range<R> && constructible_from<V, all_view<R>> constexpr explicit reverse_view(R&& r);
Effects: Initializes base_­ with views​::​all(std​::​forward<R>(r)).
constexpr reverse_iterator<iterator_t<V>> begin();
Returns:
make_reverse_iterator(ranges::next(ranges::begin(base_), ranges::end(base_)))
Remarks: In order to provide the amortized constant time complexity required by the range concept, this function caches the result within the reverse_­view for use on subsequent calls.
constexpr reverse_iterator<iterator_t<V>> begin() requires common_range<V>; constexpr reverse_iterator<iterator_t<const V>> begin() const requires common_range<const V>;
Effects: Equivalent to: return make_­reverse_­iterator(ranges​::​end(base_­));
constexpr reverse_iterator<iterator_t<V>> end(); constexpr reverse_iterator<iterator_t<const V>> end() const requires common_range<const V>;
Effects: Equivalent to: return make_­reverse_­iterator(ranges​::​begin(base_­));

24.7.14.3 views​::​reverse [range.reverse.adaptor]

The name views​::​reverse denotes a range adaptor object ([range.adaptor.object]).
For some subexpression E, the expression views​::​reverse(E) is expression-equivalent to:
  • If the type of E is a (possibly cv-qualified) specialization of reverse_­view, equivalent to E.base().
  • Otherwise, if the type of E is cv-qualified
    subrange<reverse_iterator<I>, reverse_iterator<I>, K>
    
    for some iterator type I and value K of type subrange_­kind,
    • if K is subrange_­kind​::​sized, equivalent to:
      subrange<I, I, K>(E.end().base(), E.begin().base(), E.size())
      
    • otherwise, equivalent to:
      subrange<I, I, K>(E.end().base(), E.begin().base())
      
    However, in either case E is evaluated only once.
  • Otherwise, equivalent to reverse_­view{E}.