https://gcc.gnu.org/g:68b90fc4e95ba1ecaa6a2ca9d59be87000968e78
commit r17-805-g68b90fc4e95ba1ecaa6a2ca9d59be87000968e78 Author: Tomasz Kamiński <[email protected]> Date: Fri Apr 24 05:25:47 2026 +0200 libstdc++: Merged concept for ranges with static sized. This patch replaces duplicated __detail::__statically_sized (from std/meta) and simd::__static_sized_range (from include/bits/simd_details.h) concepts with single range::__static_sized_range. The concept uses the implementation based on __statically_sized concept, as it avoids triggering instantiations of some class template for each possible size value. libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (ranges::__static_sized_range): Define. * include/bits/simd_details.h (simd::__static_sized_range): Remove. (simd::__static_range_size): Use ranges::__static_sized_range. * include/bits/simd_loadstore.h (simd::unchecked_store) (simd::unchecked_load): Use ranges::__static_sized_range. * include/bits/simd_vec.h (basic_vec::basic_vec(_Rg&&, flags<_Flags>)): Replace __static_sized_range<_Rg, _S_size> with ranges::__static_sized_range<_Rg> and traing requires size for size value. * include/std/meta (__detail::__statically_sized): Remove. (std::define_static_array): Use ranges::__static_sized_range. * testsuite/std/simd/traits_impl.cc: Remove test for simd::__static_sized_range. Reviewed-by: Jonathan Wakely <[email protected]> Reviewed-by: Patrick Palka <[email protected]> Signed-off-by: Tomasz Kamiński <[email protected]> Diff: --- libstdc++-v3/include/bits/ranges_base.h | 6 ++++++ libstdc++-v3/include/bits/simd_details.h | 9 +-------- libstdc++-v3/include/bits/simd_loadstore.h | 8 ++++---- libstdc++-v3/include/bits/simd_vec.h | 12 +++++++----- libstdc++-v3/include/std/meta | 12 +----------- libstdc++-v3/testsuite/std/simd/traits_impl.cc | 4 ---- 6 files changed, 19 insertions(+), 32 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 519927f5613e..fea4100eb09e 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -558,6 +558,12 @@ namespace ranges template<sized_range _Range> using range_size_t = decltype(ranges::size(std::declval<_Range&>())); +#if __cplusplus > 202302L + template<typename _Tp> + concept __static_sized_range = sized_range<_Tp> && requires (_Tp& __t) + { static_cast<char(*)[size_t(ranges::size(__t) >= 0)]>(nullptr); }; +#endif // C++26 + template<typename _Derived> requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> class view_interface; // defined in <bits/ranges_util.h> diff --git a/libstdc++-v3/include/bits/simd_details.h b/libstdc++-v3/include/bits/simd_details.h index a1acc5bd9464..e2002b6de824 100644 --- a/libstdc++-v3/include/bits/simd_details.h +++ b/libstdc++-v3/include/bits/simd_details.h @@ -986,18 +986,11 @@ namespace simd using mask = basic_mask<sizeof(_Tp), __deduce_abi_t<_Tp, _Np>>; // [simd.ctor] load constructor constraints - template <typename _Tp, size_t _Np = -1uz> - concept __static_sized_range - = ranges::sized_range<_Tp> && requires(_Tp&& __r) { - typename integral_constant<size_t, ranges::size(__r)>; - requires (_Np == -1uz || ranges::size(__r) == _Np); - }; - template <typename _Rg> consteval size_t __static_range_size(_Rg& __r) { - if constexpr (requires { typename integral_constant<size_t, ranges::size(__r)>; }) + if constexpr (ranges::__static_sized_range<_Rg>) return ranges::size(__r); else return dynamic_extent; diff --git a/libstdc++-v3/include/bits/simd_loadstore.h b/libstdc++-v3/include/bits/simd_loadstore.h index 20c5fb5cf7fe..2390ea289f5c 100644 --- a/libstdc++-v3/include/bits/simd_loadstore.h +++ b/libstdc++-v3/include/bits/simd_loadstore.h @@ -75,7 +75,7 @@ namespace simd constexpr bool __allow_out_of_bounds = __f._S_test(__allow_partial_loadstore); constexpr size_t __static_size = __static_range_size(__r); - if constexpr (!__allow_out_of_bounds && __static_sized_range<_Rg>) + if constexpr (!__allow_out_of_bounds && ranges::__static_sized_range<_Rg>) static_assert(ranges::size(__r) >= _RV::size(), "given range must have sufficient size"); const auto* __ptr = __f.template _S_adjust_pointer<_RV>(ranges::data(__r)); @@ -121,7 +121,7 @@ namespace simd constexpr bool __allow_out_of_bounds = __f._S_test(__allow_partial_loadstore); constexpr auto __static_size = __static_range_size(__r); - if constexpr (!__allow_out_of_bounds && __static_sized_range<_Rg>) + if constexpr (!__allow_out_of_bounds && ranges::__static_sized_range<_Rg>) static_assert(ranges::size(__r) >= _RV::size(), "given range must have sufficient size"); const auto* __ptr = __f.template _S_adjust_pointer<_RV>(ranges::data(__r)); @@ -248,7 +248,7 @@ namespace simd "'flag_convert' must be used for conversions that are not value-preserving"); constexpr bool __allow_out_of_bounds = __f._S_test(__allow_partial_loadstore); - if constexpr (!__allow_out_of_bounds && __static_sized_range<_Rg>) + if constexpr (!__allow_out_of_bounds && ranges::__static_sized_range<_Rg>) static_assert(ranges::size(__r) >= _TV::size(), "given range must have sufficient size"); auto* __ptr = __f.template _S_adjust_pointer<_TV>(ranges::data(__r)); @@ -285,7 +285,7 @@ namespace simd "'flag_convert' must be used for conversions that are not value-preserving"); constexpr bool __allow_out_of_bounds = __f._S_test(__allow_partial_loadstore); - if constexpr (!__allow_out_of_bounds && __static_sized_range<_Rg>) + if constexpr (!__allow_out_of_bounds && ranges::__static_sized_range<_Rg>) static_assert(ranges::size(__r) >= _TV::size(), "given range must have sufficient size"); auto* __ptr = __f.template _S_adjust_pointer<_TV>(ranges::data(__r)); diff --git a/libstdc++-v3/include/bits/simd_vec.h b/libstdc++-v3/include/bits/simd_vec.h index 5f3bd7fd2f61..6657587e4d4a 100644 --- a/libstdc++-v3/include/bits/simd_vec.h +++ b/libstdc++-v3/include/bits/simd_vec.h @@ -1207,14 +1207,15 @@ namespace simd } template <ranges::contiguous_range _Rg, typename... _Flags> - requires __static_sized_range<_Rg, _S_size> + requires ranges::__static_sized_range<_Rg> && __vectorizable<ranges::range_value_t<_Rg>> && __explicitly_convertible_to<ranges::range_value_t<_Rg>, value_type> [[__gnu__::__always_inline__]] constexpr basic_vec(_Rg&& __range, flags<_Flags...> __flags = {}) - : basic_vec(_LoadCtorTag(), __flags.template _S_adjust_pointer<basic_vec>( - ranges::data(__range))) + requires (ranges::size(__range) == _S_size) + : basic_vec(_LoadCtorTag(), __flags.template _S_adjust_pointer<basic_vec>( + ranges::data(__range))) { static_assert(__loadstore_convertible_to<ranges::range_value_t<_Rg>, value_type, _Flags...>); @@ -2072,11 +2073,12 @@ namespace simd {} template <ranges::contiguous_range _Rg, typename... _Flags> - requires __static_sized_range<_Rg, _S_size> + requires ranges::__static_sized_range<_Rg> && __vectorizable<ranges::range_value_t<_Rg>> && __explicitly_convertible_to<ranges::range_value_t<_Rg>, value_type> constexpr basic_vec(_Rg&& __range, flags<_Flags...> __flags = {}) + requires (ranges::size(__range) == _S_size) : basic_vec(_LoadCtorTag(), __flags.template _S_adjust_pointer<basic_vec>(ranges::data(__range))) { @@ -2245,7 +2247,7 @@ namespace simd // [simd.overview] deduction guide ------------------------------------------ template <ranges::contiguous_range _Rg, typename... _Ts> - requires __static_sized_range<_Rg> + requires ranges::__static_sized_range<_Rg> basic_vec(_Rg&& __r, _Ts...) -> basic_vec<ranges::range_value_t<_Rg>, __deduce_abi_t<ranges::range_value_t<_Rg>, diff --git a/libstdc++-v3/include/std/meta b/libstdc++-v3/include/std/meta index 21a4df45bfc0..bc04dddcb649 100644 --- a/libstdc++-v3/include/std/meta +++ b/libstdc++-v3/include/std/meta @@ -640,16 +640,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return meta::extract<const ranges::range_value_t<_Rg>*>(__str); } - namespace __detail - { - template<typename _Rg> - concept __statically_sized - = requires(_Rg&& __r) { - static_cast<char(*)[static_cast<size_t>(ranges::size(__r)) - >= 0]>(nullptr); - }; - } // namespace __detail - template<ranges::input_range _Rg> consteval auto define_static_array(_Rg&& __r) @@ -657,7 +647,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _Tp = ranges::range_value_t<_Rg>; auto __array = meta::reflect_constant_array(__r); auto __type = meta::type_of(__array); - if constexpr (__detail::__statically_sized<_Rg>) + if constexpr (ranges::__static_sized_range<_Rg>) { constexpr size_t __extent = static_cast<size_t>(ranges::size(__r)); if constexpr (__extent) diff --git a/libstdc++-v3/testsuite/std/simd/traits_impl.cc b/libstdc++-v3/testsuite/std/simd/traits_impl.cc index 2f705c7df2f7..02e2b690a6a6 100644 --- a/libstdc++-v3/testsuite/std/simd/traits_impl.cc +++ b/libstdc++-v3/testsuite/std/simd/traits_impl.cc @@ -83,10 +83,6 @@ void test() static_assert(!__streq_to_1("0")); static_assert(!__streq_to_1("1 ")); - static_assert(__static_sized_range<int[4]>); - static_assert(__static_sized_range<int[4], 4>); - static_assert(__static_sized_range<std::array<int, 4>, 4>); - static_assert( __value_preserving_convertible_to<int, double>); static_assert(!__value_preserving_convertible_to<int, float>); static_assert( __value_preserving_convertible_to<float, double>);
