Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / third_party / abseil-cpp / absl / types / compare.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 // -----------------------------------------------------------------------------
16 // compare.h
17 // -----------------------------------------------------------------------------
18 //
19 // This header file defines the `absl::weak_equality`, `absl::strong_equality`,
20 // `absl::partial_ordering`, `absl::weak_ordering`, and `absl::strong_ordering`
21 // types for storing the results of three way comparisons.
22 //
23 // Example:
24 //   absl::weak_ordering compare(const std::string& a, const std::string& b);
25 //
26 // These are C++11 compatible versions of the C++20 corresponding types
27 // (`std::weak_equality`, etc.) and are designed to be drop-in replacements
28 // for code compliant with C++20.
29
30 #ifndef ABSL_TYPES_COMPARE_H_
31 #define ABSL_TYPES_COMPARE_H_
32
33 #include <cstddef>
34 #include <cstdint>
35 #include <cstdlib>
36 #include <type_traits>
37
38 #include "absl/base/attributes.h"
39 #include "absl/meta/type_traits.h"
40
41 namespace absl {
42 namespace compare_internal {
43
44 using value_type = int8_t;
45
46 template <typename T>
47 struct Fail {
48   static_assert(sizeof(T) < 0, "Only literal `0` is allowed.");
49 };
50
51 // We need the NullPtrT template to avoid triggering the modernize-use-nullptr
52 // ClangTidy warning in user code.
53 template <typename NullPtrT = std::nullptr_t>
54 struct OnlyLiteralZero {
55   constexpr OnlyLiteralZero(NullPtrT) noexcept {}  // NOLINT
56
57   // Fails compilation when `nullptr` or integral type arguments other than
58   // `int` are passed. This constructor doesn't accept `int` because literal `0`
59   // has type `int`. Literal `0` arguments will be implicitly converted to
60   // `std::nullptr_t` and accepted by the above constructor, while other `int`
61   // arguments will fail to be converted and cause compilation failure.
62   template <
63       typename T,
64       typename = typename std::enable_if<
65           std::is_same<T, std::nullptr_t>::value ||
66           (std::is_integral<T>::value && !std::is_same<T, int>::value)>::type,
67       typename = typename Fail<T>::type>
68   OnlyLiteralZero(T);  // NOLINT
69 };
70
71 enum class eq : value_type {
72   equal = 0,
73   equivalent = equal,
74   nonequal = 1,
75   nonequivalent = nonequal,
76 };
77
78 enum class ord : value_type { less = -1, greater = 1 };
79
80 enum class ncmp : value_type { unordered = -127 };
81
82 // These template base classes allow for defining the values of the constants
83 // in the header file (for performance) without using inline variables (which
84 // aren't available in C++11).
85 template <typename T>
86 struct weak_equality_base {
87   ABSL_CONST_INIT static const T equivalent;
88   ABSL_CONST_INIT static const T nonequivalent;
89 };
90 template <typename T>
91 const T weak_equality_base<T>::equivalent(eq::equivalent);
92 template <typename T>
93 const T weak_equality_base<T>::nonequivalent(eq::nonequivalent);
94
95 template <typename T>
96 struct strong_equality_base {
97   ABSL_CONST_INIT static const T equal;
98   ABSL_CONST_INIT static const T nonequal;
99   ABSL_CONST_INIT static const T equivalent;
100   ABSL_CONST_INIT static const T nonequivalent;
101 };
102 template <typename T>
103 const T strong_equality_base<T>::equal(eq::equal);
104 template <typename T>
105 const T strong_equality_base<T>::nonequal(eq::nonequal);
106 template <typename T>
107 const T strong_equality_base<T>::equivalent(eq::equivalent);
108 template <typename T>
109 const T strong_equality_base<T>::nonequivalent(eq::nonequivalent);
110
111 template <typename T>
112 struct partial_ordering_base {
113   ABSL_CONST_INIT static const T less;
114   ABSL_CONST_INIT static const T equivalent;
115   ABSL_CONST_INIT static const T greater;
116   ABSL_CONST_INIT static const T unordered;
117 };
118 template <typename T>
119 const T partial_ordering_base<T>::less(ord::less);
120 template <typename T>
121 const T partial_ordering_base<T>::equivalent(eq::equivalent);
122 template <typename T>
123 const T partial_ordering_base<T>::greater(ord::greater);
124 template <typename T>
125 const T partial_ordering_base<T>::unordered(ncmp::unordered);
126
127 template <typename T>
128 struct weak_ordering_base {
129   ABSL_CONST_INIT static const T less;
130   ABSL_CONST_INIT static const T equivalent;
131   ABSL_CONST_INIT static const T greater;
132 };
133 template <typename T>
134 const T weak_ordering_base<T>::less(ord::less);
135 template <typename T>
136 const T weak_ordering_base<T>::equivalent(eq::equivalent);
137 template <typename T>
138 const T weak_ordering_base<T>::greater(ord::greater);
139
140 template <typename T>
141 struct strong_ordering_base {
142   ABSL_CONST_INIT static const T less;
143   ABSL_CONST_INIT static const T equal;
144   ABSL_CONST_INIT static const T equivalent;
145   ABSL_CONST_INIT static const T greater;
146 };
147 template <typename T>
148 const T strong_ordering_base<T>::less(ord::less);
149 template <typename T>
150 const T strong_ordering_base<T>::equal(eq::equal);
151 template <typename T>
152 const T strong_ordering_base<T>::equivalent(eq::equivalent);
153 template <typename T>
154 const T strong_ordering_base<T>::greater(ord::greater);
155
156 }  // namespace compare_internal
157
158 class weak_equality
159     : public compare_internal::weak_equality_base<weak_equality> {
160   explicit constexpr weak_equality(compare_internal::eq v) noexcept
161       : value_(static_cast<compare_internal::value_type>(v)) {}
162   friend struct compare_internal::weak_equality_base<weak_equality>;
163
164  public:
165   // Comparisons
166   friend constexpr bool operator==(
167       weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
168     return v.value_ == 0;
169   }
170   friend constexpr bool operator!=(
171       weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
172     return v.value_ != 0;
173   }
174   friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
175                                    weak_equality v) noexcept {
176     return 0 == v.value_;
177   }
178   friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
179                                    weak_equality v) noexcept {
180     return 0 != v.value_;
181   }
182
183  private:
184   compare_internal::value_type value_;
185 };
186
187 class strong_equality
188     : public compare_internal::strong_equality_base<strong_equality> {
189   explicit constexpr strong_equality(compare_internal::eq v) noexcept
190       : value_(static_cast<compare_internal::value_type>(v)) {}
191   friend struct compare_internal::strong_equality_base<strong_equality>;
192
193  public:
194   // Conversion
195   constexpr operator weak_equality() const noexcept {  // NOLINT
196     return value_ == 0 ? weak_equality::equivalent
197                        : weak_equality::nonequivalent;
198   }
199   // Comparisons
200   friend constexpr bool operator==(
201       strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
202     return v.value_ == 0;
203   }
204   friend constexpr bool operator!=(
205       strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
206     return v.value_ != 0;
207   }
208   friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
209                                    strong_equality v) noexcept {
210     return 0 == v.value_;
211   }
212   friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
213                                    strong_equality v) noexcept {
214     return 0 != v.value_;
215   }
216
217  private:
218   compare_internal::value_type value_;
219 };
220
221 class partial_ordering
222     : public compare_internal::partial_ordering_base<partial_ordering> {
223   explicit constexpr partial_ordering(compare_internal::eq v) noexcept
224       : value_(static_cast<compare_internal::value_type>(v)) {}
225   explicit constexpr partial_ordering(compare_internal::ord v) noexcept
226       : value_(static_cast<compare_internal::value_type>(v)) {}
227   explicit constexpr partial_ordering(compare_internal::ncmp v) noexcept
228       : value_(static_cast<compare_internal::value_type>(v)) {}
229   friend struct compare_internal::partial_ordering_base<partial_ordering>;
230
231   constexpr bool is_ordered() const noexcept {
232     return value_ !=
233            compare_internal::value_type(compare_internal::ncmp::unordered);
234   }
235
236  public:
237   // Conversion
238   constexpr operator weak_equality() const noexcept {  // NOLINT
239     return value_ == 0 ? weak_equality::equivalent
240                        : weak_equality::nonequivalent;
241   }
242   // Comparisons
243   friend constexpr bool operator==(
244       partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
245     return v.is_ordered() && v.value_ == 0;
246   }
247   friend constexpr bool operator!=(
248       partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
249     return !v.is_ordered() || v.value_ != 0;
250   }
251   friend constexpr bool operator<(
252       partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
253     return v.is_ordered() && v.value_ < 0;
254   }
255   friend constexpr bool operator<=(
256       partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
257     return v.is_ordered() && v.value_ <= 0;
258   }
259   friend constexpr bool operator>(
260       partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
261     return v.is_ordered() && v.value_ > 0;
262   }
263   friend constexpr bool operator>=(
264       partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
265     return v.is_ordered() && v.value_ >= 0;
266   }
267   friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
268                                    partial_ordering v) noexcept {
269     return v.is_ordered() && 0 == v.value_;
270   }
271   friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
272                                    partial_ordering v) noexcept {
273     return !v.is_ordered() || 0 != v.value_;
274   }
275   friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>,
276                                   partial_ordering v) noexcept {
277     return v.is_ordered() && 0 < v.value_;
278   }
279   friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>,
280                                    partial_ordering v) noexcept {
281     return v.is_ordered() && 0 <= v.value_;
282   }
283   friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>,
284                                   partial_ordering v) noexcept {
285     return v.is_ordered() && 0 > v.value_;
286   }
287   friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>,
288                                    partial_ordering v) noexcept {
289     return v.is_ordered() && 0 >= v.value_;
290   }
291
292  private:
293   compare_internal::value_type value_;
294 };
295
296 class weak_ordering
297     : public compare_internal::weak_ordering_base<weak_ordering> {
298   explicit constexpr weak_ordering(compare_internal::eq v) noexcept
299       : value_(static_cast<compare_internal::value_type>(v)) {}
300   explicit constexpr weak_ordering(compare_internal::ord v) noexcept
301       : value_(static_cast<compare_internal::value_type>(v)) {}
302   friend struct compare_internal::weak_ordering_base<weak_ordering>;
303
304  public:
305   // Conversions
306   constexpr operator weak_equality() const noexcept {  // NOLINT
307     return value_ == 0 ? weak_equality::equivalent
308                        : weak_equality::nonequivalent;
309   }
310   constexpr operator partial_ordering() const noexcept {  // NOLINT
311     return value_ == 0 ? partial_ordering::equivalent
312                        : (value_ < 0 ? partial_ordering::less
313                                      : partial_ordering::greater);
314   }
315   // Comparisons
316   friend constexpr bool operator==(
317       weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
318     return v.value_ == 0;
319   }
320   friend constexpr bool operator!=(
321       weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
322     return v.value_ != 0;
323   }
324   friend constexpr bool operator<(
325       weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
326     return v.value_ < 0;
327   }
328   friend constexpr bool operator<=(
329       weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
330     return v.value_ <= 0;
331   }
332   friend constexpr bool operator>(
333       weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
334     return v.value_ > 0;
335   }
336   friend constexpr bool operator>=(
337       weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
338     return v.value_ >= 0;
339   }
340   friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
341                                    weak_ordering v) noexcept {
342     return 0 == v.value_;
343   }
344   friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
345                                    weak_ordering v) noexcept {
346     return 0 != v.value_;
347   }
348   friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>,
349                                   weak_ordering v) noexcept {
350     return 0 < v.value_;
351   }
352   friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>,
353                                    weak_ordering v) noexcept {
354     return 0 <= v.value_;
355   }
356   friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>,
357                                   weak_ordering v) noexcept {
358     return 0 > v.value_;
359   }
360   friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>,
361                                    weak_ordering v) noexcept {
362     return 0 >= v.value_;
363   }
364
365  private:
366   compare_internal::value_type value_;
367 };
368
369 class strong_ordering
370     : public compare_internal::strong_ordering_base<strong_ordering> {
371   explicit constexpr strong_ordering(compare_internal::eq v) noexcept
372       : value_(static_cast<compare_internal::value_type>(v)) {}
373   explicit constexpr strong_ordering(compare_internal::ord v) noexcept
374       : value_(static_cast<compare_internal::value_type>(v)) {}
375   friend struct compare_internal::strong_ordering_base<strong_ordering>;
376
377  public:
378   // Conversions
379   constexpr operator weak_equality() const noexcept {  // NOLINT
380     return value_ == 0 ? weak_equality::equivalent
381                        : weak_equality::nonequivalent;
382   }
383   constexpr operator strong_equality() const noexcept {  // NOLINT
384     return value_ == 0 ? strong_equality::equal : strong_equality::nonequal;
385   }
386   constexpr operator partial_ordering() const noexcept {  // NOLINT
387     return value_ == 0 ? partial_ordering::equivalent
388                        : (value_ < 0 ? partial_ordering::less
389                                      : partial_ordering::greater);
390   }
391   constexpr operator weak_ordering() const noexcept {  // NOLINT
392     return value_ == 0
393                ? weak_ordering::equivalent
394                : (value_ < 0 ? weak_ordering::less : weak_ordering::greater);
395   }
396   // Comparisons
397   friend constexpr bool operator==(
398       strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
399     return v.value_ == 0;
400   }
401   friend constexpr bool operator!=(
402       strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
403     return v.value_ != 0;
404   }
405   friend constexpr bool operator<(
406       strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
407     return v.value_ < 0;
408   }
409   friend constexpr bool operator<=(
410       strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
411     return v.value_ <= 0;
412   }
413   friend constexpr bool operator>(
414       strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
415     return v.value_ > 0;
416   }
417   friend constexpr bool operator>=(
418       strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
419     return v.value_ >= 0;
420   }
421   friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
422                                    strong_ordering v) noexcept {
423     return 0 == v.value_;
424   }
425   friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
426                                    strong_ordering v) noexcept {
427     return 0 != v.value_;
428   }
429   friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>,
430                                   strong_ordering v) noexcept {
431     return 0 < v.value_;
432   }
433   friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>,
434                                    strong_ordering v) noexcept {
435     return 0 <= v.value_;
436   }
437   friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>,
438                                   strong_ordering v) noexcept {
439     return 0 > v.value_;
440   }
441   friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>,
442                                    strong_ordering v) noexcept {
443     return 0 >= v.value_;
444   }
445
446  private:
447   compare_internal::value_type value_;
448 };
449
450 namespace compare_internal {
451 // We also provide these comparator adapter functions for internal absl use.
452
453 // Helper functions to do a boolean comparison of two keys given a boolean
454 // or three-way comparator.
455 // SFINAE prevents implicit conversions to bool (such as from int).
456 template <typename Bool,
457           absl::enable_if_t<std::is_same<bool, Bool>::value, int> = 0>
458 constexpr bool compare_result_as_less_than(const Bool r) { return r; }
459 constexpr bool compare_result_as_less_than(const absl::weak_ordering r) {
460   return r < 0;
461 }
462
463 template <typename Compare, typename K, typename LK>
464 constexpr bool do_less_than_comparison(const Compare &compare, const K &x,
465                                        const LK &y) {
466   return compare_result_as_less_than(compare(x, y));
467 }
468
469 // Helper functions to do a three-way comparison of two keys given a boolean or
470 // three-way comparator.
471 // SFINAE prevents implicit conversions to int (such as from bool).
472 template <typename Int,
473           absl::enable_if_t<std::is_same<int, Int>::value, int> = 0>
474 constexpr absl::weak_ordering compare_result_as_ordering(const Int c) {
475   return c < 0 ? absl::weak_ordering::less
476                : c == 0 ? absl::weak_ordering::equivalent
477                         : absl::weak_ordering::greater;
478 }
479 constexpr absl::weak_ordering compare_result_as_ordering(
480     const absl::weak_ordering c) {
481   return c;
482 }
483
484 template <
485     typename Compare, typename K, typename LK,
486     absl::enable_if_t<!std::is_same<bool, absl::result_of_t<Compare(
487                                               const K &, const LK &)>>::value,
488                       int> = 0>
489 constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare,
490                                                       const K &x, const LK &y) {
491   return compare_result_as_ordering(compare(x, y));
492 }
493 template <
494     typename Compare, typename K, typename LK,
495     absl::enable_if_t<std::is_same<bool, absl::result_of_t<Compare(
496                                              const K &, const LK &)>>::value,
497                       int> = 0>
498 constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare,
499                                                       const K &x, const LK &y) {
500   return compare(x, y) ? absl::weak_ordering::less
501                        : compare(y, x) ? absl::weak_ordering::greater
502                                        : absl::weak_ordering::equivalent;
503 }
504
505 }  // namespace compare_internal
506 }  // namespace absl
507
508 #endif  // ABSL_TYPES_COMPARE_H_