diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp @@ -25,6 +25,7 @@ #include #include "almost_satisfies_types.h" +#include "immobile_bool.h" #include "test_iterators.h" struct NotEqualityComparable {}; @@ -247,6 +248,20 @@ } } + { + // check that the implicit conversion to bool works + { + ImmobileBool a[] = {false, false, false, true}; + auto ret = std::ranges::find(a, a + 4, ImmobileBool{true}); + assert(ret == a + 3); + } + { + ImmobileBool a[] = {false, false, false, true}; + auto ret = std::ranges::find(a, ImmobileBool{true}); + assert(ret == a + 3); + } + } + return true; } diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp @@ -25,6 +25,7 @@ #include #include "almost_satisfies_types.h" +#include "immobile_bool.h" #include "test_iterators.h" struct Predicate { @@ -224,6 +225,20 @@ } } + { + // check that the implicit conversion to bool works + { + ImmobileBool a[] = {false, false, false, true}; + auto ret = std::ranges::find_if(a, a + 4, [](const ImmobileBool& b) { return true == b; }); + assert(ret == a + 3); + } + { + ImmobileBool a[] = {false, false, false, true}; + auto ret = std::ranges::find_if(a, [](const ImmobileBool& b) { return true == b; }); + assert(ret == a + 3); + } + } + return true; } diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if_not.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if_not.pass.cpp --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if_not.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if_not.pass.cpp @@ -25,6 +25,7 @@ #include #include "almost_satisfies_types.h" +#include "immobile_bool.h" #include "test_iterators.h" struct Predicate { @@ -218,6 +219,20 @@ } } + { + // check that the implicit conversion to bool works + { + ImmobileBool a[] = {false, false, false, true}; + auto ret = std::ranges::find_if_not(a, a + 4, [](const ImmobileBool& b) { return true != b; }); + assert(ret == a + 3); + } + { + ImmobileBool a[] = {false, false, false, true}; + auto ret = std::ranges::find_if_not(a, [](const ImmobileBool& b) { return true != b; }); + assert(ret == a + 3); + } + } + return true; } diff --git a/libcxx/test/support/immobile_bool.h b/libcxx/test/support/immobile_bool.h new file mode 100644 --- /dev/null +++ b/libcxx/test/support/immobile_bool.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 IMMOBILE_BOOL_H +#define IMMOBILE_BOOL_H + +struct ImmobileBool { + bool b; + + constexpr operator bool() { + return b; + } + + friend constexpr ImmobileBool operator==(const ImmobileBool& lhs, const ImmobileBool& rhs) { + return lhs.b == rhs.b; + } + + friend constexpr ImmobileBool operator!=(const ImmobileBool& lhs, const ImmobileBool& rhs) { + return !(lhs == rhs); + } + + constexpr ImmobileBool(bool b_) : b{b_} {} + constexpr ImmobileBool(const ImmobileBool&) = delete; + constexpr ImmobileBool(ImmobileBool&&) = delete; +}; + +#endif // IMMOBILE_BOOL_H