@@ -62,6 +62,46 @@ is_forwarding_wrapper(T::Type) = false
62
62
is_forwarding_wrapper (@nospecialize T:: Type{<:Base.Slice} ) = true
63
63
is_forwarding_wrapper (@nospecialize x) = is_forwarding_wrapper (typeof (x))
64
64
65
+ """
66
+ GetIndex(buffer) = GetIndex{true}(buffer)
67
+ GetIndex{check}(buffer) -> g
68
+
69
+ Wraps an indexable buffer in a function type that is indexed when called, so that `g(inds..)`
70
+ is equivalent to `buffer[inds...]`. If `check` is `false`, then all indexing arguments are
71
+ considered in-bounds. The default value for `check` is `true`, requiring bounds checking for
72
+ each index.
73
+
74
+ !!! Warning
75
+ Passing `false` as `check` may result in incorrect results/crashes/corruption for
76
+ out-of-bounds indices, similar to inappropriate use of `@inbounds`. The user is
77
+ responsible for ensuring this is correctly used.
78
+
79
+ # Examples
80
+
81
+ ```julia
82
+ julia> ArrayInterfaceCore.GetIndex(1:10)[3]
83
+ 3
84
+
85
+ julia> ArrayInterfaceCore.GetIndex{false}(1:10)[11] # shouldn't be in-bounds
86
+ 11
87
+
88
+ ```
89
+
90
+ """
91
+ struct GetIndex{CB,B} <: Function
92
+ buffer:: B
93
+
94
+ GetIndex {true,B} (b) where {B} = new {true,B} (b)
95
+ GetIndex {false,B} (b) where {B} = new {false,B} (b)
96
+ GetIndex {check} (b:: B ) where {check,B} = GetIndex {check,B} (b)
97
+ GetIndex (b) = GetIndex {true} (b)
98
+ end
99
+
100
+ buffer (g:: GetIndex ) = getfield (g, :buffer )
101
+
102
+ Base. @propagate_inbounds @inline (g:: GetIndex{true} )(inds... ) = buffer (g)[inds... ]
103
+ @inline (g:: GetIndex{false} )(inds... ) = @inbounds (buffer (g)[inds... ])
104
+
65
105
"""
66
106
can_change_size(::Type{T}) -> Bool
67
107
0 commit comments