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 >
