# What is the most idiomatic way to implement bounds checking in \`getindex\` for arbitrary types?

**URL:** <https://discourse.julialang.org/t/what-is-the-most-idiomatic-way-to-implement-bounds-checking-in-getindex-for-arbitrary-types/94779>\
**Category:** General Usage\
**Tags:** inbounds\
**Created:** [February 17, 2023, 9:17am UTC](https://discourse.julialang.org/t/what-is-the-most-idiomatic-way-to-implement-bounds-checking-in-getindex-for-arbitrary-types/94779 "2023-02-17T09:17:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![loonatick-src](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/loonatick-src/32/32248_2.png) [@loonatick-src](https://discourse.julialang.org/u/loonatick-src)\
**Post date:** [February 17, 2023, 9:17am UTC](https://discourse.julialang.org/t/what-is-the-most-idiomatic-way-to-implement-bounds-checking-in-getindex-for-arbitrary-types/94779/1 "2023-02-17T09:17:41Z")

</div>

Specifically, I have two main requirements in mind.

1. It should throw `BoundsError` with complete information.
2. The `@inbounds` macro should work as intended for this type, i.e. elide the bounds checking entirely

Item 1 seems straightforward, just conditionally throw a `BoundsError` with the right arguments. But, it seems that I am not sure about item 2; how does one check if `@inbounds` is bypassing bounds checking in the first place? I tried using `@code_warntype` and friends on `@inbounds foo[i]` where `foo isa Foo`, but it seems to give info about the operations of the inbounds macro itself.

A toy example.

```julia
struct Foo{T}
    x::Vector{T}
    y::Vector{Int}
end

import Base.getindex

function Base.getindex(f::Foo{T}, i::Int) where {T}
    idx = f.y[i]
    if idx > length(f.x)
        throw(BoundsError(x, idx))
    end
    f.x[idx]
end

```

How can one transform this code to make `@inbounds` work as intended, and how does one check if it is working as intended?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [February 17, 2023, 1:24pm UTC](https://discourse.julialang.org/t/what-is-the-most-idiomatic-way-to-implement-bounds-checking-in-getindex-for-arbitrary-types/94779/2 "2023-02-17T13:24:50Z")

</div>

```julia
Base.@propagate_inbounds function Base.getindex(f::Foo{T}, i::Int) where {T}
     idx = f.y[i]
     Base.@boundscheck idx in eachindex(f.x) || throw(BoundsError(x, idx))
     f.x[idx]
end

julia> function force_getindex(x, i)
           @inbounds x[i]
       end;

julia> x, y = [1, 2, 3], [1, 2, 3];

julia> resize!(x, 2);

julia> foo = Foo(x, y);

julia> foo[1]
1

julia> foo[2]
2

julia> foo[3]
ERROR: BoundsError: attempt to access 2-element Vector{Int64} at index [3]
Stacktrace:
 [1] getindex(f::Foo{Int64}, i::Int64)
   @ Main ./REPL[2]:3
 [2] top-level scope
   @ REPL[12]:1

julia> force_getindex(foo, 3)
3

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 17, 2023, 1:38pm UTC](https://discourse.julialang.org/t/what-is-the-most-idiomatic-way-to-implement-bounds-checking-in-getindex-for-arbitrary-types/94779/3 "2023-02-17T13:38:24Z")

</div>

> [@Vasily\_Pisarev](#):
>
> `Base.@boundscheck idx in eachindex(f.x) || throw(BoundsError(x, idx))`

Better to do

```julia
@boundscheck checkbounds(f.x, idx)

```

(Although if you do `f.x[idx]` it does the bounds check anyway, so I’m not sure why the test is needed at all.)

---

<div class="post-metadata">

**Author:** ![loonatick-src](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/loonatick-src/32/32248_2.png) [@loonatick-src](https://discourse.julialang.org/u/loonatick-src)\
**Post date:** [February 18, 2023, 4:34am UTC](https://discourse.julialang.org/t/what-is-the-most-idiomatic-way-to-implement-bounds-checking-in-getindex-for-arbitrary-types/94779/4 "2023-02-18T04:34:47Z")

</div>

I guess particular example is too simple. The explicit bounds check logic that I am actually working on is bit more involved; even if the explicit check fails, the index would still point to a valid memory location i.e. would pass the bounds checking of the default types.

Should I update the question to include a more representative example?
