forked from OSchip/llvm-project
[libcxx][ranges] Add ranges::take_view.
Differential Revision: https://reviews.llvm.org/D106507
This commit is contained in:
parent
f623dc9a8c
commit
0f4b41e038
|
@ -139,7 +139,7 @@ Section,Description,Dependencies,Assignee,Complete
|
|||
`[range.filter] <http://wg21.link/range.filter>`_,filter_view,[range.all],Louis Dionne,Not started
|
||||
`[range.transform] <http://wg21.link/range.transform>`_,`transform_view <https://llvm.org/D103056>`_,[range.all],Zoe Carver,✅
|
||||
`[range.iota] <http://wg21.link/range.iota>`_,iota_view,[range.all],Louis Dionne,Not started
|
||||
`[range.take] <http://wg21.link/range.take>`_,take_view,[range.all],Zoe Carver,In Progress
|
||||
`[range.take] <http://wg21.link/range.take>`_,take_view,[range.all],Zoe Carver,✅
|
||||
`[range.join] <http://wg21.link/range.join>`_,join_view,[range.all],Christopher Di Bella,Not started
|
||||
`[range.empty] <http://wg21.link/range.empty>`_,`empty_view <https://llvm.org/D103208>`_,[view.interface],Zoe Carver,✅
|
||||
`[range.single] <http://wg21.link/range.single>`_,single_view,[view.interface],Zoe Carver,In Progress
|
||||
|
|
|
|
@ -197,6 +197,7 @@ set(files
|
|||
__ranges/enable_view.h
|
||||
__ranges/non_propagating_cache.h
|
||||
__ranges/ref_view.h
|
||||
__ranges/take_view.h
|
||||
__ranges/size.h
|
||||
__ranges/subrange.h
|
||||
__ranges/transform_view.h
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
// -*- 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_TAKE_VIEW_H
|
||||
#define _LIBCPP___RANGES_TAKE_VIEW_H
|
||||
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/counted_iterator.h>
|
||||
#include <__iterator/default_sentinel.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/all.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__utility/move.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 {
|
||||
template<view _View>
|
||||
class take_view : public view_interface<take_view<_View>> {
|
||||
[[no_unique_address]] _View __base_ = _View();
|
||||
range_difference_t<_View> __count_ = 0;
|
||||
|
||||
template<bool> class __sentinel;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
take_view() requires default_initializable<_View> = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr take_view(_View __base, range_difference_t<_View> __count)
|
||||
: __base_(_VSTD::move(__base)), __count_(__count) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() && { return _VSTD::move(__base_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() requires (!__simple_view<_View>) {
|
||||
if constexpr (sized_range<_View>) {
|
||||
if constexpr (random_access_range<_View>) {
|
||||
return ranges::begin(__base_);
|
||||
} else {
|
||||
using _DifferenceT = range_difference_t<_View>;
|
||||
auto __size = size();
|
||||
return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
|
||||
}
|
||||
} else {
|
||||
return counted_iterator(ranges::begin(__base_), __count_);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() const requires range<const _View> {
|
||||
if constexpr (sized_range<const _View>) {
|
||||
if constexpr (random_access_range<const _View>) {
|
||||
return ranges::begin(__base_);
|
||||
} else {
|
||||
using _DifferenceT = range_difference_t<const _View>;
|
||||
auto __size = size();
|
||||
return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
|
||||
}
|
||||
} else {
|
||||
return counted_iterator(ranges::begin(__base_), __count_);
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() requires (!__simple_view<_View>) {
|
||||
if constexpr (sized_range<_View>) {
|
||||
if constexpr (random_access_range<_View>) {
|
||||
return ranges::begin(__base_) + size();
|
||||
} else {
|
||||
return default_sentinel;
|
||||
}
|
||||
} else {
|
||||
return __sentinel<false>{ranges::end(__base_)};
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() const requires range<const _View> {
|
||||
if constexpr (sized_range<const _View>) {
|
||||
if constexpr (random_access_range<const _View>) {
|
||||
return ranges::begin(__base_) + size();
|
||||
} else {
|
||||
return default_sentinel;
|
||||
}
|
||||
} else {
|
||||
return __sentinel<true>{ranges::end(__base_)};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() requires sized_range<_View> {
|
||||
auto __n = ranges::size(__base_);
|
||||
// TODO: use ranges::min here.
|
||||
return _VSTD::min(__n, static_cast<decltype(__n)>(__count_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() const requires sized_range<const _View> {
|
||||
auto __n = ranges::size(__base_);
|
||||
// TODO: use ranges::min here.
|
||||
return _VSTD::min(__n, static_cast<decltype(__n)>(__count_));
|
||||
}
|
||||
};
|
||||
|
||||
template<view _View>
|
||||
template<bool _Const>
|
||||
class take_view<_View>::__sentinel {
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
template<bool _OtherConst>
|
||||
using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>;
|
||||
[[no_unique_address]] sentinel_t<_Base> __end_ = sentinel_t<_Base>();
|
||||
|
||||
template<bool>
|
||||
friend class take_view<_View>::__sentinel;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__sentinel() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(_VSTD::move(__end)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __sentinel(__sentinel<!_Const> __s)
|
||||
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
|
||||
: __end_(_VSTD::move(__s.__end_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr sentinel_t<_Base> base() const { return __end_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
|
||||
return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
|
||||
}
|
||||
|
||||
template<bool _OtherConst = !_Const>
|
||||
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
|
||||
return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Range>
|
||||
take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>;
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
} // namespace ranges
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_TAKE_VIEW_H
|
|
@ -628,6 +628,7 @@ module std [system] {
|
|||
module ref_view { private header "__ranges/ref_view.h" }
|
||||
module size { private header "__ranges/size.h" }
|
||||
module subrange { private header "__ranges/subrange.h" }
|
||||
module take_view { private header "__ranges/take_view.h" }
|
||||
module transform_view { private header "__ranges/transform_view.h" }
|
||||
module view_interface { private header "__ranges/view_interface.h" }
|
||||
}
|
||||
|
|
|
@ -156,6 +156,12 @@ namespace std::ranges {
|
|||
|
||||
template<class T>
|
||||
inline constexpr bool enable_borrowed_range<common_view<T>> = enable_borrowed_range<T>;
|
||||
|
||||
// [range.take], take view
|
||||
template<view> class take_view;
|
||||
|
||||
template<class T>
|
||||
inline constexpr bool enable_borrowed_range<take_view<T>> = enable_borrowed_range<T>;
|
||||
}
|
||||
|
||||
*/
|
||||
|
@ -173,6 +179,7 @@ namespace std::ranges {
|
|||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/enable_view.h>
|
||||
#include <__ranges/ref_view.h>
|
||||
#include <__ranges/take_view.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__ranges/transform_view.h>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// -*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// REQUIRES: modules-build
|
||||
|
||||
// WARNING: This test was generated by 'generate_private_header_tests.py'
|
||||
// and should not be edited manually.
|
||||
|
||||
// expected-error@*:* {{use of private header from outside its module: '__ranges/take_view.h'}}
|
||||
#include <__ranges/take_view.h>
|
|
@ -0,0 +1,67 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// constexpr V base() const& requires copy_constructible<V>;
|
||||
// constexpr V base() &&;
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "types.h"
|
||||
|
||||
constexpr bool hasLValueQualifiedBase(auto&& view) {
|
||||
return requires { view.base(); };
|
||||
}
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
{
|
||||
std::ranges::take_view<CopyableView> tv(CopyableView{buffer}, 0);
|
||||
assert(tv.base().ptr_ == buffer);
|
||||
assert(std::move(tv).base().ptr_ == buffer);
|
||||
|
||||
ASSERT_SAME_TYPE(decltype(tv.base()), CopyableView);
|
||||
ASSERT_SAME_TYPE(decltype(std::move(tv).base()), CopyableView);
|
||||
static_assert(hasLValueQualifiedBase(tv));
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 1);
|
||||
assert(std::move(tv).base().ptr_ == buffer);
|
||||
|
||||
ASSERT_SAME_TYPE(decltype(std::move(tv).base()), ContiguousView);
|
||||
static_assert(!hasLValueQualifiedBase(tv));
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<CopyableView> tv(CopyableView{buffer}, 2);
|
||||
assert(tv.base().ptr_ == buffer);
|
||||
assert(std::move(tv).base().ptr_ == buffer);
|
||||
|
||||
ASSERT_SAME_TYPE(decltype(tv.base()), CopyableView);
|
||||
ASSERT_SAME_TYPE(decltype(std::move(tv).base()), CopyableView);
|
||||
static_assert(hasLValueQualifiedBase(tv));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// constexpr auto begin() requires (!simple-view<V>);
|
||||
// constexpr auto begin() const requires range<const V>;
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
#include "types.h"
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
// sized_range && random_access_iterator
|
||||
{
|
||||
std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView{buffer}, 4);
|
||||
assert(tv.begin() == begin(SizedRandomAccessView(buffer)));
|
||||
ASSERT_SAME_TYPE(decltype(tv.begin()), RandomAccessIter);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView{buffer}, 4);
|
||||
assert(tv.begin() == begin(SizedRandomAccessView(buffer)));
|
||||
ASSERT_SAME_TYPE(decltype(tv.begin()), RandomAccessIter);
|
||||
}
|
||||
|
||||
// sized_range && !random_access_iterator
|
||||
{
|
||||
std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 4);
|
||||
assert(tv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 4));
|
||||
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<ForwardIter>);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 4);
|
||||
assert(tv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 4));
|
||||
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<ForwardIter>);
|
||||
}
|
||||
|
||||
// !sized_range
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(tv.begin() == std::counted_iterator<int*>(buffer, 4));
|
||||
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(tv.begin() == std::counted_iterator<int*>(buffer, 4));
|
||||
ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// template<class T>
|
||||
// inline constexpr bool enable_borrowed_range<take_view<T>> = enable_borrowed_range<T>;
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_iterators.h"
|
||||
|
||||
struct View : std::ranges::view_base {
|
||||
friend int* begin(View&);
|
||||
friend int* begin(View const&);
|
||||
friend sentinel_wrapper<int*> end(View&);
|
||||
friend sentinel_wrapper<int*> end(View const&);
|
||||
};
|
||||
|
||||
struct BorrowableView : std::ranges::view_base {
|
||||
friend int* begin(BorrowableView&);
|
||||
friend int* begin(BorrowableView const&);
|
||||
friend sentinel_wrapper<int*> end(BorrowableView&);
|
||||
friend sentinel_wrapper<int*> end(BorrowableView const&);
|
||||
};
|
||||
|
||||
template<>
|
||||
inline constexpr bool std::ranges::enable_borrowed_range<BorrowableView> = true;
|
||||
|
||||
static_assert(!std::ranges::enable_borrowed_range<std::ranges::take_view<View>>);
|
||||
static_assert( std::ranges::enable_borrowed_range<std::ranges::take_view<BorrowableView>>);
|
|
@ -0,0 +1,69 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// template<class R>
|
||||
// take_view(R&&, range_difference_t<R>) -> take_view<views::all_t<R>>;
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
|
||||
#include "test_iterators.h"
|
||||
|
||||
struct View : std::ranges::view_base {
|
||||
friend int* begin(View&);
|
||||
friend int* begin(View const&);
|
||||
friend sentinel_wrapper<int*> end(View&);
|
||||
friend sentinel_wrapper<int*> end(View const&);
|
||||
};
|
||||
|
||||
struct Range {
|
||||
friend int* begin(Range&);
|
||||
friend int* begin(Range const&);
|
||||
friend sentinel_wrapper<int*> end(Range&);
|
||||
friend sentinel_wrapper<int*> end(Range const&);
|
||||
};
|
||||
|
||||
struct BorrowedRange {
|
||||
friend int* begin(BorrowedRange&);
|
||||
friend int* begin(BorrowedRange const&);
|
||||
friend sentinel_wrapper<int*> end(BorrowedRange&);
|
||||
friend sentinel_wrapper<int*> end(BorrowedRange const&);
|
||||
};
|
||||
|
||||
template<>
|
||||
inline constexpr bool std::ranges::enable_borrowed_range<BorrowedRange> = true;
|
||||
|
||||
void testCTAD() {
|
||||
View v;
|
||||
Range r;
|
||||
BorrowedRange br;
|
||||
static_assert(std::same_as<
|
||||
decltype(std::ranges::take_view(v, 0)),
|
||||
std::ranges::take_view<View>
|
||||
>);
|
||||
static_assert(std::same_as<
|
||||
decltype(std::ranges::take_view(r, 0)),
|
||||
std::ranges::take_view<std::ranges::ref_view<Range>>
|
||||
>);
|
||||
// std::ranges::take_view(std::move(r), 0) invalid. RValue range must be borrowed.
|
||||
static_assert(std::same_as<
|
||||
decltype(std::ranges::take_view(br, 0)),
|
||||
std::ranges::take_view<std::ranges::ref_view<BorrowedRange>>
|
||||
>);
|
||||
static_assert(std::same_as<
|
||||
decltype(std::ranges::take_view(std::move(br), 0)),
|
||||
std::ranges::take_view<std::ranges::subrange<
|
||||
int *, sentinel_wrapper<int *>, std::ranges::subrange_kind::unsized>>
|
||||
>);
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// take_view() requires default_initializable<V> = default;
|
||||
// constexpr take_view(V base, range_difference_t<V> count);
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
#include "types.h"
|
||||
|
||||
int globalBuffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
template<bool IsDefaultCtorable>
|
||||
struct DefaultConstructible : std::ranges::view_base {
|
||||
DefaultConstructible() requires IsDefaultCtorable = default;
|
||||
DefaultConstructible(int*);
|
||||
int* begin();
|
||||
sentinel_wrapper<int*> end();
|
||||
};
|
||||
|
||||
struct SizedRandomAccessViewToGlobal : std::ranges::view_base {
|
||||
RandomAccessIter begin() { return RandomAccessIter(globalBuffer); }
|
||||
RandomAccessIter begin() const { return RandomAccessIter(globalBuffer); }
|
||||
sentinel_wrapper<RandomAccessIter> end() {
|
||||
return sentinel_wrapper<RandomAccessIter>{RandomAccessIter(globalBuffer + 8)};
|
||||
}
|
||||
sentinel_wrapper<RandomAccessIter> end() const {
|
||||
return sentinel_wrapper<RandomAccessIter>{RandomAccessIter(globalBuffer + 8)};
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
{
|
||||
std::ranges::take_view<CopyableView> tv(CopyableView{buffer}, 0);
|
||||
assert(tv.base().ptr_ == buffer);
|
||||
assert(tv.begin() == tv.end()); // Checking we have correct size.
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 1);
|
||||
assert(std::move(tv).base().ptr_ == buffer);
|
||||
assert(std::ranges::next(tv.begin(), 1) == tv.end()); // Checking we have correct size.
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<CopyableView> tv(CopyableView{buffer}, 2);
|
||||
assert(tv.base().ptr_ == buffer);
|
||||
assert(std::ranges::next(tv.begin(), 2) == tv.end()); // Checking we have correct size.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
// Tests for the default ctor.
|
||||
static_assert( std::default_initializable<DefaultConstructible<true>>);
|
||||
static_assert(!std::default_initializable<DefaultConstructible<false>>);
|
||||
|
||||
std::ranges::take_view<SizedRandomAccessViewToGlobal> tv;
|
||||
assert(*tv.base().begin() == 1);
|
||||
assert(tv.size() == 0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// constexpr auto end() requires (!simple-view<V>)
|
||||
// constexpr auto end() const requires range<const V>
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
#include "types.h"
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
// sized_range && random_access_iterator
|
||||
{
|
||||
std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView{buffer}, 0);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 0));
|
||||
ASSERT_SAME_TYPE(decltype(tv.end()), RandomAccessIter);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView{buffer}, 1);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 1));
|
||||
ASSERT_SAME_TYPE(decltype(tv.end()), RandomAccessIter);
|
||||
}
|
||||
|
||||
// sized_range && !random_access_iterator
|
||||
{
|
||||
std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 2);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 2));
|
||||
ASSERT_SAME_TYPE(decltype(tv.end()), std::default_sentinel_t);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 3);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 3));
|
||||
ASSERT_SAME_TYPE(decltype(tv.end()), std::default_sentinel_t);
|
||||
}
|
||||
|
||||
// !sized_range
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 4));
|
||||
|
||||
// The <sentinel> type.
|
||||
static_assert(!std::same_as<decltype(tv.end()), std::default_sentinel_t>);
|
||||
static_assert(!std::same_as<decltype(tv.end()), int*>);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 5);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 5));
|
||||
}
|
||||
|
||||
// Just to cover the case where count == 8.
|
||||
{
|
||||
std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView{buffer}, 8);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 8));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// Range concept conformance tests for take_view.
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
|
||||
static_assert(std::ranges::input_range<std::ranges::take_view<test_view<cpp20_input_iterator>>>);
|
||||
static_assert(std::ranges::forward_range<std::ranges::take_view<test_view<forward_iterator>>>);
|
||||
static_assert(std::ranges::bidirectional_range<std::ranges::take_view<test_view<bidirectional_iterator>>>);
|
||||
static_assert(std::ranges::random_access_range<std::ranges::take_view<test_view<random_access_iterator>>>);
|
||||
static_assert(std::ranges::contiguous_range<std::ranges::take_view<test_view<contiguous_iterator>>>);
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// sentinel() = default;
|
||||
// constexpr explicit sentinel(sentinel_t<Base> end);
|
||||
// constexpr sentinel(sentinel<!Const> s)
|
||||
// requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "../types.h"
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
auto sw = sentinel_wrapper<int *>(buffer + 8); // Note: not 4, but that's OK.
|
||||
|
||||
{
|
||||
const std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(tv.end().base().base() == sw.base());
|
||||
ASSERT_SAME_TYPE(decltype(tv.end().base()), sentinel_wrapper<int *>);
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(tv.end().base().base() == sw.base());
|
||||
ASSERT_SAME_TYPE(decltype(tv.end().base()), sentinel_wrapper<int *>);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// sentinel() = default;
|
||||
// constexpr explicit sentinel(sentinel_t<Base> end);
|
||||
// constexpr sentinel(sentinel<!Const> s)
|
||||
// requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "../types.h"
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
{
|
||||
// Test the default ctor.
|
||||
std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(decltype(tv.end()){} == std::ranges::next(tv.begin(), 4));
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> nonConst(ContiguousView{buffer}, 5);
|
||||
const std::ranges::take_view<ContiguousView> tvConst(ContiguousView{buffer}, 5);
|
||||
auto sent1 = nonConst.end();
|
||||
// Convert to const. Note, we cannot go the other way.
|
||||
std::remove_cv_t<decltype(tvConst.end())> sent2 = sent1;
|
||||
|
||||
assert(sent1 == std::ranges::next(tvConst.begin(), 5));
|
||||
assert(sent2 == std::ranges::next(tvConst.begin(), 5));
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<CopyableView> tv(CopyableView{buffer}, 6);
|
||||
auto sw = sentinel_wrapper<int *>(buffer + 6);
|
||||
using Sent = decltype(tv.end());
|
||||
Sent sent = Sent(sw);
|
||||
assert(sent.base().base() == sw.base());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// sentinel() = default;
|
||||
// constexpr explicit sentinel(sentinel_t<Base> end);
|
||||
// constexpr sentinel(sentinel<!Const> s)
|
||||
// requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "../types.h"
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
{
|
||||
{
|
||||
const std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 4));
|
||||
assert(std::ranges::next(tv.begin(), 4) == tv.end());
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> tv(ContiguousView{buffer}, 4);
|
||||
assert(tv.end() == std::ranges::next(tv.begin(), 4));
|
||||
assert(std::ranges::next(tv.begin(), 4) == tv.end());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<ContiguousView> tvNonConst(ContiguousView{buffer}, 4);
|
||||
const std::ranges::take_view<ContiguousView> tvConst(ContiguousView{buffer}, 4);
|
||||
assert(tvNonConst.end() == std::ranges::next(tvConst.begin(), 4));
|
||||
assert(std::ranges::next(tvConst.begin(), 4) == tvNonConst.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// UNSUPPORTED: libcpp-has-no-incomplete-ranges
|
||||
|
||||
// constexpr auto size() requires sized_range<V>
|
||||
// constexpr auto size() const requires sized_range<const V>
|
||||
|
||||
#include <ranges>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
#include "types.h"
|
||||
|
||||
template<class T>
|
||||
concept SizeEnabled = requires(const std::ranges::take_view<T>& tv) {
|
||||
tv.size();
|
||||
};
|
||||
|
||||
constexpr bool test() {
|
||||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
{
|
||||
static_assert( SizeEnabled<SizedRandomAccessView>);
|
||||
static_assert(!SizeEnabled<CopyableView>);
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView{buffer}, 0);
|
||||
assert(tv.size() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<SizedRandomAccessView> tv(SizedRandomAccessView{buffer}, 2);
|
||||
assert(tv.size() == 2);
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 4);
|
||||
assert(tv.size() == 4);
|
||||
}
|
||||
|
||||
{
|
||||
const std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 6);
|
||||
assert(tv.size() == 6);
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 8);
|
||||
assert(tv.size() == 8);
|
||||
}
|
||||
{
|
||||
const std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 8);
|
||||
assert(tv.size() == 8);
|
||||
}
|
||||
|
||||
{
|
||||
std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 10);
|
||||
assert(tv.size() == 8);
|
||||
}
|
||||
{
|
||||
const std::ranges::take_view<SizedForwardView> tv(SizedForwardView{buffer}, 10);
|
||||
assert(tv.size() == 8);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_TAKE_TYPES_H
|
||||
#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_TAKE_TYPES_H
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
|
||||
struct ContiguousView : std::ranges::view_base {
|
||||
int *ptr_;
|
||||
|
||||
constexpr ContiguousView(int* ptr) : ptr_(ptr) {}
|
||||
ContiguousView(ContiguousView&&) = default;
|
||||
ContiguousView& operator=(ContiguousView&&) = default;
|
||||
|
||||
constexpr int* begin() {return ptr_;}
|
||||
constexpr int* begin() const {return ptr_;}
|
||||
constexpr sentinel_wrapper<int*> end() {return sentinel_wrapper<int*>{ptr_ + 8};}
|
||||
constexpr sentinel_wrapper<int*> end() const {return sentinel_wrapper<int*>{ptr_ + 8};}
|
||||
};
|
||||
|
||||
struct CopyableView : std::ranges::view_base {
|
||||
int *ptr_;
|
||||
constexpr CopyableView(int* ptr) : ptr_(ptr) {}
|
||||
|
||||
constexpr int* begin() {return ptr_;}
|
||||
constexpr int* begin() const {return ptr_;}
|
||||
constexpr sentinel_wrapper<int*> end() {return sentinel_wrapper<int*>{ptr_ + 8};}
|
||||
constexpr sentinel_wrapper<int*> end() const {return sentinel_wrapper<int*>{ptr_ + 8};}
|
||||
};
|
||||
|
||||
using ForwardIter = forward_iterator<int*>;
|
||||
struct SizedForwardView : std::ranges::view_base {
|
||||
int *ptr_;
|
||||
constexpr SizedForwardView(int* ptr) : ptr_(ptr) {}
|
||||
constexpr friend ForwardIter begin(SizedForwardView& view) { return ForwardIter(view.ptr_); }
|
||||
constexpr friend ForwardIter begin(SizedForwardView const& view) { return ForwardIter(view.ptr_); }
|
||||
constexpr friend sentinel_wrapper<ForwardIter> end(SizedForwardView& view) {
|
||||
return sentinel_wrapper<ForwardIter>{ForwardIter(view.ptr_ + 8)};
|
||||
}
|
||||
constexpr friend sentinel_wrapper<ForwardIter> end(SizedForwardView const& view) {
|
||||
return sentinel_wrapper<ForwardIter>{ForwardIter(view.ptr_ + 8)};
|
||||
}
|
||||
};
|
||||
// Required to make SizedForwardView a sized view.
|
||||
constexpr auto operator-(sentinel_wrapper<ForwardIter> sent, ForwardIter iter) {
|
||||
return sent.base().base() - iter.base();
|
||||
}
|
||||
constexpr auto operator-(ForwardIter iter, sentinel_wrapper<ForwardIter> sent) {
|
||||
return iter.base() - sent.base().base();
|
||||
}
|
||||
|
||||
using RandomAccessIter = random_access_iterator<int*>;
|
||||
struct SizedRandomAccessView : std::ranges::view_base {
|
||||
int *ptr_;
|
||||
constexpr SizedRandomAccessView(int* ptr) : ptr_(ptr) {}
|
||||
constexpr friend RandomAccessIter begin(SizedRandomAccessView& view) { return RandomAccessIter(view.ptr_); }
|
||||
constexpr friend RandomAccessIter begin(SizedRandomAccessView const& view) { return RandomAccessIter(view.ptr_); }
|
||||
constexpr friend sentinel_wrapper<RandomAccessIter> end(SizedRandomAccessView& view) {
|
||||
return sentinel_wrapper<RandomAccessIter>{RandomAccessIter(view.ptr_ + 8)};
|
||||
}
|
||||
constexpr friend sentinel_wrapper<RandomAccessIter> end(SizedRandomAccessView const& view) {
|
||||
return sentinel_wrapper<RandomAccessIter>{RandomAccessIter(view.ptr_ + 8)};
|
||||
}
|
||||
};
|
||||
// Required to make SizedRandomAccessView a sized view.
|
||||
constexpr auto operator-(sentinel_wrapper<RandomAccessIter> sent, RandomAccessIter iter) {
|
||||
return sent.base().base() - iter.base();
|
||||
}
|
||||
constexpr auto operator-(RandomAccessIter iter, sentinel_wrapper<RandomAccessIter> sent) {
|
||||
return iter.base() - sent.base().base();
|
||||
}
|
||||
|
||||
#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_TAKE_TYPES_H
|
|
@ -14,6 +14,7 @@
|
|||
// CTAD tests.
|
||||
|
||||
#include <ranges>
|
||||
#include <concepts>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "types.h"
|
||||
|
|
|
@ -21,7 +21,6 @@ struct sentinel {
|
|||
bool operator==(std::input_or_output_iterator auto const&) const;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
template <template <class...> class I>
|
||||
requires std::input_or_output_iterator<I<int*> >
|
||||
struct test_range {
|
||||
|
@ -54,6 +53,13 @@ struct test_non_const_common_range {
|
|||
I<int*> end();
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
template <template <class...> class I>
|
||||
requires std::input_or_output_iterator<I<int*> >
|
||||
struct test_view : std::ranges::view_base {
|
||||
I<int*> begin();
|
||||
I<int const*> begin() const;
|
||||
sentinel end();
|
||||
sentinel end() const;
|
||||
};
|
||||
|
||||
#endif // LIBCXX_TEST_SUPPORT_TEST_RANGE_H
|
||||
|
|
Loading…
Reference in New Issue