#ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
#define _LIBCPP___RANGES_VIEW_INTERFACE_H
+#include <__concepts/derived_from.h>
+#include <__concepts/same_as.h>
#include <__config>
#include <__debug>
#include <__iterator/concepts.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/empty.h>
-#include <concepts>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
namespace ranges {
-template<class _Tp>
-concept __can_empty = requires(_Tp __t) { ranges::empty(__t); };
-
-template<class _Tp>
-void __implicitly_convert_to(type_identity_t<_Tp>) noexcept;
-
template<class _Derived>
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
class view_interface {
public:
template<class _D2 = _Derived>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
- noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
requires forward_range<_D2>
{
return ranges::begin(__derived()) == ranges::end(__derived());
template<class _D2 = _Derived>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
- noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived()))))
requires forward_range<const _D2>
{
return ranges::begin(__derived()) == ranges::end(__derived());
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool()
- noexcept(noexcept(ranges::empty(declval<_D2>())))
- requires __can_empty<_D2>
+ requires requires (_D2& __t) { ranges::empty(__t); }
{
return !ranges::empty(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool() const
- noexcept(noexcept(ranges::empty(declval<const _D2>())))
- requires __can_empty<const _D2>
+ requires requires (const _D2& __t) { ranges::empty(__t); }
{
return !ranges::empty(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto data()
- noexcept(noexcept(std::to_address(ranges::begin(__derived()))))
requires contiguous_iterator<iterator_t<_D2>>
{
return std::to_address(ranges::begin(__derived()));
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto data() const
- noexcept(noexcept(std::to_address(ranges::begin(__derived()))))
requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
{
return std::to_address(ranges::begin(__derived()));
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto size()
- noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
- requires forward_range<_D2>
- && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
+ requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
{
return ranges::end(__derived()) - ranges::begin(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto size() const
- noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived())))
- requires forward_range<const _D2>
- && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
+ requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
{
return ranges::end(__derived()) - ranges::begin(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front()
- noexcept(noexcept(*ranges::begin(__derived())))
requires forward_range<_D2>
{
_LIBCPP_ASSERT(!empty(),
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front() const
- noexcept(noexcept(*ranges::begin(__derived())))
requires forward_range<const _D2>
{
_LIBCPP_ASSERT(!empty(),
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back()
- noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
requires bidirectional_range<_D2> && common_range<_D2>
{
_LIBCPP_ASSERT(!empty(),
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back() const
- noexcept(noexcept(*ranges::prev(ranges::end(__derived()))))
requires bidirectional_range<const _D2> && common_range<const _D2>
{
_LIBCPP_ASSERT(!empty(),
template<random_access_range _RARange = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index)
- noexcept(noexcept(ranges::begin(__derived())[__index]))
{
return ranges::begin(__derived())[__index];
}
template<random_access_range _RARange = const _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const
- noexcept(noexcept(ranges::begin(__derived())[__index]))
{
return ranges::begin(__derived())[__index];
}
};
static_assert(std::ranges::view<DataIsNull>);
-template<bool IsNoexcept>
-struct BoolConvertibleComparison : std::ranges::view_interface<BoolConvertibleComparison<IsNoexcept>> {
+struct BoolConvertibleComparison : std::ranges::view_interface<BoolConvertibleComparison> {
struct ResultType {
bool value;
- constexpr operator bool() const noexcept(IsNoexcept) { return value; }
+ constexpr operator bool() const { return value; }
};
struct SentinelType {
int *base_;
- SentinelType() = default;
- explicit constexpr SentinelType(int *base) : base_(base) {}
+ explicit SentinelType() = default;
+ constexpr explicit SentinelType(int *base) : base_(base) {}
friend constexpr ResultType operator==(ForwardIter const& iter, SentinelType const& sent) noexcept { return {iter.base() == sent.base_}; }
friend constexpr ResultType operator==(SentinelType const& sent, ForwardIter const& iter) noexcept { return {iter.base() == sent.base_}; }
friend constexpr ResultType operator!=(ForwardIter const& iter, SentinelType const& sent) noexcept { return {iter.base() != sent.base_}; }
};
int buff[8] = {0, 1, 2, 3, 4, 5, 6, 7};
- constexpr ForwardIter begin() const noexcept { return ForwardIter(const_cast<int*>(buff)); }
- constexpr SentinelType end() const noexcept { return SentinelType(const_cast<int*>(buff) + 8); }
+ constexpr ForwardIter begin() const { return ForwardIter(const_cast<int*>(buff)); }
+ constexpr SentinelType end() const { return SentinelType(const_cast<int*>(buff) + 8); }
};
-static_assert(std::ranges::view<BoolConvertibleComparison<true>>);
-static_assert(std::ranges::view<BoolConvertibleComparison<false>>);
+static_assert(std::ranges::view<BoolConvertibleComparison>);
template<class T>
concept EmptyInvocable = requires (T const& obj) { obj.empty(); };
MoveOnlyForwardRange moveOnly;
assert(!std::move(moveOnly).empty());
- BoolConvertibleComparison<true> boolConv;
- BoolConvertibleComparison<false> boolConv2;
- LIBCPP_ASSERT_NOEXCEPT(boolConv.empty());
- ASSERT_NOT_NOEXCEPT(boolConv2.empty());
+ BoolConvertibleComparison boolConv;
+ ASSERT_NOT_NOEXCEPT(boolConv.empty());
assert(!boolConv.empty());
- assert(!static_cast<BoolConvertibleComparison<true> const&>(boolConv).empty());
+ assert(!static_cast<const BoolConvertibleComparison&>(boolConv).empty());
assert(boolConv);
- assert(static_cast<BoolConvertibleComparison<true> const&>(boolConv));
+ assert(static_cast<const BoolConvertibleComparison&>(boolConv));
assert(!std::ranges::empty(boolConv));
- assert(!std::ranges::empty(static_cast<BoolConvertibleComparison<true> const&>(boolConv)));
+ assert(!std::ranges::empty(static_cast<const BoolConvertibleComparison&>(boolConv)));
return true;
}