Skip to content

Commit 6714f27

Browse files
authored
Merge 2025-06 CWG Motion 7
P3491R3 define_static_{string,object,array}
2 parents 69d8608 + ec9737c commit 6714f27

File tree

3 files changed

+228
-3
lines changed

3 files changed

+228
-3
lines changed

source/basic.tex

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3596,9 +3596,17 @@
35963596

35973597
\pnum
35983598
An object is a \defnadj{potentially non-unique}{object} if it is
3599-
a string literal object\iref{lex.string},
3600-
the backing array of an initializer list\iref{dcl.init.ref}, or
3601-
a subobject thereof.
3599+
\begin{itemize}
3600+
\item
3601+
a string literal object\iref{lex.string},
3602+
\item
3603+
the backing array of an initializer list\iref{dcl.init.ref}, or
3604+
\item
3605+
the object introduced by a call to \tcode{std::meta::reflect_constant_array}
3606+
or \tcode{std::meta::\brk{}reflect_con\-stant_string}\iref{meta.reflection.array}, or
3607+
\item
3608+
a subobject thereof.
3609+
\end{itemize}
36023610

36033611
\pnum
36043612
\indextext{most derived object!bit-field}%

source/meta.tex

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,6 +2579,23 @@
25792579
\begin{codeblock}
25802580
#include <initializer_list> // see \ref{initializer.list.syn}
25812581

2582+
namespace std {
2583+
// \ref{meta.string.literal}, checking string literals
2584+
consteval bool is_string_literal(const char* p);
2585+
consteval bool is_string_literal(const wchar_t* p);
2586+
consteval bool is_string_literal(const char8_t* p);
2587+
consteval bool is_string_literal(const char16_t* p);
2588+
consteval bool is_string_literal(const char32_t* p);
2589+
2590+
// \ref{meta.define.static}, promoting to static storage strings
2591+
template<ranges::@\libconcept{input_range}@ R>
2592+
consteval const ranges::range_value_t<R>* define_static_string(R&& r);
2593+
template<ranges::@\libconcept{input_range}@ R>
2594+
consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
2595+
template<class T>
2596+
consteval const remove_cvref_t<T>* define_static_object(T&& r);
2597+
}
2598+
25822599
namespace std::meta {
25832600
using info = decltype(^^::);
25842601

@@ -2744,6 +2761,13 @@
27442761
template<class T>
27452762
consteval info reflect_function(T& fn);
27462763

2764+
// \ref{meta.reflection.array}, promoting to static storage arrays
2765+
template<ranges::@\libconcept{input_range}@ R>
2766+
consteval info reflect_constant_string(R&& r);
2767+
2768+
template<ranges::@\libconcept{input_range}@ R>
2769+
consteval info reflect_constant_array(R&& r);
2770+
27472771
// \ref{meta.reflection.define.aggregate}, class definition generation
27482772
struct data_member_options;
27492773
consteval info data_member_spec(info type, data_member_options options);
@@ -2974,6 +2998,102 @@
29742998
\end{codeblock}
29752999
\end{example}
29763000

3001+
\rSec2[meta.string.literal]{Checking string literals}
3002+
3003+
\indexlibraryglobal{is_string_literal}%
3004+
\begin{itemdecl}
3005+
consteval bool is_string_literal(const char* p);
3006+
consteval bool is_string_literal(const wchar_t* p);
3007+
consteval bool is_string_literal(const char8_t* p);
3008+
consteval bool is_string_literal(const char16_t* p);
3009+
consteval bool is_string_literal(const char32_t* p);
3010+
\end{itemdecl}
3011+
3012+
\begin{itemdescr}
3013+
\pnum
3014+
\returns
3015+
\begin{itemize}
3016+
\item
3017+
If \tcode{p} points to an unspecified object\iref{expr.const},
3018+
\tcode{false}.
3019+
\item
3020+
Otherwise, if \tcode{p} points to a subobject
3021+
of a string literal object\iref{lex.string},
3022+
\tcode{true}.
3023+
\item
3024+
Otherwise, \tcode{false}.
3025+
\end{itemize}
3026+
\end{itemdescr}
3027+
3028+
\rSec2[meta.define.static]{Promoting to static storage strings}
3029+
3030+
\pnum
3031+
The functions in this subclause promote compile-time storage into static storage.
3032+
3033+
\indexlibraryglobal{define_static_string}%
3034+
\begin{itemdecl}
3035+
template<ranges::@\libconcept{input_range}@ R>
3036+
consteval const ranges::range_value_t<R>* define_static_string(R&& r);
3037+
\end{itemdecl}
3038+
3039+
\begin{itemdescr}
3040+
\pnum
3041+
\effects
3042+
Equivalent to:
3043+
\begin{codeblock}
3044+
return extract<const ranges::range_value_t<R>*>(meta::reflect_constant_string(r));
3045+
\end{codeblock}
3046+
\end{itemdescr}
3047+
3048+
\indexlibraryglobal{define_static_array}%
3049+
\begin{itemdecl}
3050+
template<ranges::@\libconcept{input_range}@ R>
3051+
consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
3052+
\end{itemdecl}
3053+
3054+
\begin{itemdescr}
3055+
\pnum
3056+
\effects
3057+
Equivalent to:
3058+
\begin{codeblock}
3059+
using T = ranges::range_value_t<R>;
3060+
meta::info array = meta::reflect_constant_array(r);
3061+
if (is_array_type(type_of(array))) {
3062+
return span<const T>(extract<const T*>(array), extent(type_of(array)));
3063+
} else {
3064+
return span<const T>();
3065+
}
3066+
\end{codeblock}
3067+
\end{itemdescr}
3068+
3069+
\indexlibraryglobal{define_static_object}%
3070+
\begin{itemdecl}
3071+
template<class T>
3072+
consteval const remove_cvref_t<T>* define_static_object(T&& t);
3073+
\end{itemdecl}
3074+
3075+
\begin{itemdescr}
3076+
\pnum
3077+
\effects
3078+
Equivalent to:
3079+
\begin{codeblock}
3080+
using U = remove_cvref_t<T>;
3081+
if constexpr (is_class_type(^^U)) {
3082+
return addressof(extract<const U&>(meta::reflect_constant(std::forward<T>(t))));
3083+
} else {
3084+
return define_static_array(span(addressof(t), 1)).data();
3085+
}
3086+
\end{codeblock}
3087+
3088+
\pnum
3089+
\begin{note}
3090+
For class types,
3091+
\tcode{define_static_object} provides
3092+
the address of the template parameter object\iref{temp.param}
3093+
that is template-argument equivalent to \tcode{t}.
3094+
\end{note}
3095+
\end{itemdescr}
3096+
29773097
\rSec2[meta.reflection.operators]{Operator representations}
29783098

29793099
\begin{itemdecl}
@@ -5368,6 +5488,102 @@
53685488
A reflection of the function designated by \tcode{fn}.
53695489
\end{itemdescr}
53705490

5491+
\rSec2[meta.reflection.array]{Promoting to static storage arrays}
5492+
5493+
\pnum
5494+
The functions in this subclause promote compile-time storage into static storage.
5495+
5496+
\indexlibraryglobal{reflect_constant_string}%
5497+
\begin{itemdecl}
5498+
template<ranges::@\libconcept{input_range}@ R>
5499+
consteval info reflect_constant_string(R&& r);
5500+
\end{itemdecl}
5501+
5502+
\begin{itemdescr}
5503+
\pnum
5504+
Let \tcode{CharT} be \tcode{ranges::range_value_t<R>}.
5505+
5506+
\pnum
5507+
\mandates
5508+
\tcode{CharT} is one of
5509+
\tcode{char},
5510+
\tcode{wchar_t},
5511+
\tcode{char8_t},
5512+
\tcode{char16_t},
5513+
\tcode{char32_t}.
5514+
5515+
\pnum
5516+
Let $V$ be the pack of values of type \tcode{CharT}
5517+
whose elements are the corresponding elements of \tcode{r},
5518+
except that if \tcode{r} refers to a string literal object,
5519+
then $V$ does not include the trailing null terminator of \tcode{r}.
5520+
5521+
\pnum
5522+
Let $P$ be the template parameter object\iref{temp.param}
5523+
of type \tcode{const CharT[sizeof...(V)+1]}
5524+
initialized with \tcode{$V$..., CHART()}.
5525+
5526+
\pnum
5527+
\returns
5528+
\tcode{\reflexpr{$P$}}.
5529+
5530+
\pnum
5531+
\begin{note}
5532+
$P$ is a potentially non-unique object\iref{intro.object}.
5533+
\end{note}
5534+
\end{itemdescr}
5535+
5536+
\indexlibraryglobal{reflect_constant_array}%
5537+
\begin{itemdecl}
5538+
template<ranges::@\libconcept{input_range}@ R>
5539+
consteval info reflect_constant_array(R&& r);
5540+
\end{itemdecl}
5541+
5542+
\begin{itemdescr}
5543+
\pnum
5544+
Let \tcode{T} be \tcode{ranges::range_value_t<R>}.
5545+
5546+
\pnum
5547+
\mandates
5548+
\tcode{T} is a structural type\iref{temp.param},
5549+
\tcode{is_constructible_v<T, ranges::range_reference_t<R>>} is \tcode{true}, and
5550+
\tcode{is_copy_constructible_v<T>} is \tcode{true}.
5551+
5552+
\pnum
5553+
\constantwhen
5554+
\tcode{reflect_constant(e)} is a constant subexpression
5555+
for every element \tcode{e} of \tcode{r}.
5556+
5557+
\pnum
5558+
Let $V$ be the pack of values of type \tcode{info}
5559+
of the same size as \tcode{r},
5560+
where the $i^\text{th}$ element is \tcode{reflect_constant($\tcode{e}_i$)},
5561+
where $\tcode{e}_i$ is the $i^\text{th}$ element of \tcode{r}.
5562+
5563+
\pnum
5564+
Let $P$ be
5565+
\begin{itemize}
5566+
\item
5567+
If \tcode{sizeof...($V$) > 0} is true,
5568+
then the template parameter object\iref{temp.param}
5569+
of type \tcode{const T[\brk{}sizeof...(\brk{}$V$)]}
5570+
initialized with \tcode{\{[:$V$:]...\}}.
5571+
\item
5572+
Otherwise, the template parameter object
5573+
of type \tcode{array<T, 0>}
5574+
initialized with \tcode{\{\}}.
5575+
\end{itemize}
5576+
5577+
\pnum
5578+
\returns
5579+
\tcode{\reflexpr{$P$}}.
5580+
5581+
\pnum
5582+
\begin{note}
5583+
$P$ is a potentially non-unique object\iref{intro.object}.
5584+
\end{note}
5585+
\end{itemdescr}
5586+
53715587
\rSec2[meta.reflection.define.aggregate]{Reflection class definition generation}
53725588

53735589
\indexlibraryglobal{data_member_options}%

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@
646646
#define @\defnlibxname{cpp_lib_copyable_function}@ 202306L // also in \libheader{functional}
647647
#define @\defnlibxname{cpp_lib_coroutine}@ 201902L // freestanding, also in \libheader{coroutine}
648648
#define @\defnlibxname{cpp_lib_debugging}@ 202403L // freestanding, also in \libheader{debugging}
649+
#define @\defnlibxname{cpp_lib_define_static}@ 202506L // freestanding, also in \libheader{meta}
649650
#define @\defnlibxname{cpp_lib_destroying_delete}@ 201806L // freestanding, also in \libheader{new}
650651
#define @\defnlibxname{cpp_lib_enable_shared_from_this}@ 201603L // also in \libheader{memory}
651652
#define @\defnlibxname{cpp_lib_endian}@ 201907L // freestanding, also in \libheader{bit}

0 commit comments

Comments
 (0)