1 // 2 // Copyright (c) 2019 Apple, Inc. All rights reserved. 3 // 4 // @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 // 6 // This file contains Original Code and/or Modifications of Original Code 7 // as defined in and that are subject to the Apple Public Source License 8 // Version 2.0 (the 'License'). You may not use this file except in 9 // compliance with the License. The rights granted to you under the License 10 // may not be used to create, or enable the creation or redistribution of, 11 // unlawful or unlicensed copies of an Apple operating system, or to 12 // circumvent, violate, or enable the circumvention or violation of, any 13 // terms of an Apple operating system software license agreement. 14 // 15 // Please obtain a copy of the License at 16 // http://www.opensource.apple.com/apsl/ and read it before using this file. 17 // 18 // The Original Code and all software distributed under the License are 19 // distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 // EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 // INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 // FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 // Please see the License for the specific language governing rights and 24 // limitations under the License. 25 // 26 // @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 // 28 29 #ifndef XNU_LIBKERN_LIBKERN_CXX_BOUNDED_ARRAY_H 30 #define XNU_LIBKERN_LIBKERN_CXX_BOUNDED_ARRAY_H 31 32 #if !TAPI 33 34 #if DRIVERKIT_FRAMEWORK_INCLUDE 35 #include <DriverKit/bounded_ptr.h> 36 #else 37 #include <libkern/c++/bounded_ptr.h> 38 #endif /* DRIVERKIT_FRAMEWORK_INCLUDE */ 39 #include <stddef.h> 40 #include <os/base.h> 41 42 namespace libkern { 43 // `bounded_array` is a simple abstraction for a C-style array. 44 // 45 // Unlike C-style arrays, however, it ensures that the array is not accessed 46 // outside of its bounds. Furthermore, the iterators of the `bounded_array` 47 // are `bounded_ptr`, which track the range they're allowed to access. 48 // 49 // TODO: 50 // - Should we provide deep comparison operators? 51 // - Document individual methods 52 template <typename T, size_t N, typename TrappingPolicy> 53 struct bounded_array { 54 // DO NOT USE THIS MEMBER DIRECTLY OR WE WILL BREAK YOUR CODE IN THE FUTURE. 55 // THIS HAS TO BE PUBLIC FOR THIS TYPE TO SUPPORT AGGREGATE-INITIALIZATION. 56 T data_[N]; 57 58 using iterator = bounded_ptr<T, TrappingPolicy>; 59 using const_iterator = bounded_ptr<T const, TrappingPolicy>; 60 61 OS_ALWAYS_INLINE iterator beginbounded_array62 begin() noexcept 63 { 64 return iterator(data_, data_, data_ + N); 65 } 66 OS_ALWAYS_INLINE const_iterator beginbounded_array67 begin() const noexcept 68 { 69 return const_iterator(data_, data_, data_ + N); 70 } 71 iterator endbounded_array72 end() noexcept 73 { 74 return iterator(data_ + N, data_, data_ + N); 75 } 76 const_iterator endbounded_array77 end() const noexcept 78 { 79 return const_iterator(data_ + N, data_, data_ + N); 80 } 81 constexpr size_t sizebounded_array82 size() const noexcept 83 { 84 return N; 85 } 86 constexpr size_t lengthbounded_array87 length() const noexcept 88 { 89 return N; 90 } 91 constexpr T* databounded_array92 data() noexcept 93 { 94 return data_; 95 } 96 constexpr T const* databounded_array97 data() const noexcept 98 { 99 return data_; 100 } 101 OS_ALWAYS_INLINE T& 102 operator[](ptrdiff_t n) 103 { 104 return begin()[n]; 105 } 106 OS_ALWAYS_INLINE T const& 107 operator[](ptrdiff_t n) const 108 { 109 return begin()[n]; 110 } 111 }; 112 } // end namespace libkern 113 114 #endif /* !TAPI */ 115 116 #endif // !XNU_LIBKERN_LIBKERN_CXX_BOUNDED_ARRAY_H 117