On Mon, Mar 30, 2026 at 04:08:02PM +0200, Tomasz Kaminski wrote:
> The ternary expression does not have not-compiled branches, so
> ranges::size(__r) needs to always
> be constant expression.
> constexpr size_t __extent = __detail::__statically_sized<_Rg> ?
> ranges::size(__r) : dynamic_extent;
>
> You can implement it using lambda:
> constexpr size_t __extent = [&__r] {
> if constexpr (__detail::__statically_sized<_Rg> )
> return ranges::size(__r);
> else
> return dynamic_extent;
> };
>
> But my preference would be to split the whole body:
> if constexpr (__detail::__statically_sized<_Rg>)
> {
> constexpr size_t __size = ranges::size(__r) ;
> if constexpr (__size > 0)
> return span<const _Tp, __size>(meta::extract<const
> _Tp(&)[__size]>(__array)); // use span from c-array cosntructor
> // you can also use ptr, size
> else
> return span<const _Tp, 0>(); // default constructor
> }
> else // The old code that we already have, without any changes
Ah, you're right. Both the attached patches seem to work (just posting
the meta change, the rest is the same).
Tested with the uglification and std module plugins and
GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make check-g++ -j32 -k
RUNTESTFLAGS="plugin.exp dg.exp=reflect/*"
so far, range_args.C is fine now.
> > + namespace __detail
> > + {
> > + template<typename _Rg>
> > + concept __statically_sized
> > + = requires(_Rg&& __r) {
> >
> + static_cast<char(*)[static_cast<size_t>(ranges::size(__r))
> > + >= 0]>(nullptr);
> >
> That nice trick, could you rename it to __static_sized_range, and put it
> in ranges_base.h?
Into std::__detail::__static_sized_range or std::__static_sized_range ?
And somehow merge with the simd one?
> I got problem with my version when imported from module std, do you see the
> same issue?
Does the plugin.exp trigger it? There it builds bits/std.cc (but admittedly
doesn't test import module std;).
Jakub
--- libstdc++-v3/include/std/meta.jj 2026-03-30 18:14:21.058354336 +0200
+++ libstdc++-v3/include/std/meta 2026-03-30 18:37:29.988681673 +0200
@@ -632,18 +632,35 @@ _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);
+ constexpr size_t __extent = [&__r] {
+ if constexpr (__detail::__statically_sized<_Rg>)
+ return static_cast<size_t>(ranges::size(__r));
+ else
+ return dynamic_extent;
+ }();
if (meta::is_array_type(__type))
- return span<const _Tp>(meta::extract<const _Tp*>(__array),
- meta::extent(__type, 0U));
+ return span<const _Tp, __extent>(meta::extract<const _Tp*>(__array),
+ meta::extent(__type, 0U));
else
- return span<const _Tp>();
+ return span<const _Tp, __extent>(static_cast<const _Tp*>(nullptr),
+ 0);
}
template<class _Tp>
--- libstdc++-v3/include/std/meta.jj 2026-03-30 18:14:21.058354336 +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>