#include "concept.hpp" // Makes string values interchangeable with the concepts // they name. template<> struct value : public concept, public std::string { //using std::string::basic_string; value(std::string); value(cid); operator cid(); static value& of(cid c) { return *static_cast(c); } }; using str = value; cid operator"" _c(const char* str, std::size_t len) { return value({str,len}); } #include concept namesByConcept; std::unordered_map,concept,std::hash> conceptsByName; value::value(std::string s) : std::string(s) { } value::value(cid c) : std::string(of(namesByConcept.get(c))) { } value::operator cid() { try { return &conceptsByName.at(*this); } catch (std::out_of_range) { auto insertion = conceptsByName.emplace(*this, concept()); cid con = &insertion.first->second; cid nam = const_cast((const cid)&insertion.first->first); namesByConcept.link(con, nam); return con; } }