Flutter Impeller
comparable.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_IMPELLER_BASE_COMPARABLE_H_
6 #define FLUTTER_IMPELLER_BASE_COMPARABLE_H_
7 
8 #include <cstddef>
9 #include <functional>
10 #include <map>
11 #include <memory>
12 #include <type_traits>
13 
14 namespace impeller {
15 
16 struct UniqueID {
17  size_t id;
18 
19  UniqueID();
20 
21  constexpr bool operator==(const UniqueID& other) const {
22  return id == other.id;
23  }
24 };
25 
26 class ComparableBase {};
27 
28 template <class Type>
30  public:
31  virtual std::size_t GetHash() const = 0;
32 
33  virtual bool IsEqual(const Type& other) const = 0;
34 };
35 
36 template <
37  class ComparableType,
38  class = std::enable_if_t<std::is_base_of_v<ComparableBase, ComparableType>>>
40  std::size_t operator()(const ComparableType& object) const {
41  return object.GetHash();
42  }
43 };
44 
45 template <
46  class ComparableType,
47  class = std::enable_if_t<std::is_base_of_v<ComparableBase, ComparableType>>>
49  bool operator()(const ComparableType& lhs, const ComparableType& rhs) const {
50  return lhs.IsEqual(rhs);
51  }
52 };
53 
54 template <
55  class ComparableType,
56  class = std::enable_if_t<std::is_base_of_v<ComparableBase, ComparableType>>>
57 bool DeepComparePointer(const std::shared_ptr<ComparableType>& lhs,
58  const std::shared_ptr<ComparableType>& rhs) {
59  if (lhs == rhs) {
60  return true;
61  }
62 
63  if (lhs && rhs) {
64  return lhs->IsEqual(*rhs);
65  }
66 
67  return false;
68 }
69 
70 template <
71  class Key,
72  class ComparableType,
73  class = std::enable_if_t<std::is_base_of_v<ComparableBase, ComparableType>>>
74 bool DeepCompareMap(const std::map<Key, std::shared_ptr<ComparableType>>& lhs,
75  const std::map<Key, std::shared_ptr<ComparableType>>& rhs) {
76  if (lhs.size() != rhs.size()) {
77  return false;
78  }
79 
80  for (auto i = lhs.begin(), j = rhs.begin(); i != lhs.end(); i++, j++) {
81  if (i->first != j->first) {
82  return false;
83  }
84 
85  if (!DeepComparePointer(i->second, j->second)) {
86  return false;
87  }
88  }
89 
90  return true;
91 }
92 
93 } // namespace impeller
94 
95 namespace std {
96 
97 template <>
98 struct hash<impeller::UniqueID> {
99  constexpr std::size_t operator()(const impeller::UniqueID& id) {
100  return id.id;
101  }
102 };
103 
104 template <>
105 struct less<impeller::UniqueID> {
106  constexpr bool operator()(const impeller::UniqueID& lhs,
107  const impeller::UniqueID& rhs) const {
108  return lhs.id < rhs.id;
109  }
110 };
111 
112 } // namespace std
113 
114 #endif // FLUTTER_IMPELLER_BASE_COMPARABLE_H_
virtual bool IsEqual(const Type &other) const =0
virtual std::size_t GetHash() const =0
bool DeepComparePointer(const std::shared_ptr< ComparableType > &lhs, const std::shared_ptr< ComparableType > &rhs)
Definition: comparable.h:57
bool DeepCompareMap(const std::map< Key, std::shared_ptr< ComparableType >> &lhs, const std::map< Key, std::shared_ptr< ComparableType >> &rhs)
Definition: comparable.h:74
Definition: comparable.h:95
bool operator()(const ComparableType &lhs, const ComparableType &rhs) const
Definition: comparable.h:49
std::size_t operator()(const ComparableType &object) const
Definition: comparable.h:40
constexpr bool operator==(const UniqueID &other) const
Definition: comparable.h:21
constexpr std::size_t operator()(const impeller::UniqueID &id)
Definition: comparable.h:99
constexpr bool operator()(const impeller::UniqueID &lhs, const impeller::UniqueID &rhs) const
Definition: comparable.h:106