27namespace stratax::indexing {
49template<
typename Source>
51 std::is_const_v<std::remove_reference_t<Source>>,
52 const typename std::remove_cvref_t<Source>::value_type,
53 typename std::remove_cvref_t<Source>::value_type>;
68 if (extent >
static_cast<size_type>(std::numeric_limits<difference_type>::max()))
105 if (stop < 0 && stop != -1)
127template<
typename Vector>
132 const auto resolved =
133 detail::normalize_slice(
137 if (resolved.step < 0)
140 "Negative-step views are not supported.");
155 shape.elements() == 0 ? vec.data() : vec.data() +
offset,
161template<
typename Matrix>
167 const auto resolved_rows =
168 detail::normalize_slice(
172 const auto resolved_cols =
173 detail::normalize_slice(
177 if (resolved_rows.step < 0 || resolved_cols.step < 0)
180 "Negative-step views are not supported.");
184 static_cast<size_type>(resolved_rows.start) * mat.strides()[0]
185 +
static_cast<size_type>(resolved_cols.start) * mat.strides()[1];
192 if (mat.strides()[0] != 0 &&
static_cast<size_type>(resolved_rows.step) >
193 std::numeric_limits<size_type>::max() / mat.strides()[0])
204 shape.elements() == 0 ? mat.data() : mat.data() +
offset,
230 return detail::make_vector_slice_view(vec,
slice);
252 return detail::make_vector_slice_view(vec,
slice);
276 return detail::make_matrix_slice_view(mat, rows, cols);
300 return detail::make_matrix_slice_view(mat, rows, cols);
306template<
typename Tensor,
typename... Slices>
309 std::remove_cvref_t<Slices>,
321 if (ranges.size() != tensor.rank())
324 "The number of slices must match the tensor rank.");
332 std::array<
size_type,
sizeof...(Slices)> out_dims{};
334 for (
size_type dim = 0; dim < ranges.size(); ++dim)
336 resolved[dim] = detail::normalize_slice(
338 tensor.shape()[dim]);
340 out_dims[dim] = resolved[dim].size;
344 std::vector<size_type>(
348 const auto& tensor_strides = tensor.strides();
352 std::vector<size_type> view_stride_values;
353 view_stride_values.reserve(resolved.size());
355 for (
size_type dim = 0; dim < resolved.size(); ++dim)
357 if (resolved[dim].step < 0)
360 "Negative-step views are not supported.");
364 static_cast<size_type>(resolved[dim].start);
366 if (tensor_strides[dim] != 0 &&
367 start > std::numeric_limits<size_type>::max() / tensor_strides[dim])
372 const auto offset_term = start * tensor_strides[dim];
374 if (
offset > std::numeric_limits<size_type>::max() - offset_term)
381 const auto step =
static_cast<size_type>(resolved[dim].step);
384 tensor_strides[dim] > std::numeric_limits<size_type>::max() / step)
389 view_stride_values.push_back(tensor_strides[dim] * step);
396 view_shape.elements() == 0 ? tensor.data() : tensor.data() +
offset,
402template<
typename Tensor>
405 const std::vector<stratax::core::Slice>& slices)
407 if (slices.size() != tensor.rank())
410 "The number of slices must match the tensor rank.");
413 std::vector<detail::ResolvedSlice> resolved(
416 std::vector<size_type> out_dims(
419 for (
size_type dim = 0; dim < slices.size(); ++dim)
421 resolved[dim] = detail::normalize_slice(
423 tensor.shape()[dim]);
425 out_dims[dim] = resolved[dim].size;
428 const auto view_shape =
431 const auto& tensor_strides = tensor.strides();
435 std::vector<size_type> view_stride_values;
436 view_stride_values.reserve(resolved.size());
438 for (
size_type dim = 0; dim < resolved.size(); ++dim)
440 if (resolved[dim].step < 0)
443 "Negative-step views are not supported.");
447 static_cast<size_type>(resolved[dim].start);
449 if (tensor_strides[dim] != 0 &&
450 start > std::numeric_limits<size_type>::max() / tensor_strides[dim])
455 const auto offset_term = start * tensor_strides[dim];
457 if (
offset > std::numeric_limits<size_type>::max() - offset_term)
464 const auto step =
static_cast<size_type>(resolved[dim].step);
467 tensor_strides[dim] > std::numeric_limits<size_type>::max() / step)
472 view_stride_values.push_back(tensor_strides[dim] * step);
479 view_shape.elements() == 0 ? tensor.data() : tensor.data() +
offset,
501template<
typename T,
typename... Slices>
504 std::remove_cvref_t<Slices>,
510 return detail::make_tensor_slice_view(tensor, slices...);
528template<
typename T,
typename... Slices>
531 std::remove_cvref_t<Slices>,
537 return detail::make_tensor_slice_view(tensor, slices...);
558 const std::vector<stratax::core::Slice>& slices)
560 return detail::make_tensor_slice_view(tensor, slices);
581 const std::vector<stratax::core::Slice>& slices)
583 return detail::make_tensor_slice_view(tensor, slices);
605 const std::vector<stratax::core::Slice>& slices)
607 if (slices.size() != view.
rank())
610 "The number of slices must match the view rank.");
613 std::vector<detail::ResolvedSlice> resolved(slices.size());
614 std::vector<size_type> out_dims(slices.size());
615 std::vector<size_type> out_strides(slices.size());
619 for (
size_type dim = 0; dim < slices.size(); ++dim)
621 resolved[dim] = detail::normalize_slice(
625 out_dims[dim] = resolved[dim].size;
627 if (resolved[dim].step < 0)
630 "Negative-step views are not supported.");
634 static_cast<size_type>(resolved[dim].start);
637 static_cast<size_type>(resolved[dim].step);
639 if (view.
strides()[dim] != 0 &&
641 std::numeric_limits<size_type>::max() /
645 "ArrayView slice offset overflow.");
652 std::numeric_limits<size_type>::max() -
656 "ArrayView slice offset overflow.");
659 start_offset += start_term;
663 std::numeric_limits<size_type>::max() /
667 "ArrayView slice stride overflow.");
677 auto* data = view.
data();
681 data += start_offset;
Non-owning views and logical random-access iterators.
Stratax exception types derived from std::runtime_error.
std::size_t offset(const core::Shape &strides, const IndexContainer &indices)
Computes an unchecked flat offset from strides and normalized indices.
std::ptrdiff_t difference_type
Signed type for Python-style indices.
std::size_t size_type
Unsigned extent and normalized-index type.
Immutable dimension metadata and checked row-major strides.
Raw signed half-open ranges; applying views currently requires positive steps.
auto make_tensor_slice_view(Tensor &tensor, Slices... slices)
Constructs a view with one slice per axis; see the public Tensor slice overloads.
auto make_matrix_slice_view(Matrix &mat, const stratax::core::Slice &rows, const stratax::core::Slice &cols)
Constructs a two-axis view; see the public Matrix slice overload.
auto slice(stratax::container::Vector< T > &vec, const stratax::core::Slice &slice)
Returns a non-owning Vector slice view (mutable when T is non-const).
std::conditional_t< std::is_const_v< std::remove_reference_t< Source > >, const typename std::remove_cvref_t< Source >::value_type, typename std::remove_cvref_t< Source >::value_type > view_element_t
Element type preserving the source array constness.
ResolvedSlice normalize_slice(const stratax::core::Slice &slice, size_type extent)
Normalizes explicit bounds against an extent without accessing storage.
auto make_vector_slice_view(Vector &vec, const stratax::core::Slice &slice)
Constructs a one-axis view; see the public Vector slice overload.
Arbitrary-rank owning arrays; rank zero is empty.
Invalid dimension or overflow in dimension, element-count, or stride arithmetic.
Index or slice cannot be used for the requested access.
Number of axes or supplied multidimensional indices does not match the required rank.
Two-dimensional owning array of supported dtype values.
Arbitrary-rank owning array of supported dtype values.
One-dimensional owning array of supported dtype values.
Non-owning view of elements with unsigned element strides.
const Shape & strides() const noexcept
Stored element strides.
const Shape & shape() const noexcept
Logical extents.
pointer data() noexcept
Base storage pointer; empty views may have non-null pointers.
size_type rank() const noexcept
Number of logical axes.
Stores the dimensions of a multidimensional array.
size_type elements() const
Computes the total number of elements described by the shape.
Shape strides() const
Computes canonical row-major strides for this shape.
Describes a signed, strided half-open index range.
size_type size() const noexcept
Returns the number of indices described by the raw range.
Normalized first index, signed step, and selected element count.
difference_type step
Nonzero signed step.
size_type size
Number of selected elements.
difference_type start
First normalized index; not dereferenceable for an empty slice.