Initial commit
This commit is contained in:
commit
91d54c58d5
42 changed files with 2212 additions and 0 deletions
130
src/foundation/string.cppm
Normal file
130
src/foundation/string.cppm
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
export module bedrock.foundation:string;
|
||||
|
||||
import bedrock.numbers;
|
||||
import bedrock.semantics;
|
||||
import :byte;
|
||||
import :buffer;
|
||||
import :bytes_iterator;
|
||||
import :iterators.enumerate;
|
||||
import :iterators.reverse;
|
||||
|
||||
namespace br {
|
||||
|
||||
export class String final {
|
||||
private:
|
||||
BufferView m_data;
|
||||
|
||||
explicit String(BufferView&& view)
|
||||
: m_data(view) {}
|
||||
|
||||
public:
|
||||
friend class StringBuffer;
|
||||
|
||||
template <usize Size>
|
||||
constexpr String(const char (&str)[Size])
|
||||
: m_data(reinterpret_cast<const byte*>(&str), Size - 1) {}
|
||||
|
||||
[[nodiscard]]
|
||||
auto byteSize() const noexcept -> usize {
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto characterLength() const noexcept -> usize {
|
||||
usize nCharacters = 0;
|
||||
for (auto byte : m_data) {
|
||||
if ((byte & 0xc0_b) != 0x80_b) {
|
||||
++nCharacters;
|
||||
}
|
||||
}
|
||||
return nCharacters;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto isEmpty() const noexcept -> bool {
|
||||
return *this == "";
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto startsWith(const String& str) noexcept -> bool {
|
||||
for (auto [byte, i] : str.bytes() | enumerate()) {
|
||||
if (m_data[i] != byte) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto endsWith(const String& str) noexcept -> bool {
|
||||
for (auto [byte, i] : str.bytes() | reverse() | enumerate()) {
|
||||
if (m_data[i] != byte) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// Implicit conversions
|
||||
// ====================================================================
|
||||
[[nodiscard]] operator BufferView() const noexcept {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto bytes() const noexcept -> BytesIterator {
|
||||
return m_data.bytes();
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// Moveable
|
||||
// ====================================================================
|
||||
String(String&& other) noexcept
|
||||
: m_data(move(other.m_data)) {}
|
||||
|
||||
auto operator=(String&& other) noexcept -> String& {
|
||||
if (this == &other) {
|
||||
m_data = move(other.m_data);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~String() = default;
|
||||
|
||||
// ====================================================================
|
||||
// Copyable
|
||||
// ====================================================================
|
||||
String(const String& other) = default;
|
||||
|
||||
auto operator=(const String& other) noexcept -> String& {
|
||||
if (&other != this) {
|
||||
m_data = other.m_data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
// Equivalence
|
||||
// ====================================================================
|
||||
[[nodiscard]]
|
||||
auto operator==(const String& other) const noexcept -> bool {
|
||||
return m_data == other.m_data;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
auto operator!=(const String& other) const noexcept -> bool {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct EquivalenceType<String> {
|
||||
static constexpr bool is_valid = true;
|
||||
};
|
||||
|
||||
static_assert(Moveable<String>);
|
||||
static_assert(Copyable<String>);
|
||||
static_assert(Equivalence<String>);
|
||||
|
||||
} // namespace br
|
||||
Loading…
Add table
Add a link
Reference in a new issue