[libc++] Implement views::all_t and ranges::viewable_range

Differential Revision: https://reviews.llvm.org/D105816
This commit is contained in:
Louis Dionne 2021-07-12 09:55:00 -04:00
parent 0c3401c86e
commit 3001b48d76
30 changed files with 255 additions and 11 deletions

View File

@ -119,8 +119,8 @@ Section,Description,Dependencies,Assignee,Complete
| `ranges::bidirectional_range <https://llvm.org/D100278>`_
| `ranges::random_access_range <https://llvm.org/D101316>`_
| ranges::contiguous_range
| `ranges::common_range <https://llvm.org/D100269>`_
| ranges::viewable_range",[range.range],Christopher Di Bella,In progress
| `ranges::common_range <https://llvm.org/D100269>`_",[range.range],Christopher Di Bella,✅
`[range.refinements]`_,`ranges::viewable_range <https://reviews.llvm.org/D105816>`_,[range.range],Louis Dionne,✅
`[range.utility.helpers] <http://wg21.link/range.utility.helpers>`_,"| *simple-view*
| *has-arrow*
| *not-same-as*","| [range.range]

1 Section Description Dependencies Assignee Complete
119
120
121
122
123
124
125
126

View File

@ -17,6 +17,7 @@
#include <__ranges/ref_view.h>
#include <__ranges/subrange.h>
#include <__utility/__decay_copy.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
#include <type_traits>
@ -68,6 +69,9 @@ inline namespace __cpo {
inline constexpr auto all = __all::__fn{};
} // namespace __cpo
template<ranges::viewable_range _Range>
using all_t = decltype(views::all(declval<_Range>()));
} // namespace views
#endif // !defined(_LIBCPP_HAS_NO_RANGES)

View File

@ -112,6 +112,13 @@ namespace ranges {
template <class _Tp>
concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp> >;
template<class _Tp>
concept viewable_range =
range<_Tp> && (
(view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) ||
(!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>)
);
} // namespace ranges
#endif // !defined(_LIBCPP_HAS_NO_RANGES)

View File

@ -140,9 +140,7 @@ public:
};
template<class _Range>
drop_view(_Range&&, range_difference_t<_Range>)
// TODO: this is just recreating all_t.
-> drop_view<decltype(views::all(std::declval<_Range>()))>;
drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>;
template<class _Tp>
inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;

View File

@ -10,10 +10,11 @@
#define _LIBCPP___RANGES_TRANSFORM_VIEW_H
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__iterator/concepts.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
#include <__ranges/copyable_box.h>
#include <__ranges/empty.h>
@ -93,10 +94,8 @@ public:
constexpr auto size() const requires sized_range<const _View> { return ranges::size(__base_); }
};
// TODO: replace the decltype with all_t when that's implemented.
template<class _Range, class _Fn>
transform_view(_Range&&, _Fn)
-> transform_view<decltype(views::all(std::declval<_Range>())), _Fn>;
transform_view(_Range&&, _Fn) -> transform_view<views::all_t<_Range>, _Fn>;
template<class _View>
struct __transform_view_iterator_concept { using type = input_iterator_tag; };

View File

@ -50,7 +50,7 @@ namespace std::ranges {
template<range R>
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;
// [range.sized]
// [range.sized], sized ranges
template<class>
inline constexpr bool disable_sized_range = false;
@ -85,6 +85,9 @@ namespace std::ranges {
template <class _Tp>
concept common_range = see below;
template<class T>
concept viewable_range = see below;
// [view.interface], class template view_interface
template<class D>
requires is_class_v<D> && same_as<D, remove_cv_t<D>>
@ -95,6 +98,21 @@ namespace std::ranges {
requires is_object_v<T>
class empty_view;
// [range.all], all view
namespace views {
inline constexpr unspecified all = unspecified;
template<viewable_range R>
using all_t = decltype(all(declval<R>()));
}
template<range R>
requires is_object_v<R>
class ref_view;
template<class T>
inline constexpr bool enable_borrowed_range<ref_view<T>> = true;
// [range.drop], drop view
template<view V>
class drop_view;

View File

@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -28,6 +28,7 @@ static_assert(stdr::input_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::bidirectional_range<range const>);
@ -37,3 +38,4 @@ static_assert(stdr::input_range<range>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(stdr::random_access_range<range>);
static_assert(stdr::contiguous_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(!stdr::view<range const>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
@ -35,3 +36,4 @@ static_assert(stdr::random_access_range<range const>);
static_assert(stdr::contiguous_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::contiguous_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(!stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(!stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::view<range>);
static_assert(!stdr::random_access_range<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::view<range const>);
static_assert(!stdr::random_access_range<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::contiguous_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(stdr::contiguous_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(!stdr::bidirectional_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::sized_range<range>);
static_assert(!stdr::borrowed_range<range>);
static_assert(!stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(!stdr::bidirectional_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(!stdr::borrowed_range<range const>);
static_assert(!stdr::viewable_range<range const>);

View File

@ -27,6 +27,7 @@ static_assert(stdr::contiguous_range<range>);
static_assert(stdr::view<range> && stdr::enable_view<range>);
static_assert(stdr::sized_range<range>);
static_assert(stdr::borrowed_range<range>);
static_assert(stdr::viewable_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
static_assert(stdr::common_range<range const>);
@ -35,3 +36,4 @@ static_assert(stdr::contiguous_range<range const>);
static_assert(!stdr::view<range const> && !stdr::enable_view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(stdr::borrowed_range<range const>);
static_assert(stdr::viewable_range<range const>);

View File

@ -26,6 +26,7 @@ static_assert(stdr::input_range<fs::directory_iterator>);
static_assert(!stdr::view<fs::directory_iterator>);
static_assert(!stdr::sized_range<fs::directory_iterator>);
static_assert(!stdr::borrowed_range<fs::directory_iterator>);
static_assert(!stdr::viewable_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>);
@ -33,6 +34,7 @@ static_assert(stdr::input_range<fs::directory_iterator const>);
static_assert(!stdr::view<fs::directory_iterator const>);
static_assert(!stdr::sized_range<fs::directory_iterator const>);
static_assert(!stdr::borrowed_range<fs::directory_iterator const>);
static_assert(!stdr::viewable_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>);
@ -40,6 +42,7 @@ static_assert(stdr::input_range<fs::recursive_directory_iterator>);
static_assert(!stdr::view<fs::recursive_directory_iterator>);
static_assert(!stdr::sized_range<fs::recursive_directory_iterator>);
static_assert(!stdr::borrowed_range<fs::recursive_directory_iterator>);
static_assert(!stdr::viewable_range<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>);
@ -47,3 +50,4 @@ static_assert(stdr::input_range<fs::recursive_directory_iterator const>);
static_assert(!stdr::view<fs::recursive_directory_iterator const>);
static_assert(!stdr::sized_range<fs::recursive_directory_iterator const>);
static_assert(!stdr::borrowed_range<fs::recursive_directory_iterator const>);
static_assert(!stdr::viewable_range<fs::recursive_directory_iterator const>);

View File

@ -26,6 +26,7 @@ static_assert(!stdr::view<fs::path>);
static_assert(!stdr::random_access_range<fs::path>);
static_assert(!stdr::sized_range<fs::path>);
static_assert(!stdr::borrowed_range<fs::path>);
static_assert(!stdr::viewable_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>);
@ -34,3 +35,4 @@ static_assert(!stdr::view<fs::path const>);
static_assert(!stdr::random_access_range<fs::path const>);
static_assert(!stdr::sized_range<fs::path const>);
static_assert(!stdr::borrowed_range<fs::path const>);
static_assert(!stdr::viewable_range<fs::path const>);

View File

@ -0,0 +1,41 @@
//===----------------------------------------------------------------------===//
//
// 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
// template<viewable_range R>
// using all_t = decltype(views::all(declval<R>()));
#include <ranges>
#include "test_iterators.h"
#include "test_range.h"
struct View : test_range<cpp20_input_iterator>, std::ranges::view_base { };
struct Range : test_range<cpp20_input_iterator> { };
struct BorrowableRange : test_range<forward_iterator> { };
template<>
inline constexpr bool std::ranges::enable_borrowed_range<BorrowableRange> = true;
// When T is a view, returns decay-copy(T)
ASSERT_SAME_TYPE(std::views::all_t<View>, View);
ASSERT_SAME_TYPE(std::views::all_t<View&>, View);
ASSERT_SAME_TYPE(std::views::all_t<View const>, View);
ASSERT_SAME_TYPE(std::views::all_t<View const&>, View);
// Otherwise, when T is a reference to a range, returns ref_view<T>
ASSERT_SAME_TYPE(std::views::all_t<Range&>, std::ranges::ref_view<Range>);
ASSERT_SAME_TYPE(std::views::all_t<Range const&>, std::ranges::ref_view<Range const>);
ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange&>, std::ranges::ref_view<BorrowableRange>);
ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange const&>, std::ranges::ref_view<BorrowableRange const>);
// Otherwise, returns subrange<iterator_t<T>, sentinel_t<R>>
ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange>, std::ranges::subrange<forward_iterator<int*>, sentinel>);
ASSERT_SAME_TYPE(std::views::all_t<BorrowableRange const>, std::ranges::subrange<forward_iterator<int const*>, sentinel>);

View File

@ -10,7 +10,9 @@
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// std::ranges::ref_view
// template<range R>
// requires is_object_v<R>
// class ref_view;
#include <ranges>

View File

@ -0,0 +1,133 @@
//===----------------------------------------------------------------------===//
//
// 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
// template<class R>
// concept viewable_range;
#include <ranges>
#include <type_traits>
#include "test_iterators.h"
#include "test_range.h"
// The constraints we have in viewable_range are:
// range<T>
// view<remove_cvref_t<T>>
// constructible_from<remove_cvref_t<T>, T>
// borrowed_range<T>
//
// We test all the relevant combinations of satisfying/not satisfying those constraints.
// viewable_range<T> is not satisfied for (range=false, view=*, constructible_from=*, borrowed_range=*)
struct T1 { };
static_assert(!std::ranges::range<T1>);
static_assert(!std::ranges::viewable_range<T1>);
static_assert(!std::ranges::viewable_range<T1&>);
static_assert(!std::ranges::viewable_range<T1 const>);
static_assert(!std::ranges::viewable_range<T1 const&>);
// viewable_range<T> is satisfied for (range=true, view=true, constructible_from=true, borrowed_range=true)
struct T2 : test_range<cpp20_input_iterator>, std::ranges::view_base {
T2(T2 const&) = default;
};
template<> constexpr bool std::ranges::enable_borrowed_range<T2> = true;
static_assert(std::ranges::range<T2>);
static_assert(std::ranges::view<T2>);
static_assert(std::constructible_from<T2, T2>);
static_assert(std::ranges::borrowed_range<T2>);
static_assert(std::ranges::viewable_range<T2>);
static_assert(std::ranges::viewable_range<T2&>);
static_assert(std::ranges::viewable_range<T2 const>);
static_assert(std::ranges::viewable_range<T2 const&>);
// viewable_range<T> is satisfied for (range=true, view=true, constructible_from=true, borrowed_range=false)
struct T3 : test_range<cpp20_input_iterator>, std::ranges::view_base {
T3(T3 const&) = default;
};
template<> constexpr bool std::ranges::enable_borrowed_range<T3> = false;
static_assert(std::ranges::range<T3>);
static_assert(std::ranges::view<T3>);
static_assert(std::constructible_from<T3, T3>);
static_assert(!std::ranges::borrowed_range<T3>);
static_assert(std::ranges::viewable_range<T3>);
static_assert(std::ranges::viewable_range<T3&>);
static_assert(std::ranges::viewable_range<T3 const>);
static_assert(std::ranges::viewable_range<T3 const&>);
// viewable_range<T> is not satisfied for (range=true, view=true, constructible_from=false, borrowed_range=true)
struct T4 : test_range<cpp20_input_iterator>, std::ranges::view_base {
T4(T4 const&) = delete;
T4(T4&&) = default; // necessary to model view
T4& operator=(T4&&) = default; // necessary to model view
};
static_assert(std::ranges::range<T4 const&>);
static_assert(std::ranges::view<std::remove_cvref_t<T4 const&>>);
static_assert(!std::constructible_from<std::remove_cvref_t<T4 const&>, T4 const&>);
static_assert(std::ranges::borrowed_range<T4 const&>);
static_assert(!std::ranges::viewable_range<T4 const&>);
// A type that satisfies (range=true, view=true, constructible_from=false, borrowed_range=false) can't be formed
// viewable_range<T> is satisfied for (range=true, view=false, constructible_from=true, borrowed_range=true)
struct T5 : test_range<cpp20_input_iterator> { };
template<> constexpr bool std::ranges::enable_borrowed_range<T5> = true;
static_assert(std::ranges::range<T5>);
static_assert(!std::ranges::view<T5>);
static_assert(std::constructible_from<T5, T5>);
static_assert(std::ranges::borrowed_range<T5>);
static_assert(std::ranges::viewable_range<T5>);
// viewable_range<T> is not satisfied for (range=true, view=false, constructible_from=true, borrowed_range=false)
struct T6 : test_range<cpp20_input_iterator> { };
template<> constexpr bool std::ranges::enable_borrowed_range<T6> = false;
static_assert(std::ranges::range<T6>);
static_assert(!std::ranges::view<T6>);
static_assert(std::constructible_from<T6, T6>);
static_assert(!std::ranges::borrowed_range<T6>);
static_assert(!std::ranges::viewable_range<T6>);
// viewable_range<T> is satisfied for (range=true, view=false, constructible_from=false, borrowed_range=true)
struct T7 : test_range<cpp20_input_iterator> {
T7(T7 const&) = delete;
};
static_assert(std::ranges::range<T7&>);
static_assert(!std::ranges::view<std::remove_cvref_t<T7&>>);
static_assert(!std::constructible_from<std::remove_cvref_t<T7&>, T7&>);
static_assert(std::ranges::borrowed_range<T7&>);
static_assert(std::ranges::viewable_range<T7&>);
// A type that satisfies (range=true, view=false, constructible_from=false, borrowed_range=false) can't be formed
struct T8 : test_range<cpp20_input_iterator> {
T8(T8 const&) = delete;
};
static_assert(std::ranges::range<T8>);
static_assert(!std::ranges::view<T8>);
static_assert(!std::constructible_from<T8, T8>);
static_assert(!std::ranges::borrowed_range<T8>);
static_assert(!std::ranges::viewable_range<T8>);
// Test with a few degenerate types
static_assert(!std::ranges::viewable_range<void>);
static_assert(!std::ranges::viewable_range<int>);
static_assert(!std::ranges::viewable_range<int (*)(char)>);
static_assert(!std::ranges::viewable_range<int[]>);
static_assert(!std::ranges::viewable_range<int[10]>);
static_assert(!std::ranges::viewable_range<int(&)[]>); // unbounded array is not a range
static_assert( std::ranges::viewable_range<int(&)[10]>);

View File

@ -26,6 +26,7 @@ static_assert(stdr::contiguous_range<std::cmatch>);
static_assert(!stdr::view<std::cmatch>);
static_assert(stdr::sized_range<std::cmatch>);
static_assert(!stdr::borrowed_range<std::cmatch>);
static_assert(!stdr::viewable_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>);
@ -34,3 +35,4 @@ static_assert(stdr::contiguous_range<std::cmatch const>);
static_assert(!stdr::view<std::cmatch const>);
static_assert(stdr::sized_range<std::cmatch const>);
static_assert(!stdr::borrowed_range<std::cmatch const>);
static_assert(!stdr::viewable_range<std::cmatch const>);

View File

@ -26,6 +26,7 @@ static_assert(stdr::contiguous_range<std::string>);
static_assert(!stdr::view<std::string>);
static_assert(stdr::sized_range<std::string>);
static_assert(!stdr::borrowed_range<std::string>);
static_assert(!stdr::viewable_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>);
@ -34,3 +35,4 @@ static_assert(stdr::contiguous_range<std::string const>);
static_assert(!stdr::view<std::string const>);
static_assert(stdr::sized_range<std::string const>);
static_assert(!stdr::borrowed_range<std::string const>);
static_assert(!stdr::viewable_range<std::string const>);

View File

@ -26,6 +26,7 @@ static_assert(stdr::contiguous_range<std::string_view>);
static_assert(stdr::view<std::string_view> && stdr::enable_view<std::string_view>);
static_assert(stdr::sized_range<std::string_view>);
static_assert(stdr::borrowed_range<std::string_view>);
static_assert(stdr::viewable_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>);
@ -34,3 +35,4 @@ static_assert(stdr::contiguous_range<std::string_view const>);
static_assert(!stdr::view<std::string_view const> && !stdr::enable_view<std::string_view const>);
static_assert(stdr::sized_range<std::string_view const>);
static_assert(stdr::borrowed_range<std::string_view const>);
static_assert(stdr::viewable_range<std::string_view const>);