1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
3 * Copyright (C) 2018 Yusuke Suzuki <[email protected]>.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28
29#include <wtf/Markable.h>
30
31namespace TestWebKitAPI {
32
33TEST(WTF_Markable, Disengaged)
34{
35 {
36 Markable<int, IntegralMarkableTraits<int, 42>> optional;
37
38 EXPECT_FALSE(static_cast<bool>(optional));
39 }
40
41 {
42 Markable<int, IntegralMarkableTraits<int, 42>> optional { WTF::nullopt };
43
44 EXPECT_FALSE(static_cast<bool>(optional));
45 }
46}
47
48TEST(WTF_Markable, Engaged)
49{
50 {
51 Markable<int, IntegralMarkableTraits<int, 42>> optional { 10 };
52
53 EXPECT_TRUE(static_cast<bool>(optional));
54 EXPECT_EQ(10, optional.value());
55
56 optional = 41;
57 EXPECT_TRUE(static_cast<bool>(optional));
58 EXPECT_EQ(41, optional.value());
59
60 optional = WTF::nullopt;
61 EXPECT_FALSE(static_cast<bool>(optional));
62
63 optional = 42;
64 EXPECT_FALSE(static_cast<bool>(optional));
65 }
66 {
67 Markable<int, IntegralMarkableTraits<int, 42>> optional { 42 };
68
69 EXPECT_FALSE(static_cast<bool>(optional));
70
71 optional = 41;
72
73 EXPECT_TRUE(static_cast<bool>(optional));
74 EXPECT_EQ(41, optional.value());
75 }
76}
77
78TEST(WTF_Markable, Destructor)
79{
80 static bool didCallDestructor = false;
81 struct A {
82 explicit A(int value)
83 : m_value(value)
84 { }
85
86 ~A()
87 {
88 EXPECT_FALSE(didCallDestructor);
89 didCallDestructor = true;
90 }
91
92 int m_value { 42 };
93 };
94
95 struct ATraits {
96 static bool isEmptyValue(const A& value)
97 {
98 return value.m_value == 42;
99 }
100 static A emptyValue()
101 {
102 return A(42);
103 }
104 };
105
106 didCallDestructor = false;
107 {
108 Markable<A, ATraits> optional { std::in_place, 20 };
109 EXPECT_TRUE(static_cast<bool>(optional));
110 }
111 EXPECT_TRUE(didCallDestructor);
112
113 didCallDestructor = false;
114 {
115 Markable<A, ATraits> optional { std::in_place, 42 };
116 EXPECT_FALSE(static_cast<bool>(optional));
117 }
118 EXPECT_TRUE(didCallDestructor);
119}
120
121TEST(WTF_Markable, FromOptional)
122{
123 {
124 Optional<int> from;
125 EXPECT_FALSE(static_cast<bool>(from));
126 Markable<int, IntegralMarkableTraits<int, 42>> optional = from;
127 EXPECT_FALSE(static_cast<bool>(optional));
128 }
129 {
130 Optional<int> from { 42 };
131 EXPECT_TRUE(static_cast<bool>(from));
132 Markable<int, IntegralMarkableTraits<int, 42>> optional = from;
133 // We convert this to nullopt.
134 EXPECT_FALSE(static_cast<bool>(optional));
135 }
136 {
137 Optional<int> from { 43 };
138 EXPECT_TRUE(static_cast<bool>(from));
139 Markable<int, IntegralMarkableTraits<int, 42>> optional = from;
140 EXPECT_TRUE(static_cast<bool>(optional));
141 EXPECT_EQ(optional.value(), 43);
142 }
143 {
144 Optional<int> from;
145 EXPECT_FALSE(static_cast<bool>(from));
146 Markable<int, IntegralMarkableTraits<int, 42>> optional { WTFMove(from) };
147 EXPECT_FALSE(static_cast<bool>(optional));
148 }
149 {
150 Optional<int> from { 42 };
151 EXPECT_TRUE(static_cast<bool>(from));
152 Markable<int, IntegralMarkableTraits<int, 42>> optional { WTFMove(from) };
153 // We convert this to nullopt.
154 EXPECT_FALSE(static_cast<bool>(optional));
155 }
156 {
157 Optional<int> from { 43 };
158 EXPECT_TRUE(static_cast<bool>(from));
159 Markable<int, IntegralMarkableTraits<int, 42>> optional { WTFMove(from) };
160 EXPECT_TRUE(static_cast<bool>(optional));
161 EXPECT_EQ(optional.value(), 43);
162 }
163}
164
165TEST(WTF_Markable, ToOptional)
166{
167 {
168 Markable<int, IntegralMarkableTraits<int, 42>> optional;
169 EXPECT_FALSE(static_cast<bool>(optional));
170 Optional<int> to = optional;
171 EXPECT_FALSE(static_cast<bool>(to));
172 }
173 {
174 Markable<int, IntegralMarkableTraits<int, 42>> optional { 42 };
175 EXPECT_FALSE(static_cast<bool>(optional));
176 // We convert this to nullopt.
177 Optional<int> to = optional;
178 EXPECT_FALSE(static_cast<bool>(to));
179 }
180 {
181 Markable<int, IntegralMarkableTraits<int, 42>> optional { 43 };
182 EXPECT_TRUE(static_cast<bool>(optional));
183 Optional<int> to = optional;
184 EXPECT_TRUE(static_cast<bool>(to));
185 EXPECT_EQ(to.value(), 43);
186 }
187 {
188 Markable<int, IntegralMarkableTraits<int, 42>> optional;
189 EXPECT_FALSE(static_cast<bool>(optional));
190 Optional<int> to { WTFMove(optional) };
191 EXPECT_FALSE(static_cast<bool>(to));
192 }
193 {
194 Markable<int, IntegralMarkableTraits<int, 42>> optional { 42 };
195 EXPECT_FALSE(static_cast<bool>(optional));
196 // We convert this to nullopt.
197 Optional<int> to { WTFMove(optional) };
198 EXPECT_FALSE(static_cast<bool>(to));
199 }
200 {
201 Markable<int, IntegralMarkableTraits<int, 42>> optional { 43 };
202 EXPECT_TRUE(static_cast<bool>(optional));
203 Optional<int> to { WTFMove(optional) };
204 EXPECT_TRUE(static_cast<bool>(to));
205 EXPECT_EQ(to.value(), 43);
206 }
207}
208
209TEST(WTF_Markable, MoveOptional)
210{
211 class OnlyMovable {
212 public:
213 constexpr explicit OnlyMovable(int value)
214 : m_value(value)
215 {
216 }
217
218 int value() { return m_value; }
219
220 OnlyMovable& operator=(OnlyMovable&& other)
221 {
222 m_value = other.m_value;
223 other.m_value = 42;
224 return *this;
225 }
226
227 OnlyMovable(OnlyMovable&& other)
228 : m_value(other.m_value)
229 {
230 other.m_value = 42;
231 }
232
233 static OnlyMovable emptyValue()
234 {
235 return OnlyMovable(42);
236 }
237
238 static constexpr bool isEmptyValue(const OnlyMovable& value)
239 {
240 return value.m_value == 42;
241 }
242
243 private:
244 OnlyMovable(const OnlyMovable&) = delete;
245 OnlyMovable& operator=(const OnlyMovable&) = delete;
246
247 int m_value;
248 };
249 {
250 Optional<OnlyMovable> from { std::in_place, 20 };
251 EXPECT_TRUE(static_cast<bool>(from));
252 EXPECT_EQ(from.value().value(), 20);
253 Markable<OnlyMovable, OnlyMovable> compact = WTFMove(from);
254 EXPECT_TRUE(static_cast<bool>(compact));
255 EXPECT_EQ(compact.value().value(), 20);
256 Optional<OnlyMovable> to = WTFMove(compact);
257 EXPECT_TRUE(static_cast<bool>(to));
258 EXPECT_EQ(to.value().value(), 20);
259 }
260}
261
262} // namespace TestWebKitAPI
263