#include <string>
#include <string_view>
#include <array>
#include <iostream>
namespace details
{
template<typename CharT>
constexpr bool SupportedCharT =
std::is_same_v<CharT, char> ||
std::is_same_v<CharT, wchar_t> ||
std::is_same_v<CharT, char8_t> ||
std::is_same_v<CharT, char16_t> ||
std::is_same_v<CharT, char32_t>;
template<typename CharT, std::size_t N>
struct string_literal_t
{
constexpr explicit string_literal_t(const char(&chars)[N])
{
for (std::size_t n = 0; n < N; ++n)
{
m_chars[n] = convert_from(chars[n]);
}
}
// and you can add other overloaded constructors for non char strings too
//constexpr explicit string_literal_t(const char (&wchar_t)[N])
constexpr operator const CharT* () const noexcept
{
return m_chars.data();
}
private:
constexpr CharT convert_from(char c)
{
// oversimplified conversion for "ASCII" to any other char type
// or use if constexpr to put appropiate char convert here
return static_cast<CharT>(c);
}
std::array<CharT, N> m_chars;
};
}
template<typename CharT, std::size_t N>
constexpr auto string_literal(const char(&chars)[N]) -> std::enable_if_t<details::SupportedCharT<CharT>,details::string_literal_t<CharT, N>>
{
return details::string_literal_t<CharT, N>(chars);
}
static constexpr auto hello = string_literal<wchar_t>("Hello");
static constexpr auto world = string_literal<char32_t>("world");
void output(const wchar_t* str)
{
std::wcout << str;
}
int main()
{
static_assert(details::SupportedCharT<wchar_t>);
output(hello);
}