[ox/std] Add StringView split and find functions
This commit is contained in:
parent
4b9b70a90e
commit
3c9e6d10ea
68
deps/ox/src/ox/std/stringview.hpp
vendored
68
deps/ox/src/ox/std/stringview.hpp
vendored
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 - 2022 gary@drinkingtea.net
|
* Copyright 2015 - 2023 gary@drinkingtea.net
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@ -12,10 +12,11 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "bit.hpp"
|
||||||
#include "iterator.hpp"
|
#include "iterator.hpp"
|
||||||
#include "strops.hpp"
|
#include "strops.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "bit.hpp"
|
#include "vector.hpp"
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -223,8 +224,19 @@ class StringView {
|
|||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr auto substr(std::size_t pos) const noexcept {
|
constexpr auto substr(std::size_t pos) const noexcept {
|
||||||
|
if (m_len >= pos) {
|
||||||
return StringView(m_str + pos, m_len - pos);
|
return StringView(m_str + pos, m_len - pos);
|
||||||
}
|
}
|
||||||
|
return StringView();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr auto substr(std::size_t start, std::size_t end) const noexcept {
|
||||||
|
if (m_len >= start && end >= start) {
|
||||||
|
return StringView(m_str + start, end - start);
|
||||||
|
}
|
||||||
|
return StringView();
|
||||||
|
}
|
||||||
|
|
||||||
constexpr auto operator[](std::size_t i) const noexcept {
|
constexpr auto operator[](std::size_t i) const noexcept {
|
||||||
return m_str[i];
|
return m_str[i];
|
||||||
@ -276,6 +288,58 @@ constexpr bool endsWith(CRStringView base, CRStringView ending) noexcept {
|
|||||||
return base.len() >= endingLen && ox_strcmp(base.data() + (base.len() - endingLen), ending) == 0;
|
return base.len() >= endingLen && ox_strcmp(base.data() + (base.len() - endingLen), ending) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t find(CRStringView str, char search) noexcept {
|
||||||
|
std::size_t i = 0;
|
||||||
|
for (; i < str.len(); ++i) {
|
||||||
|
if (str[i] == search) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t find(CRStringView str, CRStringView search) noexcept {
|
||||||
|
std::size_t i = 0;
|
||||||
|
for (; i < str.len(); ++i) {
|
||||||
|
if (beginsWith(str.substr(i), search)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t smallSz = 0>
|
||||||
|
constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, char del) noexcept {
|
||||||
|
ox::Vector<ox::StringView, smallSz> out;
|
||||||
|
constexpr auto nextSeg = [](CRStringView current, char del) {
|
||||||
|
return current.substr(find(current, del) + 1);
|
||||||
|
};
|
||||||
|
for (auto current = str; current.len(); current = nextSeg(current, del)) {
|
||||||
|
const auto next = find(current, del);
|
||||||
|
if (const auto s = current.substr(0, next); s.len()) {
|
||||||
|
out.emplace_back(s);
|
||||||
|
}
|
||||||
|
current = current.substr(next);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t smallSz = 0>
|
||||||
|
constexpr ox::Vector<ox::StringView, smallSz> split(CRStringView str, CRStringView del) noexcept {
|
||||||
|
ox::Vector<ox::StringView, smallSz> out;
|
||||||
|
constexpr auto nextSeg = [](CRStringView current, CRStringView del) {
|
||||||
|
return current.substr(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 = current.substr(0, next); s.len()) {
|
||||||
|
out.emplace_back(s);
|
||||||
|
}
|
||||||
|
current = current.substr(next);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef OX_USE_STDLIB
|
#ifdef OX_USE_STDLIB
|
||||||
constexpr auto toStdStringView(CRStringView sv) noexcept {
|
constexpr auto toStdStringView(CRStringView sv) noexcept {
|
||||||
return std::string_view(sv.data(), sv.bytes());
|
return std::string_view(sv.data(), sv.bytes());
|
||||||
|
1
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
@ -18,3 +18,4 @@ add_test("[ox/std] HashMap" StdTest "HashMap")
|
|||||||
add_test("[ox/std] HeapMgr" StdTest malloc)
|
add_test("[ox/std] HeapMgr" StdTest malloc)
|
||||||
add_test("[ox/std] Serialize-Int" StdTest "Serialize-Int")
|
add_test("[ox/std] Serialize-Int" StdTest "Serialize-Int")
|
||||||
add_test("[ox/std] BufferWriter" StdTest "BufferWriter")
|
add_test("[ox/std] BufferWriter" StdTest "BufferWriter")
|
||||||
|
add_test("[ox/std] StringSplit" StdTest "StringSplit")
|
||||||
|
69
deps/ox/src/ox/std/test/tests.cpp
vendored
69
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 - 2022 gary@drinkingtea.net
|
* Copyright 2015 - 2023 gary@drinkingtea.net
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@ -155,6 +155,73 @@ static std::map<ox::String, ox::Error(*)()> tests = {
|
|||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"StringSplit",
|
||||||
|
[] {
|
||||||
|
ox::StringView sv = "ab.cd";
|
||||||
|
auto list = ox::split(sv, ".");
|
||||||
|
oxExpect(list.size(), 2u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
sv = "ab.cd.fg";
|
||||||
|
list = ox::split(sv, ".");
|
||||||
|
oxExpect(list.size(), 3u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
oxExpect(list[2], "fg");
|
||||||
|
sv = "ab.cd.";
|
||||||
|
list = ox::split(sv, ".");
|
||||||
|
oxExpect(list.size(), 2u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
sv = ".ab.cd.";
|
||||||
|
list = ox::split(sv, ".");
|
||||||
|
oxExpect(list.size(), 2u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
sv = ".";
|
||||||
|
list = ox::split(sv, ".");
|
||||||
|
oxExpect(list.size(), 0u);
|
||||||
|
sv = ".";
|
||||||
|
list = ox::split(sv, ".");
|
||||||
|
oxExpect(list.size(), 0u);
|
||||||
|
sv = "";
|
||||||
|
list = ox::split(sv, ".");
|
||||||
|
oxExpect(list.size(), 0u);
|
||||||
|
// split by single char
|
||||||
|
sv = "ab.cd";
|
||||||
|
list = ox::split(sv, '.');
|
||||||
|
oxExpect(list.size(), 2u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
sv = "ab.cd.fg";
|
||||||
|
list = ox::split(sv, '.');
|
||||||
|
oxExpect(list.size(), 3u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
oxExpect(list[2], "fg");
|
||||||
|
sv = "ab.cd.";
|
||||||
|
list = ox::split(sv, '.');
|
||||||
|
oxExpect(list.size(), 2u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
sv = ".ab.cd.";
|
||||||
|
list = ox::split(sv, '.');
|
||||||
|
oxExpect(list.size(), 2u);
|
||||||
|
oxExpect(list[0], "ab");
|
||||||
|
oxExpect(list[1], "cd");
|
||||||
|
sv = ".";
|
||||||
|
list = ox::split(sv, '.');
|
||||||
|
oxExpect(list.size(), 0u);
|
||||||
|
sv = ".";
|
||||||
|
list = ox::split(sv, '.');
|
||||||
|
oxExpect(list.size(), 0u);
|
||||||
|
sv = "";
|
||||||
|
list = ox::split(sv, '.');
|
||||||
|
oxExpect(list.size(), 0u);
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, const char **args) {
|
int main(int argc, const char **args) {
|
||||||
|
Loading…
Reference in New Issue
Block a user