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
42namespace 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
52template <typename T, size_t N, typename TrappingPolicy>
53struct 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
62 begin() noexcept
63 {
64 return iterator(data_, data_, data_ + N);
65 }
66 OS_ALWAYS_INLINE const_iterator
67 begin() const noexcept
68 {
69 return const_iterator(data_, data_, data_ + N);
70 }
71 iterator
72 end() noexcept
73 {
74 return iterator(data_ + N, data_, data_ + N);
75 }
76 const_iterator
77 end() const noexcept
78 {
79 return const_iterator(data_ + N, data_, data_ + N);
80 }
81 constexpr size_t
82 size() const noexcept
83 {
84 return N;
85 }
86 constexpr size_t
87 length() const noexcept
88 {
89 return N;
90 }
91 constexpr T*
92 data() noexcept
93 {
94 return data_;
95 }
96 constexpr T const*
97 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