]>
Commit | Line | Data |
---|---|---|
f427ee49 A |
1 | // |
2 | // Tests for | |
3 | // explicit bounded_ptr(T* pointer, T const* begin, T const* end); | |
4 | // | |
5 | ||
6 | #include <libkern/c++/bounded_ptr.h> | |
7 | #include <array> | |
8 | #include <darwintest.h> | |
9 | #include <darwintest_utils.h> | |
10 | #include "test_utils.h" | |
11 | ||
12 | #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) | |
13 | ||
14 | struct T { | |
15 | int i; | |
16 | friend constexpr bool | |
17 | operator==(T const volatile& a, T const& b) | |
18 | { | |
19 | return a.i == b.i; | |
20 | } | |
21 | }; | |
22 | ||
23 | template <typename T, typename QualT> | |
24 | static void | |
25 | tests() | |
26 | { | |
27 | std::array<T, 5> array = {T{0}, T{1}, T{2}, T{3}, T{4}}; | |
28 | { | |
29 | test_bounded_ptr<QualT> p(array.begin() + 0, array.begin(), array.end()); | |
30 | _assert(*p == T{0}); | |
31 | } | |
32 | { | |
33 | test_bounded_ptr<QualT> p(array.begin() + 1, array.begin(), array.end()); | |
34 | _assert(*p == T{1}); | |
35 | } | |
36 | { | |
37 | test_bounded_ptr<QualT> p(array.begin() + 2, array.begin(), array.end()); | |
38 | _assert(*p == T{2}); | |
39 | } | |
40 | { | |
41 | test_bounded_ptr<QualT> p(array.begin() + 3, array.begin(), array.end()); | |
42 | _assert(*p == T{3}); | |
43 | } | |
44 | { | |
45 | test_bounded_ptr<QualT> p(array.begin() + 4, array.begin(), array.end()); | |
46 | _assert(*p == T{4}); | |
47 | } | |
48 | ||
49 | // It must be valid to construct out-of-bounds pointers, but we obviously | |
50 | // can't dereference them. | |
51 | { | |
52 | // T{0} T{1} T{2} T{3} T{4} <one-past-last> | |
53 | // ^ ^ ^ | |
54 | // | | | | |
55 | // ptr begin end | |
56 | test_bounded_ptr<QualT> p(array.begin() + 1, array.begin() + 3, array.end()); | |
57 | _assert(p.unsafe_discard_bounds() == array.begin() + 1); | |
58 | } | |
59 | { | |
60 | // T{0} T{1} T{2} T{3} T{4} <one-past-last> | |
61 | // ^ ^ ^ | |
62 | // | | | | |
63 | // begin end ptr | |
64 | test_bounded_ptr<QualT> p(array.begin() + 4, array.begin(), array.begin() + 3); | |
65 | _assert(p.unsafe_discard_bounds() == array.begin() + 4); | |
66 | } | |
67 | { | |
68 | // T{0} T{1} T{2} T{3} T{4} <one-past-last> | |
69 | // ^ ^ | |
70 | // | | | |
71 | // begin end,ptr | |
72 | test_bounded_ptr<QualT> p(array.end(), array.begin(), array.end()); | |
73 | _assert(p.unsafe_discard_bounds() == array.end()); | |
74 | } | |
75 | ||
76 | // Test creating a bounded_ptr from a null pointer. | |
77 | { | |
78 | test_bounded_ptr<QualT> p(nullptr, nullptr, nullptr); | |
79 | _assert(p.unsafe_discard_bounds() == nullptr); | |
80 | } | |
81 | } | |
82 | ||
83 | struct Base { }; | |
84 | struct Derived : Base { }; | |
85 | ||
86 | T_DECL(ctor_begin_end, "bounded_ptr.ctor.begin_end") { | |
87 | tests<T, T>(); | |
88 | tests<T, T const>(); | |
89 | tests<T, T volatile>(); | |
90 | tests<T, T const volatile>(); | |
91 | ||
92 | // Make sure we can construct a `bounded_ptr<Base>` from `Derived*` pointers | |
93 | { | |
94 | std::array<Derived, 5> array = {}; | |
95 | test_bounded_ptr<Base> p(static_cast<Derived*>(array.begin()), | |
96 | static_cast<Derived*>(array.begin()), | |
97 | static_cast<Derived*>(array.end())); | |
98 | } | |
99 | } |