Skip to content

Commit b971ac5

Browse files
authored
Fix the implementation of OnlyLiteralZero (#1420)
This patch changes the implementation of OnlyLiteralZero to only fail if the second overload is chosen, instead of failing during overload resolution. This patch cherry-picks 2de126c. Fixes #1419
1 parent c8a2f92 commit b971ac5

File tree

2 files changed

+60
-61
lines changed

2 files changed

+60
-61
lines changed

absl/base/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
// LTS releases can be obtained from
113113
// https://github.com/abseil/abseil-cpp/releases.
114114
#define ABSL_LTS_RELEASE_VERSION 20230125
115-
#define ABSL_LTS_RELEASE_PATCH_LEVEL 1
115+
#define ABSL_LTS_RELEASE_PATCH_LEVEL 2
116116

117117
// Helper macro to convert a CPP variable to a string literal.
118118
#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x

absl/types/compare.h

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,28 @@ namespace compare_internal {
4444

4545
using value_type = int8_t;
4646

47-
template <typename T>
48-
struct Fail {
49-
static_assert(sizeof(T) < 0, "Only literal `0` is allowed.");
50-
};
47+
class OnlyLiteralZero {
48+
// A private type which cannot be named to explicitly cast to it.
49+
struct MatchLiteralZero;
5150

52-
// We need the NullPtrT template to avoid triggering the modernize-use-nullptr
53-
// ClangTidy warning in user code.
54-
template <typename NullPtrT = std::nullptr_t>
55-
struct OnlyLiteralZero {
56-
constexpr OnlyLiteralZero(NullPtrT) noexcept {} // NOLINT
51+
public:
52+
// Accept only literal zero since it can be implicitly converted to a pointer
53+
// type. nullptr constants will be caught by the other constructor which
54+
// accepts a nullptr_t.
55+
constexpr OnlyLiteralZero(MatchLiteralZero *) noexcept {} // NOLINT
5756

5857
// Fails compilation when `nullptr` or integral type arguments other than
5958
// `int` are passed. This constructor doesn't accept `int` because literal `0`
6059
// has type `int`. Literal `0` arguments will be implicitly converted to
6160
// `std::nullptr_t` and accepted by the above constructor, while other `int`
6261
// arguments will fail to be converted and cause compilation failure.
63-
template <
64-
typename T,
65-
typename = typename std::enable_if<
66-
std::is_same<T, std::nullptr_t>::value ||
67-
(std::is_integral<T>::value && !std::is_same<T, int>::value)>::type,
68-
typename = typename Fail<T>::type>
69-
OnlyLiteralZero(T); // NOLINT
62+
template <typename T, typename = typename std::enable_if<
63+
std::is_same<T, std::nullptr_t>::value ||
64+
(std::is_integral<T>::value &&
65+
!std::is_same<T, int>::value)>::type>
66+
OnlyLiteralZero(T) { // NOLINT
67+
static_assert(sizeof(T) < 0, "Only literal `0` is allowed.");
68+
}
7069
};
7170

7271
enum class eq : value_type {
@@ -163,18 +162,18 @@ class weak_equality
163162

164163
// Comparisons
165164
friend constexpr bool operator==(
166-
weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
165+
weak_equality v, compare_internal::OnlyLiteralZero) noexcept {
167166
return v.value_ == 0;
168167
}
169168
friend constexpr bool operator!=(
170-
weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
169+
weak_equality v, compare_internal::OnlyLiteralZero) noexcept {
171170
return v.value_ != 0;
172171
}
173-
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
172+
friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
174173
weak_equality v) noexcept {
175174
return 0 == v.value_;
176175
}
177-
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
176+
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
178177
weak_equality v) noexcept {
179178
return 0 != v.value_;
180179
}
@@ -214,18 +213,18 @@ class strong_equality
214213
}
215214
// Comparisons
216215
friend constexpr bool operator==(
217-
strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
216+
strong_equality v, compare_internal::OnlyLiteralZero) noexcept {
218217
return v.value_ == 0;
219218
}
220219
friend constexpr bool operator!=(
221-
strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept {
220+
strong_equality v, compare_internal::OnlyLiteralZero) noexcept {
222221
return v.value_ != 0;
223222
}
224-
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
223+
friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
225224
strong_equality v) noexcept {
226225
return 0 == v.value_;
227226
}
228-
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
227+
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
229228
strong_equality v) noexcept {
230229
return 0 != v.value_;
231230
}
@@ -277,50 +276,50 @@ class partial_ordering
277276
}
278277
// Comparisons
279278
friend constexpr bool operator==(
280-
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
279+
partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
281280
return v.is_ordered() && v.value_ == 0;
282281
}
283282
friend constexpr bool operator!=(
284-
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
283+
partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
285284
return !v.is_ordered() || v.value_ != 0;
286285
}
287286
friend constexpr bool operator<(
288-
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
287+
partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
289288
return v.is_ordered() && v.value_ < 0;
290289
}
291290
friend constexpr bool operator<=(
292-
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
291+
partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
293292
return v.is_ordered() && v.value_ <= 0;
294293
}
295294
friend constexpr bool operator>(
296-
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
295+
partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
297296
return v.is_ordered() && v.value_ > 0;
298297
}
299298
friend constexpr bool operator>=(
300-
partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
299+
partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
301300
return v.is_ordered() && v.value_ >= 0;
302301
}
303-
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
302+
friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
304303
partial_ordering v) noexcept {
305304
return v.is_ordered() && 0 == v.value_;
306305
}
307-
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
306+
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
308307
partial_ordering v) noexcept {
309308
return !v.is_ordered() || 0 != v.value_;
310309
}
311-
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>,
310+
friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
312311
partial_ordering v) noexcept {
313312
return v.is_ordered() && 0 < v.value_;
314313
}
315-
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>,
314+
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
316315
partial_ordering v) noexcept {
317316
return v.is_ordered() && 0 <= v.value_;
318317
}
319-
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>,
318+
friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
320319
partial_ordering v) noexcept {
321320
return v.is_ordered() && 0 > v.value_;
322321
}
323-
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>,
322+
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
324323
partial_ordering v) noexcept {
325324
return v.is_ordered() && 0 >= v.value_;
326325
}
@@ -369,50 +368,50 @@ class weak_ordering
369368
}
370369
// Comparisons
371370
friend constexpr bool operator==(
372-
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
371+
weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
373372
return v.value_ == 0;
374373
}
375374
friend constexpr bool operator!=(
376-
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
375+
weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
377376
return v.value_ != 0;
378377
}
379378
friend constexpr bool operator<(
380-
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
379+
weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
381380
return v.value_ < 0;
382381
}
383382
friend constexpr bool operator<=(
384-
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
383+
weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
385384
return v.value_ <= 0;
386385
}
387386
friend constexpr bool operator>(
388-
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
387+
weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
389388
return v.value_ > 0;
390389
}
391390
friend constexpr bool operator>=(
392-
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
391+
weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
393392
return v.value_ >= 0;
394393
}
395-
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
394+
friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
396395
weak_ordering v) noexcept {
397396
return 0 == v.value_;
398397
}
399-
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
398+
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
400399
weak_ordering v) noexcept {
401400
return 0 != v.value_;
402401
}
403-
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>,
402+
friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
404403
weak_ordering v) noexcept {
405404
return 0 < v.value_;
406405
}
407-
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>,
406+
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
408407
weak_ordering v) noexcept {
409408
return 0 <= v.value_;
410409
}
411-
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>,
410+
friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
412411
weak_ordering v) noexcept {
413412
return 0 > v.value_;
414413
}
415-
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>,
414+
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
416415
weak_ordering v) noexcept {
417416
return 0 >= v.value_;
418417
}
@@ -468,50 +467,50 @@ class strong_ordering
468467
}
469468
// Comparisons
470469
friend constexpr bool operator==(
471-
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
470+
strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
472471
return v.value_ == 0;
473472
}
474473
friend constexpr bool operator!=(
475-
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
474+
strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
476475
return v.value_ != 0;
477476
}
478477
friend constexpr bool operator<(
479-
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
478+
strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
480479
return v.value_ < 0;
481480
}
482481
friend constexpr bool operator<=(
483-
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
482+
strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
484483
return v.value_ <= 0;
485484
}
486485
friend constexpr bool operator>(
487-
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
486+
strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
488487
return v.value_ > 0;
489488
}
490489
friend constexpr bool operator>=(
491-
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept {
490+
strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
492491
return v.value_ >= 0;
493492
}
494-
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>,
493+
friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
495494
strong_ordering v) noexcept {
496495
return 0 == v.value_;
497496
}
498-
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>,
497+
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
499498
strong_ordering v) noexcept {
500499
return 0 != v.value_;
501500
}
502-
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>,
501+
friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
503502
strong_ordering v) noexcept {
504503
return 0 < v.value_;
505504
}
506-
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>,
505+
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
507506
strong_ordering v) noexcept {
508507
return 0 <= v.value_;
509508
}
510-
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>,
509+
friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
511510
strong_ordering v) noexcept {
512511
return 0 > v.value_;
513512
}
514-
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>,
513+
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
515514
strong_ordering v) noexcept {
516515
return 0 >= v.value_;
517516
}

0 commit comments

Comments
 (0)