diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/include/kstd/string | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/libs/kstd/include/kstd/string b/libs/kstd/include/kstd/string new file mode 100644 index 0000000..62126a9 --- /dev/null +++ b/libs/kstd/include/kstd/string @@ -0,0 +1,264 @@ +#ifndef KSTD_STRING_HPP +#define KSTD_STRING_HPP + +#include <kstd/cstring> +#include <kstd/os/error.hpp> +#include <kstd/vector> + +#include <algorithm> +#include <cstddef> +#include <string_view> + +namespace kstd +{ + /** + * @brief A simple string implementation that owns its data and provides basic operations. + */ + struct string + { + //! The type of the characters contained in this string. + using value_type = char; + //! The type of the underlying storage used by this string. + using storage_type = kstd::vector<value_type>; + //! The type of all sizes used in and with this string. + using size_type = std::size_t; + //! The type of the difference between two iterators. + using difference_type = std::ptrdiff_t; + //! The type of references to single values in this string. + using reference = value_type &; + //! The type of references to constant single values in this string. + using const_reference = value_type const &; + //! The type of pointers to single values in this string. + using pointer = value_type *; + //! The type of pointers to constant single values in this string. + using const_pointer = value_type const *; + //! The type of iterators into this string. + using iterator = pointer; + //! The type of constant iterators into this string. + using const_iterator = const_pointer; + + /** + * @brief Constructs an empty null-terminated string. + */ + string() + : m_storage{value_type{'\0'}} + {} + + /** + * @brief Constructs a string from a string view by copying the characters into owned storage. + * @param view The string view to copy the characters from. + */ + string(std::string_view view) + : string() + { + append(view); + } + + /** + * @brief Constructs a string by copying another string. + * @param other The string to copy. + */ + constexpr string(string const & other) + : m_storage{other.m_storage} + {} + + /** + * @brief Destructs the string. + */ + constexpr ~string() = default; + + /** + * @brief Assigns the value of another string to this string. + * @param other The string to assign from. + * @return A reference to this string. + */ + constexpr auto operator=(string const & other) -> string & = default; + + /** + * @brief Returns the number of characters in this string, not including the null terminator. + */ + [[nodiscard]] constexpr auto size() const noexcept -> size_type + { + return m_storage.empty() ? 0 : m_storage.size() - 1; + } + + /** + * @brief Checks if this string is empty, not including the null terminator. + */ + [[nodiscard]] constexpr auto empty() const noexcept -> bool + { + return size() == 0; + } + + /** + * @brief Clears the content of the string, resulting in an empty string. + * The string remains null-terminated after this operation. + */ + constexpr auto clear() -> void + { + m_storage.clear(); + m_storage.push_back(value_type{'\0'}); + } + + //! Get a pointer to the underlying storage of the string + [[nodiscard]] constexpr auto data() noexcept -> pointer + { + return m_storage.data(); + } + + //! Get a const pointer to the underlying storage of the string + [[nodiscard]] constexpr auto data() const noexcept -> const_pointer + { + return m_storage.data(); + } + + //! Get a const pointer to the underlying storage of the string + [[nodiscard]] constexpr auto c_str() const noexcept -> const_pointer + { + return data(); + } + + //! Get an iterator to the beginning of the string + [[nodiscard]] constexpr auto begin() noexcept -> iterator + { + return data(); + } + + //! Get an const iterator to the beginning of the string + [[nodiscard]] constexpr auto begin() const noexcept -> const_iterator + { + return data(); + } + + //! Get an const iterator to the beginning of the string + [[nodiscard]] constexpr auto cbegin() const noexcept -> const_iterator + { + return begin(); + } + + //! Get an iterator to the end of the string + [[nodiscard]] constexpr auto end() noexcept -> iterator + { + return data() + size(); + } + + //! Get an const iterator to the end of the string + [[nodiscard]] constexpr auto end() const noexcept -> const_iterator + { + return data() + size(); + } + + //! Get an const iterator to the end of the string + [[nodiscard]] constexpr auto cend() const noexcept -> const_iterator + { + return end(); + } + + //! Get a reference to the first character of the string + [[nodiscard]] constexpr auto front() -> reference + { + return m_storage.front(); + } + + //! Get a const reference to the first character of the string + [[nodiscard]] constexpr auto front() const -> const_reference + { + return m_storage.front(); + } + + //! Get a reference to the last character of the string + [[nodiscard]] constexpr auto back() -> reference + { + return m_storage[size() - 1]; + } + + //! Get a const reference to the last character of the string + [[nodiscard]] constexpr auto back() const -> const_reference + { + return m_storage[size() - 1]; + } + + /** + * @brief Appends a character to the end of the string. + * @param ch The character to append. + */ + constexpr auto push_back(value_type ch) -> void + { + m_storage.back() = ch; + m_storage.push_back(value_type{'\0'}); + } + + /** + * @brief Appends a string view to the end of the string by copying the characters into owned storage. + * @param view The string view to append. + * @return A reference to this string. + */ + constexpr auto append(std::string_view view) -> string & + { + if (!view.empty()) + { + std::ranges::for_each(view, [this](auto const ch) { push_back(ch); }); + } + + return *this; + } + + /** + * @brief Appends another string to the end of this string by copying the characters into owned storage. + * @param other The string to append. + * @return A reference to this string. + */ + constexpr auto append(string const & other) -> string & + { + return append(other.view()); + } + + /** + * @brief Appends another string to the end of this string by copying the characters into owned storage. + * @param other The string to append. + * @return A reference to this string. + */ + constexpr auto operator+=(string const & other) -> string & + { + return append(other); + } + + /** + * @brief Appends a character to the end of the string. + * @param ch The character to append. + * @return A reference to this string. + */ + constexpr auto operator+=(value_type ch) -> string & + { + push_back(ch); + return *this; + } + + /** + * @brief Returns a string view of this string, which is a non-owning view into the characters of this string. + */ + [[nodiscard]] constexpr auto view() const noexcept -> std::string_view + { + return std::string_view{data(), size()}; + } + + private: + //! The underlying storage of the string, which owns the characters and ensures null-termination. + storage_type m_storage{}; + }; + + /** + * @brief Concatenates a strings and a character and returns the result as a new string. + * @param lhs The string to concatenate. + * @param c The character to concatenate. + * @return A new string that is the result of concatenating @p lhs and @p c. + */ + [[nodiscard]] constexpr auto inline operator+(string const & lhs, char const c) -> string + { + string result{lhs}; + result += c; + return result; + } +} // namespace kstd + +#endif
\ No newline at end of file |
