Home | History | Annotate | Download | only in containers
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_CONTAINERS_ADAPTERS_H_
      6 #define BASE_CONTAINERS_ADAPTERS_H_
      7 
      8 #include <stddef.h>
      9 
     10 #include <iterator>
     11 
     12 #include "base/macros.h"
     13 
     14 namespace base {
     15 
     16 namespace internal {
     17 
     18 // Internal adapter class for implementing base::Reversed.
     19 template <typename T>
     20 class ReversedAdapter {
     21  public:
     22   using Iterator = decltype(static_cast<T*>(nullptr)->rbegin());
     23 
     24   explicit ReversedAdapter(T& t) : t_(t) {}
     25   ReversedAdapter(const ReversedAdapter& ra) : t_(ra.t_) {}
     26 
     27   // TODO(mdempsky): Once we can use C++14 library features, use std::rbegin
     28   // and std::rend instead, so we can remove the specialization below.
     29   Iterator begin() const { return t_.rbegin(); }
     30   Iterator end() const { return t_.rend(); }
     31 
     32  private:
     33   T& t_;
     34 
     35   DISALLOW_ASSIGN(ReversedAdapter);
     36 };
     37 
     38 template <typename T, size_t N>
     39 class ReversedAdapter<T[N]> {
     40  public:
     41   using Iterator = std::reverse_iterator<T*>;
     42 
     43   explicit ReversedAdapter(T (&t)[N]) : t_(t) {}
     44   ReversedAdapter(const ReversedAdapter& ra) : t_(ra.t_) {}
     45 
     46   Iterator begin() const { return Iterator(&t_[N]); }
     47   Iterator end() const { return Iterator(&t_[0]); }
     48 
     49  private:
     50   T (&t_)[N];
     51 
     52   DISALLOW_ASSIGN(ReversedAdapter);
     53 };
     54 
     55 }  // namespace internal
     56 
     57 // Reversed returns a container adapter usable in a range-based "for" statement
     58 // for iterating a reversible container in reverse order.
     59 //
     60 // Example:
     61 //
     62 //   std::vector<int> v = ...;
     63 //   for (int i : base::Reversed(v)) {
     64 //     // iterates through v from back to front
     65 //   }
     66 template <typename T>
     67 internal::ReversedAdapter<T> Reversed(T& t) {
     68   return internal::ReversedAdapter<T>(t);
     69 }
     70 
     71 }  // namespace base
     72 
     73 #endif  // BASE_CONTAINERS_ADAPTERS_H_
     74