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
>
>

Reply via email to