================
@@ -0,0 +1,190 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// template<input_iterator I, sentinel_for<I> S, class T, class Proj = 
identity>
+//     requires indirect_binary_predicate<ranges::equal_to, projected<I, 
Proj>, const T*>
+//     constexpr bool ranges::contains(I first, S last, const T& value, Proj 
proj = {});       // since C++23
+
+// template<input_range R, class T, class Proj = identity>
+//     requires indirect_binary_predicate<ranges::equal_to, 
projected<iterator_t<R>, Proj>, const T*>
+//     constexpr bool ranges::contains(R&& r, const T& value, Proj proj = {}); 
                // since C++23
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <ranges>
+#include <vector>
+
+#include "almost_satisfies_types.h"
+#include "boolean_testable.h"
+#include "test_iterators.h"
+
+struct NotEqualityComparable {};
+
+template <class Iter, class Sent = Iter>
+concept HasContainsIt = requires(Iter iter, Sent sent) { 
std::ranges::contains(iter, sent, *iter); };
+
+static_assert(HasContainsIt<int*>);
+static_assert(!HasContainsIt<NotEqualityComparable*>);
+static_assert(!HasContainsIt<InputIteratorNotDerivedFrom>);
+static_assert(!HasContainsIt<InputIteratorNotIndirectlyReadable>);
+static_assert(!HasContainsIt<InputIteratorNotInputOrOutputIterator>);
+static_assert(!HasContainsIt<cpp20_input_iterator<int*>, 
SentinelForNotSemiregular>);
+static_assert(!HasContainsIt<cpp20_input_iterator<int*>, 
InputRangeNotSentinelEqualityComparableWith>);
+
+static_assert(!HasContainsIt<int*, int>);
+static_assert(!HasContainsIt<int, int*>);
+
+template <class Range, class ValT>
+concept HasContainsR = requires(Range range) { std::ranges::contains(range, 
ValT{}); };
+
+static_assert(HasContainsR<std::array<int, 1>, int>);
+static_assert(!HasContainsR<int, int>);
+static_assert(!HasContainsR<std::array<NotEqualityComparable, 1>, 
NotEqualityComparable>);
+static_assert(!HasContainsR<InputRangeNotDerivedFrom, int>);
+static_assert(!HasContainsR<InputRangeNotIndirectlyReadable, int>);
+static_assert(!HasContainsR<InputRangeNotInputOrOutputIterator, int>);
+static_assert(!HasContainsR<InputRangeNotSentinelSemiregular, int>);
+static_assert(!HasContainsR<InputRangeNotSentinelEqualityComparableWith, int>);
+
+static std::vector<int> comparable_data;
+
+// clang-format off
+template <class Iter, class Sent = Iter>
+constexpr void test_iterators() {
+  using ValueT = std::iter_value_t<Iter>;
+  {  // simple tests
+    {
+      ValueT a[] = {1, 2, 3, 4, 5, 6};
----------------
var-const wrote:

@EricWF I think it's just conceptually simpler. Consider:
```cpp
// A
{
  int input[] = {5, 7, 8, 13, 3, 6};
  assert(ranges::contains(in, in + std::size(in), 3));
}
{
  int input[] = {48, 16, 32, 45, 99, 128, 37, 64, 15};
  assert(ranges::contains(in, 64));
}

// B
{
  int input[] = {5, 7, 8, 13, 3, 6};
  assert(ranges::contains(in, in + std::size(in), 3));
}
{
  int input[] = {5, 7, 8, 13, 3, 6};
  assert(ranges::contains(in, 3));
}

// C
int input[] = {5, 7, 8, 13, 3, 6};
{
  assert(ranges::contains(in, in + std::size(in), 3));
}
{
  assert(ranges::contains(in, 3));
}
```

IMO while `A` is valid, it's overly complicated for no reason -- now the reader 
has to examine both input sequences to understand (or verify) what the test is 
doing. `B` is better because now there is no unnecessary divergence, but there 
is still some overhead to see if the sequences are the same or not. `C` removes 
that overhead, however small, and also most directly conveys the underlying 
idea (we are running equivalent tests on the two overloads of the function). 
The fact that it reduces the line count is also nice but not the primary 
motivation.

https://github.com/llvm/llvm-project/pull/65148
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to