[libcxx-commits] [libcxx] cd7b444 - [libc++][ranges] Add implicit conversion to bool test for ranges::find{, if, if_not}

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Thu Apr 7 03:03:58 PDT 2022


Author: Nikolas Klauser
Date: 2022-04-07T12:03:43+02:00
New Revision: cd7b444078e6a93bbe3cf0122f9aef7213b418bb

URL: https://github.com/llvm/llvm-project/commit/cd7b444078e6a93bbe3cf0122f9aef7213b418bb
DIFF: https://github.com/llvm/llvm-project/commit/cd7b444078e6a93bbe3cf0122f9aef7213b418bb.diff

LOG: [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

Added: 
    libcxx/test/support/boolean_testable.h

Modified: 
    libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp
    libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp
    libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if_not.pass.cpp

Removed: 
    


################################################################################
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
index d7c38bb54ed23..ad11098df32ac 100644
--- 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 <ranges>
 
 #include "almost_satisfies_types.h"
+#include "boolean_testable.h"
 #include "test_iterators.h"
 
 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;
 }
 

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
index d5b38b13e82a7..c7147693dbf08 100644
--- 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 <ranges>
 
 #include "almost_satisfies_types.h"
+#include "boolean_testable.h"
 #include "test_iterators.h"
 
 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;
 }
 

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
index 30d14c08c6e91..f4814ee71ae85 100644
--- 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 <ranges>
 
 #include "almost_satisfies_types.h"
+#include "boolean_testable.h"
 #include "test_iterators.h"
 
 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;
 }
 

diff  --git a/libcxx/test/support/boolean_testable.h b/libcxx/test/support/boolean_testable.h
new file mode 100644
index 0000000000000..9d4f62947a321
--- /dev/null
+++ b/libcxx/test/support/boolean_testable.h
@@ -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


        


More information about the libcxx-commits mailing list