[libcxx-commits] [libcxx] [libc++] Implement ranges::iota (PR #68494)
Aaron Ballman via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 6 05:46:27 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>);
----------------
AaronBallman wrote:
> Right, testing the semantics is important, and knowing that you're testing the right semantics is what the diagnostic wording offers in this case. I'm not as concerned about the specifics of the text, only that it communicates "hey, we're testing what you think we're testing" to the reader.
Sort of yes, sort of no. In order to test that you're getting the right semantics, you need to test against specific diagnostic wording otherwise you run the risk of passing the test because of an unrelated but similarly worded diagnostic. Once you're testing against sufficiently specific diagnostic wording, it becomes more of a maintenance burden should Clang update that diagnostic wording (which is something we do somewhat frequently, but we have 1000s of warnings, so it's a statistics game as to whether any given diagnostic is likely to be hit). So I think it's easier for everyone to maintain if the test can test behavior rather than diagnostic wording whenever possible even if the tests are more complex, but there are certainly cases where it's not possible (e.g., a deprecation warning can really only be tested by looking for the diagnostic to be emitted).
https://github.com/llvm/llvm-project/pull/68494
More information about the libcxx-commits
mailing list