[WTF] Add Markable<T, Traits>
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WTF / Markable.cpp
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>.
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
31 namespace TestWebKitAPI {
32
33 TEST(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 { std::nullopt };
43
44         EXPECT_FALSE(static_cast<bool>(optional));
45     }
46 }
47
48 TEST(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 = std::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
78 TEST(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
121 TEST(WTF_Markable, FromOptional)
122 {
123     {
124         std::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         std::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         std::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         std::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         std::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         std::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
165 TEST(WTF_Markable, ToOptional)
166 {
167     {
168         Markable<int, IntegralMarkableTraits<int, 42>> optional;
169         EXPECT_FALSE(static_cast<bool>(optional));
170         std::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         std::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         std::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         std::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         std::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         std::optional<int> to { WTFMove(optional) };
204         EXPECT_TRUE(static_cast<bool>(to));
205         EXPECT_EQ(to.value(), 43);
206     }
207 }
208
209 TEST(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         std::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         std::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