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.
18 // Author: andrei.alexandrescu@fb.com
20 #include <folly/FBVector.h>
26 #include <boost/random.hpp>
28 #include <folly/FBString.h>
29 #include <folly/Foreach.h>
30 #include <folly/Random.h>
31 #include <folly/Traits.h>
32 #include <folly/portability/GTest.h>
35 using namespace folly;
39 auto static const seed = randomNumberSeed();
40 typedef boost::mt19937 RandomT;
41 static RandomT rng(seed);
43 template <class Integral1, class Integral2>
44 Integral2 random(Integral1 low, Integral2 up) {
45 boost::uniform_int<> range(low, up);
49 template <class String>
50 void randomString(String* toFill, unsigned int maxSize = 1000) {
52 toFill->resize(random(0, maxSize));
53 FOR_EACH (i, *toFill) {
54 *i = random('a', 'z');
58 template <class String, class Integral>
59 void Num2String(String& str, Integral /* n */) {
61 sprintf(&str[0], "%ul", 10);
62 str.resize(strlen(str.c_str()));
65 template <class T> T randomObject();
67 template <> int randomObject<int>() {
68 return random(0, 1024);
72 ////////////////////////////////////////////////////////////////////////////////
74 ////////////////////////////////////////////////////////////////////////////////
76 TEST(fbvector, clause_23_3_6_1_3_ambiguity) {
77 fbvector<int> v(10, 20);
78 EXPECT_EQ(v.size(), 10);
84 TEST(fbvector, clause_23_3_6_1_11_ambiguity) {
87 EXPECT_EQ(v.size(), 10);
93 TEST(fbvector, clause_23_3_6_2_6) {
95 auto const n = random(0U, 10000U);
97 auto const n1 = random(0U, 10000U);
98 auto const obj = randomObject<int>();
101 // Nothing to verify except that the call made it through
104 TEST(fbvector, clause_23_3_6_4_ambiguity) {
106 fbvector<int>::const_iterator it = v.end();
107 v.insert(it, 10, 20);
108 EXPECT_EQ(v.size(), 10);
114 TEST(fbvector, composition) {
115 fbvector< fbvector<double> > matrix(100, fbvector<double>(100));
118 TEST(fbvector, works_with_std_string) {
119 fbvector<std::string> v(10, "hello");
120 EXPECT_EQ(v.size(), 10);
121 v.push_back("world");
125 class UserDefinedType { int whatevs_; };
128 FOLLY_ASSUME_FBVECTOR_COMPATIBLE(UserDefinedType);
130 TEST(fbvector, works_with_user_defined_type) {
131 fbvector<UserDefinedType> v(10);
132 EXPECT_EQ(v.size(), 10);
133 v.push_back(UserDefinedType());
136 TEST(fbvector, move_construction) {
137 fbvector<int> v1(100, 100);
139 EXPECT_EQ(v1.size(), 100);
140 EXPECT_EQ(v1.front(), 100);
141 EXPECT_EQ(v2.size(), 0);
143 EXPECT_EQ(v1.size(), 0);
144 EXPECT_EQ(v2.size(), 100);
145 EXPECT_EQ(v2.front(), 100);
148 auto other = std::move(v1);
149 EXPECT_EQ(v1.size(), 0);
150 EXPECT_EQ(other.size(), 100);
151 EXPECT_EQ(other.front(), 100);
154 TEST(fbvector, emplace) {
155 fbvector<std::string> s(12, "asd");
156 EXPECT_EQ(s.size(), 12);
157 EXPECT_EQ(s.front(), "asd");
158 s.emplace_back("funk");
159 EXPECT_EQ(s.back(), "funk");
162 TEST(fbvector, initializer_lists) {
163 fbvector<int> vec = { 1, 2, 3 };
164 EXPECT_EQ(vec.size(), 3);
165 EXPECT_EQ(vec[0], 1);
166 EXPECT_EQ(vec[1], 2);
167 EXPECT_EQ(vec[2], 3);
169 vec = { 0, 0, 12, 16 };
170 EXPECT_EQ(vec.size(), 4);
171 EXPECT_EQ(vec[0], 0);
172 EXPECT_EQ(vec[1], 0);
173 EXPECT_EQ(vec[2], 12);
174 EXPECT_EQ(vec[3], 16);
176 vec.insert(vec.begin() + 1, { 23, 23 });
177 EXPECT_EQ(vec.size(), 6);
178 EXPECT_EQ(vec[0], 0);
179 EXPECT_EQ(vec[1], 23);
180 EXPECT_EQ(vec[2], 23);
181 EXPECT_EQ(vec[3], 0);
182 EXPECT_EQ(vec[4], 12);
183 EXPECT_EQ(vec[5], 16);
186 TEST(fbvector, unique_ptr) {
187 fbvector<std::unique_ptr<int> > v(12);
188 std::unique_ptr<int> p(new int(12));
189 v.push_back(std::move(p));
190 EXPECT_EQ(*v.back(), 12);
193 EXPECT_FALSE(v[0].get());
194 v[0].reset(new int(32));
195 std::unique_ptr<int> somePtr;
196 v.insert(v.begin(), std::move(somePtr));
197 EXPECT_EQ(*v[1], 32);
200 TEST(FBVector, task858056) {
201 fbvector<fbstring> cycle;
202 cycle.push_back("foo");
203 cycle.push_back("bar");
204 cycle.push_back("baz");
205 fbstring message("Cycle detected: ");
206 FOR_EACH_R (node_name, cycle) {
208 message += *node_name;
211 EXPECT_EQ("Cycle detected: [baz] [bar] [foo] ", message);
214 TEST(FBVector, move_iterator) {
215 fbvector<int> base = { 0, 1, 2 };
218 fbvector<int> fbvi1(std::make_move_iterator(cp1.begin()),
219 std::make_move_iterator(cp1.end()));
220 EXPECT_EQ(fbvi1, base);
224 fbvi2.assign(std::make_move_iterator(cp2.begin()),
225 std::make_move_iterator(cp2.end()));
226 EXPECT_EQ(fbvi2, base);
230 fbvi3.insert(fbvi3.end(),
231 std::make_move_iterator(cp3.begin()),
232 std::make_move_iterator(cp3.end()));
233 EXPECT_EQ(fbvi3, base);
236 TEST(FBVector, reserve_consistency) {
237 struct S { int64_t a, b, c, d; };
240 for (size_t i = 0; i < 1000; ++i) {
242 EXPECT_EQ(fb1.size(), 0);
247 TEST(FBVector, vector_of_maps) {
248 fbvector<std::map<std::string, std::string>> v;
250 v.push_back(std::map<std::string, std::string>());
251 v.push_back(std::map<std::string, std::string>());
253 EXPECT_EQ(2, v.size());
255 v[1]["hello"] = "world";
256 EXPECT_EQ(0, v[0].size());
257 EXPECT_EQ(1, v[1].size());
260 EXPECT_EQ(1, v[0].size());
261 EXPECT_EQ(1, v[1].size());
264 TEST(FBVector, shrink_to_fit_after_clear) {
270 EXPECT_EQ(fb1.size(), 0);
271 EXPECT_EQ(fb1.capacity(), 0);
274 TEST(FBVector, zero_len) {
275 fbvector<int> fb1(0);
276 fbvector<int> fb2(0, 10);
277 fbvector<int> fb3(std::move(fb1));
279 fb4 = std::move(fb2);
280 fbvector<int> fb5 = fb3;
283 std::initializer_list<int> il = {};
285 fbvector<int> fb7(fb6.begin(), fb6.end());