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.
17 #include <folly/DiscriminatedPtr.h>
19 #include <folly/portability/GTest.h>
21 using namespace folly;
23 TEST(DiscriminatedPtr, Basic) {
26 typedef DiscriminatedPtr<void, int, Foo, Bar> Ptr;
30 EXPECT_TRUE(p.empty());
31 EXPECT_FALSE(p.hasType<void>());
32 EXPECT_FALSE(p.hasType<int>());
33 EXPECT_FALSE(p.hasType<Foo>());
34 EXPECT_FALSE(p.hasType<Bar>());
37 EXPECT_FALSE(p.empty());
38 EXPECT_FALSE(p.hasType<void>());
39 EXPECT_TRUE(p.hasType<int>());
40 EXPECT_FALSE(p.hasType<Foo>());
41 EXPECT_FALSE(p.hasType<Bar>());
43 EXPECT_EQ(&a, p.get_nothrow<int>());
44 EXPECT_EQ(&a, static_cast<const Ptr&>(p).get_nothrow<int>());
45 EXPECT_EQ(&a, p.get<int>());
46 EXPECT_EQ(&a, static_cast<const Ptr&>(p).get<int>());
47 EXPECT_EQ(static_cast<void*>(nullptr), p.get_nothrow<void>());
48 EXPECT_THROW({p.get<void>();}, std::invalid_argument);
52 EXPECT_FALSE(p.empty());
53 EXPECT_FALSE(p.hasType<void>());
54 EXPECT_FALSE(p.hasType<int>());
55 EXPECT_TRUE(p.hasType<Foo>());
56 EXPECT_FALSE(p.hasType<Bar>());
58 EXPECT_EQ(static_cast<int*>(nullptr), p.get_nothrow<int>());
61 EXPECT_TRUE(p.empty());
62 EXPECT_FALSE(p.hasType<void>());
63 EXPECT_FALSE(p.hasType<int>());
64 EXPECT_FALSE(p.hasType<Foo>());
65 EXPECT_FALSE(p.hasType<Bar>());
68 TEST(DiscriminatedPtr, Apply) {
71 std::string operator()(int* /* ptr */) { return "int"; }
72 std::string operator()(const int* /* ptr */) { return "const int"; }
73 std::string operator()(Foo* /* ptr */) { return "Foo"; }
74 std::string operator()(const Foo* /* ptr */) { return "const Foo"; }
77 typedef DiscriminatedPtr<int, Foo> Ptr;
82 EXPECT_EQ("int", p.apply(Visitor()));
83 EXPECT_EQ("const int", static_cast<const Ptr&>(p).apply(Visitor()));
87 EXPECT_EQ("Foo", p.apply(Visitor()));
88 EXPECT_EQ("const Foo", static_cast<const Ptr&>(p).apply(Visitor()));
89 EXPECT_EQ("Foo", apply_visitor(Visitor(), p));
90 EXPECT_EQ("const Foo", apply_visitor(Visitor(), static_cast<const Ptr&>(p)));
91 EXPECT_EQ("Foo", apply_visitor(Visitor(), std::move(p)));
94 EXPECT_THROW({p.apply(Visitor());}, std::invalid_argument);
97 TEST(DiscriminatedPtr, ApplyVoid) {
100 void operator()(int* /* ptr */) { result = "int"; }
101 void operator()(const int* /* ptr */) { result = "const int"; }
102 void operator()(Foo* /* ptr */) { result = "Foo"; }
103 void operator()(const Foo* /* ptr */) { result = "const Foo"; }
108 typedef DiscriminatedPtr<int, Foo> Ptr;
115 EXPECT_EQ("int", v.result);
116 static_cast<const Ptr&>(p).apply(v);
117 EXPECT_EQ("const int", v.result);
122 EXPECT_EQ("Foo", v.result);
123 static_cast<const Ptr&>(p).apply(v);
124 EXPECT_EQ("const Foo", v.result);
127 EXPECT_THROW({p.apply(v);}, std::invalid_argument);