[clang] [libc++] Prevent calling the projection more than three times (PR #66315)

Louis Dionne via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 18 07:17:09 PDT 2023


================
@@ -108,7 +108,34 @@ constexpr bool test() {
     auto prvalue_proj = [](const CheckDoubleMove& x) -> CheckDoubleMove { return x; };
     assert(&std::ranges::clamp(val, low, high, moving_comp, prvalue_proj) == &val);
   }
+  { // Make sure we don't call the projection more than three times per [alg.clamp], see #64717
+    int counter = 0;
+    auto projection_function = [&counter](const int value) -> int {
+      counter++;
+      return value;
+    };
+    assert(std::ranges::clamp(3, 2, 4, std::ranges::less{}, projection_function) == 3);
+    assert(counter <= 3);
+  }
+  {
+    struct Foo {
+      std::string s;
+    };
+
+    // taking by value is important here
+    auto comparator = [](std::string a, std::string b) {
+      return std::atoi(a.c_str()) < std::atoi(b.c_str());
+    };
+
+    auto projection = [](Foo const& foo) {
+      return foo.s;
+    };
 
+    Foo foo{"12"};
+    Foo high{"10"};
+    Foo low{"1"};
+    assert(std::ranges::clamp(foo, low, high, comparator, projection).s == "10");
+  }
----------------
ldionne wrote:

Let's add the test case from https://gcc.godbolt.org/z/a8ne6e487.

In this case it means that we also need to use `std::forward` like you did previously, thanks @timsong-cpp for clarifying.

https://github.com/llvm/llvm-project/pull/66315


More information about the cfe-commits mailing list