diff options
author | mdempsky <mdempsky@chromium.org> | 2014-09-29 11:48:12 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-29 18:48:30 +0000 |
commit | ae846887d618ba498e64d79de606c8851e62f6da (patch) | |
tree | 3c9ed8e01d17b5bad9ef1b7b2f04c4a0e9147989 /base/containers | |
parent | bddf8dd3c089b6a9065b8d17e410739455143499 (diff) | |
download | chromium_src-ae846887d618ba498e64d79de606c8851e62f6da.zip chromium_src-ae846887d618ba498e64d79de606c8851e62f6da.tar.gz chromium_src-ae846887d618ba498e64d79de606c8851e62f6da.tar.bz2 |
Add base::Reversed() as an adapter for range-based for loops in reverse
See also https://groups.google.com/a/chromium.org/d/msg/chromium-dev/utDItV2a7aE/IeVDbl5L77cJ
Review URL: https://codereview.chromium.org/605243003
Cr-Commit-Position: refs/heads/master@{#297216}
Diffstat (limited to 'base/containers')
-rw-r--r-- | base/containers/adapters.h | 50 | ||||
-rw-r--r-- | base/containers/adapters_unittest.cc | 40 |
2 files changed, 90 insertions, 0 deletions
diff --git a/base/containers/adapters.h b/base/containers/adapters.h new file mode 100644 index 0000000..cc151fc2 --- /dev/null +++ b/base/containers/adapters.h @@ -0,0 +1,50 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_CONTAINERS_ADAPTERS_H_ +#define BASE_CONTAINERS_ADAPTERS_H_ + +#include "base/macros.h" + +namespace base { + +namespace internal { + +// Internal adapter class for implementing base::Reversed. +template <typename T> +class ReversedAdapter { + public: + typedef decltype(static_cast<T*>(nullptr)->rbegin()) Iterator; + + explicit ReversedAdapter(T& t) : t_(t) {} + ReversedAdapter(const ReversedAdapter& ra) : t_(ra.t_) {} + + Iterator begin() const { return t_.rbegin(); } + Iterator end() const { return t_.rend(); } + + private: + T& t_; + + DISALLOW_ASSIGN(ReversedAdapter); +}; + +} // namespace internal + +// Reversed returns a container adapter usable in a range-based "for" statement +// for iterating a reversible container in reverse order. +// +// Example: +// +// std::vector<int> v = ...; +// for (int i : base::Reversed(v)) { +// // iterates through v from back to front +// } +template <typename T> +internal::ReversedAdapter<T> Reversed(T& t) { + return internal::ReversedAdapter<T>(t); +} + +} // namespace base + +#endif // BASE_CONTAINERS_ADAPTERS_H_ diff --git a/base/containers/adapters_unittest.cc b/base/containers/adapters_unittest.cc new file mode 100644 index 0000000..4c87472 --- /dev/null +++ b/base/containers/adapters_unittest.cc @@ -0,0 +1,40 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/containers/adapters.h" + +#include <vector> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +TEST(AdaptersTest, Reversed) { + std::vector<int> v; + v.push_back(3); + v.push_back(2); + v.push_back(1); + int j = 0; + for (int& i : base::Reversed(v)) { + EXPECT_EQ(++j, i); + i += 100; + } + EXPECT_EQ(103, v[0]); + EXPECT_EQ(102, v[1]); + EXPECT_EQ(101, v[2]); +} + +TEST(AdaptersTest, ConstReversed) { + std::vector<int> v; + v.push_back(3); + v.push_back(2); + v.push_back(1); + const std::vector<int>& cv = v; + int j = 0; + for (int i : base::Reversed(cv)) { + EXPECT_EQ(++j, i); + } +} + +} // namespace |