2 * Copyright 2016-present 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/Range.h>
22 #include <folly/container/Enumerate.h>
23 #include <folly/portability/GTest.h>
28 struct IsConstReference {
29 constexpr static bool value = false;
32 struct IsConstReference<const T&> {
33 constexpr static bool value = true;
38 #define ENUMERATE_TEST_BASIC(DECL, NAME) \
39 TEST(Enumerate, NAME) { \
40 std::vector<std::string> v = {"abc", "a", "ab"}; \
42 for (DECL it : folly::enumerate(v)) { \
43 EXPECT_EQ(it.index, i); \
44 EXPECT_EQ(*it, v[i]); \
45 EXPECT_EQ(it->size(), v[i].size()); \
47 /* Test mutability. */ \
48 std::string newValue = "x"; \
50 EXPECT_EQ(newValue, v[i]); \
55 EXPECT_EQ(i, v.size()); \
58 ENUMERATE_TEST_BASIC(auto, Basic)
59 ENUMERATE_TEST_BASIC(auto&&, BasicRRef)
61 #undef ENUMERATE_TEST_BASIC
63 #define ENUMERATE_TEST_BASIC_CONST(DECL, NAME) \
64 TEST(Enumerate, NAME) { \
65 std::vector<std::string> v = {"abc", "a", "ab"}; \
67 for (DECL it : folly::enumerate(v)) { \
69 IsConstReference<decltype(*it)>::value, "Const enumeration"); \
70 EXPECT_EQ(it.index, i); \
71 EXPECT_EQ(*it, v[i]); \
72 EXPECT_EQ(it->size(), v[i].size()); \
76 EXPECT_EQ(i, v.size()); \
79 ENUMERATE_TEST_BASIC_CONST(const auto, BasicConst)
80 ENUMERATE_TEST_BASIC_CONST(const auto&, BasicConstRef)
81 ENUMERATE_TEST_BASIC_CONST(const auto&&, BasicConstRRef)
83 #undef ENUMERATE_TEST_BASIC_CONST
85 TEST(Enumerate, Temporary) {
86 std::vector<std::string> v = {"abc", "a", "ab"};
88 for (auto&& it : folly::enumerate(decltype(v)(v))) { // Copy v.
89 EXPECT_EQ(it.index, i);
91 EXPECT_EQ(it->size(), v[i].size());
95 EXPECT_EQ(i, v.size());
98 TEST(Enumerate, BasicConstArg) {
99 const std::vector<std::string> v = {"abc", "a", "ab"};
101 for (auto&& it : folly::enumerate(v)) {
103 IsConstReference<decltype(*it)>::value, "Enumerating a const vector");
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, TemporaryConstEnumerate) {
114 std::vector<std::string> v = {"abc", "a", "ab"};
116 for (const auto&& it : folly::enumerate(decltype(v)(v))) { // Copy v.
117 static_assert(IsConstReference<decltype(*it)>::value, "Const enumeration");
118 EXPECT_EQ(it.index, i);
119 EXPECT_EQ(*it, v[i]);
120 EXPECT_EQ(it->size(), v[i].size());
124 EXPECT_EQ(i, v.size());
127 TEST(Enumerate, RangeSupport) {
128 std::vector<std::string> v = {"abc", "a", "ab"};
130 for (const auto&& it : folly::enumerate(folly::range(v))) {
131 EXPECT_EQ(it.index, i);
132 EXPECT_EQ(*it, v[i]);
133 EXPECT_EQ(it->size(), v[i].size());
137 EXPECT_EQ(i, v.size());
140 TEST(Enumerate, EmptyRange) {
141 std::vector<std::string> v;
142 for (auto&& it : folly::enumerate(v)) {
143 (void)it; // Silence warnings.
154 explicit CStringRange(const char* cstr) : cstr(cstr) {}
156 const char* begin() const {
159 Sentinel end() const {
164 bool operator==(const char* c, CStringRange::Sentinel) {
168 TEST(Enumerate, Cpp17Support) {
169 std::array<char, 5> test = {"test"};
170 // Can't use range based for loop until C++17, so test manually
172 // for (const auto&& it : folly::enumerate(CStringRange{test.data()})) { ... }
174 auto&& enumerate = folly::enumerate(CStringRange{test.data()});
175 auto begin = enumerate.begin();
176 auto end = enumerate.end();
177 for (; begin != end; ++begin) {
178 const auto&& it = *begin;
180 ASSERT_LT(it.index, test.size());
181 EXPECT_EQ(*it, test[it.index]);