• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ReversedAdapter(T & t)24   explicit ReversedAdapter(T& t) : t_(t) {}
ReversedAdapter(const ReversedAdapter & ra)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.
begin()29   Iterator begin() const { return t_.rbegin(); }
end()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 
ReversedAdapter(T (& t)[N])43   explicit ReversedAdapter(T (&t)[N]) : t_(t) {}
ReversedAdapter(const ReversedAdapter & ra)44   ReversedAdapter(const ReversedAdapter& ra) : t_(ra.t_) {}
45 
begin()46   Iterator begin() const { return Iterator(&t_[N]); }
end()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>
Reversed(T & 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