|
2579 | 2579 | \begin{codeblock}
|
2580 | 2580 | #include <initializer_list> // see \ref{initializer.list.syn}
|
2581 | 2581 |
|
2582 |
| -namespace std::meta { |
| 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 |
| 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 | + %FIXME: indent the contents of this namespace with two spaces. |
| 2599 | + %This is currently not done to make reviewing easier and to avoid merge conflicts. |
| 2600 | + namespace meta { |
2583 | 2601 | using info = decltype(^^::);
|
2584 | 2602 |
|
2585 | 2603 | // \ref{meta.reflection.operators}, operator representations
|
|
2741 | 2759 | template<class T>
|
2742 | 2760 | consteval info reflect_function(T& fn);
|
2743 | 2761 |
|
| 2762 | + // \ref{meta.reflection.array}, promoting to static storage |
| 2763 | + template<ranges::@\libconcept{input_range}@ R> |
| 2764 | + consteval info reflect_constant_string(R&& r); |
| 2765 | + |
| 2766 | + template<ranges::@\libconcept{input_range}@ R> |
| 2767 | + consteval info reflect_constant_array(R&& r); |
| 2768 | + |
2744 | 2769 | // \ref{meta.reflection.define.aggregate}, class definition generation
|
2745 | 2770 | struct data_member_options;
|
2746 | 2771 | consteval info data_member_spec(info type, data_member_options options);
|
|
2912 | 2937 | consteval info variant_alternative(size_t index, info type);
|
2913 | 2938 |
|
2914 | 2939 | consteval strong_ordering type_order(info type_a, info type_b);
|
| 2940 | + } |
2915 | 2941 | }
|
2916 | 2942 | \end{codeblock}
|
2917 | 2943 |
|
|
2967 | 2993 | \end{codeblock}
|
2968 | 2994 | \end{example}
|
2969 | 2995 |
|
| 2996 | +\rSec2[meta.string.literal]{Checking string literals} |
| 2997 | + |
| 2998 | +\indexlibraryglobal{is_string_literal}% |
| 2999 | +\begin{itemdecl} |
| 3000 | +consteval bool is_string_literal(const char* p); |
| 3001 | +consteval bool is_string_literal(const wchar_t* p); |
| 3002 | +consteval bool is_string_literal(const char8_t* p); |
| 3003 | +consteval bool is_string_literal(const char16_t* p); |
| 3004 | +consteval bool is_string_literal(const char32_t* p); |
| 3005 | +\end{itemdecl} |
| 3006 | + |
| 3007 | +\begin{itemdescr} |
| 3008 | +\pnum |
| 3009 | +\returns |
| 3010 | +\begin{itemize} |
| 3011 | +\item |
| 3012 | + If \tcode{p} points to an unspecified object\iref{expr.const}, |
| 3013 | + \tcode{false}. |
| 3014 | +\item |
| 3015 | + Otherwise, if \tcode{p} points to a subobject |
| 3016 | + of a string literal object\iref{lex.string}, |
| 3017 | + \tcode{true}. |
| 3018 | +\item |
| 3019 | + Otherwise, \tcode{false}. |
| 3020 | +\end{itemize} |
| 3021 | +\end{itemdescr} |
| 3022 | + |
| 3023 | +%FIXME: weird capitalization; |
| 3024 | +%pretty sure titles are supposed to be sentence case |
| 3025 | +%also this title is duplicated (see fixme below) |
| 3026 | +\rSec2[meta.define.static]{Promoting to Static Storage} |
| 3027 | + |
| 3028 | +\pnum |
| 3029 | +%FIXME: subclause, not clause |
| 3030 | +%FIXME: I take issue with the phrasing for the same reason as in the fixme below (meta.reflection.array) |
| 3031 | +The functions in this clause 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 | + |
2970 | 3097 | \rSec2[meta.reflection.operators]{Operator representations}
|
2971 | 3098 |
|
2972 | 3099 | \begin{itemdecl}
|
|
5316 | 5443 | A reflection of the function designated by \tcode{fn}.
|
5317 | 5444 | \end{itemdescr}
|
5318 | 5445 |
|
| 5446 | +%FIXME: inconsistent title case; |
| 5447 | +%I'm pretty sure we normally use sentence case. |
| 5448 | +%Also, this title is duplicated and weird. |
| 5449 | +%Why isn't this called "array reflection" in the style of the subclause above? |
| 5450 | +\rSec2[meta.reflection.array]{Promoting to Static Storage} |
| 5451 | + |
| 5452 | +%FIXME: We generally don't like "compile-time". |
| 5453 | +%This sentence is pretty nonsensical because these terms aren't mutually exclusive. |
| 5454 | +% |
| 5455 | +%We also deal with ranges as input, and ranges aren't necessarily backed by |
| 5456 | +%storage (except for an empty class). |
| 5457 | +% |
| 5458 | +%Maybe we could say something along the lines of converting ranges of structural types |
| 5459 | +%into arrays, during program translation. |
| 5460 | +\pnum |
| 5461 | +The functions in this subclause promote compile-time storage into static storage. |
| 5462 | + |
| 5463 | +\indexlibraryglobal{reflect_constant_string}% |
| 5464 | +\begin{itemdecl} |
| 5465 | +template<ranges::@\libconcept{input_range}@ R> |
| 5466 | + consteval info reflect_constant_string(R&& r); |
| 5467 | +\end{itemdecl} |
| 5468 | + |
| 5469 | +\begin{itemdescr} |
| 5470 | +\pnum |
| 5471 | +Let \tcode{CharT} be \tcode{ranges::range_value_t<R>}. |
| 5472 | + |
| 5473 | +\pnum |
| 5474 | +\mandates |
| 5475 | +\tcode{CharT} is one of |
| 5476 | +%FIXME: this is kinda silly; we have the defined term "character type" |
| 5477 | +%which matches this set exactly. |
| 5478 | +%We may as well use it. |
| 5479 | +\tcode{char}, |
| 5480 | +\tcode{wchar_t}, |
| 5481 | +\tcode{char8_t}, |
| 5482 | +\tcode{char16_t}, |
| 5483 | +\tcode{char32_t}. |
| 5484 | + |
| 5485 | +\pnum |
| 5486 | +Let $V$ be the pack of values of type \tcode{CharT} |
| 5487 | +whose elements are the corresponding elements of \tcode{r}, |
| 5488 | +except that if \tcode{r} refers to a string literal object, |
| 5489 | +then $V$ does not include the trailing null terminator of \tcode{r}. |
| 5490 | + |
| 5491 | +\pnum |
| 5492 | +Let $P$ be the template parameter object\iref{temp.param} |
| 5493 | +of type \tcode{const CharT[sizeof...(V)+1]} |
| 5494 | +initialized with \tcode{$V$..., CHART()}. |
| 5495 | + |
| 5496 | +\pnum |
| 5497 | +\returns |
| 5498 | +\tcode{\reflexpr{$P$}}. |
| 5499 | + |
| 5500 | +\pnum |
| 5501 | +\begin{note} |
| 5502 | +$P$ is a potentially non-unique object\iref{intro.object}. |
| 5503 | +\end{note} |
| 5504 | +\end{itemdescr} |
| 5505 | + |
| 5506 | +\indexlibraryglobal{reflect_constant_array}% |
| 5507 | +\begin{itemdecl} |
| 5508 | +template<ranges::@\libconcept{input_range}@ R> |
| 5509 | + consteval info reflect_constant_array(R&& r); |
| 5510 | +\end{itemdecl} |
| 5511 | + |
| 5512 | +\begin{itemdescr} |
| 5513 | +\pnum |
| 5514 | +Let \tcode{T} be \tcode{ranges::range_value_t<R>}. |
| 5515 | + |
| 5516 | +\pnum |
| 5517 | +\mandates |
| 5518 | +\tcode{T} is a structural type\iref{temp.param}, |
| 5519 | +\tcode{is_constructible_v<T, ranges::range_reference_t<R>>} is \tcode{true}, and |
| 5520 | +\tcode{is_copy_constructible_v<T>} is \tcode{true}. |
| 5521 | + |
| 5522 | +\pnum |
| 5523 | +\constantwhen |
| 5524 | +\tcode{reflect_constant(e)} is a constant subexpression |
| 5525 | +for every element \tcode{e} of \tcode{r}. |
| 5526 | + |
| 5527 | +\pnum |
| 5528 | +Let $V$ be the pack of values of type \tcode{info} |
| 5529 | +of the same size as \tcode{r}, |
| 5530 | +where the $i^\text{th}$ element is \tcode{reflect_constant($\tcode{e}_i$)}, |
| 5531 | +where $\tcode{e}_i$ is the $i^\text{th}$ element of \tcode{r}. |
| 5532 | + |
| 5533 | +\pnum |
| 5534 | +Let $P$ be |
| 5535 | +\begin{itemize} |
| 5536 | +\item |
| 5537 | + If \tcode{sizeof...($V$) > 0}, |
| 5538 | + %FIXME: is true |
| 5539 | + then the template parameter object\iref{temp.param} |
| 5540 | + of type \tcode{const T[\brk{}sizeof...(\brk{}$V$)]} |
| 5541 | + initialized with \tcode{\{[:$V$:]...\}}. |
| 5542 | +\item |
| 5543 | + Otherwise, the template parameter object |
| 5544 | + of type \tcode{array<T, 0>} |
| 5545 | + initialized with \tcode{\{\}}. |
| 5546 | +\end{itemize} |
| 5547 | + |
| 5548 | +\pnum |
| 5549 | +\returns |
| 5550 | +\tcode{\reflexpr{$P$}}. |
| 5551 | + |
| 5552 | +\pnum |
| 5553 | +\begin{note} |
| 5554 | +$P$ is a potentially non-unique object\iref{intro.object}. |
| 5555 | +\end{note} |
| 5556 | +\end{itemdescr} |
| 5557 | + |
5319 | 5558 | \rSec2[meta.reflection.define.aggregate]{Reflection class definition generation}
|
5320 | 5559 |
|
5321 | 5560 | \indexlibraryglobal{data_member_options}%
|
|
0 commit comments