Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc++][ranges] Implement rbegin, rend, crbegin and crend.
Differential Revision: https://reviews.llvm.org/D119057
- Loading branch information
Showing
12 changed files
with
1,379 additions
and
6 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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 |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// -*- 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_RBEGIN_H | ||
#define _LIBCPP___RANGES_RBEGIN_H | ||
|
||
#include <__concepts/class_or_enum.h> | ||
#include <__concepts/same_as.h> | ||
#include <__config> | ||
#include <__iterator/concepts.h> | ||
#include <__iterator/readable_traits.h> | ||
#include <__iterator/reverse_iterator.h> | ||
#include <__ranges/access.h> | ||
#include <__utility/auto_cast.h> | ||
#include <type_traits> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) | ||
|
||
// [ranges.access.rbegin] | ||
|
||
namespace ranges { | ||
namespace __rbegin { | ||
template <class _Tp> | ||
concept __member_rbegin = | ||
__can_borrow<_Tp> && | ||
__workaround_52970<_Tp> && | ||
requires(_Tp&& __t) { | ||
{ _LIBCPP_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator; | ||
}; | ||
|
||
void rbegin(auto&) = delete; | ||
void rbegin(const auto&) = delete; | ||
|
||
template <class _Tp> | ||
concept __unqualified_rbegin = | ||
!__member_rbegin<_Tp> && | ||
__can_borrow<_Tp> && | ||
__class_or_enum<remove_cvref_t<_Tp>> && | ||
requires(_Tp&& __t) { | ||
{ _LIBCPP_AUTO_CAST(rbegin(__t)) } -> input_or_output_iterator; | ||
}; | ||
|
||
template <class _Tp> | ||
concept __can_reverse = | ||
__can_borrow<_Tp> && | ||
!__member_rbegin<_Tp> && | ||
!__unqualified_rbegin<_Tp> && | ||
requires(_Tp&& __t) { | ||
{ ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>; | ||
{ ranges::begin(__t) } -> bidirectional_iterator; | ||
}; | ||
|
||
struct __fn { | ||
template <class _Tp> | ||
requires __member_rbegin<_Tp> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rbegin()))) | ||
{ | ||
return _LIBCPP_AUTO_CAST(__t.rbegin()); | ||
} | ||
|
||
template <class _Tp> | ||
requires __unqualified_rbegin<_Tp> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(_LIBCPP_AUTO_CAST(rbegin(__t)))) | ||
{ | ||
return _LIBCPP_AUTO_CAST(rbegin(__t)); | ||
} | ||
|
||
template <class _Tp> | ||
requires __can_reverse<_Tp> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(ranges::end(__t))) | ||
{ | ||
return std::make_reverse_iterator(ranges::end(__t)); | ||
} | ||
|
||
void operator()(auto&&) const = delete; | ||
}; | ||
} // namespace __rbegin | ||
|
||
inline namespace __cpo { | ||
inline constexpr auto rbegin = __rbegin::__fn{}; | ||
} // namespace __cpo | ||
} // namespace ranges | ||
|
||
// [range.access.crbegin] | ||
|
||
namespace ranges { | ||
namespace __crbegin { | ||
struct __fn { | ||
template <class _Tp> | ||
requires is_lvalue_reference_v<_Tp&&> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI | ||
constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)))) | ||
-> decltype( ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))) | ||
{ return ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)); } | ||
|
||
template <class _Tp> | ||
requires is_rvalue_reference_v<_Tp&&> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI | ||
constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(ranges::rbegin(static_cast<const _Tp&&>(__t)))) | ||
-> decltype( ranges::rbegin(static_cast<const _Tp&&>(__t))) | ||
{ return ranges::rbegin(static_cast<const _Tp&&>(__t)); } | ||
}; | ||
} // namespace __crbegin | ||
|
||
inline namespace __cpo { | ||
inline constexpr auto crbegin = __crbegin::__fn{}; | ||
} // namespace __cpo | ||
} // namespace ranges | ||
|
||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
#endif // _LIBCPP___RANGES_RBEGIN_H |
This file contains 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 |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// -*- 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_REND_H | ||
#define _LIBCPP___RANGES_REND_H | ||
|
||
#include <__concepts/class_or_enum.h> | ||
#include <__concepts/same_as.h> | ||
#include <__config> | ||
#include <__iterator/concepts.h> | ||
#include <__iterator/readable_traits.h> | ||
#include <__iterator/reverse_iterator.h> | ||
#include <__ranges/access.h> | ||
#include <__ranges/rbegin.h> | ||
#include <__utility/auto_cast.h> | ||
#include <type_traits> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) | ||
|
||
// [range.access.rend] | ||
|
||
namespace ranges { | ||
namespace __rend { | ||
template <class _Tp> | ||
concept __member_rend = | ||
__can_borrow<_Tp> && | ||
__workaround_52970<_Tp> && | ||
requires(_Tp&& __t) { | ||
ranges::rbegin(__t); | ||
{ _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>; | ||
}; | ||
|
||
void rend(auto&) = delete; | ||
void rend(const auto&) = delete; | ||
|
||
template <class _Tp> | ||
concept __unqualified_rend = | ||
!__member_rend<_Tp> && | ||
__can_borrow<_Tp> && | ||
__class_or_enum<remove_cvref_t<_Tp>> && | ||
requires(_Tp&& __t) { | ||
ranges::rbegin(__t); | ||
{ _LIBCPP_AUTO_CAST(rend(__t)) } -> sentinel_for<decltype(ranges::rbegin(__t))>; | ||
}; | ||
|
||
template <class _Tp> | ||
concept __can_reverse = | ||
__can_borrow<_Tp> && | ||
!__member_rend<_Tp> && | ||
!__unqualified_rend<_Tp> && | ||
requires(_Tp&& __t) { | ||
{ ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>; | ||
{ ranges::begin(__t) } -> bidirectional_iterator; | ||
}; | ||
|
||
class __fn { | ||
public: | ||
template <class _Tp> | ||
requires __member_rend<_Tp> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend()))) | ||
{ | ||
return _LIBCPP_AUTO_CAST(__t.rend()); | ||
} | ||
|
||
template <class _Tp> | ||
requires __unqualified_rend<_Tp> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t)))) | ||
{ | ||
return _LIBCPP_AUTO_CAST(rend(__t)); | ||
} | ||
|
||
template <class _Tp> | ||
requires __can_reverse<_Tp> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(ranges::begin(__t))) | ||
{ | ||
return std::make_reverse_iterator(ranges::begin(__t)); | ||
} | ||
|
||
void operator()(auto&&) const = delete; | ||
}; | ||
} // namespace __rend | ||
|
||
inline namespace __cpo { | ||
inline constexpr auto rend = __rend::__fn{}; | ||
} // namespace __cpo | ||
} // namespace ranges | ||
|
||
// [range.access.crend] | ||
|
||
namespace ranges { | ||
namespace __crend { | ||
struct __fn { | ||
template <class _Tp> | ||
requires is_lvalue_reference_v<_Tp&&> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI | ||
constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)))) | ||
-> decltype( ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))) | ||
{ return ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)); } | ||
|
||
template <class _Tp> | ||
requires is_rvalue_reference_v<_Tp&&> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI | ||
constexpr auto operator()(_Tp&& __t) const | ||
noexcept(noexcept(ranges::rend(static_cast<const _Tp&&>(__t)))) | ||
-> decltype( ranges::rend(static_cast<const _Tp&&>(__t))) | ||
{ return ranges::rend(static_cast<const _Tp&&>(__t)); } | ||
}; | ||
} // namespace __crend | ||
|
||
inline namespace __cpo { | ||
inline constexpr auto crend = __crend::__fn{}; | ||
} // namespace __cpo | ||
} // namespace ranges | ||
|
||
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
#endif // _LIBCPP___RANGES_REND_H |
This file contains 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
This file contains 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
15 changes: 15 additions & 0 deletions
15
libcxx/test/libcxx/diagnostics/detail.headers/ranges/rbegin.module.verify.cpp
This file contains 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 |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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/rbegin.h'}} | ||
#include <__ranges/rbegin.h> |
15 changes: 15 additions & 0 deletions
15
libcxx/test/libcxx/diagnostics/detail.headers/ranges/rend.module.verify.cpp
This file contains 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 |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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/rend.h'}} | ||
#include <__ranges/rend.h> |
Oops, something went wrong.