aboutsummaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/kstd/include/kstd/string264
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