libstdc++: Revert final/non-addressable changes to ranges CPOs
In r12-1489-g8b93548778a487f31f21e0c6afe7e0bde9711fc4 I made the [range.access] CPO types final and non-addressable. Tim Song pointed out this is wrong. Only the [range.iter.ops] functions should be final and non-addressable. Revert the changes to the [range.access] objects. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (ranges::begin, ranges::end) (ranges::cbegin, ranges::cend, ranges::rbeing, ranges::rend) (ranges::crbegin, ranges::crend, ranges::size, ranges::ssize) (ranges::empty, ranges::data, ranges::cdata): Remove final keywords and deleted operator& overloads. * testsuite/24_iterators/customization_points/iter_move.cc: Use new is_customization_point_object function. * testsuite/24_iterators/customization_points/iter_swap.cc: Likewise. * testsuite/std/concepts/concepts.lang/concept.swappable/swap.cc: Likewise. * testsuite/std/ranges/access/begin.cc: Likewise. * testsuite/std/ranges/access/cbegin.cc: Likewise. * testsuite/std/ranges/access/cdata.cc: Likewise. * testsuite/std/ranges/access/cend.cc: Likewise. * testsuite/std/ranges/access/crbegin.cc: Likewise. * testsuite/std/ranges/access/crend.cc: Likewise. * testsuite/std/ranges/access/data.cc: Likewise. * testsuite/std/ranges/access/empty.cc: Likewise. * testsuite/std/ranges/access/end.cc: Likewise. * testsuite/std/ranges/access/rbegin.cc: Likewise. * testsuite/std/ranges/access/rend.cc: Likewise. * testsuite/std/ranges/access/size.cc: Likewise. * testsuite/std/ranges/access/ssize.cc: Likewise. * testsuite/util/testsuite_iterators.h (is_customization_point_object): New function.
This commit is contained in:
parent
dbfc149b63
commit
b9e35ee6d6
@ -91,7 +91,7 @@ namespace ranges
|
||||
using std::ranges::__detail::__maybe_borrowed_range;
|
||||
using std::__detail::__range_iter_t;
|
||||
|
||||
struct _Begin final
|
||||
struct _Begin
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
@ -106,8 +106,6 @@ namespace ranges
|
||||
return noexcept(__decay_copy(begin(std::declval<_Tp&>())));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
|
||||
public:
|
||||
template<__maybe_borrowed_range _Tp>
|
||||
requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
|
||||
@ -144,7 +142,7 @@ namespace ranges
|
||||
{ __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>;
|
||||
};
|
||||
|
||||
struct _End final
|
||||
struct _End
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
@ -159,8 +157,6 @@ namespace ranges
|
||||
return noexcept(__decay_copy(end(std::declval<_Tp&>())));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
|
||||
public:
|
||||
template<__maybe_borrowed_range _Tp>
|
||||
requires is_bounded_array_v<remove_reference_t<_Tp>>
|
||||
@ -193,7 +189,7 @@ namespace ranges
|
||||
return static_cast<const _Tp&&>(__t);
|
||||
}
|
||||
|
||||
struct _CBegin final
|
||||
struct _CBegin
|
||||
{
|
||||
template<typename _Tp>
|
||||
constexpr auto
|
||||
@ -203,8 +199,6 @@ namespace ranges
|
||||
{
|
||||
return _Begin{}(__cust_access::__as_const<_Tp>(__e));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
};
|
||||
|
||||
struct _CEnd final
|
||||
@ -217,8 +211,6 @@ namespace ranges
|
||||
{
|
||||
return _End{}(__cust_access::__as_const<_Tp>(__e));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
@ -244,7 +236,7 @@ namespace ranges
|
||||
{ _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
|
||||
};
|
||||
|
||||
struct _RBegin final
|
||||
struct _RBegin
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
@ -268,8 +260,6 @@ namespace ranges
|
||||
}
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
|
||||
public:
|
||||
template<__maybe_borrowed_range _Tp>
|
||||
requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
|
||||
@ -304,7 +294,7 @@ namespace ranges
|
||||
-> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
|
||||
};
|
||||
|
||||
struct _REnd final
|
||||
struct _REnd
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
@ -328,8 +318,6 @@ namespace ranges
|
||||
}
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
|
||||
public:
|
||||
template<__maybe_borrowed_range _Tp>
|
||||
requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
|
||||
@ -346,7 +334,7 @@ namespace ranges
|
||||
}
|
||||
};
|
||||
|
||||
struct _CRBegin final
|
||||
struct _CRBegin
|
||||
{
|
||||
template<typename _Tp>
|
||||
constexpr auto
|
||||
@ -356,11 +344,9 @@ namespace ranges
|
||||
{
|
||||
return _RBegin{}(__cust_access::__as_const<_Tp>(__e));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
};
|
||||
|
||||
struct _CREnd final
|
||||
struct _CREnd
|
||||
{
|
||||
template<typename _Tp>
|
||||
constexpr auto
|
||||
@ -370,8 +356,6 @@ namespace ranges
|
||||
{
|
||||
return _REnd{}(__cust_access::__as_const<_Tp>(__e));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
@ -402,7 +386,7 @@ namespace ranges
|
||||
__detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
|
||||
};
|
||||
|
||||
struct _Size final
|
||||
struct _Size
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
@ -420,8 +404,6 @@ namespace ranges
|
||||
- _Begin{}(std::declval<_Tp&>()));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
|
||||
public:
|
||||
template<typename _Tp>
|
||||
requires is_bounded_array_v<remove_reference_t<_Tp>>
|
||||
@ -440,7 +422,7 @@ namespace ranges
|
||||
}
|
||||
};
|
||||
|
||||
struct _SSize final
|
||||
struct _SSize
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 3403. Domain of ranges::ssize(E) doesn't match ranges::size(E)
|
||||
@ -469,8 +451,6 @@ namespace ranges
|
||||
else // Must be one of __max_diff_type or __max_size_type.
|
||||
return __detail::__max_diff_type(__size);
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
@ -487,7 +467,7 @@ namespace ranges
|
||||
bool(_Begin{}(__t) == _End{}(__t));
|
||||
};
|
||||
|
||||
struct _Empty final
|
||||
struct _Empty
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
@ -503,8 +483,6 @@ namespace ranges
|
||||
== _End{}(std::declval<_Tp&>())));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
|
||||
public:
|
||||
template<typename _Tp>
|
||||
requires __member_empty<_Tp> || __size0_empty<_Tp>
|
||||
@ -534,7 +512,7 @@ namespace ranges
|
||||
template<typename _Tp>
|
||||
concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>;
|
||||
|
||||
struct _Data final
|
||||
struct _Data
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
@ -547,8 +525,6 @@ namespace ranges
|
||||
return noexcept(_Begin{}(std::declval<_Tp&>()));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
|
||||
public:
|
||||
template<__maybe_borrowed_range _Tp>
|
||||
requires __member_data<_Tp> || __begin_data<_Tp>
|
||||
@ -562,7 +538,7 @@ namespace ranges
|
||||
}
|
||||
};
|
||||
|
||||
struct _CData final
|
||||
struct _CData
|
||||
{
|
||||
template<typename _Tp>
|
||||
constexpr auto
|
||||
@ -572,8 +548,6 @@ namespace ranges
|
||||
{
|
||||
return _Data{}(__cust_access::__as_const<_Tp>(__e));
|
||||
}
|
||||
|
||||
void operator&() const = delete;
|
||||
};
|
||||
|
||||
} // namespace __cust_access
|
||||
|
@ -20,6 +20,9 @@
|
||||
|
||||
#include <iterator>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::iter_move));
|
||||
|
||||
struct X
|
||||
{
|
||||
|
@ -20,6 +20,9 @@
|
||||
|
||||
#include <iterator>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::iter_swap));
|
||||
|
||||
struct X
|
||||
{
|
||||
|
@ -19,6 +19,10 @@
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
#include <concepts>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::swap));
|
||||
|
||||
namespace nu
|
||||
{
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::begin));
|
||||
|
||||
using std::same_as;
|
||||
|
||||
void
|
||||
|
@ -20,6 +20,10 @@
|
||||
|
||||
#include <ranges>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::cbegin));
|
||||
|
||||
using std::same_as;
|
||||
|
||||
void
|
||||
|
@ -20,6 +20,9 @@
|
||||
|
||||
#include <ranges>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::cdata));
|
||||
|
||||
template<typename T>
|
||||
concept has_cdata
|
||||
|
@ -20,6 +20,9 @@
|
||||
|
||||
#include <ranges>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::cend));
|
||||
|
||||
using std::same_as;
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::crbegin));
|
||||
|
||||
struct R1
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::crend));
|
||||
|
||||
struct R1
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::data));
|
||||
|
||||
template<typename T>
|
||||
concept has_data
|
||||
= requires (T&& t) { std::ranges::data(std::forward<T>(t)); };
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::empty));
|
||||
|
||||
using std::same_as;
|
||||
|
||||
void
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::end));
|
||||
|
||||
using std::same_as;
|
||||
|
||||
void
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::rbegin));
|
||||
|
||||
struct R1
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::rend));
|
||||
|
||||
struct R1
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::size));
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
|
||||
static_assert(__gnu_test::is_customization_point_object(std::ranges::ssize));
|
||||
|
||||
using std::ptrdiff_t;
|
||||
|
||||
void
|
||||
|
@ -894,6 +894,22 @@ namespace __gnu_test
|
||||
// This is also true for test_container, although only when it has forward
|
||||
// iterators (because output_iterator_wrapper and input_iterator_wrapper are
|
||||
// not default constructible so do not model std::input_or_output_iterator).
|
||||
|
||||
|
||||
// Test for basic properties of C++20 16.3.3.6 [customization.point.object].
|
||||
template<typename T>
|
||||
constexpr bool
|
||||
is_customization_point_object(T& obj) noexcept
|
||||
{
|
||||
// A [CPO] is a function object with a literal class type.
|
||||
static_assert( std::is_class_v<T> || std::is_union_v<T> );
|
||||
static_assert( __is_literal_type(T) );
|
||||
// The type of a [CPO], ignoring cv-qualifiers, shall model semiregular.
|
||||
static_assert( std::semiregular<std::remove_cv_t<T>> );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // C++20
|
||||
} // namespace __gnu_test
|
||||
#endif // _TESTSUITE_ITERATORS
|
||||
|
Loading…
Reference in New Issue
Block a user