19#ifndef MTCORE_SLICE_ALGO_H
20#define MTCORE_SLICE_ALGO_H
46 if (needle.
size() > haystack.
size()) {
50 for (
size_t i = 0; i < needle.
size(); ++i) {
51 if (needle[i] != haystack[i]) {
67 for (
size_t i = 0; i < slice.
size() - amt; ++i) {
68 auto destIndex = i + amt;
69 if (destIndex < amt) {
72 auto srcIndex = destIndex - amt;
73 slice[destIndex] = slice[srcIndex];
86 for (
size_t i = slice.
size(); i > 0; --i) {
87 auto destIndex = i - amt;
88 if (destIndex < amt) {
91 auto srcIndex = destIndex - amt;
92 slice[destIndex] = slice[srcIndex];
108 if (haystack.
empty()) {
111 return haystack[0] == needle;
126 if (haystack.
empty()) {
129 for (
size_t i = 0; i < haystack.
size(); ++i) {
130 if (needle == haystack[i]) {
148 if (needle.
empty()) {
152 if (needle.
size() > haystack.
size()) {
156 for (
size_t i = 0; i < haystack.
size() - needle.
size() + 1; ++i) {
157 if (needle[0] == haystack[i]) {
159 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
160 if (needle[ni] != haystack[i + ni]) {
182 const std::remove_const_t<T> &needle,
184 if (haystack.
empty()) {
188 for (
size_t i = 0; i < haystack.
size(); ++i) {
193 if (haystack[i] == prefix) {
196 else if (needle == haystack[i]) {
214 if (needle.
empty()) {
218 if (needle.
size() > haystack.
size()) {
223 for (
size_t i = 0; i < haystack.
size() - needle.
size() + 1; ++i) {
228 if (haystack[i] == prefix) {
231 else if (needle[0] == haystack[i]) {
233 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
234 if (needle[ni] != haystack[i + ni]) {
256 if (needle.
empty()) {
260 if (needle.
size() > haystack.
size()) {
264 for (
size_t i = 0; i < haystack.
size() - needle.
size() + 1; ++i) {
265 if (needle[0] == haystack[i]) {
267 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
268 if (needle[ni] != haystack[i + ni]) {
290 if (needles.
empty()) {
294 for (
size_t i = 0; i < haystack.
size(); ++i) {
295 if (
contains(haystack[i], needles)) {
312 if (haystack.
empty()) {
317 for (; i < haystack.
size() && needle == haystack[i]; ++i) {}
319 if (i >= haystack.
size()) {
335 if (haystack.
empty()) {
338 for (
size_t i = 0; i < haystack.
size(); ++i) {
339 if (needle == haystack[i]) {
356 if (needle.
empty()) {
360 if (needle.
size() > haystack.
size()) {
364 for (
size_t indx = haystack.
size() - needle.
size() + 1; indx > 0; --indx) {
365 const auto i = indx - 1;
366 if (needle[0] == haystack[i]) {
368 for (
size_t ni = 1; looking && ni < needle.
size(); ++ni) {
369 if (needle[ni] != haystack[i + ni]) {
391 if (haystack.
empty()) {
394 for (
size_t indx = haystack.
size(); indx > 0; --indx) {
395 const auto i = indx - 1;
396 if (needle == haystack[i]) {
403 template<
typename T,
typename N>
416 if (!opt.has_value()) {
421 return cur + opt.value();
435 return {needle, haystack};
448 return {needle, haystack};
456 template<
typename T,
typename N>
475 if (!nxt.has_value()) {
483 auto res =
haystack.sub(0, nxt.value());
489 template<
typename T,
typename N>
505 if (!nxt.has_value()) {
513 auto res =
haystack.sub(0, nxt.value());
529 return {needle, haystack};
542 return {needle, haystack};
562 if (!nxt.has_value()) {
591 return {needles, haystack};
#define mtcore_warn_trace(...)
Prints a warning message in debug builds Does nothing in release builds`.
SplitOneOfIter< T > split_one_of(const Slice< std::add_const_t< T > > &needles, const Slice< T > &haystack)
Splits a slice into smaller sub slices.
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 ...
Pair< T1, T2 > make_pair(T1 first, T2 second)
Helper to make a pair with type inference.
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 ...
mtcore::Optional< size_t > first_index_one_of(const Slice< T > &needles, const Slice< T > &haystack)
Gets the first index that one of the provided needles appears in the haystack, or nullopt if the need...
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_left(Slice< T > slice, size_t amt)
Shifts elements to the left by a certain number of places Does not loop around.
void shift_right(Slice< T > slice, size_t amt)
Shifts elements to the right by a certain number of places Does not loop around.
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()
Splits a slice and iterates over the split portions.
Optional< Slice< T > > next()
Slice< std::add_const_t< T > > needles
Optional< std::remove_const_t< T > > foundNeedle
Optional< Pair< Slice< T >, Optional< std::remove_const_t< T > > > > next()