1 // 2 // Tests for 3 // explicit safe_allocation(size_t n, allocate_memory_t); 4 // 5 6 #include <libkern/c++/safe_allocation.h> 7 #include <darwintest.h> 8 #include "test_utils.h" 9 #include <cstddef> 10 #include <limits> 11 12 struct T { 13 int i; 14 }; 15 16 struct TrackInit { 17 bool initialized; 18 TrackInit() : initialized(true) 19 { 20 } 21 }; 22 23 template <typename T> 24 static void 25 tests() 26 { 27 { 28 tracking_allocator::reset(); 29 { 30 tracked_safe_allocation<T> array(10, libkern::allocate_memory); 31 CHECK(tracking_allocator::allocated_size == 10 * sizeof(T)); 32 CHECK(array.data() != nullptr); 33 CHECK(array.size() == 10); 34 CHECK(array.begin() == array.data()); 35 CHECK(array.end() == array.data() + 10); 36 } 37 CHECK(tracking_allocator::deallocated_size == 10 * sizeof(T)); 38 } 39 40 // Check with a huge number of elements that will overflow size_t 41 { 42 std::size_t max_n = std::numeric_limits<std::size_t>::max() / sizeof(T); 43 tracking_allocator::reset(); 44 45 { 46 tracked_safe_allocation<T> array(max_n + 1, libkern::allocate_memory); 47 CHECK(array.data() == nullptr); 48 CHECK(array.size() == 0); 49 CHECK(array.begin() == array.end()); 50 CHECK(!tracking_allocator::did_allocate); 51 } 52 CHECK(!tracking_allocator::did_deallocate); 53 } 54 } 55 56 T_DECL(ctor_allocate, "safe_allocation.ctor.allocate") { 57 tests<T>(); 58 tests<T const>(); 59 60 // Make sure we value-initialize elements 61 { 62 tracked_safe_allocation<TrackInit> array(10, libkern::allocate_memory); 63 for (int i = 0; i != 10; ++i) { 64 CHECK(array[i].initialized == true); 65 } 66 } 67 } 68