diff options
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/Makefile.am | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.in | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/chrono_io.h | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/ptr_traits.h | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_iterator.h | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/version.def | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/version.h | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/debug.h | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/atomicity.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/precompiled/stdc++.h | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/pstl/glue_numeric_impl.h | 16 | ||||
-rw-r--r-- | libstdc++-v3/include/pstl/numeric_impl.h | 36 | ||||
-rw-r--r-- | libstdc++-v3/include/std/mdspan | 309 | ||||
-rw-r--r-- | libstdc++-v3/include/std/numeric | 6 |
14 files changed, 376 insertions, 41 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 537774c..1140fa0 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -38,6 +38,7 @@ std_freestanding = \ ${std_srcdir}/generator \ ${std_srcdir}/iterator \ ${std_srcdir}/limits \ + ${std_srcdir}/mdspan \ ${std_srcdir}/memory \ ${std_srcdir}/numbers \ ${std_srcdir}/numeric \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 7b96b22..c96e981 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -396,6 +396,7 @@ std_freestanding = \ ${std_srcdir}/generator \ ${std_srcdir}/iterator \ ${std_srcdir}/limits \ + ${std_srcdir}/mdspan \ ${std_srcdir}/memory \ ${std_srcdir}/numbers \ ${std_srcdir}/numeric \ diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index b7f6f5f..620227a 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -705,8 +705,13 @@ namespace __format if (__write_direct) return __out; - auto __str = std::move(__sink).get(); - return __format::__write_padded_as_spec(__str, __str.size(), + auto __str = __sink.view(); + size_t __width; + if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + __width = __unicode::__field_width(__str); + else + __width = __str.size(); + return __format::__write_padded_as_spec(__str, __width, __fc, _M_spec); } diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h index 4308669..91da88b 100644 --- a/libstdc++-v3/include/bits/ptr_traits.h +++ b/libstdc++-v3/include/bits/ptr_traits.h @@ -36,7 +36,7 @@ #if __cplusplus > 201703L #include <concepts> -namespace __gnu_debug { struct _Safe_iterator_base; } +namespace __gnu_debug { class _Safe_iterator_base; } #endif namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index bed7295..478a98f 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -2511,17 +2511,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[nodiscard]] friend constexpr iter_difference_t<_It2> operator-(const counted_iterator& __x, - const counted_iterator<_It2>& __y) + const counted_iterator<_It2>& __y) noexcept { return __y._M_length - __x._M_length; } [[nodiscard]] friend constexpr iter_difference_t<_It> - operator-(const counted_iterator& __x, default_sentinel_t) + operator-(const counted_iterator& __x, default_sentinel_t) noexcept { return -__x._M_length; } [[nodiscard]] friend constexpr iter_difference_t<_It> - operator-(default_sentinel_t, const counted_iterator& __y) + operator-(default_sentinel_t, const counted_iterator& __y) noexcept { return __y._M_length; } constexpr counted_iterator& @@ -2548,19 +2548,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [[nodiscard]] friend constexpr bool operator==(const counted_iterator& __x, - const counted_iterator<_It2>& __y) + const counted_iterator<_It2>& __y) noexcept { return __x._M_length == __y._M_length; } [[nodiscard]] friend constexpr bool - operator==(const counted_iterator& __x, default_sentinel_t) + operator==(const counted_iterator& __x, default_sentinel_t) noexcept { return __x._M_length == 0; } template<common_with<_It> _It2> [[nodiscard]] friend constexpr strong_ordering operator<=>(const counted_iterator& __x, - const counted_iterator<_It2>& __y) + const counted_iterator<_It2>& __y) noexcept { return __y._M_length <=> __x._M_length; } [[nodiscard]] diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 282667e..f4d3de8 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -1000,6 +1000,15 @@ ftms = { }; ftms = { + name = mdspan; + no_stdname = true; // FIXME: remove + values = { + v = 1; // FIXME: 202207 + cxxmin = 23; + }; +}; + +ftms = { name = ssize; values = { v = 201902; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index bb7c047..d5d75ce 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -1114,6 +1114,15 @@ #endif /* !defined(__cpp_lib_span) && defined(__glibcxx_want_span) */ #undef __glibcxx_want_span +#if !defined(__cpp_lib_mdspan) +# if (__cplusplus >= 202100L) +# define __glibcxx_mdspan 1L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_mdspan) +# endif +# endif +#endif /* !defined(__cpp_lib_mdspan) && defined(__glibcxx_want_mdspan) */ +#undef __glibcxx_want_mdspan + #if !defined(__cpp_lib_ssize) # if (__cplusplus >= 202002L) # define __glibcxx_ssize 201902L diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h index 0e02d58..0131c0a 100644 --- a/libstdc++-v3/include/debug/debug.h +++ b/libstdc++-v3/include/debug/debug.h @@ -58,7 +58,7 @@ namespace __gnu_debug using namespace std::__debug; template<typename _Ite, typename _Seq, typename _Cat> - struct _Safe_iterator; + class _Safe_iterator; } #if ! defined _GLIBCXX_DEBUG || ! _GLIBCXX_HOSTED diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h index 98f745c..650b786 100644 --- a/libstdc++-v3/include/ext/atomicity.h +++ b/libstdc++-v3/include/ext/atomicity.h @@ -61,7 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // To abstract locking primitives across all thread policies, use: // __exchange_and_add_dispatch // __atomic_add_dispatch -#ifdef _GLIBCXX_ATOMIC_BUILTINS +#ifdef _GLIBCXX_ATOMIC_WORD_BUILTINS inline _Atomic_word __attribute__((__always_inline__)) __exchange_and_add(volatile _Atomic_word* __mem, int __val) @@ -71,7 +71,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __attribute__((__always_inline__)) __atomic_add(volatile _Atomic_word* __mem, int __val) { __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); } -#else +#else // Defined in config/cpu/.../atomicity.h _Atomic_word __exchange_and_add(volatile _Atomic_word*, int) _GLIBCXX_NOTHROW; diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h index f4b312d..e7d89c9 100644 --- a/libstdc++-v3/include/precompiled/stdc++.h +++ b/libstdc++-v3/include/precompiled/stdc++.h @@ -228,6 +228,7 @@ #include <flat_map> #include <flat_set> #include <generator> +#include <mdspan> #include <print> #include <spanstream> #include <stacktrace> diff --git a/libstdc++-v3/include/pstl/glue_numeric_impl.h b/libstdc++-v3/include/pstl/glue_numeric_impl.h index 10d4912..fe2d0fd 100644 --- a/libstdc++-v3/include/pstl/glue_numeric_impl.h +++ b/libstdc++-v3/include/pstl/glue_numeric_impl.h @@ -25,7 +25,7 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op) { - return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, + return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::move(__init), __binary_op, __pstl::__internal::__no_op()); } @@ -33,7 +33,7 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) { - return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, std::plus<_Tp>(), + return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::move(__init), std::plus<_Tp>(), __pstl::__internal::__no_op()); } @@ -58,7 +58,7 @@ transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forward typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __init, std::plus<_InputType>(), + __first1, __last1, __first2, std::move(__init), std::plus<_InputType>(), std::multiplies<_InputType>()); } @@ -70,7 +70,7 @@ transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forward { auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __init, __binary_op1, + __first1, __last1, __first2, std::move(__init), __binary_op1, __binary_op2); } @@ -81,7 +81,7 @@ transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIt { auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first, __last, __init, __binary_op, __unary_op); + __first, __last, std::move(__init), __binary_op, __unary_op); } // [exclusive.scan] @@ -139,7 +139,7 @@ inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIte _ForwardIterator2 __result, _BinaryOperation __binary_op, _Tp __init) { return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, - __pstl::__internal::__no_op(), __init); + __pstl::__internal::__no_op(), std::move(__init)); } // [transform.exclusive.scan] @@ -154,7 +154,7 @@ transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __result, __unary_op, __init, __binary_op, + __last, __result, __unary_op, std::move(__init), __binary_op, /*inclusive=*/std::false_type()); } @@ -170,7 +170,7 @@ transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __result, __unary_op, __init, __binary_op, + __last, __result, __unary_op, std::move(__init), __binary_op, /*inclusive=*/std::true_type()); } diff --git a/libstdc++-v3/include/pstl/numeric_impl.h b/libstdc++-v3/include/pstl/numeric_impl.h index e1ebec1..b285a66 100644 --- a/libstdc++-v3/include/pstl/numeric_impl.h +++ b/libstdc++-v3/include/pstl/numeric_impl.h @@ -35,7 +35,7 @@ __brick_transform_reduce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2, /*is_vector=*/std::false_type) noexcept { - return std::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2); + return std::inner_product(__first1, __last1, __first2, std::move(__init), __binary_op1, __binary_op2); } template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Tp, class _BinaryOperation1, @@ -48,7 +48,7 @@ __brick_transform_reduce(_RandomAccessIterator1 __first1, _RandomAccessIterator1 { typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; return __unseq_backend::__simd_transform_reduce( - __last1 - __first1, __init, __binary_op1, + __last1 - __first1, std::move(__init), __binary_op1, [=, &__binary_op2](_DifferenceType __i) { return __binary_op2(__first1[__i], __first2[__i]); }); } @@ -59,7 +59,7 @@ __pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) noexcept { - return __brick_transform_reduce(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, + return __brick_transform_reduce(__first1, __last1, __first2, std::move(__init), __binary_op1, __binary_op2, typename _Tag::__is_vector{}); } @@ -79,12 +79,12 @@ __pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& _ __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, [__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable { return __binary_op2(*__i, *(__first2 + (__i - __first1))); }, - __init, + std::move(__init), __binary_op1, // Combine [__first1, __first2, __binary_op1, __binary_op2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j, _Tp __init) -> _Tp { - return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init, + return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), std::move(__init), __binary_op1, __binary_op2, _IsVector{}); }); }); @@ -99,7 +99,7 @@ _Tp __brick_transform_reduce(_ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op, /*is_vector=*/std::false_type) noexcept { - return std::transform_reduce(__first, __last, __init, __binary_op, __unary_op); + return std::transform_reduce(__first, __last, std::move(__init), __binary_op, __unary_op); } template <class _RandomAccessIterator, class _Tp, class _UnaryOperation, class _BinaryOperation> @@ -110,7 +110,7 @@ __brick_transform_reduce(_RandomAccessIterator __first, _RandomAccessIterator __ { typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; return __unseq_backend::__simd_transform_reduce( - __last - __first, __init, __binary_op, + __last - __first, std::move(__init), __binary_op, [=, &__unary_op](_DifferenceType __i) { return __unary_op(__first[__i]); }); } @@ -120,7 +120,7 @@ _Tp __pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op) noexcept { - return __internal::__brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op, + return __internal::__brick_transform_reduce(__first, __last, std::move(__init), __binary_op, __unary_op, typename _Tag::__is_vector{}); } @@ -138,9 +138,9 @@ __pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& _ { return __par_backend::__parallel_transform_reduce( __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__unary_op](_RandomAccessIterator __i) mutable { return __unary_op(*__i); }, __init, __binary_op, + [__unary_op](_RandomAccessIterator __i) mutable { return __unary_op(*__i); }, std::move(__init), __binary_op, [__unary_op, __binary_op](_RandomAccessIterator __i, _RandomAccessIterator __j, _Tp __init) { - return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, _IsVector{}); + return __internal::__brick_transform_reduce(__i, __j, std::move(__init), __binary_op, __unary_op, _IsVector{}); }); }); } @@ -181,7 +181,7 @@ __brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __la __init = __binary_op(__init, __unary_op(*__first)); *__result = __init; } - return std::make_pair(__result, __init); + return std::make_pair(__result, std::move(__init)); } // type is arithmetic and binary operation is a user defined operation. @@ -199,11 +199,11 @@ __brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __la /*is_vector=*/std::true_type) noexcept { #if defined(_PSTL_UDS_PRESENT) - return __unseq_backend::__simd_scan(__first, __last - __first, __result, __unary_op, __init, __binary_op, + return __unseq_backend::__simd_scan(__first, __last - __first, __result, __unary_op, std::move(__init), __binary_op, _Inclusive()); #else // We need to call serial brick here to call function for inclusive and exclusive scan that depends on _Inclusive() value - return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), + return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, std::move(__init), __binary_op, _Inclusive(), /*is_vector=*/std::false_type()); #endif } @@ -215,7 +215,7 @@ __brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __la _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _Inclusive, /*is_vector=*/std::true_type) noexcept { - return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), + return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, std::move(__init), __binary_op, _Inclusive(), /*is_vector=*/std::false_type()); } @@ -247,19 +247,19 @@ __pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __e { __par_backend::__parallel_transform_scan( __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __last - __first, - [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, __init, + [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, std::move(__init), __binary_op, [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) { // Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan. - return __internal::__brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op, + return __internal::__brick_transform_reduce(__first + __i, __first + __j, std::move(__init), __binary_op, __unary_op, /*__is_vector*/ std::false_type()); }, [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init) { return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op, - __init, __binary_op, _Inclusive(), _IsVector{}) + std::move(__init), __binary_op, _Inclusive(), _IsVector{}) .second; }); return __result + (__last - __first); @@ -286,7 +286,7 @@ __pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __e [&]() { __par_backend::__parallel_strict_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, __init, + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, std::move(__init), [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len) { return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i, diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan new file mode 100644 index 0000000..aee96dd --- /dev/null +++ b/libstdc++-v3/include/std/mdspan @@ -0,0 +1,309 @@ +// <mdspan> -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file mdspan + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_MDSPAN +#define _GLIBCXX_MDSPAN 1 + +#ifdef _GLIBCXX_SYSHDR +#pragma GCC system_header +#endif + +#include <span> +#include <array> +#include <type_traits> +#include <limits> +#include <utility> + +#define __glibcxx_want_mdspan +#include <bits/version.h> + +#ifdef __glibcxx_mdspan + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + namespace __mdspan + { + template<typename _IndexType, array _Extents> + class _ExtentsStorage + { + public: + static consteval bool + _S_is_dyn(size_t __ext) noexcept + { return __ext == dynamic_extent; } + + template<typename _OIndexType> + static constexpr _IndexType + _S_int_cast(const _OIndexType& __other) noexcept + { return _IndexType(__other); } + + static constexpr size_t _S_rank = _Extents.size(); + + // For __r in [0, _S_rank], _S_dynamic_index[__r] is the number + // of dynamic extents up to (and not including) __r. + // + // If __r is the index of a dynamic extent, then + // _S_dynamic_index[__r] is the index of that extent in + // _M_dynamic_extents. + static constexpr auto _S_dynamic_index = [] consteval + { + array<size_t, _S_rank+1> __ret; + size_t __dyn = 0; + for(size_t __i = 0; __i < _S_rank; ++__i) + { + __ret[__i] = __dyn; + __dyn += _S_is_dyn(_Extents[__i]); + } + __ret[_S_rank] = __dyn; + return __ret; + }(); + + static constexpr size_t _S_rank_dynamic = _S_dynamic_index[_S_rank]; + + // For __r in [0, _S_rank_dynamic), _S_dynamic_index_inv[__r] is the + // index of the __r-th dynamic extent in _Extents. + static constexpr auto _S_dynamic_index_inv = [] consteval + { + array<size_t, _S_rank_dynamic> __ret; + for (size_t __i = 0, __r = 0; __i < _S_rank; ++__i) + if (_S_is_dyn(_Extents[__i])) + __ret[__r++] = __i; + return __ret; + }(); + + static constexpr size_t + _S_static_extent(size_t __r) noexcept + { return _Extents[__r]; } + + constexpr _IndexType + _M_extent(size_t __r) const noexcept + { + auto __se = _Extents[__r]; + if (__se == dynamic_extent) + return _M_dynamic_extents[_S_dynamic_index[__r]]; + else + return __se; + } + + template<size_t _OtherRank, typename _GetOtherExtent> + constexpr void + _M_init_dynamic_extents(_GetOtherExtent __get_extent) noexcept + { + for(size_t __i = 0; __i < _S_rank_dynamic; ++__i) + { + size_t __di = __i; + if constexpr (_OtherRank != _S_rank_dynamic) + __di = _S_dynamic_index_inv[__i]; + _M_dynamic_extents[__i] = _S_int_cast(__get_extent(__di)); + } + } + + constexpr + _ExtentsStorage() noexcept = default; + + template<typename _OIndexType, array _OExtents> + constexpr + _ExtentsStorage(const _ExtentsStorage<_OIndexType, _OExtents>& + __other) noexcept + { + _M_init_dynamic_extents<_S_rank>([&__other](size_t __i) + { return __other._M_extent(__i); }); + } + + template<typename _OIndexType, size_t _Nm> + constexpr + _ExtentsStorage(span<const _OIndexType, _Nm> __exts) noexcept + { + _M_init_dynamic_extents<_Nm>( + [&__exts](size_t __i) -> const _OIndexType& + { return __exts[__i]; }); + } + + private: + using _S_storage = __array_traits<_IndexType, _S_rank_dynamic>::_Type; + [[no_unique_address]] _S_storage _M_dynamic_extents; + }; + + template<typename _OIndexType, typename _SIndexType> + concept __valid_index_type = + is_convertible_v<_OIndexType, _SIndexType> && + is_nothrow_constructible_v<_SIndexType, _OIndexType>; + + template<size_t _Extent, typename _IndexType> + concept + __valid_static_extent = _Extent == dynamic_extent + || _Extent <= numeric_limits<_IndexType>::max(); + } + + template<typename _IndexType, size_t... _Extents> + class extents + { + static_assert(is_integral_v<_IndexType>, "_IndexType must be integral."); + static_assert( + (__mdspan::__valid_static_extent<_Extents, _IndexType> && ...), + "Extents must either be dynamic or representable as _IndexType"); + + public: + using index_type = _IndexType; + using size_type = make_unsigned_t<index_type>; + using rank_type = size_t; + + static constexpr rank_type + rank() noexcept { return _S_storage::_S_rank; } + + static constexpr rank_type + rank_dynamic() noexcept { return _S_storage::_S_rank_dynamic; } + + static constexpr size_t + static_extent(rank_type __r) noexcept + { + __glibcxx_assert(__r < rank()); + if constexpr (rank() == 0) + __builtin_trap(); + else + return _S_storage::_S_static_extent(__r); + } + + constexpr index_type + extent(rank_type __r) const noexcept + { + __glibcxx_assert(__r < rank()); + if constexpr (rank() == 0) + __builtin_trap(); + else + return _M_dynamic_extents._M_extent(__r); + } + + constexpr + extents() noexcept = default; + + private: + static consteval bool + _S_is_less_dynamic(size_t __ext, size_t __oext) + { return (__ext != dynamic_extent) && (__oext == dynamic_extent); } + + template<typename _OIndexType, size_t... _OExtents> + static consteval bool + _S_ctor_explicit() + { + return (_S_is_less_dynamic(_Extents, _OExtents) || ...) + || (numeric_limits<index_type>::max() + < numeric_limits<_OIndexType>::max()); + } + + template<size_t... _OExtents> + static consteval bool + _S_is_compatible_extents() + { + if constexpr (sizeof...(_OExtents) != rank()) + return false; + else + return ((_OExtents == dynamic_extent || _Extents == dynamic_extent + || _OExtents == _Extents) && ...); + } + + public: + template<typename _OIndexType, size_t... _OExtents> + requires (_S_is_compatible_extents<_OExtents...>()) + constexpr explicit(_S_ctor_explicit<_OIndexType, _OExtents...>()) + extents(const extents<_OIndexType, _OExtents...>& __other) noexcept + : _M_dynamic_extents(__other._M_dynamic_extents) + { } + + template<__mdspan::__valid_index_type<index_type>... _OIndexTypes> + requires (sizeof...(_OIndexTypes) == rank() + || sizeof...(_OIndexTypes) == rank_dynamic()) + constexpr explicit extents(_OIndexTypes... __exts) noexcept + : _M_dynamic_extents(span<const _IndexType, sizeof...(_OIndexTypes)>( + initializer_list{_S_storage::_S_int_cast(__exts)...})) + { } + + template<__mdspan::__valid_index_type<index_type> _OIndexType, size_t _Nm> + requires (_Nm == rank() || _Nm == rank_dynamic()) + constexpr explicit(_Nm != rank_dynamic()) + extents(span<_OIndexType, _Nm> __exts) noexcept + : _M_dynamic_extents(span<const _OIndexType, _Nm>(__exts)) + { } + + + template<__mdspan::__valid_index_type<index_type> _OIndexType, size_t _Nm> + requires (_Nm == rank() || _Nm == rank_dynamic()) + constexpr explicit(_Nm != rank_dynamic()) + extents(const array<_OIndexType, _Nm>& __exts) noexcept + : _M_dynamic_extents(span<const _OIndexType, _Nm>(__exts)) + { } + + template<typename _OIndexType, size_t... _OExtents> + friend constexpr bool + operator==(const extents& __self, + const extents<_OIndexType, _OExtents...>& __other) noexcept + { + if constexpr (!_S_is_compatible_extents<_OExtents...>()) + return false; + else + { + for (size_t __i = 0; __i < __self.rank(); ++__i) + if (!cmp_equal(__self.extent(__i), __other.extent(__i))) + return false; + return true; + } + } + + private: + using _S_storage = __mdspan::_ExtentsStorage< + _IndexType, array<size_t, sizeof...(_Extents)>{_Extents...}>; + [[no_unique_address]] _S_storage _M_dynamic_extents; + + template<typename _OIndexType, size_t... _OExtents> + friend class extents; + }; + + namespace __mdspan + { + template<typename _IndexType, size_t... _Counts> + auto __build_dextents_type(integer_sequence<size_t, _Counts...>) + -> extents<_IndexType, ((void) _Counts, dynamic_extent)...>; + + template<typename _Tp> + consteval size_t + __dynamic_extent() { return dynamic_extent; } + } + + template<typename _IndexType, size_t _Rank> + using dextents = decltype(__mdspan::__build_dextents_type<_IndexType>( + make_index_sequence<_Rank>())); + + template<typename... _Integrals> + requires (is_convertible_v<_Integrals, size_t> && ...) + explicit extents(_Integrals...) -> + extents<size_t, __mdspan::__dynamic_extent<_Integrals>()...>; + +_GLIBCXX_END_NAMESPACE_VERSION +} +#endif +#endif diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric index 490963e..cbabf031 100644 --- a/libstdc++-v3/include/std/numeric +++ b/libstdc++-v3/include/std/numeric @@ -582,7 +582,7 @@ namespace __detail { if (__first != __last) { - auto __init = *__first; + auto __init = std::move(*__first); *__result++ = __init; ++__first; if (__first != __last) @@ -645,8 +645,8 @@ namespace __detail { while (__first != __last) { - auto __v = __init; - __init = __binary_op(__init, __unary_op(*__first)); + auto __v = std::move(__init); + __init = __binary_op(__v, __unary_op(*__first)); ++__first; *__result++ = std::move(__v); } |