On Tue, 31 Mar 2026 at 09:19, Jakub Jelinek <[email protected]> wrote:
>
> On Mon, Mar 30, 2026 at 07:37:58PM +0200, Tomasz Kaminski wrote:
> > I have patches fixing other LWG issues that need above concept, that
> > are waiting for stage-1. I will handle move and merge then. So let's keep
> > it as is.
>
> Ok.  Here is what I've actually bootstrapped/regtested on x86_64-linux
> and i686-linux successfully.  Ok for trunk?

OK thanks.
>
> 2026-03-31  Jakub Jelinek  <[email protected]>
>
>         * include/std/meta (std::meta::__detail::__statically_sized): New
>         concept.
>         (std::meta::define_static_array): Change return type to auto.  If
>         __statically_sized<_Rg>, return span with ranges::size(__r) as
>         second argument.
>
>         * g++.dg/reflect/define_static_array1.C (l): Another variable
>         with define_static_array test from array<int, 0>.
>         Add static assertions for types of the define_static_array results.
>
> --- libstdc++-v3/include/std/meta.jj    2026-03-30 12:57:50.289580921 +0200
> +++ libstdc++-v3/include/std/meta       2026-03-30 18:44:44.485289658 +0200
> @@ -632,18 +632,41 @@ _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 span<const ranges::range_value_t<_Rg>>
> +    consteval auto
>      define_static_array(_Rg&& __r)
>      {
>        using _Tp = ranges::range_value_t<_Rg>;
>        auto __array = meta::reflect_constant_array(__r);
>        auto __type = meta::type_of(__array);
> -      if (meta::is_array_type(__type))
> -       return span<const _Tp>(meta::extract<const _Tp*>(__array),
> -                              meta::extent(__type, 0U));
> +      if constexpr (__detail::__statically_sized<_Rg>)
> +       {
> +         constexpr size_t __extent = static_cast<size_t>(ranges::size(__r));
> +         if constexpr (__extent)
> +           return span<const _Tp,
> +                       __extent>(meta::extract<const _Tp*>(__array),
> +                                 meta::extent(__type, 0U));
> +         else
> +           return span<const _Tp, 0>();
> +       }
>        else
> -       return span<const _Tp>();
> +       {
> +         if (meta::is_array_type(__type))
> +           return span<const _Tp>(meta::extract<const _Tp*>(__array),
> +                                  meta::extent(__type, 0U));
> +         else
> +           return span<const _Tp>();
> +       }
>      }
>
>    template<class _Tp>
> --- gcc/testsuite/g++.dg/reflect/define_static_array1.C.jj      2026-03-27 
> 10:17:16.120298331 +0100
> +++ gcc/testsuite/g++.dg/reflect/define_static_array1.C 2026-03-30 
> 15:19:15.286549988 +0200
> @@ -22,6 +22,7 @@ constexpr auto h = std::define_static_ar
>  constexpr auto i = std::define_static_array (std::vector <V> { V { 1, 2, 3 
> }, V { 2, 3, 4 }, V { 3, 4, 5 } });
>  constexpr auto j = std::define_static_array (std::vector <long long> {});
>  constexpr auto k = std::define_static_array 
> (std::meta::nonstatic_data_members_of (^^V, 
> std::meta::access_context::current ()));
> +constexpr auto l = std::define_static_array (std::array <int, 0> {});
>  static_assert (a.data () == std::define_static_string ("abcd") && a.size () 
> == 5);
>  static_assert (b.data () == std::define_static_string (U"abcd\0ef\N{LATIN 
> CAPITAL LETTER AE}")
>                && b.size () == sizeof (U"abcd\0ef\N{LATIN CAPITAL LETTER 
> AE}") / sizeof (char32_t));
> @@ -40,6 +41,19 @@ static_assert (h.data () == std::define_
>  static_assert (i.size () == 3);
>  static_assert (j.data () == nullptr && j.size () == 0);
>  static_assert (k.size () == 3 && k[0] == ^^V::a && k[1] == ^^V::b && k[2] == 
> ^^V::c);
> +static_assert (l.data () == nullptr && l.size () == 0);
> +static_assert (type_of (^^a) == ^^const std::span <const char, 5>);
> +static_assert (type_of (^^b) == ^^const std::span <const char32_t, sizeof 
> (U"abcd\0ef\N{LATIN CAPITAL LETTER AE}") / sizeof (char32_t)>);
> +static_assert (type_of (^^c) == ^^const std::span <const char, 
> std::dynamic_extent>);
> +static_assert (type_of (^^d) == ^^const std::span <const int, 4>);
> +static_assert (type_of (^^e) == ^^const std::span <const float, 6>);
> +static_assert (type_of (^^f) == ^^const std::span <const int, 
> std::dynamic_extent>);
> +static_assert (type_of (^^g) == ^^const std::span <const int, 
> std::dynamic_extent>);
> +static_assert (type_of (^^h) == ^^const std::span <const int, 
> std::dynamic_extent>);
> +static_assert (type_of (^^i) == ^^const std::span <const V, 
> std::dynamic_extent>);
> +static_assert (type_of (^^j) == ^^const std::span <const long long, 
> std::dynamic_extent>);
> +static_assert (type_of (^^k) == ^^const std::span <const std::meta::info, 
> std::dynamic_extent>);
> +static_assert (type_of (^^l) == ^^const std::span <const int, 0>);
>
>  int
>  main ()
>
>
>         Jakub
>

Reply via email to