2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <folly/Enumerate.h>
22 #include <folly/Range.h>
23 #include <folly/portability/GTest.h>
25 TEST(Enumerate, Basic) {
26 std::vector<std::string> v = {"abc", "a", "ab"};
28 for (auto it : folly::enumerate(v)) {
29 EXPECT_EQ(it.index, i);
31 EXPECT_EQ(it->size(), v[i].size());
34 std::string newValue = "x";
36 EXPECT_EQ(newValue, v[i]);
41 EXPECT_EQ(i, v.size());
44 TEST(Enumerate, Temporary) {
45 std::vector<std::string> v = {"abc", "a", "ab"};
47 for (auto it : folly::enumerate(decltype(v)(v))) { // Copy v.
48 EXPECT_EQ(it.index, i);
50 EXPECT_EQ(it->size(), v[i].size());
54 EXPECT_EQ(i, v.size());
60 struct IsConstReference {
61 constexpr static bool value = false;
64 struct IsConstReference<const T&> {
65 constexpr static bool value = true;
70 TEST(Enumerate, BasicConstArg) {
71 const std::vector<std::string> v = {"abc", "a", "ab"};
73 for (auto it : folly::enumerate(v)) {
75 IsConstReference<decltype(*it)>::value, "Enumerating a const vector");
76 EXPECT_EQ(it.index, i);
78 EXPECT_EQ(it->size(), v[i].size());
82 EXPECT_EQ(i, v.size());
85 TEST(Enumerate, BasicConstEnumerate) {
86 std::vector<std::string> v = {"abc", "a", "ab"};
88 for (const auto it : folly::enumerate(v)) {
89 static_assert(IsConstReference<decltype(*it)>::value, "Const enumeration");
90 EXPECT_EQ(it.index, i);
92 EXPECT_EQ(it->size(), v[i].size());
96 EXPECT_EQ(i, v.size());
99 TEST(Enumerate, TemporaryConstEnumerate) {
100 std::vector<std::string> v = {"abc", "a", "ab"};
102 for (const auto it : folly::enumerate(decltype(v)(v))) { // Copy v.
103 static_assert(IsConstReference<decltype(*it)>::value, "Const enumeration");
104 EXPECT_EQ(it.index, i);
105 EXPECT_EQ(*it, v[i]);
106 EXPECT_EQ(it->size(), v[i].size());
110 EXPECT_EQ(i, v.size());
113 TEST(Enumerate, RangeSupport) {
114 std::vector<std::string> v = {"abc", "a", "ab"};
116 for (const auto it : folly::enumerate(folly::range(v))) {
117 EXPECT_EQ(it.index, i);
118 EXPECT_EQ(*it, v[i]);
119 EXPECT_EQ(it->size(), v[i].size());
123 EXPECT_EQ(i, v.size());
126 TEST(Enumerate, EmptyRange) {
127 std::vector<std::string> v;
128 for (auto it : folly::enumerate(v)) {
129 (void)it; // Silence warnings.
140 explicit CStringRange(const char* cstr) : cstr(cstr) {}
142 const char* begin() const {
145 Sentinel end() const {
150 bool operator==(const char* c, CStringRange::Sentinel) {
154 TEST(Enumerate, Cpp17Support) {
155 std::array<char, 5> test = {"test"};
156 // Can't use range based for loop until C++17, so test manually
158 // for (const auto it : folly::enumerate(CStringRange{test.data()})) { ... }
160 auto&& enumerate = folly::enumerate(CStringRange{test.data()});
161 auto begin = enumerate.begin();
162 auto end = enumerate.end();
163 for (; begin != end; ++begin) {
164 const auto it = *begin;
166 ASSERT_LT(it.index, test.size());
167 EXPECT_EQ(*it, test[it.index]);