|
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
|
|
2744 | 2762 | template<class T>
|
2745 | 2763 | consteval info reflect_function(T& fn);
|
2746 | 2764 |
|
| 2765 | + // \ref{meta.reflection.array}, promoting to static storage |
| 2766 | + template<ranges::@\libconcept{input_range}@ R> |
| 2767 | + consteval info reflect_constant_string(R&& r); |
| 2768 | + |
| 2769 | + template<ranges::@\libconcept{input_range}@ R> |
| 2770 | + consteval info reflect_constant_array(R&& r); |
| 2771 | + |
2747 | 2772 | // \ref{meta.reflection.define.aggregate}, class definition generation
|
2748 | 2773 | struct data_member_options;
|
2749 | 2774 | consteval info data_member_spec(info type, data_member_options options);
|
|
2919 | 2944 | // \ref{meta.reflection.annotation}, annotation reflection
|
2920 | 2945 | consteval vector<info> annotations_of(info item);
|
2921 | 2946 | consteval vector<info> annotations_of_with_type(info item, info type);
|
| 2947 | + } |
2922 | 2948 | }
|
2923 | 2949 | \end{codeblock}
|
2924 | 2950 |
|
|
2974 | 3000 | \end{codeblock}
|
2975 | 3001 | \end{example}
|
2976 | 3002 |
|
| 3003 | +\rSec2[meta.string.literal]{Checking string literals} |
| 3004 | + |
| 3005 | +\indexlibraryglobal{is_string_literal}% |
| 3006 | +\begin{itemdecl} |
| 3007 | +consteval bool is_string_literal(const char* p); |
| 3008 | +consteval bool is_string_literal(const wchar_t* p); |
| 3009 | +consteval bool is_string_literal(const char8_t* p); |
| 3010 | +consteval bool is_string_literal(const char16_t* p); |
| 3011 | +consteval bool is_string_literal(const char32_t* p); |
| 3012 | +\end{itemdecl} |
| 3013 | + |
| 3014 | +\begin{itemdescr} |
| 3015 | +\pnum |
| 3016 | +\returns |
| 3017 | +\begin{itemize} |
| 3018 | +\item |
| 3019 | + If \tcode{p} points to an unspecified object\iref{expr.const}, |
| 3020 | + \tcode{false}. |
| 3021 | +\item |
| 3022 | + Otherwise, if \tcode{p} points to a subobject |
| 3023 | + of a string literal object\iref{lex.string}, |
| 3024 | + \tcode{true}. |
| 3025 | +\item |
| 3026 | + Otherwise, \tcode{false}. |
| 3027 | +\end{itemize} |
| 3028 | +\end{itemdescr} |
| 3029 | + |
| 3030 | +%FIXME: weird capitalization; |
| 3031 | +%pretty sure titles are supposed to be sentence case |
| 3032 | +%also this title is duplicated (see fixme below) |
| 3033 | +\rSec2[meta.define.static]{Promoting to Static Storage} |
| 3034 | + |
| 3035 | +\pnum |
| 3036 | +%FIXME: subclause, not clause |
| 3037 | +%FIXME: I take issue with the phrasing for the same reason as in the fixme below (meta.reflection.array) |
| 3038 | +The functions in this clause promote compile-time storage into static storage. |
| 3039 | + |
| 3040 | +\indexlibraryglobal{define_static_string}% |
| 3041 | +\begin{itemdecl} |
| 3042 | +template<ranges::@\libconcept{input_range}@ R> |
| 3043 | + consteval const ranges::range_value_t<R>* define_static_string(R&& r); |
| 3044 | +\end{itemdecl} |
| 3045 | + |
| 3046 | +\begin{itemdescr} |
| 3047 | +\pnum |
| 3048 | +\effects |
| 3049 | +Equivalent to: |
| 3050 | +\begin{codeblock} |
| 3051 | +return extract<const ranges::range_value_t<R>*>(meta::reflect_constant_string(r)); |
| 3052 | +\end{codeblock} |
| 3053 | +\end{itemdescr} |
| 3054 | + |
| 3055 | +\indexlibraryglobal{define_static_array}% |
| 3056 | +\begin{itemdecl} |
| 3057 | +template<ranges::@\libconcept{input_range}@ R> |
| 3058 | + consteval span<const ranges::range_value_t<R>> define_static_array(R&& r); |
| 3059 | +\end{itemdecl} |
| 3060 | + |
| 3061 | +\begin{itemdescr} |
| 3062 | +\pnum |
| 3063 | +\effects |
| 3064 | +Equivalent to: |
| 3065 | +\begin{codeblock} |
| 3066 | +using T = ranges::range_value_t<R>; |
| 3067 | +meta::info array = meta::reflect_constant_array(r); |
| 3068 | +if (is_array_type(type_of(array))) { |
| 3069 | + return span<const T>(extract<const T*>(array), extent(type_of(array))); |
| 3070 | +} else { |
| 3071 | + return span<const T>(); |
| 3072 | +} |
| 3073 | +\end{codeblock} |
| 3074 | +\end{itemdescr} |
| 3075 | + |
| 3076 | +\indexlibraryglobal{define_static_object}% |
| 3077 | +\begin{itemdecl} |
| 3078 | +template<class T> |
| 3079 | + consteval const remove_cvref_t<T>* define_static_object(T&& t); |
| 3080 | +\end{itemdecl} |
| 3081 | + |
| 3082 | +\begin{itemdescr} |
| 3083 | +\pnum |
| 3084 | +\effects |
| 3085 | +Equivalent to: |
| 3086 | +\begin{codeblock} |
| 3087 | +using U = remove_cvref_t<T>; |
| 3088 | +if constexpr (is_class_type(^^U)) { |
| 3089 | + return addressof(extract<const U&>(meta::reflect_constant(std::forward<T>(t)))); |
| 3090 | +} else { |
| 3091 | + return define_static_array(span(addressof(t), 1)).data(); |
| 3092 | +} |
| 3093 | +\end{codeblock} |
| 3094 | + |
| 3095 | +\pnum |
| 3096 | +\begin{note} |
| 3097 | +For class types, |
| 3098 | +\tcode{define_static_object} provides |
| 3099 | +the address of the template parameter object\iref{temp.param} |
| 3100 | +that is template-argument equivalent to \tcode{t}. |
| 3101 | +\end{note} |
| 3102 | +\end{itemdescr} |
| 3103 | + |
2977 | 3104 | \rSec2[meta.reflection.operators]{Operator representations}
|
2978 | 3105 |
|
2979 | 3106 | \begin{itemdecl}
|
|
5368 | 5495 | A reflection of the function designated by \tcode{fn}.
|
5369 | 5496 | \end{itemdescr}
|
5370 | 5497 |
|
| 5498 | +%FIXME: inconsistent title case; |
| 5499 | +%I'm pretty sure we normally use sentence case. |
| 5500 | +%Also, this title is duplicated and weird. |
| 5501 | +%Why isn't this called "array reflection" in the style of the subclause above? |
| 5502 | +\rSec2[meta.reflection.array]{Promoting to Static Storage} |
| 5503 | + |
| 5504 | +%FIXME: We generally don't like "compile-time". |
| 5505 | +%This sentence is pretty nonsensical because these terms aren't mutually exclusive. |
| 5506 | +% |
| 5507 | +%We also deal with ranges as input, and ranges aren't necessarily backed by |
| 5508 | +%storage (except for an empty class). |
| 5509 | +% |
| 5510 | +%Maybe we could say something along the lines of converting ranges of structural types |
| 5511 | +%into arrays, during program translation. |
| 5512 | +\pnum |
| 5513 | +The functions in this subclause promote compile-time storage into static storage. |
| 5514 | + |
| 5515 | +\indexlibraryglobal{reflect_constant_string}% |
| 5516 | +\begin{itemdecl} |
| 5517 | +template<ranges::@\libconcept{input_range}@ R> |
| 5518 | + consteval info reflect_constant_string(R&& r); |
| 5519 | +\end{itemdecl} |
| 5520 | + |
| 5521 | +\begin{itemdescr} |
| 5522 | +\pnum |
| 5523 | +Let \tcode{CharT} be \tcode{ranges::range_value_t<R>}. |
| 5524 | + |
| 5525 | +\pnum |
| 5526 | +\mandates |
| 5527 | +\tcode{CharT} is one of |
| 5528 | +%FIXME: this is kinda silly; we have the defined term "character type" |
| 5529 | +%which matches this set exactly. |
| 5530 | +%We may as well use it. |
| 5531 | +\tcode{char}, |
| 5532 | +\tcode{wchar_t}, |
| 5533 | +\tcode{char8_t}, |
| 5534 | +\tcode{char16_t}, |
| 5535 | +\tcode{char32_t}. |
| 5536 | + |
| 5537 | +\pnum |
| 5538 | +Let $V$ be the pack of values of type \tcode{CharT} |
| 5539 | +whose elements are the corresponding elements of \tcode{r}, |
| 5540 | +except that if \tcode{r} refers to a string literal object, |
| 5541 | +then $V$ does not include the trailing null terminator of \tcode{r}. |
| 5542 | + |
| 5543 | +\pnum |
| 5544 | +Let $P$ be the template parameter object\iref{temp.param} |
| 5545 | +of type \tcode{const CharT[sizeof...(V)+1]} |
| 5546 | +initialized with \tcode{$V$..., CHART()}. |
| 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 | + |
| 5558 | +\indexlibraryglobal{reflect_constant_array}% |
| 5559 | +\begin{itemdecl} |
| 5560 | +template<ranges::@\libconcept{input_range}@ R> |
| 5561 | + consteval info reflect_constant_array(R&& r); |
| 5562 | +\end{itemdecl} |
| 5563 | + |
| 5564 | +\begin{itemdescr} |
| 5565 | +\pnum |
| 5566 | +Let \tcode{T} be \tcode{ranges::range_value_t<R>}. |
| 5567 | + |
| 5568 | +\pnum |
| 5569 | +\mandates |
| 5570 | +\tcode{T} is a structural type\iref{temp.param}, |
| 5571 | +\tcode{is_constructible_v<T, ranges::range_reference_t<R>>} is \tcode{true}, and |
| 5572 | +\tcode{is_copy_constructible_v<T>} is \tcode{true}. |
| 5573 | + |
| 5574 | +\pnum |
| 5575 | +\constantwhen |
| 5576 | +\tcode{reflect_constant(e)} is a constant subexpression |
| 5577 | +for every element \tcode{e} of \tcode{r}. |
| 5578 | + |
| 5579 | +\pnum |
| 5580 | +Let $V$ be the pack of values of type \tcode{info} |
| 5581 | +of the same size as \tcode{r}, |
| 5582 | +where the $i^\text{th}$ element is \tcode{reflect_constant($\tcode{e}_i$)}, |
| 5583 | +where $\tcode{e}_i$ is the $i^\text{th}$ element of \tcode{r}. |
| 5584 | + |
| 5585 | +\pnum |
| 5586 | +Let $P$ be |
| 5587 | +\begin{itemize} |
| 5588 | +\item |
| 5589 | + If \tcode{sizeof...($V$) > 0}, |
| 5590 | + %FIXME: is true |
| 5591 | + then the template parameter object\iref{temp.param} |
| 5592 | + of type \tcode{const T[\brk{}sizeof...(\brk{}$V$)]} |
| 5593 | + initialized with \tcode{\{[:$V$:]...\}}. |
| 5594 | +\item |
| 5595 | + Otherwise, the template parameter object |
| 5596 | + of type \tcode{array<T, 0>} |
| 5597 | + initialized with \tcode{\{\}}. |
| 5598 | +\end{itemize} |
| 5599 | + |
| 5600 | +\pnum |
| 5601 | +\returns |
| 5602 | +\tcode{\reflexpr{$P$}}. |
| 5603 | + |
| 5604 | +\pnum |
| 5605 | +\begin{note} |
| 5606 | +$P$ is a potentially non-unique object\iref{intro.object}. |
| 5607 | +\end{note} |
| 5608 | +\end{itemdescr} |
| 5609 | + |
5371 | 5610 | \rSec2[meta.reflection.define.aggregate]{Reflection class definition generation}
|
5372 | 5611 |
|
5373 | 5612 | \indexlibraryglobal{data_member_options}%
|
|
0 commit comments