-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Fix handling of array rvalues for ranges::cbegin
and its friends
#3316
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
Merged
StephanTLavavej
merged 9 commits into
microsoft:main
from
frederick-vs-ja:cpo-incomplete-array-rvalue
Jan 12, 2023
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
24d6419
Test coverage for array rvalues of incomplete elements
frederick-vs-ja 69135fd
Fix handling of array rvalues for some CPOs
frederick-vs-ja d1505ad
Workaround for clang
frederick-vs-ja 1180750
Clang-format
frederick-vs-ja 006f552
Pass lvalues to `begin` etc.
frederick-vs-ja 8b32947
Fix copy pasta: use `const_sentinel` instead of `const_iterator`
frederick-vs-ja 6493d8e
Fix copy pasta: use `_Rend_adapted`
frederick-vs-ja 997f655
The same treatment should be done for `cdata`
frederick-vs-ja e0af83f
Name changes and transition comments by @strega-nil-ms
frederick-vs-ja File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2479,17 +2479,34 @@ namespace ranges { | |
_NODISCARD constexpr auto _As_const_pointer(const _Ty* _Ptr) noexcept { | ||
return _Ptr; | ||
} | ||
|
||
template <class _Ty> | ||
using _Begin_on_const = decltype(_RANGES begin(_RANGES _Possibly_const_range(_STD declval<_Ty&>()))); | ||
|
||
// TRANSITION, LLVM-55945 | ||
template <class _Ty> | ||
concept _Range_accessible_and_begin_adaptable = | ||
_Should_range_access<_Ty> | ||
&& requires( | ||
_Ty& _Val) { const_iterator<_Begin_on_const<_Ty>>{_RANGES begin(_RANGES _Possibly_const_range(_Val))}; }; | ||
|
||
template <class _Ty> | ||
using _End_on_const = decltype(_RANGES end(_RANGES _Possibly_const_range(_STD declval<_Ty&>()))); | ||
|
||
// TRANSITION, LLVM-55945 | ||
template <class _Ty> | ||
concept _Range_accessible_and_end_adaptable = | ||
_Should_range_access<_Ty> | ||
&& requires( | ||
_Ty& _Val) { const_sentinel<_End_on_const<_Ty>>{_RANGES end(_RANGES _Possibly_const_range(_Val))}; }; | ||
#endif // _HAS_CXX23 | ||
|
||
struct _Cbegin_fn { | ||
#if _HAS_CXX23 | ||
template <_Should_range_access _Ty, | ||
class _Uty = decltype(_RANGES begin(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))> | ||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const | ||
noexcept(noexcept(const_iterator<_Uty>{_RANGES begin(_RANGES _Possibly_const_range(_Val))})) | ||
requires requires { const_iterator<_Uty>{_RANGES begin(_RANGES _Possibly_const_range(_Val))}; } | ||
{ | ||
return const_iterator<_Uty>{_RANGES begin(_RANGES _Possibly_const_range(_Val))}; | ||
template <_Range_accessible_and_begin_adaptable _Ty> | ||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const noexcept( | ||
noexcept(const_iterator<_Begin_on_const<_Ty>>{_RANGES begin(_RANGES _Possibly_const_range(_Val))})) { | ||
return const_iterator<_Begin_on_const<_Ty>>{_RANGES begin(_RANGES _Possibly_const_range(_Val))}; | ||
} | ||
#else // ^^^ C++23 / C++20 vvv | ||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>> | ||
|
@@ -2508,13 +2525,10 @@ namespace ranges { | |
|
||
struct _Cend_fn { | ||
#if _HAS_CXX23 | ||
template <_Should_range_access _Ty, | ||
class _Uty = decltype(_RANGES end(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))> | ||
template <_Range_accessible_and_end_adaptable _Ty> | ||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const | ||
noexcept(noexcept(const_sentinel<_Uty>{_RANGES end(_RANGES _Possibly_const_range(_Val))})) | ||
requires requires { const_sentinel<_Uty>{_RANGES end(_RANGES _Possibly_const_range(_Val))}; } | ||
{ | ||
return const_sentinel<_Uty>{_RANGES end(_RANGES _Possibly_const_range(_Val))}; | ||
noexcept(noexcept(const_sentinel<_End_on_const<_Ty>>{_RANGES end(_RANGES _Possibly_const_range(_Val))})) { | ||
return const_sentinel<_End_on_const<_Ty>>{_RANGES end(_RANGES _Possibly_const_range(_Val))}; | ||
} | ||
#else // ^^^ C++23 / C++20 vvv | ||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>> | ||
|
@@ -2670,15 +2684,34 @@ namespace ranges { | |
_EXPORT_STD inline constexpr _Rend::_Cpo rend; | ||
} | ||
|
||
#if _HAS_CXX23 | ||
template <class _Ty> | ||
using _Rbegin_on_const = decltype(_RANGES rbegin(_RANGES _Possibly_const_range(_STD declval<_Ty&>()))); | ||
|
||
// TRANSITION, LLVM-55945 | ||
template <class _Ty> | ||
concept _Range_accessible_and_rbegin_adaptable = | ||
_Should_range_access<_Ty> | ||
&& requires( | ||
_Ty& _Val) { const_iterator<_Rbegin_on_const<_Ty>>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))}; }; | ||
|
||
template <class _Ty> | ||
using _Rend_on_const = decltype(_RANGES rend(_RANGES _Possibly_const_range(_STD declval<_Ty&>()))); | ||
|
||
// TRANSITION, LLVM-55945 | ||
template <class _Ty> | ||
concept _Range_accessible_and_rend_adaptable = | ||
_Should_range_access<_Ty> | ||
&& requires( | ||
_Ty& _Val) { const_sentinel<_Rend_on_const<_Ty>>{_RANGES rend(_RANGES _Possibly_const_range(_Val))}; }; | ||
#endif // _HAS_CXX23 | ||
|
||
struct _Crbegin_fn { | ||
#if _HAS_CXX23 | ||
template <_Should_range_access _Ty, | ||
class _Uty = decltype(_RANGES rbegin(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))> | ||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const | ||
noexcept(noexcept(const_iterator<_Uty>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))})) | ||
requires requires { const_iterator<_Uty>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))}; } | ||
{ | ||
return const_iterator<_Uty>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))}; | ||
template <_Range_accessible_and_rbegin_adaptable _Ty> | ||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const noexcept( | ||
noexcept(const_iterator<_Rbegin_on_const<_Ty>>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))})) { | ||
return const_iterator<_Rbegin_on_const<_Ty>>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))}; | ||
} | ||
#else // ^^^ C++23 / C++20 vvv | ||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>> | ||
|
@@ -2697,13 +2730,10 @@ namespace ranges { | |
|
||
struct _Crend_fn { | ||
#if _HAS_CXX23 | ||
template <_Should_range_access _Ty, | ||
class _Uty = decltype(_RANGES rend(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))> | ||
template <_Range_accessible_and_rend_adaptable _Ty> | ||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const | ||
noexcept(noexcept(const_sentinel<_Uty>{_RANGES rend(_RANGES _Possibly_const_range(_Val))})) | ||
requires requires { const_sentinel<_Uty>{_RANGES rend(_RANGES _Possibly_const_range(_Val))}; } | ||
{ | ||
return const_sentinel<_Uty>{_RANGES rend(_RANGES _Possibly_const_range(_Val))}; | ||
noexcept(noexcept(const_sentinel<_Rend_on_const<_Ty>>{_RANGES rend(_RANGES _Possibly_const_range(_Val))})) { | ||
return const_sentinel<_Rend_on_const<_Ty>>{_RANGES rend(_RANGES _Possibly_const_range(_Val))}; | ||
} | ||
#else // ^^^ C++23 / C++20 vvv | ||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>> | ||
|
@@ -2922,13 +2952,19 @@ namespace ranges { | |
_EXPORT_STD inline constexpr _Data::_Cpo data; | ||
} | ||
|
||
#if _HAS_CXX23 | ||
// TRANSITION, LLVM-55945 | ||
template <class _Ty> | ||
concept _Range_accessible_and_data_adaptable = | ||
_Should_range_access<_Ty> | ||
&& requires(_Ty& _Val) { _RANGES _As_const_pointer(_RANGES data(_RANGES _Possibly_const_range(_Val))); }; | ||
#endif // _HAS_CXX23 | ||
|
||
struct _Cdata_fn { | ||
#if _HAS_CXX23 | ||
template <_Should_range_access _Ty> | ||
template <_Range_accessible_and_data_adaptable _Ty> | ||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const | ||
noexcept(noexcept(_RANGES data(_RANGES _Possibly_const_range(_Val)))) | ||
requires requires { _RANGES _As_const_pointer(_RANGES data(_RANGES _Possibly_const_range(_Val))); } | ||
{ | ||
noexcept(noexcept(_RANGES data(_RANGES _Possibly_const_range(_Val)))) { | ||
return _RANGES _As_const_pointer(_RANGES data(_RANGES _Possibly_const_range(_Val))); | ||
Comment on lines
+2967
to
2968
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No change requested: I observe that the |
||
} | ||
#else // ^^^ C++23 / C++20 vvv | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.