compare.h
Go to the documentation of this file.
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>
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<
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,
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>
87  ABSL_CONST_INIT static const T equivalent;
89 };
90 template <typename T>
92 template <typename T>
94 
95 template <typename T>
97  ABSL_CONST_INIT static const T equal;
98  ABSL_CONST_INIT static const T nonequal;
99  ABSL_CONST_INIT static const T equivalent;
101 };
102 template <typename T>
104 template <typename T>
106 template <typename T>
108 template <typename T>
110 
111 template <typename T>
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>
120 template <typename T>
122 template <typename T>
124 template <typename T>
126 
127 template <typename T>
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>
135 template <typename T>
137 template <typename T>
139 
140 template <typename T>
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>
149 template <typename T>
151 template <typename T>
153 template <typename T>
155 
156 } // namespace compare_internal
157 
160  explicit constexpr weak_equality(compare_internal::eq v) noexcept
161  : value_(static_cast<compare_internal::value_type>(v)) {}
163 
164  public:
165  // Comparisons
166  friend constexpr bool operator==(
168  return v.value_ == 0;
169  }
170  friend constexpr bool operator!=(
172  return v.value_ != 0;
173  }
175  weak_equality v) noexcept {
176  return 0 == v.value_;
177  }
179  weak_equality v) noexcept {
180  return 0 != v.value_;
181  }
182 
183  private:
185 };
186 
189  explicit constexpr strong_equality(compare_internal::eq v) noexcept
190  : value_(static_cast<compare_internal::value_type>(v)) {}
192 
193  public:
194  // Conversion
195  constexpr operator weak_equality() const noexcept { // NOLINT
196  return value_ == 0 ? weak_equality::equivalent
198  }
199  // Comparisons
200  friend constexpr bool operator==(
202  return v.value_ == 0;
203  }
204  friend constexpr bool operator!=(
206  return v.value_ != 0;
207  }
209  strong_equality v) noexcept {
210  return 0 == v.value_;
211  }
213  strong_equality v) noexcept {
214  return 0 != v.value_;
215  }
216 
217  private:
219 };
220 
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)) {}
230 
231  constexpr bool is_ordered() const noexcept {
232  return value_ !=
234  }
235 
236  public:
237  // Conversion
238  constexpr operator weak_equality() const noexcept { // NOLINT
239  return value_ == 0 ? weak_equality::equivalent
241  }
242  // Comparisons
243  friend constexpr bool operator==(
245  return v.is_ordered() && v.value_ == 0;
246  }
247  friend constexpr bool operator!=(
249  return !v.is_ordered() || v.value_ != 0;
250  }
251  friend constexpr bool operator<(
253  return v.is_ordered() && v.value_ < 0;
254  }
255  friend constexpr bool operator<=(
257  return v.is_ordered() && v.value_ <= 0;
258  }
259  friend constexpr bool operator>(
261  return v.is_ordered() && v.value_ > 0;
262  }
263  friend constexpr bool operator>=(
265  return v.is_ordered() && v.value_ >= 0;
266  }
268  partial_ordering v) noexcept {
269  return v.is_ordered() && 0 == v.value_;
270  }
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  }
284  partial_ordering v) noexcept {
285  return v.is_ordered() && 0 > v.value_;
286  }
288  partial_ordering v) noexcept {
289  return v.is_ordered() && 0 >= v.value_;
290  }
291 
292  private:
294 };
295 
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)) {}
303 
304  public:
305  // Conversions
306  constexpr operator weak_equality() const noexcept { // NOLINT
307  return value_ == 0 ? weak_equality::equivalent
309  }
310  constexpr operator partial_ordering() const noexcept { // NOLINT
311  return value_ == 0 ? partial_ordering::equivalent
312  : (value_ < 0 ? partial_ordering::less
314  }
315  // Comparisons
316  friend constexpr bool operator==(
318  return v.value_ == 0;
319  }
320  friend constexpr bool operator!=(
322  return v.value_ != 0;
323  }
324  friend constexpr bool operator<(
326  return v.value_ < 0;
327  }
328  friend constexpr bool operator<=(
330  return v.value_ <= 0;
331  }
332  friend constexpr bool operator>(
334  return v.value_ > 0;
335  }
336  friend constexpr bool operator>=(
338  return v.value_ >= 0;
339  }
341  weak_ordering v) noexcept {
342  return 0 == v.value_;
343  }
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  }
357  weak_ordering v) noexcept {
358  return 0 > v.value_;
359  }
361  weak_ordering v) noexcept {
362  return 0 >= v.value_;
363  }
364 
365  private:
367 };
368 
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)) {}
376 
377  public:
378  // Conversions
379  constexpr operator weak_equality() const noexcept { // NOLINT
380  return value_ == 0 ? weak_equality::equivalent
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
390  }
391  constexpr operator weak_ordering() const noexcept { // NOLINT
392  return value_ == 0
394  : (value_ < 0 ? weak_ordering::less : weak_ordering::greater);
395  }
396  // Comparisons
397  friend constexpr bool operator==(
399  return v.value_ == 0;
400  }
401  friend constexpr bool operator!=(
403  return v.value_ != 0;
404  }
405  friend constexpr bool operator<(
407  return v.value_ < 0;
408  }
409  friend constexpr bool operator<=(
411  return v.value_ <= 0;
412  }
413  friend constexpr bool operator>(
415  return v.value_ > 0;
416  }
417  friend constexpr bool operator>=(
419  return v.value_ >= 0;
420  }
422  strong_ordering v) noexcept {
423  return 0 == v.value_;
424  }
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  }
438  strong_ordering v) noexcept {
439  return 0 > v.value_;
440  }
442  strong_ordering v) noexcept {
443  return 0 >= v.value_;
444  }
445 
446  private:
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,
458 constexpr bool compare_result_as_less_than(const Bool r) { return 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,
475  return c < 0 ? absl::weak_ordering::less
478 }
480  const absl::weak_ordering c) {
481  return c;
482 }
483 
484 template <
485  typename Compare, typename K, typename LK,
487  const K &, const LK &)>>::value,
488  int> = 0>
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,
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
503 }
504 
505 } // namespace compare_internal
506 } // namespace absl
507 
508 #endif // ABSL_TYPES_COMPARE_H_
int v
Definition: variant_test.cc:81
friend constexpr bool operator!=(strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:401
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, weak_ordering v) noexcept
Definition: compare.h:356
static ABSL_CONST_INIT const T unordered
Definition: compare.h:116
friend constexpr bool operator==(partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:243
constexpr weak_ordering(compare_internal::ord v) noexcept
Definition: compare.h:300
static ABSL_CONST_INIT const T equivalent
Definition: compare.h:114
constexpr strong_ordering(compare_internal::ord v) noexcept
Definition: compare.h:373
friend constexpr bool operator<=(weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:328
typename std::result_of< T >::type result_of_t
Definition: type_traits.h:559
static ABSL_CONST_INIT const T greater
Definition: compare.h:115
#define ABSL_CONST_INIT
Definition: attributes.h:605
static ABSL_CONST_INIT const T equivalent
Definition: compare.h:130
friend constexpr bool operator!=(strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:204
constexpr bool do_less_than_comparison(const Compare &compare, const K &x, const LK &y)
Definition: compare.h:464
constexpr bool compare_result_as_less_than(const Bool r)
Definition: compare.h:458
static ABSL_CONST_INIT const T equal
Definition: compare.h:97
friend constexpr bool operator>(strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:413
constexpr absl::weak_ordering compare_result_as_ordering(const Int c)
Definition: compare.h:474
compare_internal::value_type value_
Definition: compare.h:184
friend constexpr bool operator==(weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:316
static ABSL_CONST_INIT const T less
Definition: compare.h:129
constexpr strong_equality(compare_internal::eq v) noexcept
Definition: compare.h:189
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, partial_ordering v) noexcept
Definition: compare.h:267
compare_internal::value_type value_
Definition: compare.h:218
constexpr weak_ordering(compare_internal::eq v) noexcept
Definition: compare.h:298
constexpr weak_equality(compare_internal::eq v) noexcept
Definition: compare.h:160
friend constexpr bool operator<=(strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:409
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, strong_equality v) noexcept
Definition: compare.h:212
static ABSL_CONST_INIT const T greater
Definition: compare.h:131
Definition: algorithm.h:29
friend constexpr bool operator<(partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:251
friend constexpr bool operator<(strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:405
typename std::enable_if< B, T >::type enable_if_t
Definition: type_traits.h:547
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, partial_ordering v) noexcept
Definition: compare.h:287
constexpr partial_ordering(compare_internal::ord v) noexcept
Definition: compare.h:225
friend constexpr bool operator!=(weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:320
constexpr partial_ordering(compare_internal::eq v) noexcept
Definition: compare.h:223
static ABSL_CONST_INIT const T nonequivalent
Definition: compare.h:88
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, partial_ordering v) noexcept
Definition: compare.h:271
constexpr bool is_ordered() const noexcept
Definition: compare.h:231
friend constexpr bool operator>=(weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:336
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, weak_ordering v) noexcept
Definition: compare.h:360
size_t value
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, strong_ordering v) noexcept
Definition: compare.h:425
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, strong_ordering v) noexcept
Definition: compare.h:441
static ABSL_CONST_INIT const T nonequal
Definition: compare.h:98
constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, const K &x, const LK &y)
Definition: compare.h:489
static ABSL_CONST_INIT const T equivalent
Definition: compare.h:144
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, weak_ordering v) noexcept
Definition: compare.h:340
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, weak_equality v) noexcept
Definition: compare.h:174
constexpr OnlyLiteralZero(NullPtrT) noexcept
Definition: compare.h:55
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, strong_equality v) noexcept
Definition: compare.h:208
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, strong_ordering v) noexcept
Definition: compare.h:421
friend constexpr bool operator!=(partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:247
static ABSL_CONST_INIT const T nonequivalent
Definition: compare.h:100
friend constexpr bool operator<=(partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:255
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, weak_equality v) noexcept
Definition: compare.h:178
friend constexpr bool operator>(weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:332
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, strong_ordering v) noexcept
Definition: compare.h:437
static ABSL_CONST_INIT const T less
Definition: compare.h:113
friend constexpr bool operator<(weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:324
compare_internal::value_type value_
Definition: compare.h:447
static ABSL_CONST_INIT const T equal
Definition: compare.h:143
friend constexpr bool operator==(strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:397
static ABSL_CONST_INIT const T less
Definition: compare.h:142
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, partial_ordering v) noexcept
Definition: compare.h:283
friend constexpr bool operator==(strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:200
friend constexpr bool operator!=(weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:170
constexpr partial_ordering(compare_internal::ncmp v) noexcept
Definition: compare.h:227
int Compare(const BigUnsigned< N > &lhs, const BigUnsigned< M > &rhs)
compare_internal::value_type value_
Definition: compare.h:293
friend constexpr bool operator>(partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:259
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, weak_ordering v) noexcept
Definition: compare.h:344
friend constexpr bool operator>=(strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:417
constexpr strong_ordering(compare_internal::eq v) noexcept
Definition: compare.h:371
friend constexpr bool operator>=(partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:263
static ABSL_CONST_INIT const T equivalent
Definition: compare.h:99
static ABSL_CONST_INIT const T equivalent
Definition: compare.h:87
friend constexpr bool operator==(weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept
Definition: compare.h:166
compare_internal::value_type value_
Definition: compare.h:366
static ABSL_CONST_INIT const T greater
Definition: compare.h:145


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:18