19#ifndef MTCORE_SLICE_ALGO_H
20#define MTCORE_SLICE_ALGO_H
45 if (needle.
size() > haystack.
size()) {
49 for (
size_t i = 0; i < needle.
size(); ++i) {
50 if (needle[i] != haystack[i]) {
59 for (
size_t i = slice.
size(); i > 0; --i) {
60 auto destIndex = i - 1;
61 if (destIndex < amt) {
64 auto srcIndex = destIndex - amt;
65 slice[destIndex] = slice[srcIndex];
81 if (haystack.
empty()) {
84 return haystack[0] == needle;
99 if (haystack.
empty()) {
102 for (
size_t i = 0; i < haystack.
size(); ++i) {
103 if (needle == haystack[i]) {
121 if (needle.
empty()) {
125 if (needle.
size() > haystack.
size()) {
129 for (
size_t i = 0; i < haystack.
size() - needle.
size() + 1; ++i) {
130 if (needle[0] == haystack[i]) {
132 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
133 if (needle[ni] != haystack[i + ni]) {
155 const std::remove_const_t<T> &needle,
157 if (haystack.
empty()) {
161 for (
size_t i = 0; i < haystack.
size(); ++i) {
166 if (haystack[i] == prefix) {
169 else if (needle == haystack[i]) {
187 if (needle.
empty()) {
191 if (needle.
size() > haystack.
size()) {
196 for (
size_t i = 0; i < haystack.
size() - needle.
size() + 1; ++i) {
201 if (haystack[i] == prefix) {
204 else if (needle[0] == haystack[i]) {
206 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
207 if (needle[ni] != haystack[i + ni]) {
229 if (needle.
empty()) {
233 if (needle.
size() > haystack.
size()) {
237 for (
size_t i = 0; i < haystack.
size() - needle.
size() + 1; ++i) {
238 if (needle[0] == haystack[i]) {
240 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
241 if (needle[ni] != haystack[i + ni]) {
263 if (haystack.
empty()) {
268 for (; i < haystack.
size() && needle == haystack[i]; ++i) {}
270 if (i >= haystack.
size()) {
286 if (haystack.
empty()) {
289 for (
size_t i = 0; i < haystack.
size(); ++i) {
290 if (needle == haystack[i]) {
307 if (needle.
empty()) {
311 if (needle.
size() > haystack.
size()) {
315 for (
size_t indx = haystack.
size() - needle.
size() + 1; indx > 0; --indx) {
316 const auto i = indx - 1;
317 if (needle[0] == haystack[i]) {
319 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
320 if (needle[ni] != haystack[i + ni]) {
342 if (haystack.
empty()) {
345 for (
size_t indx = haystack.
size(); indx > 0; --indx) {
346 const auto i = indx - 1;
347 if (needle == haystack[i]) {
354 template<
typename T,
typename N>
367 if (!opt.has_value()) {
372 return cur + opt.value();
386 return {needle, haystack};
399 return {needle, haystack};
402 template<
typename T,
typename N>
421 if (!nxt.has_value()) {
429 auto res =
haystack.sub(0, nxt.value());
435 template<
typename T,
typename N>
451 if (!nxt.has_value()) {
459 auto res =
haystack.sub(0, nxt.value());
475 return {needle, haystack};
488 return {needle, haystack};
#define mtcore_warn_trace(...)
Prints a warning message in debug builds Does nothing in release builds`.
SplitIter< T, Slice< T > > split(const Slice< T > &needle, const Slice< T > &haystack)
Splits a slice into smaller sub slices.
SearchIndexes< T, Slice< T > > indexes_of(const Slice< T > &needle, const Slice< T > &haystack)
Returns an iterator of all indexes of occurrences of a needle in a haystack If the needle isn't prese...
bool starts_with(const Slice< T > &needle, const Slice< T > &haystack)
Checks whether a slice (the haystack) starts with elements in another slice in the same order (the ne...
mtcore::Optional< size_t > last_index(const Slice< T > &needle, const Slice< T > &haystack)
Gets the last index that a needle appears in the haystack, or nullopt if the needle does not appear -...
constexpr auto nullopt
Placeholder value for an empty Optional.
mtcore::Optional< size_t > first_index_not_proceeded_by(const std::remove_const_t< T > &prefix, const std::remove_const_t< T > &needle, const Slice< T > &haystack)
Gets the first index that a needle appears in the haystack, or nullopt if the needle does not appear ...
mtcore::Optional< size_t > first_index(const Slice< T > &needle, const Slice< T > &haystack)
Gets the first index that a needle appears in the haystack, or nullopt if the needle does not appear ...
mtcore::Optional< size_t > first_index_not(const std::remove_const_t< T > &needle, const Slice< T > &haystack)
Gets the first index that a needle appears in the haystack, or nullopt if the needle does not appear ...
bool contains(const std::remove_const_t< T > &needle, const Slice< T > &haystack)
Checks whether a slice (the haystack) contains an element (the needle) Uses the equality operator of ...
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
#define mtdefer
Defer statement that will mtdefer execution until the scope is left, at which point the code will run...
Additional algorithms that can be performed on slices, such as comparisons, searching,...
void shift(Slice< T > slice, size_t amt)
Represents a value that may or may not exist (an "Optional" value) Similar concept to std::optional,...
A Slice which is just a pointer + length Accessing elements through the array operator will do bounds...
constexpr size_t size() const noexcept
Gets the size of a Slice.
constexpr bool empty() const noexcept
Checks if a Slice is empty.
Optional< size_t > next()
Optional< Slice< T > > next()
Optional< Slice< T > > next()