2 * Copyright 2013 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.
17 #include "folly/Optional.h"
25 #include <glog/logging.h>
26 #include <gtest/gtest.h>
27 #include <boost/optional.hpp>
29 using namespace folly;
30 using std::unique_ptr;
31 using std::shared_ptr;
34 NoDefault(int, int) {}
38 static_assert(sizeof(Optional<char>) == 2, "");
39 static_assert(sizeof(Optional<int>) == 8, "");
40 static_assert(sizeof(Optional<NoDefault>) == 4, "");
41 static_assert(sizeof(Optional<char>) == sizeof(boost::optional<char>), "");
42 static_assert(sizeof(Optional<short>) == sizeof(boost::optional<short>), "");
43 static_assert(sizeof(Optional<int>) == sizeof(boost::optional<int>), "");
44 static_assert(sizeof(Optional<double>) == sizeof(boost::optional<double>), "");
46 TEST(Optional, NoDefault) {
47 Optional<NoDefault> x;
55 TEST(Optional, String) {
56 Optional<std::string> maybeString;
57 EXPECT_FALSE(maybeString);
58 maybeString = "hello";
59 EXPECT_TRUE(maybeString);
62 TEST(Optional, Const) {
63 { // default construct
64 Optional<const int> opt;
75 Optional<const int> opt(x);
80 Optional<const int> opt(std::move(x));
83 // no assignment allowed
86 TEST(Optional, Simple) {
98 TEST(Optional, EmptyConstruct) {
101 Optional<int> test1(opt);
103 Optional<int> test2(std::move(opt));
107 TEST(Optional, Unique) {
108 Optional<unique_ptr<int>> opt;
113 opt.emplace(new int(5));
119 opt = unique_ptr<int>(new int(6));
122 opt = unique_ptr<int>(new int(7));
125 // move it out by move construct
126 Optional<unique_ptr<int>> moved(std::move(opt));
129 EXPECT_EQ(7, **moved);
132 opt = std::move(moved); // move it back by move assign
138 TEST(Optional, Shared) {
140 Optional<shared_ptr<int>> opt;
143 opt.emplace(new int(5));
146 EXPECT_EQ(ptr.get(), opt->get());
147 EXPECT_EQ(2, ptr.use_count());
149 EXPECT_EQ(1, ptr.use_count());
152 EXPECT_EQ(2, ptr.use_count());
153 EXPECT_EQ(ptr.get(), opt->get());
155 EXPECT_EQ(1, ptr.use_count());
157 opt = std::move(ptr);
158 EXPECT_EQ(1, opt->use_count());
159 EXPECT_EQ(nullptr, ptr.get());
161 Optional<shared_ptr<int>> copied(opt);
162 EXPECT_EQ(2, opt->use_count());
163 Optional<shared_ptr<int>> moved(std::move(opt));
164 EXPECT_EQ(2, moved->use_count());
165 moved.emplace(new int(6));
166 EXPECT_EQ(1, moved->use_count());
168 EXPECT_EQ(2, moved->use_count());
172 TEST(Optional, Order) {
173 std::vector<Optional<int>> vect{
180 std::vector<Optional<int>> expected {
187 std::sort(vect.begin(), vect.end());
188 EXPECT_TRUE(vect == expected);
191 TEST(Optional, Swap) {
192 Optional<std::string> a;
193 Optional<std::string> b;
196 EXPECT_FALSE(a.hasValue());
197 EXPECT_FALSE(b.hasValue());
200 EXPECT_TRUE(a.hasValue());
201 EXPECT_FALSE(b.hasValue());
202 EXPECT_EQ("hello", a.value());
205 EXPECT_FALSE(a.hasValue());
206 EXPECT_TRUE(b.hasValue());
207 EXPECT_EQ("hello", b.value());
210 EXPECT_TRUE(a.hasValue());
211 EXPECT_EQ("bye", a.value());
216 TEST(Optional, Comparisons) {
222 EXPECT_TRUE(o_ <= 1);
223 EXPECT_TRUE(o_ <= o_);
224 EXPECT_TRUE(o_ == o_);
225 EXPECT_TRUE(o_ != 1);
226 EXPECT_TRUE(o_ >= o_);
227 EXPECT_TRUE(1 >= o_);
230 EXPECT_TRUE(o1 < o2);
231 EXPECT_TRUE(o1 <= o2);
232 EXPECT_TRUE(o1 <= o1);
233 EXPECT_TRUE(o1 == o1);
234 EXPECT_TRUE(o1 != o2);
235 EXPECT_TRUE(o1 >= o1);
236 EXPECT_TRUE(o2 >= o1);
237 EXPECT_TRUE(o2 > o1);
239 EXPECT_FALSE(o2 < o1);
240 EXPECT_FALSE(o2 <= o1);
241 EXPECT_FALSE(o2 <= o1);
242 EXPECT_FALSE(o2 == o1);
243 EXPECT_FALSE(o1 != o1);
244 EXPECT_FALSE(o1 >= o2);
245 EXPECT_FALSE(o1 >= o2);
246 EXPECT_FALSE(o1 > o2);
249 EXPECT_TRUE(1 <= o2);
250 EXPECT_TRUE(1 <= o1);
251 EXPECT_TRUE(1 == o1);
252 EXPECT_TRUE(2 != o1);
253 EXPECT_TRUE(1 >= o1);
254 EXPECT_TRUE(2 >= o1);
257 EXPECT_FALSE(o2 < 1);
258 EXPECT_FALSE(o2 <= 1);
259 EXPECT_FALSE(o2 <= 1);
260 EXPECT_FALSE(o2 == 1);
261 EXPECT_FALSE(o2 != 2);
262 EXPECT_FALSE(o1 >= 2);
263 EXPECT_FALSE(o1 >= 2);
264 EXPECT_FALSE(o1 > 2);
267 TEST(Optional, Pointee) {
269 EXPECT_FALSE(get_pointer(x));
271 EXPECT_TRUE(get_pointer(x));
275 EXPECT_FALSE(get_pointer(x));
278 TEST(Optional, MakeOptional) {
279 // const L-value version
280 const std::string s("abc");
281 auto optStr = make_optional(s);
282 ASSERT_TRUE(optStr.hasValue());
283 EXPECT_EQ(*optStr, "abc");
286 EXPECT_EQ(*optStr, "cde");
289 std::string s2("abc");
290 auto optStr2 = make_optional(s2);
291 ASSERT_TRUE(optStr2.hasValue());
292 EXPECT_EQ(*optStr2, "abc");
294 // it's vital to check that s2 wasn't clobbered
295 EXPECT_EQ(s2, "abc");
297 // L-value reference version
299 auto optStr3 = make_optional(s3);
300 ASSERT_TRUE(optStr3.hasValue());
301 EXPECT_EQ(*optStr3, "abc");
303 EXPECT_EQ(s3, "abc");
305 // R-value ref version
306 unique_ptr<int> pInt(new int(3));
307 auto optIntPtr = make_optional(std::move(pInt));
308 EXPECT_TRUE(pInt.get() == nullptr);
309 ASSERT_TRUE(optIntPtr.hasValue());
310 EXPECT_EQ(**optIntPtr, 3);