{ __i - __s } -> same_as<iter_difference_t<_Ip> >;
};
+// [iterator.concept.input]
+template<class _Ip>
+concept input_iterator =
+ input_or_output_iterator<_Ip> &&
+ indirectly_readable<_Ip> &&
+ requires { typename _ITER_CONCEPT<_Ip>; } &&
+ derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>;
+
// clang-format on
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
// [range.refinements], other range refinements
template <class _Tp>
+ concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp> >;
+
+ template <class _Tp>
concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp> >;
} // namespace ranges
template<class S, class I>
concept sized_sentinel_for = see below;
+// [iterator.concept.input], concept input_iterator
+template<class I>
+ concept input_iterator = see below; // since C++20
+
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
// [range.refinements], other range refinements
+ template<class T>
+ concept input_range = see below;
+
template <class _Tp>
concept common_range = see below;
}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+// XFAIL: msvc && clang
+
+// template<class T>
+// concept input_iterator;
+
+#include <iterator>
+
+#include <concepts>
+
+// clang-format off
+template<std::input_or_output_iterator I>
+requires std::indirectly_readable<I> &&
+ std::derived_from<std::_ITER_CONCEPT<I>, std::input_iterator_tag>
+[[nodiscard]] constexpr bool check_subsumption() {
+ return false;
+}
+
+template<std::input_iterator>
+[[nodiscard]] constexpr bool check_subsumption() {
+ return true;
+}
+// clang-format on
+
+static_assert(check_subsumption<int*>());
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(std::sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(!std::indirectly_writable<local_iterator, value_type>);
static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<local_iterator>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_local_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(!std::indirectly_writable<local_iterator, value_type>);
static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<local_iterator>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_local_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(!std::indirectly_writable<local_iterator, value_type>);
static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<local_iterator>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_local_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(std::sentinel_for<iterator, const_iterator>);
static_assert(!std::sentinel_for<iterator, local_iterator>);
static_assert(!std::sentinel_for<iterator, const_local_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::indirectly_readable<const_iterator>);
static_assert(!std::indirectly_writable<const_iterator, value_type>);
static_assert(std::sentinel_for<const_iterator, iterator>);
static_assert(!std::sentinel_for<const_iterator, local_iterator>);
static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::indirectly_readable<local_iterator>);
static_assert(std::incrementable<local_iterator>);
static_assert(!std::sentinel_for<local_iterator, const_iterator>);
static_assert(std::sentinel_for<local_iterator, local_iterator>);
static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<local_iterator>);
static_assert(std::indirectly_readable<const_local_iterator>);
static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(std::input_iterator<const_local_iterator>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
+static_assert(stdr::input_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
static_assert(stdr::common_range<range const>);
+static_assert(stdr::input_range<range const>);
static_assert(!std::sentinel_for<iterator, reverse_iterator>);
static_assert(std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::input_or_output_iterator<fs::directory_iterator>);
static_assert(std::sentinel_for<fs::directory_iterator, fs::directory_iterator>);
static_assert(!std::sized_sentinel_for<fs::directory_iterator, fs::directory_iterator>);
+static_assert(std::input_iterator<fs::directory_iterator>);
static_assert(std::indirectly_readable<fs::recursive_directory_iterator>);
static_assert(!std::indirectly_writable<fs::recursive_directory_iterator, value_type>);
static_assert(std::input_or_output_iterator<fs::recursive_directory_iterator>);
static_assert(std::sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
static_assert(!std::sized_sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
+static_assert(std::input_iterator<fs::recursive_directory_iterator>);
static_assert(std::same_as<stdr::iterator_t<fs::directory_iterator>, fs::directory_iterator>);
static_assert(stdr::common_range<fs::directory_iterator>);
+static_assert(stdr::input_range<fs::directory_iterator>);
static_assert(std::same_as<stdr::iterator_t<fs::directory_iterator const>, fs::directory_iterator>);
static_assert(stdr::common_range<fs::directory_iterator const>);
+static_assert(stdr::input_range<fs::directory_iterator const>);
static_assert(std::same_as<stdr::iterator_t<fs::recursive_directory_iterator>, fs::recursive_directory_iterator>);
static_assert(stdr::common_range<fs::recursive_directory_iterator>);
+static_assert(stdr::input_range<fs::directory_iterator>);
static_assert(std::same_as<stdr::iterator_t<fs::recursive_directory_iterator const>, fs::recursive_directory_iterator>);
static_assert(stdr::common_range<fs::recursive_directory_iterator const>);
+static_assert(stdr::input_range<fs::directory_iterator const>);
static_assert(std::same_as<stdr::iterator_t<fs::path>, fs::path::iterator>);
static_assert(stdr::common_range<fs::path>);
+static_assert(stdr::input_range<fs::path>);
static_assert(std::same_as<stdr::iterator_t<fs::path const>, fs::path::const_iterator>);
static_assert(stdr::common_range<fs::path const>);
+static_assert(stdr::input_range<fs::path const>);
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+// XFAIL: msvc && clang
+
+// template<class T>
+// concept input_iterator;
+
+#include <iterator>
+
+#include "test_iterators.h"
+
+static_assert(std::input_iterator<input_iterator<int*> >);
+static_assert(std::input_iterator<cpp20_input_iterator<int*> >);
+
+struct no_explicit_iter_concept {
+ using value_type = int;
+ using difference_type = std::ptrdiff_t;
+
+ no_explicit_iter_concept() = default;
+
+ no_explicit_iter_concept(no_explicit_iter_concept&&) = default;
+ no_explicit_iter_concept& operator=(no_explicit_iter_concept&&) = default;
+
+ no_explicit_iter_concept(no_explicit_iter_concept const&) = delete;
+ no_explicit_iter_concept& operator=(no_explicit_iter_concept const&) = delete;
+
+ value_type operator*() const;
+
+ no_explicit_iter_concept& operator++();
+ void operator++(int);
+};
+// ITER-CONCEPT is `random_access_iterator_tag` >:(
+static_assert(std::input_iterator<no_explicit_iter_concept>);
+
+static_assert(std::input_iterator<int*>);
+static_assert(std::input_iterator<int const*>);
+static_assert(std::input_iterator<int volatile*>);
+static_assert(std::input_iterator<int const volatile*>);
+
+struct not_weakly_incrementable {
+ using difference_type = std::ptrdiff_t;
+ using iterator_concept = std::input_iterator_tag;
+
+ not_weakly_incrementable() = default;
+
+ not_weakly_incrementable(not_weakly_incrementable&&) = default;
+ not_weakly_incrementable& operator=(not_weakly_incrementable&&) = default;
+
+ not_weakly_incrementable(not_weakly_incrementable const&) = delete;
+ not_weakly_incrementable& operator=(not_weakly_incrementable const&) = delete;
+
+ int operator*() const;
+
+ not_weakly_incrementable& operator++();
+};
+static_assert(!std::input_or_output_iterator<not_weakly_incrementable> &&
+ !std::input_iterator<not_weakly_incrementable>);
+
+struct not_indirectly_readable {
+ using difference_type = std::ptrdiff_t;
+ using iterator_concept = std::input_iterator_tag;
+
+ not_indirectly_readable() = default;
+
+ not_indirectly_readable(not_indirectly_readable&&) = default;
+ not_indirectly_readable& operator=(not_indirectly_readable&&) = default;
+
+ not_indirectly_readable(not_indirectly_readable const&) = delete;
+ not_indirectly_readable& operator=(not_indirectly_readable const&) = delete;
+
+ int operator*() const;
+
+ not_indirectly_readable& operator++();
+ void operator++(int);
+};
+static_assert(!std::indirectly_readable<not_indirectly_readable> && !std::input_iterator<not_indirectly_readable>);
+
+struct bad_iterator_category {
+ using value_type = int;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = void;
+
+ bad_iterator_category() = default;
+
+ bad_iterator_category(bad_iterator_category&&) = default;
+ bad_iterator_category& operator=(bad_iterator_category&&) = default;
+
+ bad_iterator_category(bad_iterator_category const&) = delete;
+ bad_iterator_category& operator=(bad_iterator_category const&) = delete;
+
+ value_type operator*() const;
+
+ bad_iterator_category& operator++();
+ void operator++(int);
+};
+static_assert(!std::input_iterator<bad_iterator_category>);
+
+struct bad_iterator_concept {
+ using value_type = int;
+ using difference_type = std::ptrdiff_t;
+ using iterator_concept = void*;
+
+ bad_iterator_concept() = default;
+
+ bad_iterator_concept(bad_iterator_concept&&) = default;
+ bad_iterator_concept& operator=(bad_iterator_concept&&) = default;
+
+ bad_iterator_concept(bad_iterator_concept const&) = delete;
+ bad_iterator_concept& operator=(bad_iterator_concept const&) = delete;
+
+ value_type operator*() const;
+
+ bad_iterator_concept& operator++();
+ void operator++(int);
+};
+static_assert(!std::input_iterator<bad_iterator_concept>);
--- /dev/null
+// Due to the need to check _ITER_CONCEPT, this test is located in `test/libcxx/iterators/iterator.concepts/iterator.concept.input/subsumption.compile.pass.cpp`.
static_assert(!std::input_or_output_iterator<iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_iterator<iterator>);
static_assert(!std::input_or_output_iterator<iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_iterator<iterator>);
static_assert(!std::weakly_incrementable<iterator>);
static_assert(!std::input_or_output_iterator<iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
+static_assert(!std::input_iterator<iterator>);
static_assert(std::input_or_output_iterator<iterator>);
static_assert(std::sentinel_for<iterator, iterator>);
static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::input_or_output_iterator<iterator>);
static_assert(std::sentinel_for<iterator, iterator>);
static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_iterator<iterator>);
using other_iterator = std::reverse_iterator<float*>;
static_assert(std::sentinel_for<iterator, other_iterator>);
static_assert(std::input_or_output_iterator<iterator>);
static_assert(std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(std::input_or_output_iterator<iterator>);
static_assert(std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::input_iterator<iterator>);
static_assert(!std::input_or_output_iterator<iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_iterator<iterator>);
static_assert(!std::input_or_output_iterator<iterator>);
static_assert(!std::sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::input_iterator<iterator>);
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+// XFAIL: msvc && clang
+
+// template<range _Rp>
+// concept input_range;
+
+#include <ranges>
+
+#include "test_range.h"
+
+namespace stdr = std::ranges;
+
+static_assert(stdr::input_range<test_range<input_iterator> >);
+static_assert(stdr::input_range<test_range<input_iterator> const>);
+
+static_assert(stdr::input_range<test_range<cpp20_input_iterator> >);
+static_assert(stdr::input_range<test_range<cpp20_input_iterator> const>);
+
+static_assert(stdr::input_range<test_non_const_range<input_iterator> >);
+static_assert(stdr::input_range<test_non_const_range<cpp20_input_iterator> >);
+
+static_assert(!stdr::input_range<test_non_const_range<input_iterator> const>);
+static_assert(!stdr::input_range<test_non_const_range<cpp20_input_iterator> const>);
+
+static_assert(stdr::input_range<test_common_range<input_iterator> >);
+static_assert(!stdr::input_range<test_common_range<cpp20_input_iterator> >);
+
+static_assert(stdr::input_range<test_common_range<input_iterator> const>);
+static_assert(!stdr::input_range<test_common_range<cpp20_input_iterator> const>);
+
+static_assert(stdr::input_range<test_non_const_common_range<input_iterator> >);
+static_assert(!stdr::input_range<test_non_const_common_range<cpp20_input_iterator> >);
+
+static_assert(!stdr::input_range<test_non_const_common_range<input_iterator> const>);
+static_assert(!stdr::input_range<test_non_const_common_range<cpp20_input_iterator> const>);
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+// XFAIL: msvc && clang
+
+// template<class T>
+// concept input_iterator;
+
+#include <ranges>
+
+#include <iterator>
+
+struct range {
+ int* begin();
+ int* end();
+};
+
+// clang-format off
+template<std::ranges::range R>
+requires std::input_iterator<std::ranges::iterator_t<R> >
+[[nodiscard]] constexpr bool check_input_range_subsumption() {
+ return false;
+}
+
+template<std::ranges::input_range>
+requires true
+[[nodiscard]] constexpr bool check_input_range_subsumption() {
+ return true;
+}
+// clang-format on
+
+static_assert(check_input_range_subsumption<range>());
static_assert(std::input_or_output_iterator<std::cregex_iterator>);
static_assert(std::sentinel_for<std::cregex_iterator, std::cregex_iterator>);
static_assert(!std::sized_sentinel_for<std::cregex_iterator, std::cregex_iterator>);
+static_assert(std::input_iterator<std::cregex_iterator>);
static_assert(std::input_or_output_iterator<std::cregex_token_iterator>);
static_assert(std::sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
static_assert(!std::sized_sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
+static_assert(std::input_iterator<std::cregex_token_iterator>);
static_assert(std::same_as<stdr::iterator_t<std::cmatch>, std::cmatch::iterator>);
static_assert(stdr::common_range<std::cmatch>);
+static_assert(stdr::input_range<std::cmatch>);
static_assert(std::same_as<stdr::iterator_t<std::cmatch const>, std::cmatch::const_iterator>);
static_assert(stdr::common_range<std::cmatch const>);
+static_assert(stdr::input_range<std::cmatch const>);
static_assert(std::same_as<stdr::iterator_t<std::string>, std::string::iterator>);
static_assert(stdr::common_range<std::string>);
+static_assert(stdr::input_range<std::string>);
static_assert(std::same_as<stdr::iterator_t<std::string const>, std::string::const_iterator>);
static_assert(stdr::common_range<std::string const>);
+static_assert(stdr::input_range<std::string const>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);
static_assert(std::same_as<stdr::iterator_t<std::string_view>, std::string_view::iterator>);
static_assert(stdr::common_range<std::string_view>);
+static_assert(stdr::input_range<std::string_view>);
static_assert(std::same_as<stdr::iterator_t<std::string_view const>, std::string_view::const_iterator>);
static_assert(stdr::common_range<std::string_view const>);
+static_assert(stdr::input_range<std::string_view const>);
static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::input_iterator<const_iterator>);
bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
{ return !a.operator==(b); }
+#ifdef TEST_SUPPORTS_RANGES
+
+template <class I>
+struct cpp20_input_iterator {
+ using value_type = std::iter_value_t<I>;
+ using difference_type = std::iter_difference_t<I>;
+ using iterator_concept = std::input_iterator_tag;
+
+ cpp20_input_iterator() = default;
+
+ cpp20_input_iterator(cpp20_input_iterator&&) = default;
+ cpp20_input_iterator& operator=(cpp20_input_iterator&&) = default;
+
+ cpp20_input_iterator(cpp20_input_iterator const&) = delete;
+ cpp20_input_iterator& operator=(cpp20_input_iterator const&) = delete;
+
+ explicit constexpr cpp20_input_iterator(I base) : base_(std::move(base)) {}
+
+ constexpr decltype(auto) operator*() const { return *base_; }
+
+ cpp20_input_iterator& operator++() {
+ ++base_;
+ return *this;
+ }
+
+ void operator++(int) { ++base_; }
+
+ [[nodiscard]] I const& base() const& { return base_; }
+
+ [[nodiscard]] I base() && { return std::move(base_); }
+
+private:
+ I base_ = I();
+};
+
+#endif // TEST_STD_VER > 17 && defined(__cpp_lib_concepts)
+
#undef DELETE_FUNCTION
#endif // ITERATORS_H
#define LIBCPP_ONLY(...) ((void)0)
#endif
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+#define TEST_SUPPORTS_RANGES
+#endif
+
#define TEST_IGNORE_NODISCARD (void)
namespace test_macros_detail {
#endif
struct sentinel {
- bool operator==(std::input_or_output_iterator auto) const;
+ bool operator==(std::input_or_output_iterator auto const&) const;
};
// clang-format off