1 //
2 // Tests for
3 //  friend bounded_ptr operator+(bounded_ptr p, std::ptrdiff_t n);
4 //  friend bounded_ptr operator+(std::ptrdiff_t n, bounded_ptr p);
5 //
6 // The heavy lifting is done in operator+=, so we only check basic functioning.
7 //
8 
9 #include <libkern/c++/bounded_ptr.h>
10 #include <array>
11 #include <darwintest.h>
12 #include <darwintest_utils.h>
13 #include "test_utils.h"
14 
15 #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__)
16 
17 struct T {
18 	int i;
19 };
20 
21 template <typename T, typename QualT>
22 static void
23 tests()
24 {
25 	std::array<T, 5> array = {T{0}, T{1}, T{2}, T{3}, T{4}};
26 
27 	// Add positive offsets
28 	// T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last>
29 	//   ^                                                ^
30 	//   |                                                |
31 	// begin, ptr                                        end
32 	{
33 		test_bounded_ptr<QualT> const ptr(array.begin(), array.begin(), array.end());
34 
35 		{
36 			test_bounded_ptr<QualT> res = ptr + 0;
37 			_assert(&*res == &array[0]);
38 		}
39 		{
40 			test_bounded_ptr<QualT> res = ptr + 1;
41 			_assert(&*res == &array[1]);
42 		}
43 		{
44 			test_bounded_ptr<QualT> res = ptr + 2;
45 			_assert(&*res == &array[2]);
46 		}
47 		{
48 			test_bounded_ptr<QualT> res = ptr + 3;
49 			_assert(&*res == &array[3]);
50 		}
51 		{
52 			test_bounded_ptr<QualT> res = ptr + 4;
53 			_assert(&*res == &array[4]);
54 		}
55 		{
56 			test_bounded_ptr<QualT> res = ptr + 5;
57 			_assert(res == array.end());
58 		}
59 	}
60 
61 	// Add negative offsets
62 	// T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last>
63 	//   ^                                                ^
64 	//   |                                                |
65 	// begin                                           end,ptr
66 	{
67 		test_bounded_ptr<QualT> const ptr(array.end(), array.begin(), array.end());
68 
69 		{
70 			test_bounded_ptr<QualT> res = ptr + 0;
71 			_assert(res == array.end());
72 		}
73 		{
74 			test_bounded_ptr<QualT> res = ptr + -1;
75 			_assert(&*res == &array[4]);
76 		}
77 		{
78 			test_bounded_ptr<QualT> res = ptr + -2;
79 			_assert(&*res == &array[3]);
80 		}
81 		{
82 			test_bounded_ptr<QualT> res = ptr + -3;
83 			_assert(&*res == &array[2]);
84 		}
85 		{
86 			test_bounded_ptr<QualT> res = ptr + -4;
87 			_assert(&*res == &array[1]);
88 		}
89 		{
90 			test_bounded_ptr<QualT> res = ptr + -5;
91 			_assert(&*res == &array[0]);
92 		}
93 	}
94 
95 	// Make sure the original pointer isn't modified
96 	{
97 		test_bounded_ptr<QualT> const ptr(array.begin() + 1, array.begin(), array.end());
98 		(void)(ptr + 3);
99 		_assert(&*ptr == &array[1]);
100 	}
101 
102 	// Make sure the operator is commutative
103 	{
104 		{
105 			test_bounded_ptr<QualT> const ptr(array.begin(), array.begin(), array.end());
106 			test_bounded_ptr<QualT> res = 0 + ptr;
107 			_assert(&*res == &array[0]);
108 		}
109 		{
110 			test_bounded_ptr<QualT> const ptr(array.begin(), array.begin(), array.end());
111 			test_bounded_ptr<QualT> res = 3 + ptr;
112 			_assert(&*res == &array[3]);
113 		}
114 		{
115 			test_bounded_ptr<QualT> const ptr(array.begin() + 3, array.begin(), array.end());
116 			test_bounded_ptr<QualT> res = -2 + ptr;
117 			_assert(&*res == &array[1]);
118 		}
119 	}
120 }
121 
122 T_DECL(arith_add, "bounded_ptr.arith.add") {
123 	tests<T, T>();
124 	tests<T, T const>();
125 	tests<T, T volatile>();
126 	tests<T, T const volatile>();
127 }
128