42    using mapped_type = V;
 
   43    using value_type = std::pair<cstring, V>;
 
   44    using reference = value_type &;
 
   45    using const_reference = 
const value_type &;
 
   49    using list_type = std::list<value_type>;
 
   50    using list_iterator = 
typename list_type::iterator;
 
   54    using iterator = 
typename list_type::iterator;
 
   55    using const_iterator = 
typename list_type::const_iterator;
 
   56    using reverse_iterator = std::reverse_iterator<iterator>;
 
   57    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
   60    using map_type = absl::flat_hash_map<cstring, list_iterator>;
 
   62    void init_data_map() {
 
   64        for (
auto it = data.begin(); it != data.end(); it++) data_map.emplace(it->first, it);
 
   66    iterator tr_iter(
typename map_type::iterator i) {
 
   67        if (i == data_map.end()) 
return data.end();
 
   70    const_iterator tr_iter(
typename map_type::const_iterator i)
 const {
 
   71        if (i == data_map.end()) 
return data.end();
 
   76    using size_type = 
typename map_type::size_type;
 
   80    template <
typename InputIt>
 
   88            data.insert(data.end(), a.data.begin(), a.data.end());
 
   94    string_map(std::initializer_list<value_type> il) { insert(il.begin(), il.end()); }
 
   96    iterator begin() 
noexcept { 
return data.begin(); }
 
   97    const_iterator begin() 
const noexcept { 
return data.begin(); }
 
   98    iterator end() 
noexcept { 
return data.end(); }
 
   99    const_iterator end() 
const noexcept { 
return data.end(); }
 
  100    reverse_iterator rbegin() 
noexcept { 
return data.rbegin(); }
 
  101    const_reverse_iterator rbegin() 
const noexcept { 
return data.rbegin(); }
 
  102    reverse_iterator rend() 
noexcept { 
return data.rend(); }
 
  103    const_reverse_iterator rend() 
const noexcept { 
return data.rend(); }
 
  104    const_iterator cbegin() 
const noexcept { 
return data.cbegin(); }
 
  105    const_iterator cend() 
const noexcept { 
return data.cend(); }
 
  106    const_reverse_iterator crbegin() 
const noexcept { 
return data.crbegin(); }
 
  107    const_reverse_iterator crend() 
const noexcept { 
return data.crend(); }
 
  109    bool empty() 
const noexcept { 
return data.empty(); }
 
  110    size_type size() 
const noexcept { 
return data_map.size(); }
 
  111    size_type max_size() 
const noexcept { 
return data_map.max_size(); }
 
  115    bool operator!=(
const string_map &a)
 const { 
return data != a.data; }
 
  121    iterator find(
cstring a) { 
return tr_iter(data_map.find(a)); }
 
  126    iterator 
find(std::string_view a) {
 
  128        if (key.isNull()) 
return data.end();
 
  130        return tr_iter(data_map.find(key));
 
 
  132    const_iterator find(
cstring a)
 const { 
return tr_iter(data_map.find(a)); }
 
  133    const_iterator find(std::string_view a)
 const {
 
  135        if (key.isNull()) 
return data.end();
 
  137        return tr_iter(data_map.find(key));
 
  140    size_type count(
cstring a)
 const { 
return data_map.count(a); }
 
  141    size_type count(std::string_view a)
 const {
 
  143        if (key.isNull()) 
return 0;
 
  145        return data_map.count(key);
 
  148    bool contains(
cstring a)
 const { 
return data_map.contains(a); }
 
  149    bool contains(std::string_view a)
 const {
 
  151        if (key.isNull()) 
return false;
 
  153        return data_map.contains(key);
 
  156    template <
typename Key>
 
  157    V &operator[](Key &&k) {
 
  158        auto it = find(key_type(std::forward<Key>(k)));
 
  159        if (it == data.end()) {
 
  160            it = data.emplace(data.end(), std::piecewise_construct, std::forward_as_tuple(k),
 
  161                              std::forward_as_tuple());
 
  162            data_map.emplace(it->first, it);
 
  167    template <
typename Key>
 
  169        auto it = find(std::forward<Key>(k));
 
  170        if (it == data.end()) 
throw std::out_of_range(
"string_map::at");
 
  173    template <
typename Key>
 
  174    const V &at(Key &&k)
 const {
 
  175        auto it = find(std::forward<Key>(k));
 
  176        if (it == data.end()) 
throw std::out_of_range(
"string_map::at");
 
  180    template <
typename Key, 
typename... VV>
 
  181    std::pair<iterator, bool> emplace(Key &&k, VV &&...v) {
 
  182        auto it = find(key_type(std::forward<Key>(k)));
 
  183        if (it == data.end()) {
 
  184            it = data.emplace(data.end(), std::piecewise_construct, std::forward_as_tuple(k),
 
  185                              std::forward_as_tuple(std::forward<VV>(v)...));
 
  186            data_map.emplace(it->first, it);
 
  192    std::pair<iterator, bool> insert(value_type &&value) {
 
  193        return emplace(std::move(value.first), std::move(value.second));
 
  195    std::pair<iterator, bool> insert(
const value_type &value) {
 
  196        return emplace(value.first, value.second);
 
  199    template <
class InputIterator>
 
  200    void insert(InputIterator b, InputIterator e) {
 
  201        while (b != e) insert(*b++);
 
  204    iterator erase(const_iterator pos) {
 
  205        auto it = data_map.find(pos->first);
 
  206        assert(it != data_map.end());
 
  209        auto list_it = it->second;
 
  211        return data.erase(list_it);
 
  215        if (it != data.end()) {
 
  222    size_type erase(std::string_view k) {
 
  224        if (it != data.end()) {
 
  225            data_map.erase(it->first);
 
  234        swap(data, other.data);
 
  235        swap(data_map, other.data_map);