1 /*
2 * Copyright (c) 2016, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
8 */
9
10 #include <fatal/type/pointer_selector.h>
11
12 #include <fatal/test/driver.h>
13
14 #include <memory>
15
16 namespace fatal {
17
18 struct test_deleter {
19 template <typename T>
operator ()fatal::test_deleter20 void operator ()(T *p) const { delete p; }
21 };
22
FATAL_TEST(pointer_selector,element_type)23 FATAL_TEST(pointer_selector, element_type) {
24 FATAL_EXPECT_SAME<
25 int,
26 pointer_selector<pointer_class::raw, int>::element_type
27 >();
28
29 FATAL_EXPECT_SAME<
30 int const,
31 pointer_selector<pointer_class::raw, int const>::element_type
32 >();
33
34 FATAL_EXPECT_SAME<
35 int,
36 pointer_selector<pointer_class::unique, int>::element_type
37 >();
38
39 FATAL_EXPECT_SAME<
40 int const,
41 pointer_selector<pointer_class::unique, int const>::element_type
42 >();
43
44 FATAL_EXPECT_SAME<
45 int,
46 pointer_selector<pointer_class::unique, int, test_deleter>::element_type
47 >();
48
49 FATAL_EXPECT_SAME<
50 int const,
51 pointer_selector<
52 pointer_class::unique, int const, test_deleter
53 >::element_type
54 >();
55
56 FATAL_EXPECT_SAME<
57 int,
58 pointer_selector<pointer_class::shared, int>::element_type
59 >();
60
61 FATAL_EXPECT_SAME<
62 int const,
63 pointer_selector<pointer_class::shared, int const>::element_type
64 >();
65 }
66
FATAL_TEST(pointer_selector,pointer)67 FATAL_TEST(pointer_selector, pointer) {
68 FATAL_EXPECT_SAME<
69 int *,
70 pointer_selector<pointer_class::raw, int>::pointer
71 >();
72
73 FATAL_EXPECT_SAME<
74 int const *,
75 pointer_selector<pointer_class::raw, int const>::pointer
76 >();
77
78 FATAL_EXPECT_SAME<
79 int *,
80 pointer_selector<pointer_class::unique, int>::pointer
81 >();
82
83 FATAL_EXPECT_SAME<
84 int const *,
85 pointer_selector<pointer_class::unique, int const>::pointer
86 >();
87
88 FATAL_EXPECT_SAME<
89 int *,
90 pointer_selector<pointer_class::unique, int, test_deleter>::pointer
91 >();
92
93 FATAL_EXPECT_SAME<
94 int const *,
95 pointer_selector<pointer_class::unique, int const, test_deleter>::pointer
96 >();
97
98 FATAL_EXPECT_SAME<
99 int *,
100 pointer_selector<pointer_class::shared, int>::pointer
101 >();
102
103 FATAL_EXPECT_SAME<
104 int const *,
105 pointer_selector<pointer_class::shared, int const>::pointer
106 >();
107 }
108
FATAL_TEST(pointer_selector,type)109 FATAL_TEST(pointer_selector, type) {
110 FATAL_EXPECT_SAME<
111 int *,
112 pointer_selector<pointer_class::raw, int>::type
113 >();
114
115 FATAL_EXPECT_SAME<
116 int const *,
117 pointer_selector<pointer_class::raw, int const>::type
118 >();
119
120 FATAL_EXPECT_SAME<
121 std::unique_ptr<int>,
122 pointer_selector<pointer_class::unique, int>::type
123 >();
124
125 FATAL_EXPECT_SAME<
126 std::unique_ptr<int const>,
127 pointer_selector<pointer_class::unique, int const>::type
128 >();
129
130 FATAL_EXPECT_SAME<
131 std::unique_ptr<int, test_deleter>,
132 pointer_selector<pointer_class::unique, int, test_deleter>::type
133 >();
134
135 FATAL_EXPECT_SAME<
136 std::unique_ptr<int const, test_deleter>,
137 pointer_selector<pointer_class::unique, int const, test_deleter>::type
138 >();
139
140 FATAL_EXPECT_SAME<
141 std::shared_ptr<int>,
142 pointer_selector<pointer_class::shared, int>::type
143 >();
144
145 FATAL_EXPECT_SAME<
146 std::shared_ptr<int const>,
147 pointer_selector<pointer_class::shared, int const>::type
148 >();
149 }
150
FATAL_TEST(pointer_selector,managed)151 FATAL_TEST(pointer_selector, managed) {
152 FATAL_EXPECT_FALSE((
153 pointer_selector<pointer_class::raw, int>::managed::value
154 ));
155 FATAL_EXPECT_FALSE((
156 pointer_selector<pointer_class::raw, int const>::managed::value
157 ));
158 FATAL_EXPECT_TRUE((
159 pointer_selector<pointer_class::unique, int>::managed::value
160 ));
161 FATAL_EXPECT_TRUE((
162 pointer_selector<pointer_class::unique, int const>::managed::value
163 ));
164 FATAL_EXPECT_TRUE((
165 pointer_selector<pointer_class::unique, int, test_deleter>::managed::value
166 ));
167 FATAL_EXPECT_TRUE((
168 pointer_selector<
169 pointer_class::unique, int const, test_deleter
170 >::managed::value
171 ));
172 FATAL_EXPECT_TRUE((
173 pointer_selector<pointer_class::shared, int>::managed::value
174 ));
175 FATAL_EXPECT_TRUE((
176 pointer_selector<pointer_class::shared, int const>::managed::value
177 ));
178 }
179
180 struct pointer_selector_tester {
pointer_selector_testerfatal::pointer_selector_tester181 pointer_selector_tester(int &v_): v(v_) { v = 99; }
~pointer_selector_testerfatal::pointer_selector_tester182 ~pointer_selector_tester() { v = 55; }
183
184 private:
185 int &v;
186 };
187
FATAL_TEST(pointer_selector,make_get_destroy)188 FATAL_TEST(pointer_selector, make_get_destroy) {
189 # define TEST_IMPL(PtrClass, ...) \
190 do { \
191 value = 11; \
192 using selector = pointer_selector<pointer_class::PtrClass, __VA_ARGS__>; \
193 { \
194 auto p = selector::make(value); \
195 FATAL_ASSERT_NE(nullptr, selector::get(p)); \
196 FATAL_EXPECT_EQ(99, value); \
197 if (!selector::managed::value) { \
198 selector::destroy(p); \
199 } \
200 } \
201 FATAL_EXPECT_EQ(55, value); \
202 \
203 value = 22; \
204 auto p = selector::make(value); \
205 FATAL_ASSERT_NE(nullptr, selector::get(p)); \
206 FATAL_EXPECT_EQ(99, value); \
207 selector::destroy(p); \
208 if (selector::managed::value) { \
209 FATAL_EXPECT_EQ(nullptr, selector::get(p)); \
210 } \
211 FATAL_EXPECT_EQ(55, value); \
212 } while (false)
213
214 int value = 0;
215
216 TEST_IMPL(raw, pointer_selector_tester);
217 TEST_IMPL(unique, pointer_selector_tester);
218 TEST_IMPL(unique, pointer_selector_tester, test_deleter);
219 TEST_IMPL(shared, pointer_selector_tester);
220
221 # undef TEST_IMPL
222 }
223
FATAL_TEST(pointer_selector_t,sanity_check)224 FATAL_TEST(pointer_selector_t, sanity_check) {
225 FATAL_EXPECT_SAME<
226 int *,
227 pointer_selector_t<pointer_class::raw, int>
228 >();
229
230 FATAL_EXPECT_SAME<
231 int const *,
232 pointer_selector_t<pointer_class::raw, int const>
233 >();
234
235 FATAL_EXPECT_SAME<
236 std::unique_ptr<int>,
237 pointer_selector_t<pointer_class::unique, int>
238 >();
239
240 FATAL_EXPECT_SAME<
241 std::unique_ptr<int const>,
242 pointer_selector_t<pointer_class::unique, int const>
243 >();
244
245 FATAL_EXPECT_SAME<
246 std::unique_ptr<int, test_deleter>,
247 pointer_selector_t<pointer_class::unique, int, test_deleter>
248 >();
249
250 FATAL_EXPECT_SAME<
251 std::unique_ptr<int const, test_deleter>,
252 pointer_selector_t<pointer_class::unique, int const, test_deleter>
253 >();
254
255 FATAL_EXPECT_SAME<
256 std::shared_ptr<int>,
257 pointer_selector_t<pointer_class::shared, int>
258 >();
259
260 FATAL_EXPECT_SAME<
261 std::shared_ptr<int const>,
262 pointer_selector_t<pointer_class::shared, int const>
263 >();
264 }
265
FATAL_TEST(make_ptr,sanity_check)266 FATAL_TEST(make_ptr, sanity_check) {
267 # define TEST_IMPL(PtrClass, ...) \
268 do { \
269 value = 12; \
270 using selector = pointer_selector<pointer_class::PtrClass, __VA_ARGS__>; \
271 { \
272 auto p = make_ptr<pointer_class::PtrClass, __VA_ARGS__>(value); \
273 FATAL_ASSERT_NE(nullptr, selector::get(p)); \
274 FATAL_EXPECT_EQ(99, value); \
275 if (!selector::managed::value) { \
276 selector::destroy(p); \
277 } \
278 } \
279 FATAL_EXPECT_EQ(55, value); \
280 \
281 value = 22; \
282 auto p = make_ptr<pointer_class::PtrClass, __VA_ARGS__>(value); \
283 FATAL_ASSERT_NE(nullptr, selector::get(p)); \
284 FATAL_EXPECT_EQ(99, value); \
285 selector::destroy(p); \
286 if (selector::managed::value) { \
287 FATAL_EXPECT_EQ(nullptr, selector::get(p)); \
288 } \
289 FATAL_EXPECT_EQ(55, value); \
290 } while (false)
291
292 int value = 0;
293
294 TEST_IMPL(raw, pointer_selector_tester);
295 TEST_IMPL(unique, pointer_selector_tester);
296 TEST_IMPL(unique, pointer_selector_tester, test_deleter);
297 TEST_IMPL(shared, pointer_selector_tester);
298
299 # undef TEST_IMPL
300 }
301
302 } // namespace fatal {
303