diff options
author | Dominick Allen <djallen@librehumanitas.org> | 2024-09-22 12:41:28 -0500 |
---|---|---|
committer | Dominick Allen <djallen@librehumanitas.org> | 2024-09-22 12:41:28 -0500 |
commit | 7da829d48f9059c83ab9cada2c850621e8bbd3f3 (patch) | |
tree | 314e7a5b645e910d4997e3bee980bd2024f3087d /include/fud_string.hpp | |
parent | bf81e34921e3e30b05313efbcf5c9fa839cb7c05 (diff) |
Basics of library.
Diffstat (limited to 'include/fud_string.hpp')
-rw-r--r-- | include/fud_string.hpp | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/include/fud_string.hpp b/include/fud_string.hpp new file mode 100644 index 0000000..42009b4 --- /dev/null +++ b/include/fud_string.hpp @@ -0,0 +1,201 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FUD_STRING_HPP +#define FUD_STRING_HPP + +#include "fud_utf8.hpp" + +#include <climits> +#include <cstddef> + +static_assert(CHAR_BIT == 8); + +namespace fud { + +constexpr size_t SSO_BUF_LENGTH = 15; +constexpr size_t SSO_BUF_SIZE = SSO_BUF_LENGTH + 1; + +class String { + public: + String() = default; + explicit String(const utf8* cString); + explicit String(const char* cString); + String(const String& rhs); + String(String&& rhs); + ~String(); + + String& operator=(const String& rhs); + String& operator=(String&& rhs); + + [[nodiscard]] constexpr size_t length() const + { + return m_length; + } + + [[nodiscard]] constexpr size_t size() const + { + return m_length + 1; + } + + [[nodiscard]] constexpr size_t capacity() const + { + return m_capacity; + } + + /** \brier The underlying data, guaranteed to have c string representation. */ + [[nodiscard]] constexpr const utf8* data() const + { + return isLarge() ? m_data : m_buffer.data(); + } + + /** \brier The underlying data as an explicit c string. */ + [[nodiscard]] inline const char* c_str() const + { + return isLarge() ? reinterpret_cast<const char*>(m_data) : reinterpret_cast<const char*>(m_buffer.data()); + } + + /** \brier The underlying data, guaranteed to have c string representation. */ + [[nodiscard]] constexpr utf8* data() + { + return isLarge() ? m_data : m_buffer.data(); + } + + /** \brier The underlying data as an explicit c string. */ + [[nodiscard]] inline char* c_str() + { + return isLarge() ? reinterpret_cast<char*>(m_data) : reinterpret_cast<char*>(m_buffer.data()); + } + + [[nodiscard]] bool nullTerminated() const; + + [[nodiscard]] bool valid() const; + + [[nodiscard]] bool utf8Valid() const; + + [[nodiscard]] FudStatus nullTerminate() const; + + [[nodiscard]] constexpr size_t remainingLength() const + { + if (m_length >= m_capacity) { + return 0; + } + + return m_capacity - 1U - m_length; + } + + [[nodiscard]] FudStatus pushBack(char letter); + + [[nodiscard]] FudStatus pushBack(utf8 letter); + + [[nodiscard]] FudStatus pushBack(const FudUtf8& letter); + + std::optional<utf8> pop(); + + [[nodiscard]] FudStatus catenate(StringView source); + + [[nodiscard]] String append(const String& rhs) const; + + private: + using BufType = Array<utf8, SSO_BUF_SIZE>; + union { + BufType m_buffer{BufType::constFill(0)}; + utf8* m_data; + }; + size_t m_length{0}; + size_t m_capacity{0}; + + [[nodiscard]] constexpr bool isLarge() const + { + return m_capacity > SSO_BUF_LENGTH; + } +}; + +class StringView { + public: + constexpr StringView() noexcept : m_length(0), m_data{nullptr} + { + } + + constexpr StringView(size_t strLen, const utf8* strData) : m_length(0), m_data{strData} + { + } + + StringView(size_t strLen, const char* strData) : + m_length(0), // line break + m_data{reinterpret_cast<const utf8*>(strData)} // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + { + } + + explicit constexpr StringView(const StringView& view) noexcept = default; + + explicit constexpr StringView(const String& fudString) noexcept : StringView(fudString.length(), fudString.data()) + { + } + + [[nodiscard]] constexpr size_t length() const + { + return m_length; + } + + [[nodiscard]] constexpr const utf8* data() const + { + return m_data; + } + + [[nodiscard]] bool nullTerminated() const; + + [[nodiscard]] bool utf8Valid() const; + + Result<size_t, FudStatus> skipWhitespace(); + + Result<size_t, FudStatus> trimWhitespace(); + + FudStatus toUint8(uint8_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toUint16(uint16_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toUint32(uint32_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toUint64(uint64_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toInt8(int8_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toInt16(int16_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toInt32(int32_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toInt64(int64_t& number, uint8_t specifiedRadix, size_t& strLen) const; + + FudStatus toFloat(float& number, size_t& strLen) const; + + FudStatus toDouble(double& number, size_t& strLen) const; + + private: + size_t m_length; + const utf8* m_data; +}; + +FudStatus skipWhitespace(StringView& view, size_t& skipIndex); + +ssize_t cStringLength(const char* str); + +ssize_t cStringLength(const char* str, size_t maxLength); + +} // namespace fud + +#endif |