tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AutoMappable.h (2137B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef MOZILLA_AUTO_MAPPABLE_H
      6 #define MOZILLA_AUTO_MAPPABLE_H
      7 
      8 // Here be dragons.
      9 
     10 #include <functional>
     11 #include <tuple>
     12 
     13 namespace mozilla {
     14 
     15 template <class T>
     16 size_t StdHash(const T& t) {
     17  return std::hash<T>()(t);
     18 }
     19 
     20 //-
     21 // From Boost:
     22 // https://www.boost.org/doc/libs/1_37_0/doc/html/hash/reference.html#boost.hash_combine
     23 
     24 inline size_t HashCombine(size_t seed, const size_t hash) {
     25  seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
     26  return seed;
     27 }
     28 
     29 // -
     30 
     31 namespace detail {
     32 template <class... Args, size_t... Ids>
     33 size_t StdHashTupleN(const std::tuple<Args...>& tup,
     34                     const std::index_sequence<Ids...>&) {
     35  size_t seed = 0;
     36  for (const auto& hash : {StdHash(std::get<Ids>(tup))...}) {
     37    seed = HashCombine(seed, hash);
     38  }
     39  return seed;
     40 }
     41 }  // namespace detail
     42 
     43 // -
     44 
     45 template <class T>
     46 struct StdHashMembers {
     47  size_t operator()(const T& t) const {
     48    const auto members = t.Members();
     49    return StdHash(members);
     50  }
     51 };
     52 
     53 // -
     54 
     55 #define MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(OP, T) \
     56  bool operator OP(const T& rhs) const { return Members() OP rhs.Members(); }
     57 
     58 #define MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(T) \
     59  MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(==, T)    \
     60  MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(!=, T)    \
     61  MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(<, T)     \
     62  MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(<=, T)    \
     63  MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(>, T)     \
     64  MOZ_MIXIN_DERIVE_CMP_OP_BY_MEMBERS(>=, T)
     65 
     66 template <class T>
     67 struct DeriveCmpOpMembers {
     68 private:
     69  auto Members() const { return reinterpret_cast<const T*>(this)->Members(); }
     70 
     71 public:
     72  MOZ_MIXIN_DERIVE_CMP_OPS_BY_MEMBERS(T)
     73 };
     74 
     75 }  // namespace mozilla
     76 
     77 template <class... Args>
     78 struct std::hash<std::tuple<Args...>> {
     79  size_t operator()(const std::tuple<Args...>& t) const {
     80    return mozilla::detail::StdHashTupleN(
     81        t, std::make_index_sequence<sizeof...(Args)>());
     82  }
     83 };
     84 
     85 #endif  // MOZILLA_AUTO_MAPPABLE_H