Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / third_party / abseil-cpp / absl / container / internal / hash_policy_testing.h
1 // Copyright 2018 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Utilities to help tests verify that hash tables properly handle stateful
16 // allocators and hash functions.
17
18 #ifndef ABSL_CONTAINER_INTERNAL_HASH_POLICY_TESTING_H_
19 #define ABSL_CONTAINER_INTERNAL_HASH_POLICY_TESTING_H_
20
21 #include <cstdlib>
22 #include <limits>
23 #include <memory>
24 #include <ostream>
25 #include <type_traits>
26 #include <utility>
27 #include <vector>
28
29 #include "absl/hash/hash.h"
30 #include "absl/strings/string_view.h"
31
32 namespace absl {
33 namespace container_internal {
34 namespace hash_testing_internal {
35
36 template <class Derived>
37 struct WithId {
38   WithId() : id_(next_id<Derived>()) {}
39   WithId(const WithId& that) : id_(that.id_) {}
40   WithId(WithId&& that) : id_(that.id_) { that.id_ = 0; }
41   WithId& operator=(const WithId& that) {
42     id_ = that.id_;
43     return *this;
44   }
45   WithId& operator=(WithId&& that) {
46     id_ = that.id_;
47     that.id_ = 0;
48     return *this;
49   }
50
51   size_t id() const { return id_; }
52
53   friend bool operator==(const WithId& a, const WithId& b) {
54     return a.id_ == b.id_;
55   }
56   friend bool operator!=(const WithId& a, const WithId& b) { return !(a == b); }
57
58  protected:
59   explicit WithId(size_t id) : id_(id) {}
60
61  private:
62   size_t id_;
63
64   template <class T>
65   static size_t next_id() {
66     // 0 is reserved for moved from state.
67     static size_t gId = 1;
68     return gId++;
69   }
70 };
71
72 }  // namespace hash_testing_internal
73
74 struct NonStandardLayout {
75   NonStandardLayout() {}
76   explicit NonStandardLayout(std::string s) : value(std::move(s)) {}
77   virtual ~NonStandardLayout() {}
78
79   friend bool operator==(const NonStandardLayout& a,
80                          const NonStandardLayout& b) {
81     return a.value == b.value;
82   }
83   friend bool operator!=(const NonStandardLayout& a,
84                          const NonStandardLayout& b) {
85     return a.value != b.value;
86   }
87
88   template <typename H>
89   friend H AbslHashValue(H h, const NonStandardLayout& v) {
90     return H::combine(std::move(h), v.value);
91   }
92
93   std::string value;
94 };
95
96 struct StatefulTestingHash
97     : absl::container_internal::hash_testing_internal::WithId<
98           StatefulTestingHash> {
99   template <class T>
100   size_t operator()(const T& t) const {
101     return absl::Hash<T>{}(t);
102   }
103 };
104
105 struct StatefulTestingEqual
106     : absl::container_internal::hash_testing_internal::WithId<
107           StatefulTestingEqual> {
108   template <class T, class U>
109   bool operator()(const T& t, const U& u) const {
110     return t == u;
111   }
112 };
113
114 // It is expected that Alloc() == Alloc() for all allocators so we cannot use
115 // WithId base. We need to explicitly assign ids.
116 template <class T = int>
117 struct Alloc : std::allocator<T> {
118   using propagate_on_container_swap = std::true_type;
119
120   // Using old paradigm for this to ensure compatibility.
121   explicit Alloc(size_t id = 0) : id_(id) {}
122
123   Alloc(const Alloc&) = default;
124   Alloc& operator=(const Alloc&) = default;
125
126   template <class U>
127   Alloc(const Alloc<U>& that) : std::allocator<T>(that), id_(that.id()) {}
128
129   template <class U>
130   struct rebind {
131     using other = Alloc<U>;
132   };
133
134   size_t id() const { return id_; }
135
136   friend bool operator==(const Alloc& a, const Alloc& b) {
137     return a.id_ == b.id_;
138   }
139   friend bool operator!=(const Alloc& a, const Alloc& b) { return !(a == b); }
140
141  private:
142   size_t id_ = (std::numeric_limits<size_t>::max)();
143 };
144
145 template <class Map>
146 auto items(const Map& m) -> std::vector<
147     std::pair<typename Map::key_type, typename Map::mapped_type>> {
148   using std::get;
149   std::vector<std::pair<typename Map::key_type, typename Map::mapped_type>> res;
150   res.reserve(m.size());
151   for (const auto& v : m) res.emplace_back(get<0>(v), get<1>(v));
152   return res;
153 }
154
155 template <class Set>
156 auto keys(const Set& s)
157     -> std::vector<typename std::decay<typename Set::key_type>::type> {
158   std::vector<typename std::decay<typename Set::key_type>::type> res;
159   res.reserve(s.size());
160   for (const auto& v : s) res.emplace_back(v);
161   return res;
162 }
163
164 }  // namespace container_internal
165 }  // namespace absl
166
167 // ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS is false for glibcxx versions
168 // where the unordered containers are missing certain constructors that
169 // take allocator arguments. This test is defined ad-hoc for the platforms
170 // we care about (notably Crosstool 17) because libstdcxx's useless
171 // versioning scheme precludes a more principled solution.
172 // From GCC-4.9 Changelog: (src: https://gcc.gnu.org/gcc-4.9/changes.html)
173 // "the unordered associative containers in <unordered_map> and <unordered_set>
174 // meet the allocator-aware container requirements;"
175 #if (defined(__GLIBCXX__) && __GLIBCXX__ <= 20140425 ) || \
176 ( __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9 ))
177 #define ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS 0
178 #else
179 #define ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS 1
180 #endif
181
182 #endif  // ABSL_CONTAINER_INTERNAL_HASH_POLICY_TESTING_H_