On Sun, 27 Jul 2025, 14:54 Luc Grosheintz, <luc.groshei...@gmail.com> wrote:
> Using __int_traits avoids the need to include <limits> from <mdspan>. > This in turn should reduce the size of the pre-compiled <mdspan>. > Similar refactoring was carried out for PR92546. Unfortunately, > > ./gcc/xgcc -std=c++23 -P -E -x c++ - -include mdspan | wc -l > > shows a decrease by 1(!) line. This is due to bits/max_size_type.h which > includes <limits>. > It should still be cheaper for the compiler to instantiate __int_traits than numeric_limits. Maybe we should split the helper macros and numeric_limits primary template into a new bits/numeric_limits.h header, which could be included separately from all the explicit specializations in <limits>. But that can wait for another day. > libstdc++-v3/ChangeLog: > > * include/std/mdspan (__valid_static_extent): Replace > numeric_limits with __int_traits. > (extents::_S_ctor_explicit): ditto. > (extents::__static_quotient): ditto. > (layout_stride::mapping::mapping): ditto. > * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: > Update test with additional diagnostics. > > Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> > --- > libstdc++-v3/include/std/mdspan | 26 ++++++++++--------- > .../mdspan/extents/class_mandates_neg.cc | 3 +++ > 2 files changed, 17 insertions(+), 12 deletions(-) > > diff --git a/libstdc++-v3/include/std/mdspan > b/libstdc++-v3/include/std/mdspan > index 2cf572f1410..8fc853e7b5b 100644 > --- a/libstdc++-v3/include/std/mdspan > +++ b/libstdc++-v3/include/std/mdspan > @@ -36,7 +36,6 @@ > #include <span> > #include <array> > #include <type_traits> > -#include <limits> > #include <utility> > > #define __glibcxx_want_mdspan > @@ -195,7 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > template<size_t _Extent, typename _IndexType> > concept > __valid_static_extent = _Extent == dynamic_extent > - || _Extent <= numeric_limits<_IndexType>::max(); > + || _Extent <= __gnu_cxx::__int_traits<_IndexType>::__max; > > template<array _Extents> > consteval size_t > @@ -306,8 +305,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > _S_ctor_explicit() > { > return (_S_is_less_dynamic(_Extents, _OExtents) || ...) > - || (numeric_limits<index_type>::max() > - < numeric_limits<_OIndexType>::max()); > + || (__gnu_cxx::__int_traits<index_type>::__max > + < __gnu_cxx::__int_traits<_OIndexType>::__max); > } > > template<size_t... _OExtents> > @@ -515,7 +514,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > template<typename _Extents, > typename _IndexType = typename _Extents::index_type> > consteval _IndexType > - __static_quotient(_IndexType __nom = > numeric_limits<_IndexType>::max()) > + __static_quotient(_IndexType __nom = > __gnu_cxx::__int_traits<_IndexType> > + ::__max) > { > auto __sta_exts = __static_extents<_Extents>(); > for (auto __factor : __sta_exts) > @@ -974,12 +974,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > static_assert(__mdspan::__representable_size<_OExtents, > index_type>, > "The size of StridedMapping::extents_type must be > representable as" > " index_type"); > - if constexpr (cmp_greater(numeric_limits<_OIndexType>::max(), > - numeric_limits<index_type>::max())) > - __glibcxx_assert(!cmp_less(numeric_limits<index_type>::max(), > - __other.required_span_size()) > - && "other.required_span_size() must be representable" > - " as index_type"); > + if constexpr > (cmp_greater(__gnu_cxx::__int_traits<_OIndexType>::__max, > + > __gnu_cxx::__int_traits<index_type>::__max)) > + __glibcxx_assert(!cmp_less( > + __gnu_cxx::__int_traits<index_type>::__max, > + __other.required_span_size()) > + && "other.required_span_size() must be representable" > + " as index_type"); > if constexpr (extents_type::rank() > 0) > for (size_t __i = 0; __i < extents_type::rank(); ++__i) > _M_strides[__i] = index_type(__other.stride(__i)); > @@ -1296,7 +1297,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > size() const noexcept > { > __glibcxx_assert(cmp_less_equal(_M_mapping.required_span_size(), > - numeric_limits<size_t>::max())); > + __gnu_cxx::__int_traits<size_t> > + ::__max)); > return size_type(__mdspan::__size(extents())); > } > > diff --git > a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > index 67d18feda96..db5cad27e52 100644 > --- > a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > +++ > b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > @@ -12,3 +12,6 @@ std::extents<double, 1> e4; // { dg-error > "from here" } > // { dg-prune-output "signed or unsigned integer" } > // { dg-prune-output "invalid use of incomplete type" } > // { dg-prune-output "non-constant condition for static assertion" } > +// { dg-prune-output "integer constants in boolean context" } > +// { dg-prune-output "__gnu_cxx::__numeric_traits_integer" } > +// { dg-prune-output "static assertion failed" } > -- > 2.50.0 > >