#pragma once #include #include #include #include #include #include namespace sc { template struct string_constant { using value_type = std::basic_string_view; private: constexpr static std::array storage{chars...}; using size_type = int; using const_iterator = typename value_type::const_iterator; constexpr static size_type npos = std::numeric_limits::max(); public: constexpr static value_type value{storage.data(), sizeof...(chars)}; constexpr static auto begin() noexcept { return std::cbegin(storage); } constexpr static auto end() noexcept { return std::cend(storage); } [[nodiscard]] constexpr static auto size() noexcept { return std::size(storage); } template [[nodiscard]] constexpr static auto substr(std::integral_constant, std::integral_constant = {}) { constexpr size_type sz = count == npos ? size() - pos : count; return [&](std::integer_sequence) { return string_constant{}; }(std::make_integer_sequence{}); } template constexpr auto apply(F &&f) const { return std::forward(f)(*this); } }; template [[nodiscard]] constexpr auto operator==(string_constant, string_constant) noexcept -> bool { return false; } template [[nodiscard]] constexpr auto operator==(string_constant, string_constant) noexcept -> bool { return true; } #if __cpp_lib_three_way_comparison < 201907L template [[nodiscard]] constexpr auto operator!=(string_constant lhs, string_constant rhs) noexcept -> bool { return not(lhs == rhs); } template [[nodiscard]] constexpr auto operator<(string_constant lhs, string_constant rhs) noexcept -> bool { return lhs.value < rhs.value; } template [[nodiscard]] constexpr auto operator>(string_constant lhs, string_constant rhs) noexcept -> bool { return lhs.value > rhs.value; } template [[nodiscard]] constexpr auto operator<=(string_constant lhs, string_constant rhs) noexcept -> bool { return lhs.value <= rhs.value; } template [[nodiscard]] constexpr auto operator>=(string_constant lhs, string_constant rhs) noexcept -> bool { return lhs.value >= rhs.value; } #else template [[nodiscard]] constexpr auto operator<=>(string_constant lhs, string_constant rhs) noexcept { return lhs.value <=> rhs.value; } #endif template [[nodiscard]] constexpr auto operator+(string_constant, string_constant) noexcept -> string_constant { return {}; } } // namespace sc