summaryrefslogtreecommitdiffstats
path: root/base/containers
diff options
context:
space:
mode:
authormdempsky <mdempsky@chromium.org>2014-09-29 11:48:12 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-29 18:48:30 +0000
commitae846887d618ba498e64d79de606c8851e62f6da (patch)
tree3c9ed8e01d17b5bad9ef1b7b2f04c4a0e9147989 /base/containers
parentbddf8dd3c089b6a9065b8d17e410739455143499 (diff)
downloadchromium_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.h50
-rw-r--r--base/containers/adapters_unittest.cc40
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