#ifndef VEG_SLICE_HPP_GKSTE2JDS #define VEG_SLICE_HPP_GKSTE2JDS #include "proxsuite/linalg/veg/util/assert.hpp" #include "proxsuite/linalg/veg/util/get.hpp" #include "proxsuite/linalg/veg/internal/narrow.hpp" #include "proxsuite/linalg/veg/tuple.hpp" #include "proxsuite/linalg/veg/internal/prologue.hpp" #include namespace proxsuite { namespace linalg { namespace veg { template using CArray = T[N]; namespace _detail { namespace _slice { namespace adl { struct AdlBase {}; } // namespace adl } // namespace _slice } // namespace _detail template struct Slice : _detail::_slice::adl::AdlBase { private: T const* data = nullptr; isize size = 0; public: VEG_INLINE constexpr Slice() = default; VEG_INLINE constexpr Slice(Unsafe /*tag*/, FromRawParts /*tag*/, T const* data_, isize count) VEG_NOEXCEPT : data{ data_ } , size{ count } { } VEG_NODISCARD VEG_INLINE constexpr auto ptr() const VEG_NOEXCEPT->T const* { return data; } VEG_NODISCARD VEG_INLINE constexpr auto len() const VEG_NOEXCEPT->isize { return size; } VEG_NODISCARD VEG_INLINE constexpr auto operator[](isize idx) const VEG_NOEXCEPT->T const& { return VEG_INTERNAL_ASSERT_PRECONDITION(usize(idx) < usize(len())), *(data + idx); } VEG_NODISCARD VEG_INLINE constexpr auto get_unchecked(Unsafe /*tag*/, isize idx) const VEG_NOEXCEPT->Ref { return ref(*(data + idx)); } VEG_NODISCARD VEG_INLINE constexpr auto split_at(isize idx) const VEG_NOEXCEPT->Tuple, Slice> { return VEG_INTERNAL_ASSERT_PRECONDITION(usize(idx) <= usize(len())), Tuple, Slice>{ tuplify, Slice{ unsafe, FromRawParts{}, data, idx, }, Slice{ unsafe, FromRawParts{}, data + idx, size - idx, }, }; } VEG_NODISCARD VEG_INLINE auto as_bytes() const VEG_NOEXCEPT->Slice { return { unsafe, from_raw_parts, reinterpret_cast(data), isize(sizeof(T)) * size, }; } }; template struct SliceMut : private Slice { VEG_INLINE constexpr SliceMut() = default; VEG_INLINE constexpr SliceMut(Unsafe /*tag*/, FromRawParts /*tag*/, T const* data_, isize count) VEG_NOEXCEPT : Slice{ unsafe, from_raw_parts, data_, count, } { } using Slice::ptr; using Slice::as_bytes; using Slice::split_at; using Slice::len; using Slice::get_unchecked; VEG_NODISCARD VEG_INLINE constexpr auto as_const() const noexcept -> Slice { return *this; } VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto operator[](isize idx) VEG_NOEXCEPT->T& { return const_cast(static_cast const&>(*this)[idx]); } VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto ptr_mut() VEG_NOEXCEPT->T* { return const_cast(ptr()); } VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto get_mut_unchecked(Unsafe /*tag*/, isize idx) VEG_NOEXCEPT->RefMut { return mut(const_cast(*(this->data + idx))); } VEG_NODISCARD VEG_INLINE auto as_mut_bytes() VEG_NOEXCEPT->SliceMut { return { unsafe, from_raw_parts, reinterpret_cast(ptr_mut()), isize(sizeof(T)) * len(), }; } VEG_NODISCARD VEG_INLINE VEG_CPP14(constexpr) auto split_at_mut(isize idx) VEG_NOEXCEPT->Tuple, SliceMut> { return VEG_INTERNAL_ASSERT_PRECONDITION(usize(idx) <= usize(len())), Tuple, SliceMut>{ tuplify, SliceMut{ unsafe, from_raw_parts, ptr_mut(), idx, }, SliceMut{ unsafe, from_raw_parts, ptr_mut() + idx, len() - idx, }, }; } }; namespace array { template struct Array { static_assert(N > 0, "."); T _[static_cast(N)]; constexpr auto as_ref() const -> Slice { return { unsafe, from_raw_parts, static_cast(_), N, }; } VEG_CPP14(constexpr) auto as_mut() -> SliceMut { return { unsafe, from_raw_parts, static_cast(_), N, }; } }; } // namespace array using array::Array; namespace nb { struct init_list { template VEG_CPP14(constexpr) auto operator()(std::initializer_list init_list) const noexcept -> Slice { return { unsafe, from_raw_parts, init_list.begin(), isize(init_list.size()), }; } }; } // namespace nb VEG_NIEBLOID(init_list); template struct cpo::is_trivially_constructible> : meta::bool_constant {}; } // namespace veg } // namespace linalg } // namespace proxsuite #include "proxsuite/linalg/veg/internal/epilogue.hpp" #endif /* end of include guard VEG_SLICE_HPP_GKSTE2JDS */