forked from OSchip/llvm-project
[libc++][ranges] Add implicit conversion to bool test for ranges::find{, if, if_not}
Reviewed By: ldionne, var-const, #libc Spies: libcxx-commits Differential Revision: https://reviews.llvm.org/D122011
This commit is contained in:
parent
3031fa88f0
commit
cd7b444078
|
@ -25,6 +25,7 @@
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
#include "almost_satisfies_types.h"
|
#include "almost_satisfies_types.h"
|
||||||
|
#include "boolean_testable.h"
|
||||||
#include "test_iterators.h"
|
#include "test_iterators.h"
|
||||||
|
|
||||||
struct NotEqualityComparable {};
|
struct NotEqualityComparable {};
|
||||||
|
@ -247,6 +248,20 @@ constexpr bool test() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// check that the implicit conversion to bool works
|
||||||
|
{
|
||||||
|
StrictComparable<int> a[] = {1, 2, 3, 4};
|
||||||
|
auto ret = std::ranges::find(a, a + 4, StrictComparable<int>{2});
|
||||||
|
assert(ret == a + 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
StrictComparable<int> a[] = {1, 2, 3, 4};
|
||||||
|
auto ret = std::ranges::find(a, StrictComparable<int>{2});
|
||||||
|
assert(ret == a + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
#include "almost_satisfies_types.h"
|
#include "almost_satisfies_types.h"
|
||||||
|
#include "boolean_testable.h"
|
||||||
#include "test_iterators.h"
|
#include "test_iterators.h"
|
||||||
|
|
||||||
struct Predicate {
|
struct Predicate {
|
||||||
|
@ -224,6 +225,20 @@ constexpr bool test() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// check that the implicit conversion to bool works
|
||||||
|
{
|
||||||
|
int a[] = {1, 2, 3, 4};
|
||||||
|
auto ret = std::ranges::find_if(a, a + 4, [](const int& i) { return BooleanTestable{i == 3}; });
|
||||||
|
assert(ret == a + 2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int a[] = {1, 2, 3, 4};
|
||||||
|
auto ret = std::ranges::find_if(a, [](const int& b) { return BooleanTestable{b == 3}; });
|
||||||
|
assert(ret == a + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
#include "almost_satisfies_types.h"
|
#include "almost_satisfies_types.h"
|
||||||
|
#include "boolean_testable.h"
|
||||||
#include "test_iterators.h"
|
#include "test_iterators.h"
|
||||||
|
|
||||||
struct Predicate {
|
struct Predicate {
|
||||||
|
@ -218,6 +219,20 @@ constexpr bool test() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// check that the implicit conversion to bool works
|
||||||
|
{
|
||||||
|
int a[] = {1, 2, 3, 4};
|
||||||
|
auto ret = std::ranges::find_if_not(a, a + 4, [](const int& i) { return BooleanTestable{i != 3}; });
|
||||||
|
assert(ret == a + 2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int a[] = {1, 2, 3, 4};
|
||||||
|
auto ret = std::ranges::find_if_not(a, [](const int& b) { return BooleanTestable{b != 3}; });
|
||||||
|
assert(ret == a + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
|
||||||
|
#define LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
|
||||||
|
|
||||||
|
#if TEST_STD_VER > 17
|
||||||
|
|
||||||
|
class BooleanTestable {
|
||||||
|
public:
|
||||||
|
constexpr operator bool() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend constexpr BooleanTestable operator==(const BooleanTestable& lhs, const BooleanTestable& rhs) {
|
||||||
|
return lhs.value_ == rhs.value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend constexpr BooleanTestable operator!=(const BooleanTestable& lhs, const BooleanTestable& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr BooleanTestable operator!() {
|
||||||
|
return BooleanTestable{!value_};
|
||||||
|
}
|
||||||
|
|
||||||
|
// this class should behave like a bool, so the constructor shouldn't be explicit
|
||||||
|
constexpr BooleanTestable(bool value) : value_{value} {}
|
||||||
|
constexpr BooleanTestable(const BooleanTestable&) = delete;
|
||||||
|
constexpr BooleanTestable(BooleanTestable&&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class StrictComparable {
|
||||||
|
public:
|
||||||
|
// this shouldn't be explicit to make it easier to initlaize inside arrays (which it almost always is)
|
||||||
|
constexpr StrictComparable(T value) : value_{value} {}
|
||||||
|
|
||||||
|
friend constexpr BooleanTestable operator==(const StrictComparable& lhs, const StrictComparable& rhs) {
|
||||||
|
return (lhs.value_ == rhs.value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend constexpr BooleanTestable operator!=(const StrictComparable& lhs, const StrictComparable& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TEST_STD_VER > 17
|
||||||
|
|
||||||
|
#endif // LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
|
Loading…
Reference in New Issue