[ranges.primitives],"size, empty, data, and cdata",[iterator.concepts],Zoe Carver,,
[range.range],,[range.access],,,
[range.sized],,"[range.primitives], [range.range]",,,
-[range.view],View and enable_view,[range.range],,,
+[range.view],View and enable_view,[range.range],Louis Dionne,https://reviews.llvm.org/D101547,✅
[range.refinements],"OutputRange, InputRange, ForwardRange, BidirectionalRange, RandomAccessRange, ContiguousRange, CommonRange, ViewableRange","[ranges.syn]: pt. 2, [range.range]",Christopher Di Bella,"input_range: `D100271 <https://llvm.org/D100271>`_
forward_range: `D100275 <https://llvm.org/D100275>`_
bidirectional_range: `D100278 <https://llvm.org/D100278>`_",
__ranges/access.h
__ranges/concepts.h
__ranges/enable_borrowed_range.h
+ __ranges/view.h
__split_buffer
__sso_allocator
__std_stream
--- /dev/null
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_VIEW_H
+#define _LIBCPP___RANGES_VIEW_H
+
+#include <__config>
+#include <__ranges/concepts.h>
+#include <concepts>
+
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+namespace ranges {
+
+struct view_base { };
+
+template <class _Tp>
+inline constexpr bool enable_view = derived_from<_Tp, view_base>;
+
+template <class _Tp>
+concept view =
+ range<_Tp> &&
+ movable<_Tp> &&
+ default_initializable<_Tp> &&
+ enable_view<_Tp>;
+
+} // end namespace ranges
+
+#endif // !_LIBCPP_HAS_NO_RANGES
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_VIEW_H
template<range R>
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
+ // [range.view], views
+ template<class T>
+ inline constexpr bool enable_view = ...;
+
+ struct view_base { };
+
+ template<class T>
+ concept view = ...;
+
// [range.refinements], other range refinements
template<class T>
concept input_range = see below;
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/view.h>
#include <compare> // Required by the standard.
#include <initializer_list> // Required by the standard.
#include <iterator> // Required by the standard.
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<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(!stdr::view<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(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(stdr::common_range<range>);
static_assert(stdr::forward_range<range>);
static_assert(!stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::forward_range<range const>);
static_assert(!stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(stdr::common_range<range>);
static_assert(stdr::forward_range<range>);
static_assert(!stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::forward_range<range const>);
static_assert(!stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(stdr::common_range<range>);
static_assert(stdr::forward_range<range>);
static_assert(!stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::forward_range<range const>);
static_assert(!stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(stdr::common_range<range>);
static_assert(stdr::forward_range<range>);
static_assert(!stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::forward_range<range const>);
static_assert(!stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(stdr::common_range<range>);
static_assert(stdr::forward_range<range>);
static_assert(!stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::forward_range<range const>);
static_assert(!stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::bidirectional_range<range>);
+static_assert(!stdr::view<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::bidirectional_range<range const>);
+static_assert(!stdr::view<range const>);
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(!stdr::view<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(!stdr::view<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(stdr::input_range<fs::recursive_directory_iterator>);
+static_assert(!stdr::view<fs::recursive_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(stdr::input_range<fs::recursive_directory_iterator const>);
+static_assert(!stdr::view<fs::recursive_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::bidirectional_range<fs::path>);
+static_assert(!stdr::view<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::bidirectional_range<fs::path const>);
+static_assert(!stdr::view<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
+
+// <ranges>
+
+// template<class T>
+// inline constexpr bool enable_view = ...;
+
+#include <ranges>
+
+#include "test_macros.h"
+
+// Doesn't derive from view_base
+struct Empty { };
+static_assert(!std::ranges::enable_view<Empty>);
+
+// Derives from view_base, but privately
+struct PrivateViewBase : private std::ranges::view_base { };
+static_assert(!std::ranges::enable_view<PrivateViewBase>);
+
+// Derives from view_base, but specializes enable_view to false
+struct EnableViewFalse : std::ranges::view_base { };
+namespace std::ranges { template <> constexpr bool enable_view<EnableViewFalse> = false; }
+static_assert(!std::ranges::enable_view<EnableViewFalse>);
+
+
+// Derives from view_base
+struct PublicViewBase : std::ranges::view_base { };
+static_assert(std::ranges::enable_view<PublicViewBase>);
+
+// Does not derive from view_base, but specializes enable_view to true
+struct EnableViewTrue { };
+namespace std::ranges { template <> constexpr bool enable_view<EnableViewTrue> = true; }
+static_assert(std::ranges::enable_view<EnableViewTrue>);
+
+
+// Make sure that enable_view is a bool, not some other contextually-convertible-to-bool type.
+ASSERT_SAME_TYPE(decltype(std::ranges::enable_view<Empty>), const bool);
+ASSERT_SAME_TYPE(decltype(std::ranges::enable_view<PublicViewBase>), const bool);
--- /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
+
+// <ranges>
+
+// template<class T>
+// concept view = ...;
+
+#include <ranges>
+
+#include "test_macros.h"
+
+// The type would be a view, but it's not moveable.
+struct NotMoveable : std::ranges::view_base {
+ NotMoveable() = default;
+ NotMoveable(NotMoveable&&) = delete;
+ NotMoveable& operator=(NotMoveable&&) = delete;
+ friend int* begin(NotMoveable&);
+ friend int* begin(NotMoveable const&);
+ friend int* end(NotMoveable&);
+ friend int* end(NotMoveable const&);
+};
+static_assert(std::ranges::range<NotMoveable>);
+static_assert(!std::movable<NotMoveable>);
+static_assert(std::default_initializable<NotMoveable>);
+static_assert(std::ranges::enable_view<NotMoveable>);
+static_assert(!std::ranges::view<NotMoveable>);
+
+// The type would be a view, but it's not default initializable
+struct NotDefaultInit : std::ranges::view_base {
+ NotDefaultInit() = delete;
+ friend int* begin(NotDefaultInit&);
+ friend int* begin(NotDefaultInit const&);
+ friend int* end(NotDefaultInit&);
+ friend int* end(NotDefaultInit const&);
+};
+static_assert(std::ranges::range<NotDefaultInit>);
+static_assert(std::movable<NotDefaultInit>);
+static_assert(!std::default_initializable<NotDefaultInit>);
+static_assert(std::ranges::enable_view<NotDefaultInit>);
+static_assert(!std::ranges::view<NotDefaultInit>);
+
+// The type would be a view, but it doesn't enable it with enable_view
+struct NotExplicitlyEnabled {
+ NotExplicitlyEnabled() = default;
+ NotExplicitlyEnabled(NotExplicitlyEnabled&&) = default;
+ NotExplicitlyEnabled& operator=(NotExplicitlyEnabled&&) = default;
+ friend int* begin(NotExplicitlyEnabled&);
+ friend int* begin(NotExplicitlyEnabled const&);
+ friend int* end(NotExplicitlyEnabled&);
+ friend int* end(NotExplicitlyEnabled const&);
+};
+static_assert(std::ranges::range<NotExplicitlyEnabled>);
+static_assert(std::movable<NotExplicitlyEnabled>);
+static_assert(std::default_initializable<NotExplicitlyEnabled>);
+static_assert(!std::ranges::enable_view<NotExplicitlyEnabled>);
+static_assert(!std::ranges::view<NotExplicitlyEnabled>);
+
+// The type has everything else, but it's not a range
+struct NotARange : std::ranges::view_base {
+ NotARange() = default;
+ NotARange(NotARange&&) = default;
+ NotARange& operator=(NotARange&&) = default;
+};
+static_assert(!std::ranges::range<NotARange>);
+static_assert(std::movable<NotARange>);
+static_assert(std::default_initializable<NotARange>);
+static_assert(std::ranges::enable_view<NotARange>);
+static_assert(!std::ranges::view<NotARange>);
+
+// The type satisfies all requirements
+struct View : std::ranges::view_base {
+ View() = default;
+ View(View&&) = default;
+ View& operator=(View&&) = default;
+ friend int* begin(View&);
+ friend int* begin(View const&);
+ friend int* end(View&);
+ friend int* end(View const&);
+};
+static_assert(std::ranges::range<View>);
+static_assert(std::movable<View>);
+static_assert(std::default_initializable<View>);
+static_assert(std::ranges::enable_view<View>);
+static_assert(std::ranges::view<View>);
--- /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
+
+// <ranges>
+
+// template<class T>
+// concept view = ...;
+
+#include <ranges>
+
+#include "test_macros.h"
+
+struct View : std::ranges::view_base {
+ View() = default;
+ View(View&&) = default;
+ View& operator=(View&&) = default;
+ friend int* begin(View&);
+ friend int* begin(View const&);
+ friend int* end(View&);
+ friend int* end(View const&);
+};
+
+namespace subsume_range {
+ template <std::ranges::view>
+ constexpr bool test() { return true; }
+ template <std::ranges::range>
+ constexpr bool test() { return false; }
+ static_assert(test<View>());
+}
+
+namespace subsume_movable {
+ template <std::ranges::view>
+ constexpr bool test() { return true; }
+ template <std::movable>
+ constexpr bool test() { return false; }
+ static_assert(test<View>());
+}
+
+namespace subsume_default_initializable {
+ template <std::ranges::view>
+ constexpr bool test() { return true; }
+ template <std::default_initializable>
+ constexpr bool test() { return false; }
+ static_assert(test<View>());
+}
--- /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
+
+// <ranges>
+
+// struct view_base { };
+
+#include <ranges>
+#include <type_traits>
+
+static_assert(std::is_empty_v<std::ranges::view_base>);
+static_assert(std::is_trivial_v<std::ranges::view_base>);
+
+// Make sure we can inherit from it, as it's intended (that wouldn't be the
+// case if e.g. it was marked as final).
+struct View : std::ranges::view_base { };
static_assert(std::same_as<stdr::iterator_t<std::cmatch>, std::cmatch::iterator>);
static_assert(stdr::common_range<std::cmatch>);
static_assert(stdr::bidirectional_range<std::cmatch>);
+static_assert(!stdr::view<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::bidirectional_range<std::cmatch const>);
+static_assert(!stdr::view<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::bidirectional_range<std::string>);
+static_assert(!stdr::view<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::bidirectional_range<std::string const>);
+static_assert(!stdr::view<std::string const>);
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::bidirectional_range<std::string_view>);
+static_assert(!stdr::view<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::bidirectional_range<std::string_view const>);
+static_assert(!stdr::view<std::string_view const>);