fork(24) download
  1. #include <iostream>
  2.  
  3. namespace variadic_toolbox
  4. {
  5. template<unsigned count,
  6. template<unsigned...> class meta_functor, unsigned... indices>
  7. struct apply_range
  8. {
  9. typedef typename apply_range<count - 1, meta_functor, count - 1, indices...>::result result;
  10. };
  11.  
  12. template<template<unsigned...> class meta_functor, unsigned... indices>
  13. struct apply_range<0, meta_functor, indices...>
  14. {
  15. typedef typename meta_functor<indices...>::result result;
  16. };
  17. }
  18.  
  19. namespace compile_time
  20. {
  21. template<char... str>
  22. struct string
  23. {
  24. static constexpr const char chars[] = { str..., '\0' };
  25. };
  26.  
  27. template<char... str>
  28. constexpr const char string<str...>::chars[];
  29.  
  30. template<typename lambda_str_type>
  31. struct string_builder
  32. {
  33. template<unsigned... indices>
  34. struct produce
  35. {
  36. typedef string<lambda_str_type {}.chars[indices]...> result;
  37. };
  38. };
  39.  
  40. template<char... str0, char... str1>
  41. string<str0..., str1...> operator+(string<str0...>, string<str1...>)
  42. {
  43. return {};
  44. }
  45. }
  46.  
  47. #define CSTRING(string_literal) \
  48.   []{ \
  49.   struct constexpr_string_type { const char * chars = string_literal; }; \
  50.   return variadic_toolbox::apply_range<sizeof(string_literal)-1, \
  51.   compile_time::string_builder<constexpr_string_type>::produce>::result{}; \
  52.   }()
  53.  
  54. int main()
  55. {
  56. auto str_hello = CSTRING("hello");
  57. auto str_world = CSTRING(" world");
  58.  
  59. const char* concat = (str_hello + str_world).chars;
  60.  
  61. std::cout << "runtime concat: " << str_hello.chars << str_world.chars << "\n <=> \n";
  62. std::cout << "compile concat: " << concat << std::endl;
  63. }
  64.  
Success #stdin #stdout 0s 3460KB
stdin
Standard input is empty
stdout
runtime concat: hello world
 <=> 
compile concat: hello world