From 7da829d48f9059c83ab9cada2c850621e8bbd3f3 Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Sun, 22 Sep 2024 12:41:28 -0500 Subject: Basics of library. --- include/fud_string.hpp | 201 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 include/fud_string.hpp (limited to 'include/fud_string.hpp') 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 +#include + +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(m_data) : reinterpret_cast(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(m_data) : reinterpret_cast(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 pop(); + + [[nodiscard]] FudStatus catenate(StringView source); + + [[nodiscard]] String append(const String& rhs) const; + + private: + using BufType = Array; + 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(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 skipWhitespace(); + + Result 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 -- cgit v1.2.3