1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
10 #define LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
12 #include "test_macros.h"
19 struct BooleanTestable
{
20 constexpr operator bool() const { return value_
; }
22 friend constexpr BooleanTestable
operator==(const BooleanTestable
& lhs
, const BooleanTestable
& rhs
) {
23 return lhs
.value_
== rhs
.value_
;
26 friend constexpr BooleanTestable
operator!=(const BooleanTestable
& lhs
, const BooleanTestable
& rhs
) {
27 return lhs
.value_
!= rhs
.value_
;
30 constexpr BooleanTestable
&& operator!() && {
32 return std::move(*this);
35 // this class should behave like a bool, so the constructor shouldn't be explicit
36 constexpr BooleanTestable(bool value
) : value_
{value
} {}
37 constexpr BooleanTestable(const BooleanTestable
&) = delete;
38 constexpr BooleanTestable(BooleanTestable
&&) = delete;
44 static constexpr BooleanTestable
yes(true);
45 static constexpr BooleanTestable
no(false);
48 struct StrictComparable
{
49 StrictComparable() = default;
51 // this shouldn't be explicit to make it easier to initialize inside arrays (which it almost always is)
52 constexpr StrictComparable(T value
) : value_
{value
} {}
54 friend constexpr BooleanTestable
const& operator==(StrictComparable
const& a
, StrictComparable
const& b
) {
55 return a
.value_
== b
.value_
? yes
: no
;
58 friend constexpr BooleanTestable
const& operator!=(StrictComparable
const& a
, StrictComparable
const& b
) {
59 return a
.value_
!= b
.value_
? yes
: no
;
62 friend constexpr BooleanTestable
const& operator<(StrictComparable
const& a
, StrictComparable
const& b
) {
63 return a
.value_
< b
.value_
? yes
: no
;
65 friend constexpr BooleanTestable
const& operator<=(StrictComparable
const& a
, StrictComparable
const& b
) {
66 return a
.value_
<= b
.value_
? yes
: no
;
68 friend constexpr BooleanTestable
const& operator>(StrictComparable
const& a
, StrictComparable
const& b
) {
69 return a
.value_
> b
.value_
? yes
: no
;
71 friend constexpr BooleanTestable
const& operator>=(StrictComparable
const& a
, StrictComparable
const& b
) {
72 return a
.value_
>= b
.value_
? yes
: no
;
78 auto StrictUnaryPredicate
= []<class T
>(StrictComparable
<T
> const& x
) -> BooleanTestable
const& {
79 return x
.value_
< 0 ? yes
: no
;
82 auto StrictBinaryPredicate
=
83 []<class T
>(StrictComparable
<T
> const& x
, StrictComparable
<T
> const& y
) -> BooleanTestable
const& {
84 return x
.value_
< y
.value_
? yes
: no
;
88 struct StrictBooleanIterator
{
89 using value_type
= typename
std::iterator_traits
<It
>::value_type
;
90 using reference
= typename
std::iterator_traits
<It
>::reference
;
91 using difference_type
= typename
std::iterator_traits
<It
>::difference_type
;
92 constexpr StrictBooleanIterator() = default;
93 constexpr explicit StrictBooleanIterator(It it
) : iter_(it
) {}
94 constexpr reference
operator*() const { return *iter_
; }
95 constexpr reference
operator[](difference_type n
) const { return iter_
[n
]; }
96 constexpr StrictBooleanIterator
& operator++() {
100 constexpr StrictBooleanIterator
operator++(int) {
105 constexpr StrictBooleanIterator
& operator--() {
109 constexpr StrictBooleanIterator
operator--(int) {
114 constexpr StrictBooleanIterator
& operator+=(difference_type n
) {
118 constexpr StrictBooleanIterator
& operator-=(difference_type n
) {
122 friend constexpr StrictBooleanIterator
operator+(StrictBooleanIterator x
, difference_type n
) {
126 friend constexpr StrictBooleanIterator
operator+(difference_type n
, StrictBooleanIterator x
) {
130 friend constexpr StrictBooleanIterator
operator-(StrictBooleanIterator x
, difference_type n
) {
134 friend constexpr difference_type
operator-(StrictBooleanIterator x
, StrictBooleanIterator y
) {
135 return x
.iter_
- y
.iter_
;
137 constexpr BooleanTestable
const& operator==(StrictBooleanIterator
const& other
) const {
138 return iter_
== other
.iter_
? yes
: no
;
140 constexpr BooleanTestable
const& operator!=(StrictBooleanIterator
const& other
) const {
141 return iter_
!= other
.iter_
? yes
: no
;
143 constexpr BooleanTestable
const& operator<(StrictBooleanIterator
const& other
) const {
144 return iter_
< other
.iter_
? yes
: no
;
146 constexpr BooleanTestable
const& operator<=(StrictBooleanIterator
const& other
) const {
147 return iter_
<= other
.iter_
? yes
: no
;
149 constexpr BooleanTestable
const& operator>(StrictBooleanIterator
const& other
) const {
150 return iter_
> other
.iter_
? yes
: no
;
152 constexpr BooleanTestable
const& operator>=(StrictBooleanIterator
const& other
) const {
153 return iter_
>= other
.iter_
? yes
: no
;
159 static_assert(std::forward_iterator
<StrictBooleanIterator
<int*>>);
160 static_assert(std::sentinel_for
<StrictBooleanIterator
<int*>, StrictBooleanIterator
<int*>>);
162 #endif // TEST_STD_VER > 17
164 #endif // LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H