mijin2/source/mijin/util/template_string.hpp
2023-05-29 14:51:44 +02:00

127 lines
3.1 KiB
C++

#pragma once
#if !defined(MIJIN_UTIL_TEMPLATE_STRING_HPP_INCLUDED)
#define MIJIN_UTIL_TEMPLATE_STRING_HPP_INCLUDED 1
#include <utility>
#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<char... chars>
using template_string = std::integer_sequence<char, chars...>;
namespace impl
{
template<typename T>
struct TemplateStringHelper;
template<char... chars>
struct TemplateStringHelper<template_string<chars...>>
{
static constexpr const char value[sizeof...(chars) + 1] = {chars..., '\0'}; // NOLINT
};
template<char chr, char... chars>
constexpr template_string<chr, chars...> prependToString(template_string<chars...>)
{
return {};
}
template<char... chars>
struct TemplateStringBuilder {};
template<char firstChar, char... chars>
struct TemplateStringBuilder<firstChar, chars...>
{
using previous_seq_t = typename TemplateStringBuilder<chars...>::seq_t;
using seq_t = decltype(prependToString<firstChar>(previous_seq_t()));
};
template<char... chars>
struct TemplateStringBuilder<'\0', chars...>
{
using seq_t = template_string<>;
};
template<std::size_t pos, std::size_t len>
constexpr char charAt(const char (&text)[len])
{
if constexpr (pos < len) {
return text[pos];
}
else {
return '\0';
}
}
template<char... chars>
typename TemplateStringBuilder<chars...>::seq_t buildTemplateString()
{
return {};
}
template<char... chars>
using template_string_builder = typename TemplateStringBuilder<chars...>::seq_t;
}
template<typename T>
inline constexpr auto template_string_v = impl::TemplateStringHelper<T>::value;
//
// public types
//
//
// public functions
//
} // namespace mijin
#endif // !defined(MIJIN_UTIL_TEMPLATE_STRING_HPP_INCLUDED)