duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

heterogeneous_containers.h (3687B)


      1 // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 /**
      5  * Provides a map template which doesn't require heap allocations for lookups.
      6  */
      7 
      8 #pragma once
      9 
     10 #include "types.h"
     11 #include <map>
     12 #include <set>
     13 #include <string>
     14 #include <unordered_map>
     15 #include <unordered_set>
     16 
     17 namespace detail {
     18 struct transparent_string_hash
     19 {
     20   using is_transparent = void;
     21 
     22   std::size_t operator()(const std::string_view& v) const { return std::hash<std::string_view>{}(v); }
     23   std::size_t operator()(const std::string& s) const { return std::hash<std::string>{}(s); }
     24   std::size_t operator()(const char* s) const { return operator()(std::string_view(s)); }
     25 };
     26 
     27 struct transparent_string_equal
     28 {
     29   using is_transparent = void;
     30 
     31   bool operator()(const std::string& lhs, const std::string_view& rhs) const { return lhs == rhs; }
     32   bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs == rhs; }
     33   bool operator()(const std::string& lhs, const char* rhs) const { return lhs == rhs; }
     34   bool operator()(const std::string_view& lhs, const std::string& rhs) const { return lhs == rhs; }
     35   bool operator()(const char* lhs, const std::string& rhs) const { return lhs == rhs; }
     36 };
     37 
     38 struct transparent_string_less
     39 {
     40   using is_transparent = void;
     41 
     42   bool operator()(const std::string& lhs, const std::string_view& rhs) const { return lhs < rhs; }
     43   bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs < rhs; }
     44   bool operator()(const std::string& lhs, const char* rhs) const { return lhs < rhs; }
     45   bool operator()(const std::string_view& lhs, const std::string& rhs) const { return lhs < rhs; }
     46   bool operator()(const char* lhs, const std::string& rhs) const { return lhs < rhs; }
     47 };
     48 } // namespace detail
     49 
     50 template<typename ValueType>
     51 using StringMap = std::map<std::string, ValueType, detail::transparent_string_less>;
     52 template<typename ValueType>
     53 using StringMultiMap = std::multimap<std::string, ValueType, detail::transparent_string_less>;
     54 using StringSet = std::set<std::string, detail::transparent_string_less>;
     55 using StringMultiSet = std::multiset<std::string, detail::transparent_string_less>;
     56 
     57 #if defined(__cpp_lib_generic_unordered_lookup) && __cpp_lib_generic_unordered_lookup >= 201811L
     58 template<typename ValueType>
     59 using UnorderedStringMap =
     60   std::unordered_map<std::string, ValueType, detail::transparent_string_hash, detail::transparent_string_equal>;
     61 template<typename ValueType>
     62 using UnorderedStringMultimap =
     63   std::unordered_multimap<std::string, ValueType, detail::transparent_string_hash, detail::transparent_string_equal>;
     64 using UnorderedStringSet =
     65   std::unordered_set<std::string, detail::transparent_string_hash, detail::transparent_string_equal>;
     66 using UnorderedStringMultiSet =
     67   std::unordered_multiset<std::string, detail::transparent_string_hash, detail::transparent_string_equal>;
     68 
     69 template<typename ValueType>
     70 using PreferUnorderedStringMap = UnorderedStringMap<ValueType>;
     71 template<typename ValueType>
     72 using PreferUnorderedStringMultimap = UnorderedStringMultimap<ValueType>;
     73 using PreferUnorderedStringSet = UnorderedStringSet;
     74 using PreferUnorderedStringMultiSet = UnorderedStringMultiSet;
     75 #else
     76 
     77 #pragma message "__cpp_lib_generic_unordered_lookup is missing, performance will be slower."
     78 
     79 // GCC 10 doesn't support generic_unordered_lookup...
     80 template<typename ValueType>
     81 using PreferUnorderedStringMap = StringMap<ValueType>;
     82 template<typename ValueType>
     83 using PreferUnorderedStringMultimap = StringMultiMap<ValueType>;
     84 using PreferUnorderedStringSet = StringSet;
     85 using PreferUnorderedStringMultiSet = StringMultiSet;
     86 
     87 #endif