1*19c3b8c2SApple OSS Distributions // 2*19c3b8c2SApple OSS Distributions // Copyright (c) 2019 Apple, Inc. All rights reserved. 3*19c3b8c2SApple OSS Distributions // 4*19c3b8c2SApple OSS Distributions // @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*19c3b8c2SApple OSS Distributions // 6*19c3b8c2SApple OSS Distributions // This file contains Original Code and/or Modifications of Original Code 7*19c3b8c2SApple OSS Distributions // as defined in and that are subject to the Apple Public Source License 8*19c3b8c2SApple OSS Distributions // Version 2.0 (the 'License'). You may not use this file except in 9*19c3b8c2SApple OSS Distributions // compliance with the License. The rights granted to you under the License 10*19c3b8c2SApple OSS Distributions // may not be used to create, or enable the creation or redistribution of, 11*19c3b8c2SApple OSS Distributions // unlawful or unlicensed copies of an Apple operating system, or to 12*19c3b8c2SApple OSS Distributions // circumvent, violate, or enable the circumvention or violation of, any 13*19c3b8c2SApple OSS Distributions // terms of an Apple operating system software license agreement. 14*19c3b8c2SApple OSS Distributions // 15*19c3b8c2SApple OSS Distributions // Please obtain a copy of the License at 16*19c3b8c2SApple OSS Distributions // http://www.opensource.apple.com/apsl/ and read it before using this file. 17*19c3b8c2SApple OSS Distributions // 18*19c3b8c2SApple OSS Distributions // The Original Code and all software distributed under the License are 19*19c3b8c2SApple OSS Distributions // distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*19c3b8c2SApple OSS Distributions // EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*19c3b8c2SApple OSS Distributions // INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*19c3b8c2SApple OSS Distributions // FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*19c3b8c2SApple OSS Distributions // Please see the License for the specific language governing rights and 24*19c3b8c2SApple OSS Distributions // limitations under the License. 25*19c3b8c2SApple OSS Distributions // 26*19c3b8c2SApple OSS Distributions // @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*19c3b8c2SApple OSS Distributions // 28*19c3b8c2SApple OSS Distributions 29*19c3b8c2SApple OSS Distributions #ifndef XNU_LIBKERN_LIBKERN_CXX_BOUNDED_ARRAY_REF_H 30*19c3b8c2SApple OSS Distributions #define XNU_LIBKERN_LIBKERN_CXX_BOUNDED_ARRAY_REF_H 31*19c3b8c2SApple OSS Distributions 32*19c3b8c2SApple OSS Distributions #if !TAPI 33*19c3b8c2SApple OSS Distributions 34*19c3b8c2SApple OSS Distributions #if DRIVERKIT_FRAMEWORK_INCLUDE 35*19c3b8c2SApple OSS Distributions #include <DriverKit/bounded_array.h> 36*19c3b8c2SApple OSS Distributions #include <DriverKit/bounded_ptr.h> 37*19c3b8c2SApple OSS Distributions #else 38*19c3b8c2SApple OSS Distributions #include <libkern/c++/bounded_array.h> 39*19c3b8c2SApple OSS Distributions #include <libkern/c++/bounded_ptr.h> 40*19c3b8c2SApple OSS Distributions #endif /* DRIVERKIT_FRAMEWORK_INCLUDE */ 41*19c3b8c2SApple OSS Distributions 42*19c3b8c2SApple OSS Distributions #include <stddef.h> 43*19c3b8c2SApple OSS Distributions #include <os/base.h> 44*19c3b8c2SApple OSS Distributions 45*19c3b8c2SApple OSS Distributions namespace libkern { 46*19c3b8c2SApple OSS Distributions namespace bar_detail { 47*19c3b8c2SApple OSS Distributions using nullptr_t = decltype(nullptr); 48*19c3b8c2SApple OSS Distributions } 49*19c3b8c2SApple OSS Distributions 50*19c3b8c2SApple OSS Distributions // Represents a reference to a sequence of 0 or more elements consecutively in 51*19c3b8c2SApple OSS Distributions // memory, i.e. a start pointer and a length. 52*19c3b8c2SApple OSS Distributions // 53*19c3b8c2SApple OSS Distributions // When elements of the sequence are accessed, `bounded_array_ref` ensures 54*19c3b8c2SApple OSS Distributions // that those elements are in the bounds of the sequence (which are provided 55*19c3b8c2SApple OSS Distributions // when the `bounded_array_ref` is constructed). 56*19c3b8c2SApple OSS Distributions // 57*19c3b8c2SApple OSS Distributions // This class does not own the underlying data. It is expected to be used in 58*19c3b8c2SApple OSS Distributions // situations where the data resides in some other buffer, whose lifetime 59*19c3b8c2SApple OSS Distributions // extends past that of the `bounded_array_ref`. For this reason, storing a 60*19c3b8c2SApple OSS Distributions // `bounded_array_ref` adds the risk of a dangling pointer if the lifetime of 61*19c3b8c2SApple OSS Distributions // the `bounded_array_ref` extends past that of the underlying data. 62*19c3b8c2SApple OSS Distributions // 63*19c3b8c2SApple OSS Distributions // `bounded_array_ref` is trivially copyable and it should be passed by value. 64*19c3b8c2SApple OSS Distributions template <typename T, typename TrappingPolicy> 65*19c3b8c2SApple OSS Distributions struct bounded_array_ref { 66*19c3b8c2SApple OSS Distributions // Creates an empty `bounded_array_ref`. 67*19c3b8c2SApple OSS Distributions // 68*19c3b8c2SApple OSS Distributions // An empty `bounded_array_ref` does not reference anything, so its 69*19c3b8c2SApple OSS Distributions // `data()` is null and its `size()` is 0. bounded_array_refbounded_array_ref70*19c3b8c2SApple OSS Distributions explicit constexpr bounded_array_ref() noexcept : data_(nullptr), size_(0) 71*19c3b8c2SApple OSS Distributions { 72*19c3b8c2SApple OSS Distributions } 73*19c3b8c2SApple OSS Distributions 74*19c3b8c2SApple OSS Distributions // Creates a `bounded_array_ref` from a bounded pointer and a size. 75*19c3b8c2SApple OSS Distributions // 76*19c3b8c2SApple OSS Distributions // The resulting `bounded_array_ref` starts at the location where the 77*19c3b8c2SApple OSS Distributions // pointer points, and has the given number of elements. All the elements 78*19c3b8c2SApple OSS Distributions // must be in the bounds of the `bounded_ptr`, otherwise this constructor 79*19c3b8c2SApple OSS Distributions // will trap. bounded_array_refbounded_array_ref80*19c3b8c2SApple OSS Distributions explicit constexpr bounded_array_ref(bounded_ptr<T, TrappingPolicy> data, size_t n) 81*19c3b8c2SApple OSS Distributions : data_(data.unsafe_discard_bounds()), size_(static_cast<uint32_t>(n)) 82*19c3b8c2SApple OSS Distributions { 83*19c3b8c2SApple OSS Distributions if (n != 0) { 84*19c3b8c2SApple OSS Distributions data[n - 1]; // make sure the bounds are valid 85*19c3b8c2SApple OSS Distributions // TODO: find a better way to do that 86*19c3b8c2SApple OSS Distributions } 87*19c3b8c2SApple OSS Distributions if (__improbable(n > UINT32_MAX)) { 88*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: Can't construct from a size greater than UINT32_MAX"); 89*19c3b8c2SApple OSS Distributions } 90*19c3b8c2SApple OSS Distributions } 91*19c3b8c2SApple OSS Distributions 92*19c3b8c2SApple OSS Distributions // Creates a `bounded_array_ref` from a raw pointer and a size. 93*19c3b8c2SApple OSS Distributions // 94*19c3b8c2SApple OSS Distributions // The resulting `bounded_array_ref` starts at the location where the 95*19c3b8c2SApple OSS Distributions // pointer points, and has the given number of elements. This constructor 96*19c3b8c2SApple OSS Distributions // trusts that `n` elements are reachable from the given pointer. bounded_array_refbounded_array_ref97*19c3b8c2SApple OSS Distributions explicit constexpr bounded_array_ref(T* data, size_t n) : data_(data), size_(static_cast<uint32_t>(n)) 98*19c3b8c2SApple OSS Distributions { 99*19c3b8c2SApple OSS Distributions if (__improbable(n > UINT32_MAX)) { 100*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: Can't construct from a size greater than UINT32_MAX"); 101*19c3b8c2SApple OSS Distributions } 102*19c3b8c2SApple OSS Distributions } 103*19c3b8c2SApple OSS Distributions 104*19c3b8c2SApple OSS Distributions // Creates a `bounded_array_ref` from a `[first, last)` half-open range. 105*19c3b8c2SApple OSS Distributions // 106*19c3b8c2SApple OSS Distributions // The resulting `bounded_array_ref` starts at the location pointed-to by 107*19c3b8c2SApple OSS Distributions // `first`, and contains `last - first` elements. The `[first, last)` 108*19c3b8c2SApple OSS Distributions // half-open range must be a valid range, i.e. it must be the case that 109*19c3b8c2SApple OSS Distributions // `first <= last`, otherwise the constructor traps. bounded_array_refbounded_array_ref110*19c3b8c2SApple OSS Distributions explicit constexpr bounded_array_ref(T* first, T* last) : data_(first), size_(static_cast<uint32_t>(last - first)) 111*19c3b8c2SApple OSS Distributions { 112*19c3b8c2SApple OSS Distributions if (__improbable(first > last)) { 113*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: The [first, last) constructor requires a valid range."); 114*19c3b8c2SApple OSS Distributions } 115*19c3b8c2SApple OSS Distributions if (__improbable(last - first > UINT32_MAX)) { 116*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: Can't construct from a size greater than UINT32_MAX"); 117*19c3b8c2SApple OSS Distributions } 118*19c3b8c2SApple OSS Distributions } 119*19c3b8c2SApple OSS Distributions 120*19c3b8c2SApple OSS Distributions // Creates a `bounded_array_ref` from a `bounded_array`. 121*19c3b8c2SApple OSS Distributions // 122*19c3b8c2SApple OSS Distributions // The resulting `bounded_array_ref` starts at the first element of the 123*19c3b8c2SApple OSS Distributions // `bounded_array`, and has the number of elements in the `bounded_array`. 124*19c3b8c2SApple OSS Distributions template <size_t N> bounded_array_refbounded_array_ref125*19c3b8c2SApple OSS Distributions constexpr bounded_array_ref(bounded_array<T, N, TrappingPolicy>& data) : data_(data.data()), size_(static_cast<uint32_t>(data.size())) 126*19c3b8c2SApple OSS Distributions { 127*19c3b8c2SApple OSS Distributions if (__improbable(data.size() > UINT32_MAX)) { 128*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: Can't construct from a size greater than UINT32_MAX"); 129*19c3b8c2SApple OSS Distributions } 130*19c3b8c2SApple OSS Distributions } 131*19c3b8c2SApple OSS Distributions 132*19c3b8c2SApple OSS Distributions // Creates a `bounded_array_ref` from a C-style array. 133*19c3b8c2SApple OSS Distributions // 134*19c3b8c2SApple OSS Distributions // The resulting `bounded_array_ref` starts at the first element of the 135*19c3b8c2SApple OSS Distributions // C-style array, and has the number of elements in that array. 136*19c3b8c2SApple OSS Distributions template <size_t N> bounded_array_refbounded_array_ref137*19c3b8c2SApple OSS Distributions constexpr bounded_array_ref(T (&array)[N]) : data_(array), size_(static_cast<uint32_t>(N)) 138*19c3b8c2SApple OSS Distributions { 139*19c3b8c2SApple OSS Distributions if (__improbable(N > UINT32_MAX)) { 140*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: Can't construct from a size greater than UINT32_MAX"); 141*19c3b8c2SApple OSS Distributions } 142*19c3b8c2SApple OSS Distributions } 143*19c3b8c2SApple OSS Distributions 144*19c3b8c2SApple OSS Distributions constexpr 145*19c3b8c2SApple OSS Distributions bounded_array_ref(bounded_array_ref const&) = default; 146*19c3b8c2SApple OSS Distributions constexpr 147*19c3b8c2SApple OSS Distributions bounded_array_ref(bounded_array_ref&& other) noexcept = default; 148*19c3b8c2SApple OSS Distributions 149*19c3b8c2SApple OSS Distributions constexpr bounded_array_ref& operator=(bounded_array_ref const&) = default; 150*19c3b8c2SApple OSS Distributions constexpr bounded_array_ref& operator=(bounded_array_ref&& other) = default; 151*19c3b8c2SApple OSS Distributions ~bounded_array_ref() = default; 152*19c3b8c2SApple OSS Distributions 153*19c3b8c2SApple OSS Distributions // Returns whether the `bounded_array_ref` points to a sequence or not. 154*19c3b8c2SApple OSS Distributions // 155*19c3b8c2SApple OSS Distributions // Note that pointing to a sequence at all is different from pointing to 156*19c3b8c2SApple OSS Distributions // a valid sequence, or having a size of 0. If a `bounded_array_ref` 157*19c3b8c2SApple OSS Distributions // points to a sequence (regardless of whether it is valid or whether 158*19c3b8c2SApple OSS Distributions // the size of that sequence is 0), this operator will return true. 159*19c3b8c2SApple OSS Distributions explicit 160*19c3b8c2SApple OSS Distributions operator bool() const noexcept 161*19c3b8c2SApple OSS Distributions { 162*19c3b8c2SApple OSS Distributions return data_ != nullptr; 163*19c3b8c2SApple OSS Distributions } 164*19c3b8c2SApple OSS Distributions 165*19c3b8c2SApple OSS Distributions using iterator = bounded_ptr<T, TrappingPolicy>; 166*19c3b8c2SApple OSS Distributions 167*19c3b8c2SApple OSS Distributions // The following methods allow obtaining iterators (i.e. cursors) to 168*19c3b8c2SApple OSS Distributions // objects inside a `bounded_array_ref`. 169*19c3b8c2SApple OSS Distributions // 170*19c3b8c2SApple OSS Distributions // The iterators of a `bounded_array_ref` are `bounded_ptr`s, which know 171*19c3b8c2SApple OSS Distributions // the bounds of the sequence and will trap when dereferenced outside 172*19c3b8c2SApple OSS Distributions // of those bounds. 173*19c3b8c2SApple OSS Distributions // 174*19c3b8c2SApple OSS Distributions // `begin()` returns an iterator to the first element in the range, and 175*19c3b8c2SApple OSS Distributions // `end()` returns an iterator to one-past-the-last element in the range. 176*19c3b8c2SApple OSS Distributions // The `end()` iterator can't be dereferenced, since it is out of bounds. 177*19c3b8c2SApple OSS Distributions // 178*19c3b8c2SApple OSS Distributions // If the `bounded_array_ref` is empty, these methods will return null 179*19c3b8c2SApple OSS Distributions // `bounded_ptr`s, which can be checked for equality but can't be 180*19c3b8c2SApple OSS Distributions // dereferenced. 181*19c3b8c2SApple OSS Distributions iterator beginbounded_array_ref182*19c3b8c2SApple OSS Distributions begin() const noexcept 183*19c3b8c2SApple OSS Distributions { 184*19c3b8c2SApple OSS Distributions return iterator(data_, data_, data_ + size_); 185*19c3b8c2SApple OSS Distributions } 186*19c3b8c2SApple OSS Distributions iterator endbounded_array_ref187*19c3b8c2SApple OSS Distributions end() const noexcept 188*19c3b8c2SApple OSS Distributions { 189*19c3b8c2SApple OSS Distributions return iterator(data_ + size_, data_, data_ + size_); 190*19c3b8c2SApple OSS Distributions } 191*19c3b8c2SApple OSS Distributions 192*19c3b8c2SApple OSS Distributions // Returns the number of elements in the range referenced by the 193*19c3b8c2SApple OSS Distributions // `bounded_array_ref`. 194*19c3b8c2SApple OSS Distributions // 195*19c3b8c2SApple OSS Distributions // This method returns `0` if the `bounded_array_ref` is null, since 196*19c3b8c2SApple OSS Distributions // such an array ref behaves the same as an empty range. 197*19c3b8c2SApple OSS Distributions constexpr size_t sizebounded_array_ref198*19c3b8c2SApple OSS Distributions size() const noexcept 199*19c3b8c2SApple OSS Distributions { 200*19c3b8c2SApple OSS Distributions return size_; 201*19c3b8c2SApple OSS Distributions } 202*19c3b8c2SApple OSS Distributions 203*19c3b8c2SApple OSS Distributions // This has the same behavior as size(), but is intended to avoid confusion 204*19c3b8c2SApple OSS Distributions // about whether it is returning an array count or size in bytes. 205*19c3b8c2SApple OSS Distributions constexpr size_t lengthbounded_array_ref206*19c3b8c2SApple OSS Distributions length() const noexcept 207*19c3b8c2SApple OSS Distributions { 208*19c3b8c2SApple OSS Distributions return size_; 209*19c3b8c2SApple OSS Distributions } 210*19c3b8c2SApple OSS Distributions 211*19c3b8c2SApple OSS Distributions // Returns a non-owning pointer to the underlying memory referenced by a 212*19c3b8c2SApple OSS Distributions // `bounded_array_ref`. 213*19c3b8c2SApple OSS Distributions // 214*19c3b8c2SApple OSS Distributions // This method can be called even if the `bounded_array_ref` is null, in 215*19c3b8c2SApple OSS Distributions // which case the returned pointer will be null. 216*19c3b8c2SApple OSS Distributions constexpr T* databounded_array_ref217*19c3b8c2SApple OSS Distributions data() const noexcept 218*19c3b8c2SApple OSS Distributions { 219*19c3b8c2SApple OSS Distributions return data_; 220*19c3b8c2SApple OSS Distributions } 221*19c3b8c2SApple OSS Distributions 222*19c3b8c2SApple OSS Distributions // Access the n-th element of a `bounded_array_ref`. 223*19c3b8c2SApple OSS Distributions // 224*19c3b8c2SApple OSS Distributions // If `n` is out of the bounds of the sequence, this operation will 225*19c3b8c2SApple OSS Distributions // trap. If the array ref is null, this operation will trap too. 226*19c3b8c2SApple OSS Distributions // 227*19c3b8c2SApple OSS Distributions // Design note: 228*19c3b8c2SApple OSS Distributions // We voluntarily use a signed type to represent the index even though a 229*19c3b8c2SApple OSS Distributions // negative index will always cause a trap. If we used an unsigned type, 230*19c3b8c2SApple OSS Distributions // we could get an implicit conversion from signed to unsigned, which 231*19c3b8c2SApple OSS Distributions // could silently wrap around. We think trapping early is more likely 232*19c3b8c2SApple OSS Distributions // to be helpful in this situation. 233*19c3b8c2SApple OSS Distributions OS_ALWAYS_INLINE T& 234*19c3b8c2SApple OSS Distributions operator[](ptrdiff_t n) const 235*19c3b8c2SApple OSS Distributions { 236*19c3b8c2SApple OSS Distributions return begin()[n]; 237*19c3b8c2SApple OSS Distributions } 238*19c3b8c2SApple OSS Distributions 239*19c3b8c2SApple OSS Distributions // Chop off the first `n` elements of the array, and keep `m` elements 240*19c3b8c2SApple OSS Distributions // in the array. 241*19c3b8c2SApple OSS Distributions // 242*19c3b8c2SApple OSS Distributions // The resulting range can be described by `[beg + n, beg + n + m)`, where 243*19c3b8c2SApple OSS Distributions // `beg` is the `begin()` of the range being sliced. This operation traps 244*19c3b8c2SApple OSS Distributions // if `n + m` is larger than the number of elements in the array. 245*19c3b8c2SApple OSS Distributions // 246*19c3b8c2SApple OSS Distributions // Since `bounded_array_ref` checks (or assumes) that the range it is 247*19c3b8c2SApple OSS Distributions // given on construction is within bounds and `slice()` checks that the 248*19c3b8c2SApple OSS Distributions // produced slice is within the original range, it is impossible to create 249*19c3b8c2SApple OSS Distributions // a `bounded_array_ref` that isn't a subset of a valid range using this 250*19c3b8c2SApple OSS Distributions // function. 251*19c3b8c2SApple OSS Distributions bounded_array_ref<T, TrappingPolicy> slicebounded_array_ref252*19c3b8c2SApple OSS Distributions slice(size_t n, size_t m) const 253*19c3b8c2SApple OSS Distributions { 254*19c3b8c2SApple OSS Distributions uint32_t total; 255*19c3b8c2SApple OSS Distributions if (__improbable(os_add_overflow(n, m, &total))) { 256*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: n + m is larger than the size of any bounded_array_ref"); 257*19c3b8c2SApple OSS Distributions } 258*19c3b8c2SApple OSS Distributions if (__improbable(total > size())) { 259*19c3b8c2SApple OSS Distributions TrappingPolicy::trap("bounded_array_ref: invalid slice provided, the indices are of bounds for the bounded_array_ref"); 260*19c3b8c2SApple OSS Distributions } 261*19c3b8c2SApple OSS Distributions return bounded_array_ref(data_ + n, m); 262*19c3b8c2SApple OSS Distributions } 263*19c3b8c2SApple OSS Distributions 264*19c3b8c2SApple OSS Distributions private: 265*19c3b8c2SApple OSS Distributions T* data_; 266*19c3b8c2SApple OSS Distributions uint32_t size_; 267*19c3b8c2SApple OSS Distributions }; 268*19c3b8c2SApple OSS Distributions 269*19c3b8c2SApple OSS Distributions // The comparison functions against `nullptr` all return whether the 270*19c3b8c2SApple OSS Distributions // `bounded_array_ref` references a sequence or not. 271*19c3b8c2SApple OSS Distributions template <typename T, typename P> 272*19c3b8c2SApple OSS Distributions bool 273*19c3b8c2SApple OSS Distributions operator==(bounded_array_ref<T, P> const& x, bar_detail::nullptr_t) 274*19c3b8c2SApple OSS Distributions { 275*19c3b8c2SApple OSS Distributions return !static_cast<bool>(x); 276*19c3b8c2SApple OSS Distributions } 277*19c3b8c2SApple OSS Distributions 278*19c3b8c2SApple OSS Distributions template <typename T, typename P> 279*19c3b8c2SApple OSS Distributions bool 280*19c3b8c2SApple OSS Distributions operator!=(bounded_array_ref<T, P> const& x, bar_detail::nullptr_t) 281*19c3b8c2SApple OSS Distributions { 282*19c3b8c2SApple OSS Distributions return !(x == nullptr); 283*19c3b8c2SApple OSS Distributions } 284*19c3b8c2SApple OSS Distributions 285*19c3b8c2SApple OSS Distributions template <typename T, typename P> 286*19c3b8c2SApple OSS Distributions bool 287*19c3b8c2SApple OSS Distributions operator==(bar_detail::nullptr_t, bounded_array_ref<T, P> const& x) 288*19c3b8c2SApple OSS Distributions { 289*19c3b8c2SApple OSS Distributions return x == nullptr; 290*19c3b8c2SApple OSS Distributions } 291*19c3b8c2SApple OSS Distributions 292*19c3b8c2SApple OSS Distributions template <typename T, typename P> 293*19c3b8c2SApple OSS Distributions bool 294*19c3b8c2SApple OSS Distributions operator!=(bar_detail::nullptr_t, bounded_array_ref<T, P> const& x) 295*19c3b8c2SApple OSS Distributions { 296*19c3b8c2SApple OSS Distributions return x != nullptr; 297*19c3b8c2SApple OSS Distributions } 298*19c3b8c2SApple OSS Distributions } // end namespace libkern 299*19c3b8c2SApple OSS Distributions 300*19c3b8c2SApple OSS Distributions #endif /* !TAPI */ 301*19c3b8c2SApple OSS Distributions 302*19c3b8c2SApple OSS Distributions #endif // !XNU_LIBKERN_LIBKERN_CXX_BOUNDED_ARRAY_REF_H 303