diff --git a/runtime/cpp/emboss_array_view.h b/runtime/cpp/emboss_array_view.h index 674b2ad..fa8ccd3 100644 --- a/runtime/cpp/emboss_array_view.h +++ b/runtime/cpp/emboss_array_view.h @@ -56,7 +56,7 @@ class ElementViewIterator { explicit ElementViewIterator(const GenericArrayView array_view, ::std::ptrdiff_t index) - : array_view_(array_view), view_(array_view[index]), index_(index) {} + : array_view_(array_view), view_(array_view.at(index)), index_(index) {} ElementViewIterator() = default; @@ -66,7 +66,7 @@ class ElementViewIterator { ElementViewIterator &operator+=(difference_type d) { index_ += (kDirection == ElementViewIteratorDirection::kForward ? d : -d); - view_ = array_view_[index_]; + view_ = array_view_.at(index_); return *this; } @@ -178,9 +178,15 @@ class GenericArrayView final { : parameters_{parameters...}, buffer_{buffer} {} ElementView operator[](::std::size_t index) const { - return IndexOperatorHelper::ConstructElement(parameters_, buffer_, - index); + return IndexOperatorHelper<(sizeof...(ElementViewParameterTypes) == + 0)>::UncheckedConstructElement(parameters_, + buffer_, index); + } + + ElementView at(::std::size_t index) const { + return IndexOperatorHelper<(sizeof...(ElementViewParameterTypes) == + 0)>::ConstructElement(parameters_, buffer_, + index, ElementCount()); } ForwardIterator begin() const { return ForwardIterator(*this, 0); } @@ -315,17 +321,37 @@ class GenericArrayView final { template struct IndexOperatorHelper { static ElementView ConstructElement( + const ::std::tuple ¶meters, + BufferType buffer, ::std::size_t index, ::std::size_t size) { + return IndexOperatorHelper< + (sizeof...(ElementViewParameterTypes) == 1 + sizeof...(N)), N..., + sizeof...(N)>::ConstructElement(parameters, buffer, index, size); + } + + static ElementView UncheckedConstructElement( const ::std::tuple ¶meters, BufferType buffer, ::std::size_t index) { return IndexOperatorHelper< - sizeof...(ElementViewParameterTypes) == 1 + sizeof...(N), N..., - sizeof...(N)>::ConstructElement(parameters, buffer, index); + (sizeof...(ElementViewParameterTypes) == 1 + sizeof...(N)), N..., + sizeof...(N)>::UncheckedConstructElement(parameters, buffer, index); } }; template struct IndexOperatorHelper { static ElementView ConstructElement( + const ::std::tuple ¶meters, + BufferType buffer, ::std::size_t index, ::std::size_t size) { + return ElementView( + ::std::get(parameters)..., + index < 0 || index >= size + ? typename BufferType::template OffsetStorageType(nullptr) + : buffer.template GetOffsetStorage( + kElementSize * index, kElementSize)); + } + + static ElementView UncheckedConstructElement( const ::std::tuple ¶meters, BufferType buffer, ::std::size_t index) { return ElementView(::std::get(parameters)...,