[libcxx-commits] [libcxx] [libc++] Implement ranges::iota (PR #68494)
Christopher Di Bella via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Aug 5 10:20:30 PDT 2024
================
@@ -0,0 +1,215 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Testing std::ranges::iota
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <numeric>
+#include <utility>
+
+#include "almost_satisfies_types.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+//
+// Testing constraints
+//
+
+// Concepts to check different overloads of std::ranges::iota
+template <class Iter = int*, class Sent = int*, class Value = int>
+concept HasIotaIter = requires(Iter&& iter, Sent&& sent, Value&& val) {
+ std::ranges::iota(std::forward<Iter>(iter), std::forward<Sent>(sent), std::forward<Value>(val));
+};
+
+template <class Range, class Value = int>
+concept HasIotaRange =
+ requires(Range&& range, Value&& val) { std::ranges::iota(std::forward<Range>(range), std::forward<Value>(val)); };
+
+// Test constraints of the iterator/sentinel overload
+// ==================================================
+static_assert(HasIotaIter<int*, int*, int>);
+
+// !input_or_output_iterator<O>
+static_assert(!HasIotaIter<InputIteratorNotInputOrOutputIterator>);
+
+// !sentinel_for<S, O>
+static_assert(!HasIotaIter<int*, SentinelForNotSemiregular>);
+static_assert(!HasIotaIter<int*, SentinelForNotWeaklyEqualityComparableWith>);
+
+// !weakly_incrementable<T>
+static_assert(!HasIotaIter<int*, int*, WeaklyIncrementableNotMovable>);
+
+// !indirectly writable <O, T>
+static_assert(!HasIotaIter<OutputIteratorNotIndirectlyWritable, int*, int>);
+
+// Test constraints for the range overload
+// =======================================
+static_assert(HasIotaRange<UncheckedRange<int*>, int>);
+
+// !weakly_incrementable<T>
+static_assert(!HasIotaRange<UncheckedRange<int*>, WeaklyIncrementableNotMovable>);
+
+// !ranges::output_range<const _Tp&>
+static_assert(!HasIotaRange<UncheckedRange<int*>, OutputIteratorNotIndirectlyWritable>);
----------------
cjdb wrote:
> I don't think it's a big problem. You're basically asking to test the test, which doesn't work 99% of the time.
It sounds like it doesn't solve the problem at all and I think it is worth our attention. Tests need to be correct _on inspection_, and a static assert isn't offering us that in this case. This limits confidence in our test suite, and I'm not okay with that.
> OTOH `.verfiy.cpp` tests are extremely fragile and only work for the exact implementation we have.
Diagnostic text doesn't change all that frequently: Clang would have a serious problem if they did (cc @AaronBallman).
How frequently do we (libc++) need to update our existing verification tests?
> They also don't test that things _actually_ SFINAE away.
Are these static assertions actually testing that?
> Anyways, this would require discussion beyond the current patch, since that's how we've done it for all the other ranges algorithms.
We should be committed to doing things right the first time, not to remaining consistent with a status quo in need of change. If that means deviating from what's currently done, that's fine. We can have the discussion afterwards, using this PR as the pilot commit.
I'd really prefer to see this PR landed with maximum confidence in correctness, and also not block @jamesETsmith on a policy discussion.
https://github.com/llvm/llvm-project/pull/68494
More information about the libcxx-commits
mailing list