#pragma once #if !defined(MIJIN_UTIL_TEMPLATE_STRING_HPP_INCLUDED) #define MIJIN_UTIL_TEMPLATE_STRING_HPP_INCLUDED 1 #include #include "../detect.hpp" namespace mijin { // // public defines // // #define MIJIN_MAKE_TEMPLATE_STRING(str) decltype(str ## _mijin_template_string) #define MIJIN_MAKE_TEMPLATE_STRING(str) \ mijin::impl::template_string_builder< \ mijin::impl::charAt<0>(str), \ mijin::impl::charAt<1>(str), \ mijin::impl::charAt<2>(str), \ mijin::impl::charAt<3>(str), \ mijin::impl::charAt<4>(str), \ mijin::impl::charAt<5>(str), \ mijin::impl::charAt<6>(str), \ mijin::impl::charAt<7>(str), \ mijin::impl::charAt<8>(str), \ mijin::impl::charAt<9>(str), \ mijin::impl::charAt<10>(str), \ mijin::impl::charAt<11>(str), \ mijin::impl::charAt<12>(str), \ mijin::impl::charAt<13>(str), \ mijin::impl::charAt<14>(str), \ mijin::impl::charAt<15>(str), \ mijin::impl::charAt<16>(str), \ mijin::impl::charAt<17>(str), \ mijin::impl::charAt<18>(str), \ mijin::impl::charAt<19>(str), \ mijin::impl::charAt<20>(str), \ mijin::impl::charAt<21>(str), \ mijin::impl::charAt<22>(str), \ mijin::impl::charAt<23>(str), \ mijin::impl::charAt<24>(str), \ mijin::impl::charAt<25>(str), \ mijin::impl::charAt<26>(str), \ mijin::impl::charAt<27>(str), \ mijin::impl::charAt<28>(str), \ mijin::impl::charAt<29>(str) \ > // // public constants // template using template_string = std::integer_sequence; namespace impl { template struct TemplateStringHelper; template struct TemplateStringHelper> { static constexpr const char value[sizeof...(chars) + 1] = {chars..., '\0'}; // NOLINT }; template constexpr template_string prependToString(template_string) { return {}; } template struct TemplateStringBuilder {}; template struct TemplateStringBuilder { using previous_seq_t = typename TemplateStringBuilder::seq_t; using seq_t = decltype(prependToString(previous_seq_t())); }; template struct TemplateStringBuilder<'\0', chars...> { using seq_t = template_string<>; }; template constexpr char charAt(const char (&text)[len]) { if constexpr (pos < len) { return text[pos]; } else { return '\0'; } } template typename TemplateStringBuilder::seq_t buildTemplateString() { return {}; } template using template_string_builder = typename TemplateStringBuilder::seq_t; } template inline constexpr auto template_string_v = impl::TemplateStringHelper::value; // // public types // // // public functions // } // namespace mijin #endif // !defined(MIJIN_UTIL_TEMPLATE_STRING_HPP_INCLUDED)