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)67internal::ReversedAdapter<T> Reversed(T& t) { 68 return internal::ReversedAdapter<T>(t); 69 } 70 71 } // namespace base 72 73 #endif // BASE_CONTAINERS_ADAPTERS_H_ 74