proxygen
EnumerateTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #include <array>
18 #include <string>
19 #include <vector>
20 
21 #include <folly/Range.h>
24 
25 namespace {
26 
27 template <class T>
28 struct IsConstReference {
29  constexpr static bool value = false;
30 };
31 template <class T>
32 struct IsConstReference<const T&> {
33  constexpr static bool value = true;
34 };
35 
36 } // namespace
37 
38 #define ENUMERATE_TEST_BASIC(DECL, NAME) \
39  TEST(Enumerate, NAME) { \
40  std::vector<std::string> v = {"abc", "a", "ab"}; \
41  size_t i = 0; \
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()); \
46  \
47  /* Test mutability. */ \
48  std::string newValue = "x"; \
49  *it = newValue; \
50  EXPECT_EQ(newValue, v[i]); \
51  \
52  ++i; \
53  } \
54  \
55  EXPECT_EQ(i, v.size()); \
56  }
57 
59 ENUMERATE_TEST_BASIC(auto&&, BasicRRef)
60 
61 #undef ENUMERATE_TEST_BASIC
62 
63 #define ENUMERATE_TEST_BASIC_CONST(DECL, NAME) \
64  TEST(Enumerate, NAME) { \
65  std::vector<std::string> v = {"abc", "a", "ab"}; \
66  size_t i = 0; \
67  for (DECL it : folly::enumerate(v)) { \
68  static_assert( \
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()); \
73  ++i; \
74  } \
75  \
76  EXPECT_EQ(i, v.size()); \
77  }
78 
79 ENUMERATE_TEST_BASIC_CONST(const auto, BasicConst)
80 ENUMERATE_TEST_BASIC_CONST(const auto&, BasicConstRef)
81 ENUMERATE_TEST_BASIC_CONST(const auto&&, BasicConstRRef)
82 
83 #undef ENUMERATE_TEST_BASIC_CONST
84 
85 TEST(Enumerate, Temporary) {
86  std::vector<std::string> v = {"abc", "a", "ab"};
87  size_t i = 0;
88  for (auto&& it : folly::enumerate(decltype(v)(v))) { // Copy v.
89  EXPECT_EQ(it.index, i);
90  EXPECT_EQ(*it, v[i]);
91  EXPECT_EQ(it->size(), v[i].size());
92  ++i;
93  }
94 
95  EXPECT_EQ(i, v.size());
96 }
97 
98 TEST(Enumerate, BasicConstArg) {
99  const std::vector<std::string> v = {"abc", "a", "ab"};
100  size_t i = 0;
101  for (auto&& it : folly::enumerate(v)) {
102  static_assert(
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());
107  ++i;
108  }
109 
110  EXPECT_EQ(i, v.size());
111 }
112 
113 TEST(Enumerate, TemporaryConstEnumerate) {
114  std::vector<std::string> v = {"abc", "a", "ab"};
115  size_t i = 0;
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());
121  ++i;
122  }
123 
124  EXPECT_EQ(i, v.size());
125 }
126 
127 TEST(Enumerate, RangeSupport) {
128  std::vector<std::string> v = {"abc", "a", "ab"};
129  size_t i = 0;
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());
134  ++i;
135  }
136 
137  EXPECT_EQ(i, v.size());
138 }
139 
140 TEST(Enumerate, EmptyRange) {
141  std::vector<std::string> v;
142  for (auto&& it : folly::enumerate(v)) {
143  (void)it; // Silence warnings.
144  ADD_FAILURE();
145  }
146 }
147 
149  const char* cstr;
150 
151  public:
152  struct Sentinel {};
153 
154  explicit CStringRange(const char* cstr_) : cstr(cstr_) {}
155 
156  const char* begin() const {
157  return cstr;
158  }
159  Sentinel end() const {
160  return Sentinel{};
161  }
162 };
163 
164 bool operator==(const char* c, CStringRange::Sentinel) {
165  return *c == 0;
166 }
167 
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
171  // Equivalent to:
172  // for (const auto&& it : folly::enumerate(CStringRange{test.data()})) { ... }
173  {
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;
179 
180  ASSERT_LT(it.index, test.size());
181  EXPECT_EQ(*it, test[it.index]);
182  }
183  }
184 }
#define ENUMERATE_TEST_BASIC(DECL, NAME)
const char * begin() const
bool operator==(const char *c, CStringRange::Sentinel)
#define T(v)
Definition: http_parser.c:233
TEST(Enumerate, Basic)
auto v
#define ASSERT_LT(val1, val2)
Definition: gtest.h:1968
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
CStringRange(const char *cstr_)
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
const char * cstr
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
static const char *const value
Definition: Conv.cpp:50
detail::RangeEnumerator< Range > enumerate(Range &&r)
Definition: Enumerate.h:167
const
Definition: upload.py:398
#define ENUMERATE_TEST_BASIC_CONST(DECL, NAME)
#define ADD_FAILURE()
Definition: gtest.h:1808
char c
Sentinel end() const