#pragma once #include #ifdef UTEMPL_MODULE export module utempl.string; import std; #else #include #include #endif UTEMPL_EXPORT_BEGIN namespace utempl { template struct ConstexprString { std::array data; using char_type = char; constexpr auto begin() -> char* { return this->data.begin(); }; [[nodiscard]] constexpr auto begin() const -> const char* { return this->data.begin(); }; [[nodiscard]] constexpr auto end() -> char* { return this->data.end(); }; [[nodiscard]] constexpr auto end() const -> const char* { return this->data.end(); }; static constexpr auto kSize = Size == 0 ? 0 : Size - 1; explicit constexpr ConstexprString() = default; constexpr ConstexprString(const char (&data)[Size]) : data{} { // NOLINT std::ranges::copy_n(data, Size, this->data.begin()); }; explicit constexpr ConstexprString(std::string_view data) : data{} { std::ranges::copy_n(data.begin(), Size, this->data.begin()); }; explicit constexpr ConstexprString(std::array data) : data(std::move(data)) {}; constexpr auto size() const { return Size == 0 ? 0 : Size - 1; }; constexpr operator std::string_view() const& { // NOLINT return {this->begin()}; }; constexpr auto operator==(std::string_view other) const -> bool { return static_cast(*this) == other; }; constexpr auto operator==(const ConstexprString& other) const { return static_cast(*this) == static_cast(other); }; template constexpr auto operator==(const ConstexprString& other) const -> bool { return false; }; constexpr auto operator==(const std::string& other) const -> bool { return static_cast(*this) == other; }; template constexpr auto operator+(const ConstexprString& other) -> ConstexprString { ConstexprString response; std::ranges::copy_n(this->begin(), Size - 1, response.begin()); std::ranges::copy_n(other.begin(), SSize, response.begin() + Size - 1); return response; }; constexpr ConstexprString(const ConstexprString&) = default; constexpr ConstexprString(ConstexprString&&) = default; }; template constexpr auto operator<<(std::ostream& stream, const ConstexprString& str) -> std::ostream& { stream << static_cast(str); return stream; }; template constexpr auto CreateStringWith(char c) { ConstexprString str{}; for(std::size_t i = 0; i < Count; i++) { str.data[i] = c; }; str.data[Count] = '\0'; return str; }; template ConstexprString(const char (&data)[Size]) -> ConstexprString; // NOLINT } // namespace utempl UTEMPL_EXPORT_END