Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P2446R2: views::as_rvalue #3008

Merged
merged 13 commits into from
Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -1627,6 +1627,124 @@ namespace ranges {
using all_t = decltype(all(_STD declval<_Rng>()));
} // namespace views

#if _HAS_CXX23
template <input_range _Vw>
requires view<_Vw>
strega-nil-ms marked this conversation as resolved.
Show resolved Hide resolved
class as_rvalue_view : public view_interface<as_rvalue_view<_Vw>> {
private:
/* [[no_unique_address]] */ _Vw _Range{};

template <range _Rng>
static constexpr bool _Is_end_nothrow_v = noexcept(move_sentinel{_RANGES end(_STD declval<_Rng&>())});

template <common_range _Rng>
static constexpr bool _Is_end_nothrow_v<_Rng> = noexcept(move_iterator{_RANGES end(_STD declval<_Rng&>())});

public:
// clang-format off
as_rvalue_view() requires default_initializable<_Vw> = default;
// clang-format on

constexpr explicit as_rvalue_view(_Vw _Range_) noexcept(is_nothrow_move_constructible_v<_Vw>) // strengthened
: _Range(_STD move(_Range_)) {}

_NODISCARD constexpr _Vw base() const& noexcept(is_nothrow_copy_constructible_v<_Vw>) // strengthened
requires copy_constructible<_Vw> {
return _Range;
}

_NODISCARD constexpr _Vw base() && noexcept(is_nothrow_move_constructible_v<_Vw>) /* strengthened */ {
return _STD move(_Range);
}

_NODISCARD constexpr auto begin() noexcept(noexcept(move_iterator{_RANGES begin(_Range)})) // strengthened
requires(!_Simple_view<_Vw>) {
return move_iterator{_RANGES begin(_Range)};
}

_NODISCARD constexpr auto begin() const noexcept(noexcept(move_iterator{_RANGES begin(_Range)})) // strengthened
requires range<const _Vw> {
return move_iterator{_RANGES begin(_Range)};
}

_NODISCARD constexpr auto end() noexcept(_Is_end_nothrow_v<_Vw>) // strengthened
requires(!_Simple_view<_Vw>) {
if constexpr (common_range<_Vw>) {
return move_iterator{_RANGES end(_Range)};
} else {
return move_sentinel{_RANGES end(_Range)};
}
}

_NODISCARD constexpr auto end() const noexcept(_Is_end_nothrow_v<const _Vw>) // strengthened
requires range<const _Vw> {
if constexpr (common_range<const _Vw>) {
return move_iterator{_RANGES end(_Range)};
} else {
return move_sentinel{_RANGES end(_Range)};
}
}

_NODISCARD constexpr auto size() noexcept(noexcept(_RANGES size(_Range))) // strengthened
strega-nil-ms marked this conversation as resolved.
Show resolved Hide resolved
requires sized_range<_Vw> {
return _RANGES size(_Range);
}

_NODISCARD constexpr auto size() const noexcept(noexcept(_RANGES size(_Range))) // strengthened
requires sized_range<const _Vw> {
return _RANGES size(_Range);
}
};

template <class _Rng>
as_rvalue_view(_Rng&&) -> as_rvalue_view<views::all_t<_Rng>>;

template <class _Rng>
inline constexpr bool enable_borrowed_range<as_rvalue_view<_Rng>> = enable_borrowed_range<_Rng>;

namespace views {
template <class _Rng>
concept _Can_as_rvalue = requires(_Rng&& __r) {
as_rvalue_view{static_cast<_Rng&&>(__r)};
};

struct _As_rvalue_fn : _Pipe::_Base<_As_rvalue_fn> {
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
private:
enum class _St { _None, _All, _As_rvalue };

template <class _Rng>
_NODISCARD static _CONSTEVAL _Choice_t<_St> _Choose() noexcept {
if constexpr (same_as<range_rvalue_reference_t<_Rng>, range_reference_t<_Rng>>) {
return {_St::_All, noexcept(views::all(_STD declval<_Rng>()))};
} else if constexpr (_Can_as_rvalue<_Rng>) {
return {_St::_As_rvalue, noexcept(as_rvalue_view{_STD declval<_Rng>()})};
} else {
return {_St::_None};
}
}

template <class _Rng>
static constexpr _Choice_t<_St> _Choice = _Choose<_Rng>();

public:
template <viewable_range _Rng>
requires(_Choice<_Rng>._Strategy != _St::_None)
_NODISCARD constexpr auto operator()(_Rng&& _Range) const noexcept(_Choice<_Rng>._No_throw) {
constexpr _St _Strat = _Choice<_Rng>._Strategy;
if constexpr (_Strat == _St::_All) {
return views::all(_STD forward<_Rng>(_Range));
} else if constexpr (_Strat == _St::_As_rvalue) {
return as_rvalue_view{_STD forward<_Rng>(_Range)};
} else {
static_assert(_Always_false<_Rng>, "Should be unreachable");
}
}
};

inline constexpr _As_rvalue_fn as_rvalue;
} // namespace views
#endif // _HAS_CXX23

template <input_range _Vw, indirect_unary_predicate<iterator_t<_Vw>> _Pr>
requires view<_Vw> && is_object_v<_Pr>
class filter_view : public _Cached_position_t<forward_range<_Vw>, _Vw, filter_view<_Vw, _Pr>> {
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@
// P2442R1 Windowing Range Adaptors: views::chunk, views::slide
// P2443R1 views::chunk_by
// P2445R1 forward_like()
// P2446R2 views::as_rvalue
// P2499R0 string_view Range Constructor Should Be explicit
// P2549R0 unexpected<E>::error()

Expand Down Expand Up @@ -1511,6 +1512,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect

#ifdef __cpp_lib_concepts
#define __cpp_lib_out_ptr 202106L
#define __cpp_lib_ranges_as_rvalue 202207L
#define __cpp_lib_ranges_chunk 202202L
#define __cpp_lib_ranges_chunk_by 202202L
#define __cpp_lib_ranges_contains 202207L
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ tests\P2442R1_views_slide
tests\P2443R1_views_chunk_by
tests\P2443R1_views_chunk_by_death
tests\P2445R1_forward_like
tests\P2446R2_views_as_rvalue
tests\P2517R1_apply_conditional_noexcept
tests\VSO_0000000_allocator_propagation
tests\VSO_0000000_any_calling_conventions
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P2446R2_views_as_rvalue/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\concepts_latest_matrix.lst
Loading