1 //
2 // Tests for
3 //  iterator begin();
4 //  const_iterator begin() const;
5 //
6 //  iterator end();
7 //  const_iterator end() const;
8 //
9 
10 #include <libkern/c++/safe_allocation.h>
11 #include <darwintest.h>
12 #include "test_utils.h"
13 #include <type_traits>
14 
15 struct T {
16 	int i;
17 };
18 
19 template <typename T>
20 static void
tests()21 tests()
22 {
23 	using A = test_safe_allocation<T>;
24 
25 	// Check begin()/end() for a non-null allocation
26 	{
27 		A array(10, libkern::allocate_memory);
28 		T* data = array.data();
29 		test_bounded_ptr<T> begin = array.begin();
30 		test_bounded_ptr<T> end = array.end();
31 		CHECK(begin.discard_bounds() == data);
32 		CHECK(end.unsafe_discard_bounds() == data + 10);
33 	}
34 	{
35 		A const array(10, libkern::allocate_memory);
36 		T const* data = array.data();
37 		test_bounded_ptr<T const> begin = array.begin();
38 		test_bounded_ptr<T const> end = array.end();
39 		CHECK(begin.discard_bounds() == data);
40 		CHECK(end.unsafe_discard_bounds() == data + 10);
41 	}
42 
43 	// Check begin()/end() for a null allocation
44 	{
45 		A array = nullptr;
46 		test_bounded_ptr<T> begin = array.begin();
47 		test_bounded_ptr<T> end = array.end();
48 		CHECK(begin.unsafe_discard_bounds() == nullptr);
49 		CHECK(end.unsafe_discard_bounds() == nullptr);
50 		CHECK(begin == end);
51 	}
52 	{
53 		A const array = nullptr;
54 		test_bounded_ptr<T const> begin = array.begin();
55 		test_bounded_ptr<T const> end = array.end();
56 		CHECK(begin.unsafe_discard_bounds() == nullptr);
57 		CHECK(end.unsafe_discard_bounds() == nullptr);
58 		CHECK(begin == end);
59 	}
60 
61 	// Check associated types
62 	{
63 		static_assert(std::is_same_v<typename A::iterator, test_bounded_ptr<T> >);
64 		static_assert(std::is_same_v<typename A::const_iterator, test_bounded_ptr<T const> >);
65 	}
66 }
67 
68 T_DECL(begin_end, "safe_allocation.begin_end", T_META_TAG_VM_PREFERRED) {
69 	tests<T>();
70 	tests<T const>();
71 }
72