[ox/std] Make String(StringView) constructor explicit, add StringLiteral
This commit is contained in:
parent
7008ebfb40
commit
3a62650d62
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -118,6 +118,7 @@ install(
|
||||
std.hpp
|
||||
stddef.hpp
|
||||
string.hpp
|
||||
stringliteral.hpp
|
||||
stringview.hpp
|
||||
strongint.hpp
|
||||
strops.hpp
|
||||
|
4
deps/ox/src/ox/std/memory.hpp
vendored
4
deps/ox/src/ox/std/memory.hpp
vendored
@ -282,10 +282,10 @@ constexpr bool operator!=(std::nullptr_t, const UniquePtr<T> &p2) noexcept {
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename ...Args>
|
||||
template<typename T, typename U = T, typename ...Args>
|
||||
[[nodiscard]]
|
||||
constexpr auto make_unique(Args&&... args) {
|
||||
return UniquePtr(new T(ox::forward<Args>(args)...));
|
||||
return UniquePtr<U>(new T(ox::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
}
|
||||
|
4
deps/ox/src/ox/std/new.hpp
vendored
4
deps/ox/src/ox/std/new.hpp
vendored
@ -35,9 +35,9 @@ constexpr void *operator new[](std::size_t, void *addr) noexcept {
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename T, typename ...Args>
|
||||
template<typename T, typename U = T, typename ...Args>
|
||||
[[nodiscard]]
|
||||
constexpr T *make(Args &&...args) noexcept {
|
||||
constexpr U *make(Args &&...args) noexcept {
|
||||
#ifdef __cpp_exceptions
|
||||
try {
|
||||
return new T(ox::forward<Args>(args)...);
|
||||
|
12
deps/ox/src/ox/std/string.hpp
vendored
12
deps/ox/src/ox/std/string.hpp
vendored
@ -118,6 +118,8 @@ class BasicString {
|
||||
|
||||
constexpr BasicString &operator=(BasicString &&src) noexcept;
|
||||
|
||||
constexpr BasicString &operator=(CRStringView src) noexcept;
|
||||
|
||||
constexpr BasicString &operator+=(const char *str) noexcept;
|
||||
|
||||
constexpr BasicString &operator+=(char *str) noexcept;
|
||||
@ -341,7 +343,15 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
|
||||
|
||||
template<std::size_t SmallStringSize_v>
|
||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(BasicString &&src) noexcept {
|
||||
m_buff = std::move(src.m_buff);
|
||||
if (this != &src) {
|
||||
m_buff = std::move(src.m_buff);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize_v>
|
||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(CRStringView src) noexcept {
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
47
deps/ox/src/ox/std/stringliteral.hpp
vendored
Normal file
47
deps/ox/src/ox/std/stringliteral.hpp
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2015 - 2022 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 "basestringview.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
/**
|
||||
* StringLiteral is used for functions that want to ensure that they are taking
|
||||
* string literals, and not strings outside of the data section of the program
|
||||
* that might get deleted.
|
||||
* This type cannot force you to use it correctly, so don't give it something
|
||||
* that is not a literal.
|
||||
* If you do this:
|
||||
* StringLiteral(str.c_str())
|
||||
* the resulting segfault is on you.
|
||||
*/
|
||||
class StringLiteral: public detail::BaseStringView {
|
||||
public:
|
||||
constexpr StringLiteral() noexcept = default;
|
||||
|
||||
constexpr StringLiteral(StringLiteral const&sv) noexcept = default;
|
||||
|
||||
constexpr explicit StringLiteral(std::nullptr_t) noexcept {}
|
||||
|
||||
constexpr explicit StringLiteral(const char *str) noexcept: BaseStringView(str) {}
|
||||
|
||||
constexpr explicit StringLiteral(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {}
|
||||
|
||||
constexpr auto &operator=(StringLiteral const&other) noexcept {
|
||||
if (&other != this) {
|
||||
set(other.data(), other.len());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
285
deps/ox/src/ox/std/stringview.hpp
vendored
285
deps/ox/src/ox/std/stringview.hpp
vendored
@ -13,11 +13,11 @@
|
||||
#endif
|
||||
|
||||
#include "bit.hpp"
|
||||
#include "concepts.hpp"
|
||||
#include "iterator.hpp"
|
||||
#include "stringliteral.hpp"
|
||||
#include "strops.hpp"
|
||||
#include "types.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "writer.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
@ -27,256 +27,69 @@ class BString;
|
||||
template<std::size_t buffLen>
|
||||
class BasicString;
|
||||
|
||||
class StringView {
|
||||
public:
|
||||
template<typename RefType = char&, typename PtrType = char*, bool reverse = false>
|
||||
struct iterator: public Iterator<std::bidirectional_iterator_tag, char> {
|
||||
private:
|
||||
PtrType m_t = nullptr;
|
||||
std::size_t m_offset = 0;
|
||||
std::size_t m_max = 0;
|
||||
|
||||
public:
|
||||
constexpr iterator() noexcept = default;
|
||||
|
||||
constexpr iterator(PtrType t, std::size_t offset, std::size_t max) noexcept {
|
||||
m_t = t;
|
||||
m_offset = offset;
|
||||
m_max = max;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto offset() const noexcept {
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
constexpr iterator operator+(std::size_t s) const noexcept {
|
||||
if constexpr(reverse) {
|
||||
return iterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
||||
} else {
|
||||
return iterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto operator-(const iterator &other) const noexcept {
|
||||
if constexpr(reverse) {
|
||||
return m_offset + other.m_offset;
|
||||
} else {
|
||||
return m_offset - other.m_offset;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr iterator operator-(std::size_t s) const noexcept {
|
||||
if constexpr(reverse) {
|
||||
return iterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
||||
} else {
|
||||
return iterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr iterator &operator+=(std::size_t s) noexcept {
|
||||
if constexpr(reverse) {
|
||||
m_offset = max<std::size_t>(m_offset - s, 0);
|
||||
} else {
|
||||
m_offset = min(m_offset + s, m_max);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr iterator &operator-=(std::size_t s) noexcept {
|
||||
if constexpr(reverse) {
|
||||
m_offset = min(m_offset + s, m_max);
|
||||
} else {
|
||||
m_offset = max<std::size_t>(m_offset - s, 0);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr iterator &operator++() noexcept {
|
||||
return operator+=(1);
|
||||
}
|
||||
|
||||
constexpr iterator &operator--() noexcept {
|
||||
return operator-=(1);
|
||||
}
|
||||
|
||||
constexpr RefType operator*() const noexcept {
|
||||
return m_t[m_offset];
|
||||
}
|
||||
|
||||
constexpr RefType operator[](std::size_t s) const noexcept {
|
||||
return m_t[s];
|
||||
}
|
||||
|
||||
constexpr bool operator<(const iterator &other) const noexcept {
|
||||
return m_offset < other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator>(const iterator &other) const noexcept {
|
||||
return m_offset > other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(const iterator &other) const noexcept {
|
||||
return m_offset <= other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const iterator &other) const noexcept {
|
||||
return m_offset >= other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator==(const iterator &other) const noexcept {
|
||||
return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const iterator &other) const noexcept {
|
||||
return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
const char *m_str = nullptr;
|
||||
std::size_t m_len = 0;
|
||||
class StringView: public detail::BaseStringView {
|
||||
public:
|
||||
constexpr StringView() noexcept = default;
|
||||
|
||||
constexpr StringView(const StringView &sv) noexcept = default;
|
||||
|
||||
#ifdef OX_USE_STDLIB
|
||||
constexpr StringView(const std::string_view &sv) noexcept: m_str(sv.data()), m_len(sv.size()) {}
|
||||
constexpr StringView(const std::string_view &sv) noexcept: BaseStringView(sv.data(), sv.size()) {}
|
||||
#endif
|
||||
|
||||
template<std::size_t SmallStrSz>
|
||||
constexpr StringView(const BasicString<SmallStrSz> &str) noexcept: m_str(str.c_str()), m_len(str.len()) {}
|
||||
constexpr StringView(BaseStringView const&str) noexcept: BaseStringView(str.data(), str.bytes()) {}
|
||||
|
||||
template<std::size_t SmallStrSz>
|
||||
constexpr StringView(const BString<SmallStrSz> &str) noexcept: m_str(str.c_str()), m_len(str.len()) {}
|
||||
constexpr StringView(const BasicString<SmallStrSz> &str) noexcept: BaseStringView(str.data(), str.len()) {}
|
||||
|
||||
template<std::size_t SmallStrSz>
|
||||
constexpr StringView(const BString<SmallStrSz> &str) noexcept: BaseStringView(str.data(), str.len()) {}
|
||||
|
||||
constexpr StringView(std::nullptr_t) noexcept {}
|
||||
|
||||
constexpr StringView(const char *str) noexcept: m_str(str), m_len(str ? ox_strlen(str) : 0) {}
|
||||
constexpr StringView(const char *str) noexcept: BaseStringView(str) {}
|
||||
|
||||
constexpr StringView(const char *str, std::size_t len) noexcept: m_str(str), m_len(len) {}
|
||||
constexpr StringView(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*> begin() const noexcept {
|
||||
return {m_str, 0, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*> end() const noexcept {
|
||||
return {m_str, m_len, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*> cbegin() const noexcept {
|
||||
return {m_str, 0, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*> cend() const noexcept {
|
||||
return {m_str, m_len, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*, true> crbegin() const noexcept {
|
||||
return {m_str, m_len - 1, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*, true> crend() const noexcept {
|
||||
return {m_str, MaxValue<std::size_t>, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*, true> rbegin() const noexcept {
|
||||
return {m_str, m_len - 1, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const char&, const char*, true> rend() const noexcept {
|
||||
return {m_str, MaxValue<std::size_t>, m_len};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto bytes() const noexcept {
|
||||
return m_len;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto len() const noexcept {
|
||||
return m_len;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto *data() const noexcept {
|
||||
return &m_str[0];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto &front() const noexcept {
|
||||
return m_str[0];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto &back() const noexcept {
|
||||
return m_str[m_len - 1];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto substr(std::size_t pos) const noexcept {
|
||||
if (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 {
|
||||
return m_str[i];
|
||||
}
|
||||
|
||||
constexpr ox::StringView &operator=(const StringView &other) noexcept = default;
|
||||
|
||||
constexpr auto operator==(const StringView &other) const noexcept {
|
||||
if (other.len() != len()) {
|
||||
return false;
|
||||
}
|
||||
return ox_strncmp(m_str, other.m_str, len()) == 0;
|
||||
}
|
||||
|
||||
constexpr auto operator<=>(const StringView &str2) const noexcept {
|
||||
const StringView &str1 = *this;
|
||||
const auto maxLen = ox::min(str1.len(), str2.len());
|
||||
const auto a = &str1.front();
|
||||
const auto b = &str2.front();
|
||||
for (std::size_t i = 0; i < maxLen && (a[i] || b[i]); ++i) {
|
||||
if (a[i] < b[i]) {
|
||||
return -1;
|
||||
} else if (a[i] > b[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (str1.len() > str2.len()) {
|
||||
return 1;
|
||||
} else if (str1.len() < str2.len()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
constexpr auto &operator=(StringView const&other) noexcept {
|
||||
if (&other != this) {
|
||||
set(other.data(), other.len());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
using CRStringView = const StringView&;
|
||||
|
||||
constexpr auto operator==(CRStringView s1, CRStringView s2) noexcept {
|
||||
if (s2.len() != s1.len()) {
|
||||
return false;
|
||||
}
|
||||
return ox_strncmp(s1.data(), s2.data(), s1.len()) == 0;
|
||||
}
|
||||
|
||||
constexpr auto operator<=>(CRStringView s1, CRStringView s2) noexcept {
|
||||
const auto maxLen = ox::min(s1.len(), s2.len());
|
||||
const auto a = &s1.front();
|
||||
const auto b = &s2.front();
|
||||
for (std::size_t i = 0; i < maxLen && (a[i] || b[i]); ++i) {
|
||||
if (a[i] < b[i]) {
|
||||
return -1;
|
||||
} else if (a[i] > b[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (s1.len() > s2.len()) {
|
||||
return 1;
|
||||
} else if (s1.len() < s2.len()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool beginsWith(CRStringView base, CRStringView beginning) noexcept {
|
||||
const auto beginningLen = ox::min(beginning.len(), base.len());
|
||||
@ -302,7 +115,7 @@ constexpr std::size_t find(CRStringView str, char search) noexcept {
|
||||
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)) {
|
||||
if (beginsWith(substr(str, i), search)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -313,14 +126,14 @@ 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);
|
||||
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 = current.substr(0, next); s.len()) {
|
||||
if (const auto s = substr(current, 0, next); s.len()) {
|
||||
out.emplace_back(s);
|
||||
}
|
||||
current = current.substr(next);
|
||||
current = substr(current, next);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -329,14 +142,14 @@ 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());
|
||||
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 = current.substr(0, next); s.len()) {
|
||||
if (const auto s = substr(current, 0, next); s.len()) {
|
||||
out.emplace_back(s);
|
||||
}
|
||||
current = current.substr(next);
|
||||
current = substr(current, next);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
19
deps/ox/src/ox/std/strops.hpp
vendored
19
deps/ox/src/ox/std/strops.hpp
vendored
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "concepts.hpp"
|
||||
#include "error.hpp"
|
||||
#include "math.hpp"
|
||||
#include "types.hpp"
|
||||
@ -128,6 +129,24 @@ constexpr int ox_lastIndexOf(const auto &str, int character, std::size_t maxLen
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<OxString_c Str>
|
||||
[[nodiscard]]
|
||||
constexpr Str substr(Str const&str, std::size_t pos) noexcept {
|
||||
if (str.len() >= pos) {
|
||||
return Str(str.data() + pos, str.len() - pos);
|
||||
}
|
||||
return Str();
|
||||
}
|
||||
|
||||
template<OxString_c Str>
|
||||
[[nodiscard]]
|
||||
constexpr Str substr(Str const&str, std::size_t start, std::size_t end) noexcept {
|
||||
if (str.len() >= start && end >= start) {
|
||||
return Str(str.data() + start, end - start);
|
||||
}
|
||||
return Str();
|
||||
}
|
||||
|
||||
template<typename Integer>
|
||||
constexpr ox::Error itoa(Integer v, ox::Writer_c auto &writer) noexcept {
|
||||
if (v) {
|
||||
|
4
deps/ox/src/ox/std/test/tests.cpp
vendored
4
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -105,6 +105,10 @@ static std::map<ox::String, ox::Error(*)()> tests = {
|
||||
oxAssert(endsWith(str, "df"), "String endsWith is broken");
|
||||
oxAssert(!endsWith(str, "awefawe"), "String endsWith is broken");
|
||||
oxAssert(!endsWith(str, "eu"), "String endsWith is broken");
|
||||
oxAssert(ox::StringView("Write") != ox::String(""), "String / StringView comparison broken");
|
||||
oxAssert(ox::String("Write") != ox::StringView(""), "String / StringView comparison broken");
|
||||
oxAssert(ox::String("Write") == ox::StringView("Write"), "String / StringView comparison broken");
|
||||
oxAssert(ox::String(ox::StringView("Write")) == ox::StringView("Write"), "String / StringView comparison broken");
|
||||
return OxError(0);
|
||||
}
|
||||
},
|
||||
|
2
deps/ox/src/ox/std/uuid.hpp
vendored
2
deps/ox/src/ox/std/uuid.hpp
vendored
@ -132,7 +132,7 @@ class UUID {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
const auto seg = s.substr(i, i + 2);
|
||||
const auto seg = substr(s, i, i + 2);
|
||||
if (seg.len() != 2) {
|
||||
return OxError(1, "Invalid UUID");
|
||||
}
|
||||
|
2
deps/ox/src/ox/std/vector.hpp
vendored
2
deps/ox/src/ox/std/vector.hpp
vendored
@ -324,7 +324,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::size_t size) noexce
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept {
|
||||
for (auto &item : list) {
|
||||
emplace_back(item);
|
||||
emplace_back(std::move(item));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user