xref: /xnu-8792.81.2/iokit/DriverKit/bounded_array_ref.h (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
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