#pragma once #include #include namespace saw { /** * Helper object which creates a templated string from the provided string * literal. It guarantees compile time uniqueness and thus allows using strings * in template parameters. */ template class string_literal { public: static_assert(N > 0, "string_literal needs a null terminator"); constexpr string_literal(const CharT (&input)[N]) noexcept { for (size_t i = 0; i < N; ++i) { data[i] = input[i]; } } std::array data{}; constexpr std::string_view view() const noexcept { return std::string_view{data.data()}; } constexpr bool operator==(const string_literal &) const noexcept = default; template constexpr bool operator==(const string_literal &) const noexcept { return false; } template constexpr string_literal operator+(const string_literal& rhs) const noexcept { CharT sum[N+NR-1]; // The weird i+1 happens due to needing to skip the '\0' terminator for(size_t i = 0; (i+1) < N; ++i){ sum[i] = data[i]; } for(size_t i = 0; i < NR; ++i){ sum[i+N-1] = rhs.data[i]; } return string_literal{sum}; } }; template constexpr string_literal operator""_sl() { return string_literal{{Chars..., '\0'}}; } } // namespace saw