|
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
|
|
2742 | 2760 | template<class T>
|
2743 | 2761 | consteval info reflect_function(T& fn);
|
2744 | 2762 |
|
| 2763 | + // \ref{meta.reflection.array}, promoting to static storage |
| 2764 | + template<ranges::@\libconcept{input_range}@ R> |
| 2765 | + consteval info reflect_constant_string(R&& r); |
| 2766 | + |
| 2767 | + template<ranges::@\libconcept{input_range}@ R> |
| 2768 | + consteval info reflect_constant_array(R&& r); |
| 2769 | + |
2745 | 2770 | // \ref{meta.reflection.define.aggregate}, class definition generation
|
2746 | 2771 | struct data_member_options;
|
2747 | 2772 | consteval info data_member_spec(info type, data_member_options options);
|
|
2917 | 2942 | // \ref{meta.reflection.annotation}, annotation reflection
|
2918 | 2943 | consteval vector<info> annotations_of(info item);
|
2919 | 2944 | consteval vector<info> annotations_of_with_type(info item, info type);
|
| 2945 | + } |
2920 | 2946 | }
|
2921 | 2947 | \end{codeblock}
|
2922 | 2948 |
|
|
2972 | 2998 | \end{codeblock}
|
2973 | 2999 | \end{example}
|
2974 | 3000 |
|
| 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 | +%FIXME: weird capitalization; |
| 3029 | +%pretty sure titles are supposed to be sentence case |
| 3030 | +%also this title is duplicated (see fixme below) |
| 3031 | +\rSec2[meta.define.static]{Promoting to Static Storage} |
| 3032 | + |
| 3033 | +\pnum |
| 3034 | +%FIXME: subclause, not clause |
| 3035 | +%FIXME: I take issue with the phrasing for the same reason as in the fixme below (meta.reflection.array) |
| 3036 | +The functions in this clause promote compile-time storage into static storage. |
| 3037 | + |
| 3038 | +\indexlibraryglobal{define_static_string}% |
| 3039 | +\begin{itemdecl} |
| 3040 | +template<ranges::@\libconcept{input_range}@ R> |
| 3041 | + consteval const ranges::range_value_t<R>* define_static_string(R&& r); |
| 3042 | +\end{itemdecl} |
| 3043 | + |
| 3044 | +\begin{itemdescr} |
| 3045 | +\pnum |
| 3046 | +\effects |
| 3047 | +Equivalent to: |
| 3048 | +\begin{codeblock} |
| 3049 | +return extract<const ranges::range_value_t<R>*>(meta::reflect_constant_string(r)); |
| 3050 | +\end{codeblock} |
| 3051 | +\end{itemdescr} |
| 3052 | + |
| 3053 | +\indexlibraryglobal{define_static_array}% |
| 3054 | +\begin{itemdecl} |
| 3055 | +template<ranges::@\libconcept{input_range}@ R> |
| 3056 | + consteval span<const ranges::range_value_t<R>> define_static_array(R&& r); |
| 3057 | +\end{itemdecl} |
| 3058 | + |
| 3059 | +\begin{itemdescr} |
| 3060 | +\pnum |
| 3061 | +\effects |
| 3062 | +Equivalent to: |
| 3063 | +\begin{codeblock} |
| 3064 | +using T = ranges::range_value_t<R>; |
| 3065 | +meta::info array = meta::reflect_constant_array(r); |
| 3066 | +if (is_array_type(type_of(array))) { |
| 3067 | + return span<const T>(extract<const T*>(array), extent(type_of(array))); |
| 3068 | +} else { |
| 3069 | + return span<const T>(); |
| 3070 | +} |
| 3071 | +\end{codeblock} |
| 3072 | +\end{itemdescr} |
| 3073 | + |
| 3074 | +\indexlibraryglobal{define_static_object}% |
| 3075 | +\begin{itemdecl} |
| 3076 | +template<class T> |
| 3077 | + consteval const remove_cvref_t<T>* define_static_object(T&& t); |
| 3078 | +\end{itemdecl} |
| 3079 | + |
| 3080 | +\begin{itemdescr} |
| 3081 | +\pnum |
| 3082 | +\effects |
| 3083 | +Equivalent to: |
| 3084 | +\begin{codeblock} |
| 3085 | +using U = remove_cvref_t<T>; |
| 3086 | +if constexpr (is_class_type(^^U)) { |
| 3087 | + return addressof(extract<const U&>(meta::reflect_constant(std::forward<T>(t)))); |
| 3088 | +} else { |
| 3089 | + return define_static_array(span(addressof(t), 1)).data(); |
| 3090 | +} |
| 3091 | +\end{codeblock} |
| 3092 | + |
| 3093 | +\pnum |
| 3094 | +\begin{note} |
| 3095 | +For class types, |
| 3096 | +\tcode{define_static_object} provides |
| 3097 | +the address of the template parameter object\iref{temp.param} |
| 3098 | +that is template-argument equivalent to \tcode{t}. |
| 3099 | +\end{note} |
| 3100 | +\end{itemdescr} |
| 3101 | + |
2975 | 3102 | \rSec2[meta.reflection.operators]{Operator representations}
|
2976 | 3103 |
|
2977 | 3104 | \begin{itemdecl}
|
|
5334 | 5461 | A reflection of the function designated by \tcode{fn}.
|
5335 | 5462 | \end{itemdescr}
|
5336 | 5463 |
|
| 5464 | +%FIXME: inconsistent title case; |
| 5465 | +%I'm pretty sure we normally use sentence case. |
| 5466 | +%Also, this title is duplicated and weird. |
| 5467 | +%Why isn't this called "array reflection" in the style of the subclause above? |
| 5468 | +\rSec2[meta.reflection.array]{Promoting to Static Storage} |
| 5469 | + |
| 5470 | +%FIXME: We generally don't like "compile-time". |
| 5471 | +%This sentence is pretty nonsensical because these terms aren't mutually exclusive. |
| 5472 | +% |
| 5473 | +%We also deal with ranges as input, and ranges aren't necessarily backed by |
| 5474 | +%storage (except for an empty class). |
| 5475 | +% |
| 5476 | +%Maybe we could say something along the lines of converting ranges of structural types |
| 5477 | +%into arrays, during program translation. |
| 5478 | +\pnum |
| 5479 | +The functions in this subclause promote compile-time storage into static storage. |
| 5480 | + |
| 5481 | +\indexlibraryglobal{reflect_constant_string}% |
| 5482 | +\begin{itemdecl} |
| 5483 | +template<ranges::@\libconcept{input_range}@ R> |
| 5484 | + consteval info reflect_constant_string(R&& r); |
| 5485 | +\end{itemdecl} |
| 5486 | + |
| 5487 | +\begin{itemdescr} |
| 5488 | +\pnum |
| 5489 | +Let \tcode{CharT} be \tcode{ranges::range_value_t<R>}. |
| 5490 | + |
| 5491 | +\pnum |
| 5492 | +\mandates |
| 5493 | +\tcode{CharT} is one of |
| 5494 | +%FIXME: this is kinda silly; we have the defined term "character type" |
| 5495 | +%which matches this set exactly. |
| 5496 | +%We may as well use it. |
| 5497 | +\tcode{char}, |
| 5498 | +\tcode{wchar_t}, |
| 5499 | +\tcode{char8_t}, |
| 5500 | +\tcode{char16_t}, |
| 5501 | +\tcode{char32_t}. |
| 5502 | + |
| 5503 | +\pnum |
| 5504 | +Let $V$ be the pack of values of type \tcode{CharT} |
| 5505 | +whose elements are the corresponding elements of \tcode{r}, |
| 5506 | +except that if \tcode{r} refers to a string literal object, |
| 5507 | +then $V$ does not include the trailing null terminator of \tcode{r}. |
| 5508 | + |
| 5509 | +\pnum |
| 5510 | +Let $P$ be the template parameter object\iref{temp.param} |
| 5511 | +of type \tcode{const CharT[sizeof...(V)+1]} |
| 5512 | +initialized with \tcode{$V$..., CHART()}. |
| 5513 | + |
| 5514 | +\pnum |
| 5515 | +\returns |
| 5516 | +\tcode{\reflexpr{$P$}}. |
| 5517 | + |
| 5518 | +\pnum |
| 5519 | +\begin{note} |
| 5520 | +$P$ is a potentially non-unique object\iref{intro.object}. |
| 5521 | +\end{note} |
| 5522 | +\end{itemdescr} |
| 5523 | + |
| 5524 | +\indexlibraryglobal{reflect_constant_array}% |
| 5525 | +\begin{itemdecl} |
| 5526 | +template<ranges::@\libconcept{input_range}@ R> |
| 5527 | + consteval info reflect_constant_array(R&& r); |
| 5528 | +\end{itemdecl} |
| 5529 | + |
| 5530 | +\begin{itemdescr} |
| 5531 | +\pnum |
| 5532 | +Let \tcode{T} be \tcode{ranges::range_value_t<R>}. |
| 5533 | + |
| 5534 | +\pnum |
| 5535 | +\mandates |
| 5536 | +\tcode{T} is a structural type\iref{temp.param}, |
| 5537 | +\tcode{is_constructible_v<T, ranges::range_reference_t<R>>} is \tcode{true}, and |
| 5538 | +\tcode{is_copy_constructible_v<T>} is \tcode{true}. |
| 5539 | + |
| 5540 | +\pnum |
| 5541 | +\constantwhen |
| 5542 | +\tcode{reflect_constant(e)} is a constant subexpression |
| 5543 | +for every element \tcode{e} of \tcode{r}. |
| 5544 | + |
| 5545 | +\pnum |
| 5546 | +Let $V$ be the pack of values of type \tcode{info} |
| 5547 | +of the same size as \tcode{r}, |
| 5548 | +where the $i^\text{th}$ element is \tcode{reflect_constant($\tcode{e}_i$)}, |
| 5549 | +where $\tcode{e}_i$ is the $i^\text{th}$ element of \tcode{r}. |
| 5550 | + |
| 5551 | +\pnum |
| 5552 | +Let $P$ be |
| 5553 | +\begin{itemize} |
| 5554 | +\item |
| 5555 | + If \tcode{sizeof...($V$) > 0}, |
| 5556 | + %FIXME: is true |
| 5557 | + then the template parameter object\iref{temp.param} |
| 5558 | + of type \tcode{const T[\brk{}sizeof...(\brk{}$V$)]} |
| 5559 | + initialized with \tcode{\{[:$V$:]...\}}. |
| 5560 | +\item |
| 5561 | + Otherwise, the template parameter object |
| 5562 | + of type \tcode{array<T, 0>} |
| 5563 | + initialized with \tcode{\{\}}. |
| 5564 | +\end{itemize} |
| 5565 | + |
| 5566 | +\pnum |
| 5567 | +\returns |
| 5568 | +\tcode{\reflexpr{$P$}}. |
| 5569 | + |
| 5570 | +\pnum |
| 5571 | +\begin{note} |
| 5572 | +$P$ is a potentially non-unique object\iref{intro.object}. |
| 5573 | +\end{note} |
| 5574 | +\end{itemdescr} |
| 5575 | + |
5337 | 5576 | \rSec2[meta.reflection.define.aggregate]{Reflection class definition generation}
|
5338 | 5577 |
|
5339 | 5578 | \indexlibraryglobal{data_member_options}%
|
|
0 commit comments