#include <iostream>
namespace variadic_toolbox
{
template<unsigned count,
template<unsigned...> class meta_functor, unsigned... indices>
struct apply_range
{
typedef typename apply_range<count - 1, meta_functor, count - 1, indices...>::result result;
};
template<template<unsigned...> class meta_functor, unsigned... indices>
struct apply_range<0, meta_functor, indices...>
{
typedef typename meta_functor<indices...>::result result;
};
}
namespace compile_time
{
template<char... str>
struct string
{
static constexpr const char chars[] = { str..., '\0' };
};
template<char... str>
constexpr const char string<str...>::chars[];
template<typename lambda_str_type>
struct string_builder
{
template<unsigned... indices>
struct produce
{
typedef string<lambda_str_type {}.chars[indices]...> result;
};
};
template<char... str0, char... str1>
string<str0..., str1...> operator+(string<str0...>, string<str1...>)
{
return {};
}
}
#define CSTRING(string_literal) \
[]{ \
struct constexpr_string_type { const char * chars = string_literal; }; \
return variadic_toolbox::apply_range<sizeof(string_literal)-1, \
compile_time::string_builder<constexpr_string_type>::produce>::result{}; \
}()
int main()
{
auto str_hello = CSTRING("hello");
auto str_world = CSTRING(" world");
const char* concat = (str_hello + str_world).chars;
std::cout << "runtime concat: " << str_hello.chars << str_world.chars << "\n <=> \n";
std::cout << "compile concat: " << concat << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKbmFtZXNwYWNlICB2YXJpYWRpY190b29sYm94CnsKICB0ZW1wbGF0ZTx1bnNpZ25lZCAgY291bnQsCiAgICB0ZW1wbGF0ZTx1bnNpZ25lZC4uLj4gY2xhc3MgIG1ldGFfZnVuY3RvciwgdW5zaWduZWQuLi4gIGluZGljZXM+CiAgc3RydWN0ICBhcHBseV9yYW5nZQogIHsKICAgIHR5cGVkZWYgIHR5cGVuYW1lIGFwcGx5X3JhbmdlPGNvdW50IC0gMSwgbWV0YV9mdW5jdG9yLCBjb3VudCAtIDEsIGluZGljZXMuLi4+OjpyZXN1bHQgIHJlc3VsdDsKICB9OwoKICB0ZW1wbGF0ZTx0ZW1wbGF0ZTx1bnNpZ25lZC4uLj4gY2xhc3MgIG1ldGFfZnVuY3RvciwgdW5zaWduZWQuLi4gIGluZGljZXM+CiAgc3RydWN0ICBhcHBseV9yYW5nZTwwLCBtZXRhX2Z1bmN0b3IsIGluZGljZXMuLi4+CiAgewogICAgdHlwZWRlZiAgdHlwZW5hbWUgbWV0YV9mdW5jdG9yPGluZGljZXMuLi4+OjpyZXN1bHQgIHJlc3VsdDsKICB9Owp9CgpuYW1lc3BhY2UgIGNvbXBpbGVfdGltZQp7CiAgdGVtcGxhdGU8Y2hhci4uLiAgc3RyPgogIHN0cnVjdCAgc3RyaW5nCiAgewogICAgc3RhdGljICBjb25zdGV4cHIgIGNvbnN0IGNoYXIgIGNoYXJzW10gPSB7IHN0ci4uLiwgJ1wwJyB9OwogIH07CgogIHRlbXBsYXRlPGNoYXIuLi4gIHN0cj4KICBjb25zdGV4cHIgIGNvbnN0IGNoYXIgc3RyaW5nPHN0ci4uLj46OmNoYXJzW107CgogIHRlbXBsYXRlPHR5cGVuYW1lICBsYW1iZGFfc3RyX3R5cGU+CiAgc3RydWN0ICBzdHJpbmdfYnVpbGRlcgogIHsKICAgIHRlbXBsYXRlPHVuc2lnbmVkLi4uIGluZGljZXM+CiAgICBzdHJ1Y3QgIHByb2R1Y2UKICAgIHsKICAgICAgdHlwZWRlZiAgc3RyaW5nPGxhbWJkYV9zdHJfdHlwZSB7fS5jaGFyc1tpbmRpY2VzXS4uLj4gIHJlc3VsdDsKICAgIH07CiAgfTsKCiAgdGVtcGxhdGU8Y2hhci4uLiAgc3RyMCwgY2hhci4uLiAgc3RyMT4KICBzdHJpbmc8c3RyMC4uLiwgc3RyMS4uLj4gIG9wZXJhdG9yKyhzdHJpbmc8c3RyMC4uLj4sIHN0cmluZzxzdHIxLi4uPikKICB7CiAgICByZXR1cm4ge307CiAgfQp9CgojZGVmaW5lICBDU1RSSU5HKHN0cmluZ19saXRlcmFsKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgW117ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHN0cnVjdCAgY29uc3RleHByX3N0cmluZ190eXBlIHsgY29uc3QgY2hhciAqIGNoYXJzID0gc3RyaW5nX2xpdGVyYWw7IH07ICAgICAgICAgXAogICAgICAgIHJldHVybiAgdmFyaWFkaWNfdG9vbGJveDo6YXBwbHlfcmFuZ2U8c2l6ZW9mKHN0cmluZ19saXRlcmFsKS0xLCAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICBjb21waWxlX3RpbWU6OnN0cmluZ19idWlsZGVyPGNvbnN0ZXhwcl9zdHJpbmdfdHlwZT46OnByb2R1Y2U+OjpyZXN1bHR7fTsgICAgXAogICAgfSgpCgppbnQgbWFpbigpCnsKICBhdXRvICBzdHJfaGVsbG8gPSBDU1RSSU5HKCJoZWxsbyIpOwogIGF1dG8gIHN0cl93b3JsZCA9IENTVFJJTkcoIiB3b3JsZCIpOwoKICBjb25zdCBjaGFyKiBjb25jYXQgPSAoc3RyX2hlbGxvICsgc3RyX3dvcmxkKS5jaGFyczsKCiAgc3RkOjpjb3V0IDw8ICJydW50aW1lIGNvbmNhdDogIiA8PCBzdHJfaGVsbG8uY2hhcnMgPDwgc3RyX3dvcmxkLmNoYXJzIDw8ICJcbiA8PT4gXG4iOwogIHN0ZDo6Y291dCA8PCAiY29tcGlsZSBjb25jYXQ6ICIgPDwgY29uY2F0IDw8IHN0ZDo6ZW5kbDsKfQo=