Commit a7922ddf by JeanHeyd "ThePhD" Meneide Committed by Jonathan Wakely

libstdc++: Implement P1872R0 and P1394R0 for std::span

This also fixes a bug in the implementation of LWG 3255, which causes:
FAIL: 23_containers/span/lwg3255.cc (test for excess errors)
That's because the test was wrong and verified the buggy behaviour. That
will be fixed in the following commit.

2019-12-05  JeanHeyd "ThePhD" Meneide  <phdofthehouse@gmail.com>

	Implement P1872R0 and P1394R0 for std::span
	* include/bits/range_access.h (__adl_begin, __adl_end): Remove.
	(sentinel_t, range_value_t, range_reference_t)
	(range_rvalue_reference_t, __forwarding_range, disable_sized_range)
	(output_range, input_range, forward_range, bidirectional_range)
	(random_access_range, contiguous_range, common_range): Move here from
	<ranges>, to make this the "ranges lite" internal header.
	* include/std/ranges: Move basic aliases and concepts to
	<bits/range_access.h>.
	* include/std/span: Use concepts and ranges:: calls instead of
	enable_if and friends.
	* include/std/type_traits: Add __is_array_convertible trait.

From-SVN: r279000
parent b0a71a18
2019-12-05 JeanHeyd "ThePhD" Meneide <phdofthehouse@gmail.com>
Implement P1872R0 and P1394R0 for std::span
* include/bits/range_access.h (__adl_begin, __adl_end): Remove.
(sentinel_t, range_value_t, range_reference_t)
(range_rvalue_reference_t, __forwarding_range, disable_sized_range)
(output_range, input_range, forward_range, bidirectional_range)
(random_access_range, contiguous_range, common_range): Move here from
<ranges>, to make this the "ranges lite" internal header.
* include/std/ranges: Move basic aliases and concepts to
<bits/range_access.h>.
* include/std/span: Use concepts and ranges:: calls instead of
enable_if and friends.
* include/std/type_traits: Add __is_array_convertible trait.
2019-12-05 Jonathan Wakely <jwakely@redhat.com> 2019-12-05 Jonathan Wakely <jwakely@redhat.com>
* include/bits/stl_algobase.h (lexicographical_compare_three_way): * include/bits/stl_algobase.h (lexicographical_compare_three_way):
......
...@@ -336,19 +336,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -336,19 +336,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
ssize(const _Tp (&)[_Num]) noexcept ssize(const _Tp (&)[_Num]) noexcept
{ return _Num; } { return _Num; }
// "why are these in namespace std:: and not __gnu_cxx:: ?"
// because if we don't put them here it's impossible to
// have implicit ADL with "using std::begin/end/size/data;".
template <typename _Container>
constexpr auto
__adl_begin(_Container& __cont) noexcept(noexcept(begin(__cont)))
{ return begin(__cont); }
template <typename _Container>
constexpr auto
__adl_data(_Container& __cont) noexcept(noexcept(data(__cont)))
{ return data(__cont); }
#ifdef __cpp_lib_concepts #ifdef __cpp_lib_concepts
namespace ranges namespace ranges
{ {
...@@ -869,11 +856,71 @@ namespace ranges ...@@ -869,11 +856,71 @@ namespace ranges
template<typename _Tp> template<typename _Tp>
concept range = __detail::__range_impl<_Tp&>; concept range = __detail::__range_impl<_Tp&>;
template<range _Range>
using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));
template<range _Range>
using iterator_t = decltype(ranges::begin(std::declval<_Range&>()));
template<range _Range>
using range_value_t = iter_value_t<iterator_t<_Range>>;
template<range _Range>
using range_reference_t = iter_reference_t<iterator_t<_Range>>;
template<range _Range>
using range_rvalue_reference_t
= iter_rvalue_reference_t<iterator_t<_Range>>;
template<range _Range>
using range_difference_t = iter_difference_t<iterator_t<_Range>>;
namespace __detail
{
template<typename _Tp>
concept __forwarding_range = range<_Tp> && __range_impl<_Tp>;
} // namespace __detail
/// [range.sized] The sized_range concept. /// [range.sized] The sized_range concept.
template<typename _Tp> template<typename _Tp>
concept sized_range = range<_Tp> concept sized_range = range<_Tp>
&& requires(_Tp& __t) { ranges::size(__t); }; && requires(_Tp& __t) { ranges::size(__t); };
template<typename>
inline constexpr bool disable_sized_range = false;
// [range.refinements]
template<typename _Range, typename _Tp>
concept output_range
= range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
template<typename _Tp>
concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept forward_range
= input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept bidirectional_range
= forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept random_access_range
= bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept contiguous_range
= random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
&& requires(_Tp& __t)
{
{ ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
};
template<typename _Tp>
concept common_range
= range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
// [range.iter.ops] range iterator operations // [range.iter.ops] range iterator operations
template<input_or_output_iterator _It> template<input_or_output_iterator _It>
...@@ -1009,12 +1056,6 @@ namespace ranges ...@@ -1009,12 +1056,6 @@ namespace ranges
} }
template<range _Range> template<range _Range>
using iterator_t = decltype(ranges::begin(std::declval<_Range&>()));
template<range _Range>
using range_difference_t = iter_difference_t<iterator_t<_Range>>;
template<range _Range>
constexpr range_difference_t<_Range> constexpr range_difference_t<_Range>
distance(_Range&& __r) distance(_Range&& __r)
{ {
......
...@@ -56,64 +56,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -56,64 +56,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges namespace ranges
{ {
// [range.range] The range concept. // [range.range] The range concept.
// Defined in <bits/range_iterator.h>
// template<typename> concept range;
template<range _Range>
using sentinel_t = decltype(ranges::end(std::declval<_Range&>()));
template<range _Range>
using range_value_t = iter_value_t<iterator_t<_Range>>;
template<range _Range>
using range_reference_t = iter_reference_t<iterator_t<_Range>>;
template<range _Range>
using range_rvalue_reference_t
= iter_rvalue_reference_t<iterator_t<_Range>>;
namespace __detail
{
template<typename _Tp>
concept __forwarding_range = range<_Tp> && __range_impl<_Tp>;
} // namespace __detail
// [range.sized] The sized_range concept. // [range.sized] The sized_range concept.
// Defined in <bits/range_iterator.h> // Defined in <bits/range_access.h>
// template<typename> concept sized_range;
// [range.refinements] // [range.refinements]
// Defined in <bits/range_access.h>
template<typename _Range, typename _Tp>
concept output_range
= range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
template<typename _Tp>
concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept forward_range
= input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept bidirectional_range
= forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept random_access_range
= bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
template<typename _Tp>
concept contiguous_range
= random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
&& requires(_Tp& __t)
{
{ ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
};
template<typename _Tp>
concept common_range
= range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
struct view_base { }; struct view_base { };
......
...@@ -1475,6 +1475,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1475,6 +1475,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}; };
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
// helper trait for unique_ptr<T[]>, shared_ptr<T[]>, and span<T, N>
template<typename _ToElementType, typename _FromElementType>
using __is_array_convertible
= is_convertible<_FromElementType(*)[], _ToElementType(*)[]>;
// is_nothrow_convertible for C++11 // is_nothrow_convertible for C++11
template<typename _From, typename _To> template<typename _From, typename _To>
struct __is_nothrow_convertible struct __is_nothrow_convertible
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment