#include <cstdio>
 
namespace intern {

  template<char... NN> struct string {

    static constexpr char const value[ sizeof...(NN) ]{NN...};

    static_assert( value[ sizeof...(NN) - 1 ] == '\0', "interned string was too long" );

    static constexpr auto data() { return value; }
  };

  template<char... N> constexpr char const string<N...>::value[];
 
  template<int N>
  constexpr char ch ( char const(&s)[N], int i ) { return i < N ? s[i] : '\0'; }

  template<typename T> struct is_string {
    static const bool value = false;
  };

  template<char... NN> struct is_string< string<NN...> > {
    static const bool value = true;
  };
}

//prefixing macros with a $ helps with readability
#define $c(a,b) intern::ch(a, b)

//10 characters + '\0', add $c(...) for more
#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)>

struct singleton {
	
	template<typename T>
	singleton(T) : name{ T::value } {
		if( T::value == $("db")::value )
			printf("Initializing DB singleton: %s\n", T::value);
		else 
			printf("Initializing unknown singleton: %s\n", T::value);
	}
	
	void do_action() {
		printf("singleton(%s)::do_action()\n", name);
	}

	char const *name;
};

template<typename K, typename V> struct map {
  static V value;
};

template<typename K, typename V> V map<K,V>::value{K{}};

template<typename K> using get_singleton = map<K,singleton>;

int main() {
 
	get_singleton< $("db") >::value.do_action();
	get_singleton< $("map") >::value.do_action();

}
