1 //
2 // Tests for
3 //  friend std::ptrdiff_t operator-(bounded_ptr const& a, bounded_ptr const& b);
4 //  friend std::ptrdiff_t operator-(bounded_ptr const& a, T* b);
5 //  friend std::ptrdiff_t operator-(T* a, bounded_ptr const& b);
6 //
7 
8 #include <libkern/c++/bounded_ptr.h>
9 #include <array>
10 #include <darwintest.h>
11 #include <darwintest_utils.h>
12 #include "test_utils.h"
13 
14 #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__)
15 
16 struct T {
17 	int i;
18 };
19 
20 template <typename Stored, typename Left, typename Right>
21 static void
tests()22 tests()
23 {
24 	std::array<Stored, 5> array = {Stored{0}, Stored{1}, Stored{2}, Stored{3}, Stored{4}};
25 
26 	// a >= b
27 	{
28 		test_bounded_ptr<Left> const a(array.begin(), array.begin(), array.end());
29 		test_bounded_ptr<Right> const b(array.begin(), array.begin(), array.end());
30 		std::ptrdiff_t diff = a - b;
31 		_assert(diff == 0);
32 	}
33 	{
34 		test_bounded_ptr<Left> const a(array.begin() + 1, array.begin(), array.end());
35 		test_bounded_ptr<Right> const b(array.begin(), array.begin(), array.end());
36 		std::ptrdiff_t diff = a - b;
37 		_assert(diff == 1);
38 	}
39 	{
40 		test_bounded_ptr<Left> const a(array.begin() + 2, array.begin(), array.end());
41 		test_bounded_ptr<Right> const b(array.begin(), array.begin(), array.end());
42 		std::ptrdiff_t diff = a - b;
43 		_assert(diff == 2);
44 	}
45 	{
46 		test_bounded_ptr<Left> const a(array.begin() + 3, array.begin(), array.end());
47 		test_bounded_ptr<Right> const b(array.begin(), array.begin(), array.end());
48 		std::ptrdiff_t diff = a - b;
49 		_assert(diff == 3);
50 	}
51 	{
52 		test_bounded_ptr<Left> const a(array.begin() + 4, array.begin(), array.end());
53 		test_bounded_ptr<Right> const b(array.begin(), array.begin(), array.end());
54 		std::ptrdiff_t diff = a - b;
55 		_assert(diff == 4);
56 	}
57 	{
58 		test_bounded_ptr<Left> const a(array.end(), array.begin(), array.end());
59 		test_bounded_ptr<Right> const b(array.begin(), array.begin(), array.end());
60 		std::ptrdiff_t diff = a - b;
61 		_assert(diff == 5);
62 	}
63 
64 	// a < b
65 	{
66 		test_bounded_ptr<Left> const a(array.begin(), array.begin(), array.end());
67 		test_bounded_ptr<Right> const b(array.begin() + 1, array.begin(), array.end());
68 		std::ptrdiff_t diff = a - b;
69 		_assert(diff == -1);
70 	}
71 	{
72 		test_bounded_ptr<Left> const a(array.begin(), array.begin(), array.end());
73 		test_bounded_ptr<Right> const b(array.begin() + 2, array.begin(), array.end());
74 		std::ptrdiff_t diff = a - b;
75 		_assert(diff == -2);
76 	}
77 	{
78 		test_bounded_ptr<Left> const a(array.begin(), array.begin(), array.end());
79 		test_bounded_ptr<Right> const b(array.begin() + 3, array.begin(), array.end());
80 		std::ptrdiff_t diff = a - b;
81 		_assert(diff == -3);
82 	}
83 	{
84 		test_bounded_ptr<Left> const a(array.begin(), array.begin(), array.end());
85 		test_bounded_ptr<Right> const b(array.begin() + 4, array.begin(), array.end());
86 		std::ptrdiff_t diff = a - b;
87 		_assert(diff == -4);
88 	}
89 	{
90 		test_bounded_ptr<Left> const a(array.begin(), array.begin(), array.end());
91 		test_bounded_ptr<Right> const b(array.begin() + 5, array.begin(), array.end());
92 		std::ptrdiff_t diff = a - b;
93 		_assert(diff == -5);
94 	}
95 
96 	// Subtract pointers with different bounds
97 	{
98 		test_bounded_ptr<Left> const a(array.begin() + 2, array.begin() + 1, array.end() - 1);
99 		test_bounded_ptr<Right> const b(array.begin() + 4, array.begin() + 3, array.end());
100 		_assert(a - b == -2);
101 		_assert(b - a == 2);
102 	}
103 
104 	// Subtract with raw pointers
105 	{
106 		test_bounded_ptr<Left> const a(array.begin() + 2, array.begin() + 1, array.end() - 1);
107 		Right* b = array.begin() + 4;
108 		_assert(a - b == -2);
109 	}
110 	{
111 		Left* a = array.begin() + 4;
112 		test_bounded_ptr<Right> const b(array.begin() + 2, array.begin() + 1, array.end() - 1);
113 		_assert(a - b == 2);
114 	}
115 }
116 
117 T_DECL(arith_difference, "bounded_ptr.arith.difference", T_META_TAG_VM_PREFERRED) {
118 	tests<T, T, T>();
119 	tests<T, T, T const>();
120 	tests<T, T const, T>();
121 	tests<T, T const, T const>();
122 }
123