fork download
  1. #include <cstdio>
  2.  
  3. namespace intern {
  4.  
  5. template<char... NN> struct string {
  6.  
  7. static constexpr char const value[ sizeof...(NN) ]{NN...};
  8.  
  9. static_assert( value[ sizeof...(NN) - 1 ] == '\0', "interned string was too long" );
  10.  
  11. static constexpr auto data() { return value; }
  12. };
  13.  
  14. template<char... N> constexpr char const string<N...>::value[];
  15.  
  16. template<int N>
  17. constexpr char ch ( char const(&s)[N], int i ) { return i < N ? s[i] : '\0'; }
  18.  
  19. template<typename T> struct is_string {
  20. static const bool value = false;
  21. };
  22.  
  23. template<char... NN> struct is_string< string<NN...> > {
  24. static const bool value = true;
  25. };
  26. }
  27.  
  28. //prefixing macros with a $ helps with readability
  29. #define $c(a,b) intern::ch(a, b)
  30.  
  31. //10 characters + '\0', add $c(...) for more
  32. #define $(s) intern::string<$c(s,0),$c(s,1),$c(s,2),$c(s,3),$c(s,4),$c(s,5),$c(s,6),$c(s,7),$c(s,8),$c(s,9),$c(s,10)>
  33.  
  34. struct singleton {
  35.  
  36. template<typename T>
  37. singleton(T) : name{ T::value } {
  38. if( T::value == $("db")::value )
  39. printf("Initializing DB singleton: %s\n", T::value);
  40. else
  41. printf("Initializing unknown singleton: %s\n", T::value);
  42. }
  43.  
  44. void do_action() {
  45. printf("singleton(%s)::do_action()\n", name);
  46. }
  47.  
  48. char const *name;
  49. };
  50.  
  51. template<typename K, typename V> struct map {
  52. static V value;
  53. };
  54.  
  55. template<typename K, typename V> V map<K,V>::value{K{}};
  56.  
  57. template<typename K> using get_singleton = map<K,singleton>;
  58.  
  59. int main() {
  60.  
  61. get_singleton< $("db") >::value.do_action();
  62. get_singleton< $("map") >::value.do_action();
  63.  
  64. }
  65.  
Success #stdin #stdout 0s 16064KB
stdin
Standard input is empty
stdout
Initializing DB singleton: db
Initializing unknown singleton: map
singleton(db)::do_action()
singleton(map)::do_action()