]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/third_party/ms-gsl/tests/notnull_tests.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / ms-gsl / tests / notnull_tests.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
4 //
5 // This code is licensed under the MIT License (MIT).
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13 // THE SOFTWARE.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16
17 #include <gtest/gtest.h>
18
19 #include <gsl/pointers> // for not_null, operator<, operator<=, operator>
20
21 #include <algorithm> // for addressof
22 #include <memory> // for shared_ptr, make_shared, operator<, opera...
23 #include <sstream> // for operator<<, ostringstream, basic_ostream:...
24 #include <stdint.h> // for uint16_t
25 #include <string> // for basic_string, operator==, string, operator<<
26 #include <typeinfo> // for type_info
27
28 using namespace gsl;
29
30 namespace
31 {
32 static constexpr char deathstring[] = "Expected Death";
33 } //namespace
34
35 struct MyBase
36 {
37 };
38 struct MyDerived : public MyBase
39 {
40 };
41 struct Unrelated
42 {
43 };
44
45 // stand-in for a user-defined ref-counted class
46 template <typename T>
47 struct RefCounted
48 {
49 RefCounted(T* p) : p_(p) {}
50 operator T*() { return p_; }
51 T* p_;
52 };
53
54 // user defined smart pointer with comparison operators returning non bool value
55 template <typename T>
56 struct CustomPtr
57 {
58 CustomPtr(T* p) : p_(p) {}
59 operator T*() { return p_; }
60 bool operator!=(std::nullptr_t) const { return p_ != nullptr; }
61 T* p_ = nullptr;
62 };
63
64 template <typename T, typename U>
65 std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
66 {
67 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
68 return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
69 : "false";
70 }
71
72 template <typename T, typename U>
73 std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
74 {
75 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
76 return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
77 : "false";
78 }
79
80 template <typename T, typename U>
81 std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
82 {
83 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
84 return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
85 : "false";
86 }
87
88 template <typename T, typename U>
89 std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
90 {
91 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
92 return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
93 : "false";
94 }
95
96 template <typename T, typename U>
97 std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
98 {
99 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
100 return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
101 : "false";
102 }
103
104 template <typename T, typename U>
105 std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
106 {
107 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
108 return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
109 : "false";
110 }
111
112 struct NonCopyableNonMovable
113 {
114 NonCopyableNonMovable() = default;
115 NonCopyableNonMovable(const NonCopyableNonMovable&) = delete;
116 NonCopyableNonMovable& operator=(const NonCopyableNonMovable&) = delete;
117 NonCopyableNonMovable(NonCopyableNonMovable&&) = delete;
118 NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete;
119 };
120
121 GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
122 bool helper(not_null<int*> p) { return *p == 12; }
123 GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
124 bool helper_const(not_null<const int*> p) { return *p == 12; }
125
126 int* return_pointer() { return nullptr; }
127
128 TEST(notnull_tests, TestNotNullConstructors)
129 {
130 {
131 #ifdef CONFIRM_COMPILATION_ERRORS
132 not_null<int*> p = nullptr; // yay...does not compile!
133 not_null<std::vector<char>*> p1 = 0; // yay...does not compile!
134 not_null<int*> p2; // yay...does not compile!
135 std::unique_ptr<int> up = std::make_unique<int>(120);
136 not_null<int*> p3 = up;
137
138 // Forbid non-nullptr assignable types
139 not_null<std::vector<int>> f(std::vector<int>{1});
140 not_null<int> z(10);
141 not_null<std::vector<int>> y({1, 2});
142 #endif
143 }
144
145 std::set_terminate([] {
146 std::cerr << "Expected Death. TestNotNullConstructors";
147 std::abort();
148 });
149 {
150 // from shared pointer
151 int i = 12;
152 auto rp = RefCounted<int>(&i);
153 not_null<int*> p(rp);
154 EXPECT_TRUE(p.get() == &i);
155
156 not_null<std::shared_ptr<int>> x(
157 std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
158
159 int* pi = nullptr;
160 EXPECT_DEATH((not_null<decltype(pi)>(pi)), deathstring);
161 }
162
163 {
164 // from pointer to local
165 int t = 42;
166
167 not_null<int*> x = &t;
168 helper(&t);
169 helper_const(&t);
170
171 EXPECT_TRUE(*x == 42);
172 }
173
174 {
175 // from raw pointer
176 // from not_null pointer
177
178 int t = 42;
179 int* p = &t;
180
181 not_null<int*> x = p;
182 helper(p);
183 helper_const(p);
184 helper(x);
185 helper_const(x);
186
187 EXPECT_TRUE(*x == 42);
188 }
189
190 {
191 // from raw const pointer
192 // from not_null const pointer
193
194 int t = 42;
195 const int* cp = &t;
196
197 not_null<const int*> x = cp;
198 helper_const(cp);
199 helper_const(x);
200
201 EXPECT_TRUE(*x == 42);
202 }
203
204 {
205 // from not_null const pointer, using auto
206 int t = 42;
207 const int* cp = &t;
208
209 auto x = not_null<const int*>{cp};
210
211 EXPECT_TRUE(*x == 42);
212 }
213
214 {
215 // from returned pointer
216
217 EXPECT_DEATH(helper(return_pointer()), deathstring);
218 EXPECT_DEATH(helper_const(return_pointer()), deathstring);
219 }
220 }
221
222 template <typename T>
223 void ostream_helper(T v)
224 {
225 not_null<T*> p(&v);
226 {
227 std::ostringstream os;
228 std::ostringstream ref;
229 os << static_cast<void*>(p);
230 ref << static_cast<void*>(&v);
231 EXPECT_TRUE(os.str() == ref.str());
232 }
233 {
234 std::ostringstream os;
235 std::ostringstream ref;
236 os << *p;
237 ref << v;
238 EXPECT_TRUE(os.str() == ref.str());
239 }
240 }
241
242 TEST(notnull_tests, TestNotNullostream)
243 {
244 ostream_helper<int>(17);
245 ostream_helper<float>(21.5f);
246 ostream_helper<double>(3.4566e-7);
247 ostream_helper<char>('c');
248 ostream_helper<uint16_t>(0x0123u);
249 ostream_helper<const char*>("cstring");
250 ostream_helper<std::string>("string");
251 }
252
253 TEST(notnull_tests, TestNotNullCasting)
254 {
255 MyBase base;
256 MyDerived derived;
257 Unrelated unrelated;
258 not_null<Unrelated*> u{&unrelated};
259 (void) u;
260 not_null<MyDerived*> p{&derived};
261 not_null<MyBase*> q(&base);
262 q = p; // allowed with heterogeneous copy ctor
263 EXPECT_TRUE(q == p);
264
265 #ifdef CONFIRM_COMPILATION_ERRORS
266 q = u; // no viable conversion possible between MyBase* and Unrelated*
267 p = q; // not possible to implicitly convert MyBase* to MyDerived*
268
269 not_null<Unrelated*> r = p;
270 not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p);
271 #endif
272 not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
273 EXPECT_TRUE(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
274 }
275
276 TEST(notnull_tests, TestNotNullAssignment)
277 {
278 std::set_terminate([] {
279 std::cerr << "Expected Death. TestNotNullAssignmentd";
280 std::abort();
281 });
282
283 int i = 12;
284 not_null<int*> p(&i);
285 EXPECT_TRUE(helper(p));
286
287 int* q = nullptr;
288 EXPECT_DEATH(p = not_null<int*>(q), deathstring);
289 }
290
291 TEST(notnull_tests, TestNotNullRawPointerComparison)
292 {
293 int ints[2] = {42, 43};
294 int* p1 = &ints[0];
295 const int* p2 = &ints[1];
296
297 using NotNull1 = not_null<decltype(p1)>;
298 using NotNull2 = not_null<decltype(p2)>;
299
300 EXPECT_TRUE((NotNull1(p1) == NotNull1(p1)) == true);
301 EXPECT_TRUE((NotNull1(p1) == NotNull2(p2)) == false);
302
303 EXPECT_TRUE((NotNull1(p1) != NotNull1(p1)) == false);
304 EXPECT_TRUE((NotNull1(p1) != NotNull2(p2)) == true);
305
306 EXPECT_TRUE((NotNull1(p1) < NotNull1(p1)) == false);
307 EXPECT_TRUE((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
308 EXPECT_TRUE((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
309
310 EXPECT_TRUE((NotNull1(p1) > NotNull1(p1)) == false);
311 EXPECT_TRUE((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
312 EXPECT_TRUE((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
313
314 EXPECT_TRUE((NotNull1(p1) <= NotNull1(p1)) == true);
315 EXPECT_TRUE((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
316 EXPECT_TRUE((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
317 }
318
319 TEST(notnull_tests, TestNotNullDereferenceOperator)
320 {
321 {
322 auto sp1 = std::make_shared<NonCopyableNonMovable>();
323
324 using NotNullSp1 = not_null<decltype(sp1)>;
325 EXPECT_TRUE(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
326 EXPECT_TRUE(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1));
327 }
328
329 {
330 int ints[1] = {42};
331 CustomPtr<int> p1(&ints[0]);
332
333 using NotNull1 = not_null<decltype(p1)>;
334 EXPECT_TRUE(typeid(*NotNull1(p1)) == typeid(*p1));
335 EXPECT_TRUE(*NotNull1(p1) == 42);
336 *NotNull1(p1) = 43;
337 EXPECT_TRUE(ints[0] == 43);
338 }
339
340 {
341 int v = 42;
342 gsl::not_null<int*> p(&v);
343 EXPECT_TRUE(typeid(*p) == typeid(*(&v)));
344 *p = 43;
345 EXPECT_TRUE(v == 43);
346 }
347 }
348
349 TEST(notnull_tests, TestNotNullSharedPtrComparison)
350 {
351 auto sp1 = std::make_shared<int>(42);
352 auto sp2 = std::make_shared<const int>(43);
353
354 using NotNullSp1 = not_null<decltype(sp1)>;
355 using NotNullSp2 = not_null<decltype(sp2)>;
356
357 EXPECT_TRUE((NotNullSp1(sp1) == NotNullSp1(sp1)) == true);
358 EXPECT_TRUE((NotNullSp1(sp1) == NotNullSp2(sp2)) == false);
359
360 EXPECT_TRUE((NotNullSp1(sp1) != NotNullSp1(sp1)) == false);
361 EXPECT_TRUE((NotNullSp1(sp1) != NotNullSp2(sp2)) == true);
362
363 EXPECT_TRUE((NotNullSp1(sp1) < NotNullSp1(sp1)) == false);
364 EXPECT_TRUE((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2));
365 EXPECT_TRUE((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1));
366
367 EXPECT_TRUE((NotNullSp1(sp1) > NotNullSp1(sp1)) == false);
368 EXPECT_TRUE((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2));
369 EXPECT_TRUE((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1));
370
371 EXPECT_TRUE((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true);
372 EXPECT_TRUE((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2));
373 EXPECT_TRUE((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1));
374
375 EXPECT_TRUE((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true);
376 EXPECT_TRUE((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2));
377 EXPECT_TRUE((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1));
378 }
379
380 TEST(notnull_tests, TestNotNullCustomPtrComparison)
381 {
382 int ints[2] = {42, 43};
383 CustomPtr<int> p1(&ints[0]);
384 CustomPtr<const int> p2(&ints[1]);
385
386 using NotNull1 = not_null<decltype(p1)>;
387 using NotNull2 = not_null<decltype(p2)>;
388
389 EXPECT_TRUE((NotNull1(p1) == NotNull1(p1)) == "true");
390 EXPECT_TRUE((NotNull1(p1) == NotNull2(p2)) == "false");
391
392 EXPECT_TRUE((NotNull1(p1) != NotNull1(p1)) == "false");
393 EXPECT_TRUE((NotNull1(p1) != NotNull2(p2)) == "true");
394
395 EXPECT_TRUE((NotNull1(p1) < NotNull1(p1)) == "false");
396 EXPECT_TRUE((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
397 EXPECT_TRUE((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
398
399 EXPECT_TRUE((NotNull1(p1) > NotNull1(p1)) == "false");
400 EXPECT_TRUE((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
401 EXPECT_TRUE((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
402
403 EXPECT_TRUE((NotNull1(p1) <= NotNull1(p1)) == "true");
404 EXPECT_TRUE((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
405 EXPECT_TRUE((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
406
407 EXPECT_TRUE((NotNull1(p1) >= NotNull1(p1)) == "true");
408 EXPECT_TRUE((NotNull1(p1) >= NotNull2(p2)) == (p1 >= p2));
409 EXPECT_TRUE((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
410 }
411
412 #if defined(__cplusplus) && (__cplusplus >= 201703L)
413
414 TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
415 {
416 {
417 int i = 42;
418
419 not_null x{&i};
420 helper(not_null{&i});
421 helper_const(not_null{&i});
422
423 EXPECT_TRUE(*x == 42);
424 }
425
426 {
427 int i = 42;
428 int* p = &i;
429
430 not_null x{p};
431 helper(not_null{p});
432 helper_const(not_null{p});
433
434 EXPECT_TRUE(*x == 42);
435 }
436
437 std::set_terminate([] {
438 std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction";
439 std::abort();
440 });
441
442 {
443 auto workaround_macro = []() {
444 int* p1 = nullptr;
445 const not_null x{p1};
446 };
447 EXPECT_DEATH(workaround_macro(), deathstring);
448 }
449
450 {
451 auto workaround_macro = []() {
452 const int* p1 = nullptr;
453 const not_null x{p1};
454 };
455 EXPECT_DEATH(workaround_macro(), deathstring);
456 }
457
458 {
459 int* p = nullptr;
460
461 EXPECT_DEATH(helper(not_null{p}), deathstring);
462 EXPECT_DEATH(helper_const(not_null{p}), deathstring);
463 }
464
465 #ifdef CONFIRM_COMPILATION_ERRORS
466 {
467 not_null x{nullptr};
468 helper(not_null{nullptr});
469 helper_const(not_null{nullptr});
470 }
471 #endif
472 }
473 #endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
474
475 TEST(notnull_tests, TestMakeNotNull)
476 {
477 {
478 int i = 42;
479
480 const auto x = make_not_null(&i);
481 helper(make_not_null(&i));
482 helper_const(make_not_null(&i));
483
484 EXPECT_TRUE(*x == 42);
485 }
486
487 {
488 int i = 42;
489 int* p = &i;
490
491 const auto x = make_not_null(p);
492 helper(make_not_null(p));
493 helper_const(make_not_null(p));
494
495 EXPECT_TRUE(*x == 42);
496 }
497
498 std::set_terminate([] {
499 std::cerr << "Expected Death. TestMakeNotNull";
500 std::abort();
501 });
502
503 {
504 const auto workaround_macro = []() {
505 int* p1 = nullptr;
506 const auto x = make_not_null(p1);
507 EXPECT_TRUE(*x == 42);
508 };
509 EXPECT_DEATH(workaround_macro(), deathstring);
510 }
511
512 {
513 const auto workaround_macro = []() {
514 const int* p1 = nullptr;
515 const auto x = make_not_null(p1);
516 EXPECT_TRUE(*x == 42);
517 };
518 EXPECT_DEATH(workaround_macro(), deathstring);
519 }
520
521 {
522 int* p = nullptr;
523
524 EXPECT_DEATH(helper(make_not_null(p)), deathstring);
525 EXPECT_DEATH(helper_const(make_not_null(p)), deathstring);
526 }
527
528 #ifdef CONFIRM_COMPILATION_ERRORS
529 {
530 EXPECT_DEATH(make_not_null(nullptr), deathstring);
531 EXPECT_DEATH(helper(make_not_null(nullptr)), deathstring);
532 EXPECT_DEATH(helper_const(make_not_null(nullptr)), deathstring);
533 }
534 #endif
535 }