[PATCH v1 6/6] libstdc++: Replace numeric_limit with __int_traits in mdspan.
Jonathan Wakely
jwakely.gcc@gmail.com
Mon Jul 28 08:29:03 GMT 2025
On Sun, 27 Jul 2025, 14:54 Luc Grosheintz, <luc.grosheintz@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.grosheintz@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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250728/e4972b3c/attachment-0001.htm>
More information about the Libstdc++
mailing list