1 #include <unordered_map>
2 #include <vector>
3 #include "string_id.h"
4 
5 namespace
6 {
7 using InternMapType = std::unordered_map<std::string, int>;
8 using ReverseLookupVecType = std::vector<const std::string *>;
9 } // namespace
10 
get_intern_map()11 inline static InternMapType &get_intern_map()
12 {
13     static InternMapType map{};
14     return map;
15 }
16 
get_reverse_lookup_vec()17 inline static ReverseLookupVecType &get_reverse_lookup_vec()
18 {
19     static ReverseLookupVecType vec{};
20     return vec;
21 }
22 
23 template<typename S>
universal_string_id_intern(S && s)24 inline static int universal_string_id_intern( S &&s )
25 {
26     int next_id = get_reverse_lookup_vec().size();
27     const auto &pair = get_intern_map().emplace( std::forward<S>( s ), next_id );
28     if( pair.second ) { // inserted
29         get_reverse_lookup_vec().push_back( &pair.first->first );
30     }
31     return pair.first->second;
32 }
33 
string_id_intern(const std::string & s)34 int string_identity_static::string_id_intern( const std::string &s )
35 {
36     return universal_string_id_intern( s );
37 }
38 
string_id_intern(std::string & s)39 int string_identity_static::string_id_intern( std::string &s )
40 {
41     return universal_string_id_intern( s );
42 }
43 
string_id_intern(std::string && s)44 int string_identity_static::string_id_intern( std::string &&s )
45 {
46     return universal_string_id_intern( std::move( s ) );
47 }
48 
get_interned_string(int id)49 const std::string &string_identity_static::get_interned_string( int id )
50 {
51     return *get_reverse_lookup_vec()[id];
52 }
53 
empty_interned_string()54 int string_identity_static::empty_interned_string()
55 {
56     static int empty_string_id = string_id_intern( "" );
57     return empty_string_id;
58 }
59