21#ifndef MTCORE_SLICE_HPP
22#define MTCORE_SLICE_HPP
54 [[nodiscard]]
decltype(
auto)
iter()
const noexcept {
return iter::val(*
this); }
58 return {
static_cast<std::add_pointer_t<std::add_const_t<T>
>>(
head),
len};
79 [[nodiscard]]
constexpr const T &
operator[](
size_t i)
const noexcept {
80 ensure(i <
len,
"SLICE ACCESS OUT OF BOUNDS");
91 ensure(i <
len,
"SLICE ACCESS OUT OF BOUNDS");
101 [[nodiscard]] T &
at(
size_t i)
noexcept {
return (*
this)[i]; }
108 [[nodiscard]]
constexpr const T &
at(
size_t i)
const noexcept {
return (*
this)[i]; }
113 [[nodiscard]]
constexpr size_t size() const noexcept {
return head !=
nullptr ?
len : 0; }
118 [[nodiscard]]
constexpr bool empty() const noexcept {
return head ==
nullptr ||
len == 0; }
125 [[nodiscard]]
constexpr Slice sub_rng(
size_t start,
size_t end)
const noexcept {
126 if (start >= end || start >=
len) {
128 res.
init(
nullptr, 0);
131 return sub(start, end - start);
138 [[nodiscard]]
constexpr Slice sub(
size_t start)
const noexcept {
141 res.
init(
nullptr, 0);
156 [[nodiscard]]
constexpr Slice sub(
size_t start,
size_t len)
const noexcept {
157 auto res =
sub(start);
158 res.len = res.len >
len ?
len : res.len;
168 std::strong_ordering
operator<=>(
const Slice<std::remove_const_t<T>> &other)
const noexcept {
169 return *this <=> other.to_const();
178 if (
empty() && other.empty()) {
179 return std::strong_ordering::equal;
183 return std::strong_ordering::less;
187 return std::strong_ordering::greater;
190 for (
size_t i = 0; i <
len && i < other.len; ++i) {
191 if (
head[i] > other.head[i]) {
192 return std::strong_ordering::greater;
194 if (
head[i] < other.head[i]) {
195 return std::strong_ordering::less;
199 if (
len == other.len) {
200 return std::strong_ordering::equal;
202 else if (
len < other.len) {
203 return std::strong_ordering::less;
206 return std::strong_ordering::greater;
211 return (*this <=> o) == std::strong_ordering::equal;
215 return (*this <=> o) != std::strong_ordering::equal;
219 return (*this <=> o) == std::strong_ordering::less;
223 return (*this <=> o) == std::strong_ordering::greater;
227 const auto cmp = *this <=> o;
228 return (cmp == std::strong_ordering::less || cmp == std::strong_ordering::equal);
232 const auto cmp = *this <=> o;
233 return (cmp == std::strong_ordering::greater || cmp == std::strong_ordering::equal);
237 return (*this <=> o) == std::strong_ordering::equal;
241 return (*this <=> o) != std::strong_ordering::equal;
245 return (*this <=> o) == std::strong_ordering::less;
249 return (*this <=> o) == std::strong_ordering::greater;
253 const auto cmp = *this <=> o;
254 return (cmp == std::strong_ordering::less || cmp == std::strong_ordering::equal);
258 const auto cmp = *this <=> o;
259 return (cmp == std::strong_ordering::greater || cmp == std::strong_ordering::equal);
282 for (; cstr[len]; ++len) {}
296 for (; cstr[len]; ++len) {}
328 for (; cstr[len]; ++len) {}
394 for (; cstr[len]; ++len) {}
408 for (; cstr[len]; ++len) {}
422 for (; cstr[len]; ++len) {}
436 for (; cstr[len]; ++len) {}
450 for (; cstr[len]; ++len) {}
464 for (; cstr[len]; ++len) {}
478 for (; cstr[len]; ++len) {}
492 for (; cstr[len]; ++len) {}
556 return Slice<T>{arr.data(), arr.size()};
564 template<
typename T,
size_t N>
574 template<
typename T,
size_t N>
576 return Slice<T>{arr.data(), arr.size()};
589 for (; cstr[len]; ++len) {}
609 template<
typename Left,
typename Right>
610 std::strong_ordering
str_compare(
const Left &left,
const Right &right) {
611 using L = std::decay_t<std::remove_cv_t<Left>>;
612 using R = std::decay_t<std::remove_cv_t<Right>>;
613 static_assert(std::same_as<Slice<char>, L> || std::same_as<Slice<const char>, L> || std::same_as<std::string, L> ||
614 std::same_as<std::string_view, L> || std::same_as<char *, L> || std::same_as<const char *, L>);
615 static_assert(std::same_as<Slice<char>, R> || std::same_as<Slice<const char>, R> || std::same_as<std::string, R> ||
616 std::same_as<std::string_view, R> || std::same_as<char *, R> || std::same_as<const char *, R>);
619 if constexpr (std::is_same_v<Slice<const char>, L>) {
622 else if constexpr (std::is_same_v<Slice<char>, L>) {
630 if constexpr (std::is_same_v<Slice<const char>, R>) {
633 else if constexpr (std::is_same_v<Slice<char>, R>) {
640 return leftSlice <=> rightSlice;
652 template<
typename L,
typename R>
654 return str_compare(left, right) == std::strong_ordering::equal;
constexpr Slice< char32_t > mut_slice_from(char32_t *cstr, size_t len)
Creates a mutable slice from a utf32 string and length.
ValIter< T > val(const T &r)
Generic value iterator that uses the operator[] and incrementing indexes to iterate over a collection...
ConstPtrIter< T > const_ptr(const T &r)
Generic constant pointer iterator that uses the operator[] and incrementing indexes to iterate over a...
PtrIter< T > ptr(T &r)
Generic pointer iterator that uses the operator[] and incrementing indexes to iterate over a collecti...
constexpr Slice< const char32_t > slice_from(char32_t *cstr)
Creates a slice from a utf32 string in the form of a c string.
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
Core library for C++ with Zig-related functionality.
std::strong_ordering str_compare(const Left &left, const Right &right)
Compares two string strings for ordering.
bool str_equal(const L &left, const R &right)
Compares two string strings for ordering.
A Slice which is just a pointer + length Accessing elements through the array operator will do bounds...
T & operator[](size_t i) noexcept
Access element at a specific index Non-const operator, returns a mutable reference.
constexpr void init(T *head, size_t len)
Initializes a Slice Using init instead of a constructor so that slices allocated with malloc or an ar...
decltype(auto) ptr_iter() const noexcept
constexpr Slice sub_rng(size_t start, size_t end) const noexcept
Gets a sub slice from start to end index.
constexpr Slice sub(size_t start) const noexcept
Gets a sub Slice from start.
bool operator>=(const Slice< std::remove_const_t< T > > &o) const noexcept
constexpr size_t size() const noexcept
Gets the size of a Slice.
decltype(auto) ptr_iter() noexcept
bool operator!=(const Slice< std::remove_const_t< T > > &o) const noexcept
constexpr bool empty() const noexcept
Checks if a Slice is empty.
constexpr const T & operator[](size_t i) const noexcept
Access element at a specific index Const operator, returns a const reference.
std::strong_ordering operator<=>(const Slice< std::remove_const_t< T > > &other) const noexcept
Compares against another Slice.
std::remove_const_t< ReadElem > * head
bool operator!=(const Slice< std::add_const_t< T > > &o) const noexcept
bool operator==(const Slice< std::add_const_t< T > > &o) const noexcept
bool operator<(const Slice< std::remove_const_t< T > > &o) const noexcept
bool operator<(const Slice< std::add_const_t< T > > &o) const noexcept
bool operator<=(const Slice< std::remove_const_t< T > > &o) const noexcept
constexpr const T & at(size_t i) const noexcept
Access element at a specific index Const operator, returns a const reference.
bool operator<=(const Slice< std::add_const_t< T > > &o) const noexcept
std::strong_ordering operator<=>(const Slice< std::add_const_t< T > > &other) const noexcept
Compares against another Slice.
constexpr Slice sub(size_t start, size_t len) const noexcept
Gets a sub Slice from start up to a length.
bool operator>=(const Slice< std::add_const_t< T > > &o) const noexcept
bool operator==(const Slice< std::remove_const_t< T > > &o) const noexcept
bool operator>(const Slice< std::add_const_t< T > > &o) const noexcept
bool operator>(const Slice< std::remove_const_t< T > > &o) const noexcept
constexpr Slice< std::add_const_t< T > > to_const() const noexcept
Converts to a const Slice.
decltype(auto) iter() const noexcept
T & at(size_t i) noexcept
Access element at a specific index Non-const operator, returns a mutable reference.