Files
nostalgia/deps/ox/src/ox/std/strops.hpp
Gary Talent 9f338a7429
All checks were successful
Build / build (push) Successful in 3m18s
[ox] Run liccor
2025-01-08 23:03:05 -06:00

121 lines
3.2 KiB
C++

/*
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "cstrops.hpp"
#include "def.hpp"
#include "error.hpp"
#include "math.hpp"
#include "stringview.hpp"
#include "types.hpp"
#include "vector.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
[[nodiscard]]
constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexcept {
if (str.len() >= pos) {
return {&str[pos], str.len() - pos};
}
return {};
}
[[nodiscard]]
constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std::size_t end) noexcept {
if (str.len() >= start && end >= start) {
return {&str[start], end - start};
}
return {};
}
[[nodiscard]]
constexpr bool beginsWith(StringViewCR base, StringViewCR beginning) noexcept {
const auto beginningLen = ox::min(beginning.len(), base.len());
return base.len() >= beginning.len() && ox::strncmp(base.data(), beginning, beginningLen) == 0;
}
[[nodiscard]]
constexpr bool endsWith(StringViewCR base, StringViewCR ending) noexcept {
const auto endingLen = ending.len();
return base.len() >= endingLen && ox::strcmp(base.data() + (base.len() - endingLen), ending) == 0;
}
[[nodiscard]]
constexpr std::size_t find(StringViewCR str, char search) noexcept {
std::size_t i = 0;
for (; i < str.len(); ++i) {
if (str[i] == search) {
break;
}
}
return i;
}
[[nodiscard]]
constexpr std::size_t find(StringViewCR str, StringViewCR search) noexcept {
std::size_t i = 0;
for (; i < str.len(); ++i) {
if (beginsWith(substr(str, i), search)) {
break;
}
}
return i;
}
template<std::size_t smallSz = 0>
[[nodiscard]]
constexpr ox::Vector<ox::StringView, smallSz> split(StringViewCR str, char del) noexcept {
ox::Vector<ox::StringView, smallSz> out;
constexpr auto nextSeg = [](StringViewCR current, char del) {
return substr(current, find(current, del) + 1);
};
for (auto current = str; current.len(); current = nextSeg(current, del)) {
const auto next = find(current, del);
if (const auto s = substr(current, 0, next); s.len()) {
out.emplace_back(s);
}
current = substr(current, next);
}
return out;
}
template<std::size_t smallSz = 0>
[[nodiscard]]
constexpr ox::Vector<ox::StringView, smallSz> split(StringViewCR str, StringViewCR del) noexcept {
ox::Vector<ox::StringView, smallSz> out;
constexpr auto nextSeg = [](StringViewCR current, StringViewCR del) {
return substr(current, find(current, del) + del.len());
};
for (auto current = str; current.len(); current = nextSeg(current, del)) {
const auto next = find(current, del);
if (const auto s = substr(current, 0, next); s.len()) {
out.emplace_back(s);
}
current = substr(current, next);
}
return out;
}
[[nodiscard]]
constexpr ox::Result<std::size_t> lastIndexOf(ox::StringViewCR str, int character) noexcept {
ox::Result<std::size_t> retval = ox::Error(1, "Character not found");
for (auto i = static_cast<int>(str.bytes() - 1); i >= 0; --i) {
if (str[static_cast<std::size_t>(i)] == character) {
retval = static_cast<std::size_t>(i);
}
}
return retval;
}
}
OX_CLANG_NOWARN_END