Skip to content

Commit 877620b

Browse files
committed
[libc++] Implement operator<=> for error_{code,condition}
Implements part of P1614R2 "The Mothership has Landed" Differential Revision: https://reviews.llvm.org/D131371
1 parent 0e876ed commit 877620b

File tree

4 files changed

+132
-25
lines changed

4 files changed

+132
-25
lines changed

libcxx/docs/Status/SpaceshipProjects.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Section,Description,Dependencies,Assignee,Complete
1717
| `[pairs.spec] <https://wg21.link/pairs.spec>`_,| `pair <https://reviews.llvm.org/D107721>`_,[expos.only.func],Kent Ross,|Complete|
1818
| `[syserr.errcat.nonvirtuals] <https://wg21.link/syserr.errcat.nonvirtuals>`_,| `error_category <https://reviews.llvm.org/D131363>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
1919
| `[syserr.compare] <https://wg21.link/syserr.compare>`_,"| `error_code <https://reviews.llvm.org/D131371>`_
20-
| `error_condition <https://reviews.llvm.org/D131371>`_",None,Adrian Vogelsgesang,|In Progress|
20+
| `error_condition <https://reviews.llvm.org/D131371>`_",None,Adrian Vogelsgesang,|Complete|
2121
| `[tuple.rel] <https://wg21.link/tuple.rel>`_,| `tuple <https://reviews.llvm.org/D108250>`_,[expos.only.func],Kent Ross,|Complete|
2222
"| `[optional.relops] <https://wg21.link/optional.relops>`_
2323
| `[optional.nullops] <https://wg21.link/optional.nullops>`_

libcxx/include/system_error

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ public:
7676
};
7777
7878
// non-member functions:
79-
bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
8079
template <class charT, class traits>
8180
basic_ostream<charT,traits>&
8281
operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
@@ -103,8 +102,6 @@ public:
103102
explicit operator bool() const noexcept;
104103
};
105104
106-
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
107-
108105
class system_error
109106
: public runtime_error
110107
{
@@ -129,12 +126,16 @@ error_condition make_error_condition(errc e) noexcept;
129126
// Comparison operators:
130127
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
131128
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
132-
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
129+
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; // removed in C++20
133130
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
134-
bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
135-
bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
136-
bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
137-
bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
131+
bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; // removed in C++20
132+
bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; // removed in C++20
133+
bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; // removed in C++20
134+
bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; // removed in C++20
135+
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept; // removed in C++20
136+
bool operator<(const error_code& lhs, const error_code& rhs) noexcept; // removed in C++20
137+
strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept; // C++20
138+
strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept; // C++20
138139
139140
template <> struct hash<std::error_code>;
140141
template <> struct hash<std::error_condition>;
@@ -314,14 +315,6 @@ make_error_condition(errc __e) _NOEXCEPT
314315
return error_condition(static_cast<int>(__e), generic_category());
315316
}
316317

317-
inline _LIBCPP_INLINE_VISIBILITY
318-
bool
319-
operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
320-
{
321-
return __x.category() < __y.category()
322-
|| (__x.category() == __y.category() && __x.value() < __y.value());
323-
}
324-
325318
// error_code
326319

327320
class _LIBCPP_TYPE_VIS error_code
@@ -390,14 +383,6 @@ make_error_code(errc __e) _NOEXCEPT
390383
return error_code(static_cast<int>(__e), generic_category());
391384
}
392385

393-
inline _LIBCPP_INLINE_VISIBILITY
394-
bool
395-
operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
396-
{
397-
return __x.category() < __y.category()
398-
|| (__x.category() == __y.category() && __x.value() < __y.value());
399-
}
400-
401386
inline _LIBCPP_INLINE_VISIBILITY
402387
bool
403388
operator==(const error_code& __x, const error_code& __y) _NOEXCEPT
@@ -413,12 +398,14 @@ operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT
413398
|| __y.category().equivalent(__x, __y.value());
414399
}
415400

401+
#if _LIBCPP_STD_VER <= 17
416402
inline _LIBCPP_INLINE_VISIBILITY
417403
bool
418404
operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT
419405
{
420406
return __y == __x;
421407
}
408+
#endif
422409

423410
inline _LIBCPP_INLINE_VISIBILITY
424411
bool
@@ -427,6 +414,8 @@ operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT
427414
return __x.category() == __y.category() && __x.value() == __y.value();
428415
}
429416

417+
#if _LIBCPP_STD_VER <= 17
418+
430419
inline _LIBCPP_INLINE_VISIBILITY
431420
bool
432421
operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT
@@ -447,6 +436,42 @@ bool
447436
operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
448437
{return !(__x == __y);}
449438

439+
inline _LIBCPP_INLINE_VISIBILITY
440+
bool
441+
operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
442+
{
443+
return __x.category() < __y.category()
444+
|| (__x.category() == __y.category() && __x.value() < __y.value());
445+
}
446+
447+
inline _LIBCPP_INLINE_VISIBILITY
448+
bool
449+
operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
450+
{
451+
return __x.category() < __y.category()
452+
|| (__x.category() == __y.category() && __x.value() < __y.value());
453+
}
454+
455+
#else // _LIBCPP_STD_VER <= 17
456+
457+
inline _LIBCPP_HIDE_FROM_ABI strong_ordering
458+
operator<=>(const error_code& __x, const error_code& __y) noexcept
459+
{
460+
if (auto __c = __x.category() <=> __y.category(); __c != 0)
461+
return __c;
462+
return __x.value() <=> __y.value();
463+
}
464+
465+
inline _LIBCPP_HIDE_FROM_ABI strong_ordering
466+
operator<=>(const error_condition& __x, const error_condition& __y) noexcept
467+
{
468+
if (auto __c = __x.category() <=> __y.category(); __c != 0)
469+
return __c;
470+
return __x.value() <=> __y.value();
471+
}
472+
473+
#endif // _LIBCPP_STD_VER <= 17
474+
450475
template <>
451476
struct _LIBCPP_TEMPLATE_VIS hash<error_code>
452477
: public __unary_function<error_code, size_t>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// UNSUPPORTED: c++03, c++11, c++14, c++17
9+
10+
// <system_error>
11+
12+
// class error_code
13+
14+
// strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept
15+
16+
#include <system_error>
17+
#include <cassert>
18+
19+
#include "test_macros.h"
20+
#include "test_comparisons.h"
21+
22+
int main(int, char**) {
23+
AssertOrderAreNoexcept<std::error_code>();
24+
AssertOrderReturn<std::strong_ordering, std::error_code>();
25+
26+
// Same error category
27+
std::error_code ec1a = std::error_code(1, std::generic_category());
28+
std::error_code ec1b = std::error_code(1, std::generic_category());
29+
std::error_code ec2 = std::error_code(2, std::generic_category());
30+
31+
assert(testOrder(ec1a, ec1b, std::strong_ordering::equal));
32+
assert(testOrder(ec1a, ec2, std::strong_ordering::less));
33+
34+
// Different error category
35+
const std::error_code& ec3 = std::error_code(2, std::system_category());
36+
37+
bool isLess = ec2 < ec3;
38+
assert(testOrder(ec2, ec3, isLess ? std::strong_ordering::less : std::strong_ordering::greater));
39+
40+
return 0;
41+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// UNSUPPORTED: c++03, c++11, c++14, c++17
9+
10+
// <system_error>
11+
12+
// class error_condition
13+
14+
// strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept
15+
16+
#include <system_error>
17+
#include <cassert>
18+
19+
#include "test_macros.h"
20+
#include "test_comparisons.h"
21+
22+
int main(int, char**) {
23+
AssertOrderAreNoexcept<std::error_condition>();
24+
AssertOrderReturn<std::strong_ordering, std::error_condition>();
25+
26+
// Same error category
27+
std::error_condition ec1a = std::error_condition(1, std::generic_category());
28+
std::error_condition ec1b = std::error_condition(1, std::generic_category());
29+
std::error_condition ec2 = std::error_condition(2, std::generic_category());
30+
31+
assert(testOrder(ec1a, ec1b, std::strong_ordering::equal));
32+
assert(testOrder(ec1a, ec2, std::strong_ordering::less));
33+
34+
// Different error category
35+
const std::error_condition& ec3 = std::error_condition(2, std::system_category());
36+
37+
bool isLess = ec2 < ec3;
38+
assert(testOrder(ec2, ec3, isLess ? std::strong_ordering::less : std::strong_ordering::greater));
39+
40+
return 0;
41+
}

0 commit comments

Comments
 (0)