Skip to content

Commit 4a6c402

Browse files
committed
[P3795] Updating with Tim's feedback
1 parent 1f0f29d commit 4a6c402

2 files changed

Lines changed: 305 additions & 286 deletions

File tree

3795_misc_reflection_cleanup/misc-reflection-cleanup.md

Lines changed: 51 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ Change [class.mem.general]{.sref} to extend our quintuple to a sextuple:
194194
- [#.#]{.pnum} `$A$` is an alignment or ⊥,
195195
- [#.#]{.pnum} `$W$` is a bit-field width or ⊥, [and]{.rm}
196196
- [#.#]{.pnum} `$NUA$` is a boolean value[.]{.rm} [, and]{.addu}
197-
- [#.#]{.pnum} [`$ANN$` is a sequence of annotations.]{.addu}
197+
- [#.#]{.pnum} [`$ANN$` is a sequence of reflections representing either values or objects.]{.addu}
198198
199199
Two data member descriptions are equal if each of their respective components are the same entities, are the same identifiers, have equal values, or are both ⊥.
200200
@@ -276,7 +276,7 @@ Add to the front matter in [meta.syn]{.sref}:
276276
[1]{.pnum} Unless otherwise specified, each function, and each specialization of any function template, specified in this header is a designated addressable function ([namespace.std]).
277277

278278
::: addu
279-
[*]{.pnum} When a function or function template `$F$` specified in this header throws a `meta::exception` `$E$`, `$E$.from()` is a reflection representing `$F$`.
279+
[*]{.pnum} When a function or function template specialization `$F$` specified in this header throws a `meta::exception` `$E$`, `$E$.from()` is a reflection representing `$F$` and `$E$.where()` is a `source_location` representing where the call to `$F$` originated from.
280280
:::
281281

282282
[2]{.pnum} The behavior of any function specified in namespace `std::meta` is implementation-defined when a reflection of a construct not otherwise specified by this document is provided as an argument.
@@ -290,6 +290,7 @@ consteval bool has_identifier(info r);
290290
```
291291
[1]{.pnum} *Returns* [...]
292292
293+
* [1.1]{.pnum} [...]
293294
* [1.13]{.pnum} Otherwise, `r` represents a data member description (`$T$`, `$N$`, `$A$`, `$W$`, `$NUA$`[, `$ANN$`]{.addu}) ([class.mem.general]); `true` if `N` is not `⊥`. Otherwise, `false`.
294295
295296
```cpp
@@ -298,8 +299,10 @@ consteval u8string_view u8identifier_of(info r);
298299
```
299300

300301
[2]{.pnum} Let `$E$` be [...]
302+
301303
[3]{.pnum} *Returns*: An NTMBS, encoded with E, determined as follows:
302304

305+
* [3.1]{.pnum} [...]
303306
* [3.6]{.pnum} Otherwise, `r` represents a data member description (`$T$`, `$N$`, `$A$`, `$W$`, `$NUA$`[, `$ANN$`]{.addu}) ([class.mem.general]); a `string_view` or `u8string_view`, respectively, containing the identifier `N`.
304307
:::
305308

@@ -465,42 +468,38 @@ consteval size_t bit_size_of(info r);
465468
466469
Change [meta.reflection.annotation]{.sref}:
467470
471+
[This doesn't work for data member specifications, because those contain constants — not annotations yet. Is it even useful to pull them back out? They're not annotations yet. Do we have to synthesize annotations? It's useful to add annotations to generated data members — I'm not sure if it's useful to query the annotations on a pre-generated data member? There's also a drive-by cleanup of the wording around direct base class relationships, since `$base-specifier$`s aren't technically declared. ]{.draftnote}
472+
468473
::: std
469474
```cpp
470475
consteval vector<info> annotations_of(info item);
471476
```
472477

473-
[1]{.pnum} Let `$S$(r)` be:
474-
475-
* [#.#]{.pnum} if `r` represents a direct base class relationship, then the set of all declarations of the corresponding `$base-specifier$`,
476-
* [#.#]{.pnum} otherwise, if `r` represents a function `$F$`, then the set of declarations, ignoring any explicit instantiations, that precede some point in the evaluation context and that declare either `$F$` or a templated function of which `$F$` is a specialization,
477-
* [#.#]{.pnum} otherwise, if `r` represents a function parameter `$P$` of a function `$F$`, then `$S$(^^$F$)`.
478-
* [#.#]{.pnum} otherwise, the set of declarations of the entity represented by `r`.
479-
480-
[2]{.pnum} Let `$E$(d)` be
481-
482-
* [#.#]{.pnum} if `item` represents a function parameter `$P$` of a function `$F$`, then the corresponding function parameter of `d`.
483-
* [#.#]{.pnum} otherwise, `d`.
478+
::: addu
479+
[1]{.pnum} Let `$S$(F)` for a function `$F$` be the set of declarations, ignoring any explicit instantiations, that precede some point in the evaluation context and that declare either `$F$` or a templated function of which `$F$` is a specialization.
480+
:::
484481

485-
[3]{.pnum} *Returns*:
482+
::: rm
483+
[1]{.pnum} Let `$E$` be
486484

487-
* [#.1]{.pnum} If `item` represents the data member description (`$T$`, `$N$`, `$A$`, `$W$`, `$NUA$`, `$ANN$`), then a `vector` containing all of the reflections in `$ANN$`, in order.
488-
* [#.2]{.pnum} Otherwise, a `vector` containing all of the reflections `$R$` representing each annotation applying to `$E$($D$)` for each declaration `$D$` in `$S$(item)` that precedes either some point in the evaluation context ([expr.const]) or a point immediately following the `$class-specifier$` of the outermost class for which such a point is in a complete-class context. For any two reflections `@*R*~1~@` and `@*R*~2~@` in the returned `vector`, if the annotation represented by `@*R*~1~@` precedes the annotation represented by `@*R*~2~@`, then `@*R*~1~@` appears before `@*R*~2~@`. If `@*R*~1~@` and `@*R*~2~@` represent annotations from the same translation unit `T`, any element in the returned `vector` between `@*R*~1~@` and `@*R*~2~@` represents an annotation from `T`.
485+
* [#.#]{.pnum} the corresponding `$base-specifier$` if `item` represents a direct base class relationship,
486+
* [#.#]{.pnum} otherwise, the entity represented by `item`.
487+
:::
489488

490-
[3]{.pnum} *Returns*:
489+
[2]{.pnum} *Returns*: a `vector` containing all of the reflections `$R$` representing each annotation applying to [each declaration of `$E$` that]{.rm}:
491490

492-
* [#.1]{.pnum} If `item` represents the data member description (`$T$`, `$N$`, `$A$`, `$W$`, `$NUA$`, `$ANN$`), then a `vector` containing all of the reflections in `$ANN$`, in order.
493-
* [#.2]{.pnum} Otherwise, a `vector` containing all of the reflections `$R$` representing each annotation applying to:
494-
* [#.#.1]{.pnum} if `item` represents a function parameter `$P$` of a function `$F$`, then the declaration of `$P$` in each declaration of `$F$` in `$S$($F$)`,
495-
* [#.#.#]{.pnum} otherwise, if `item` represents a function `$F$`, then each declaration of `$F$` in `$S$($F$)`,
496-
* [#.#.#]{.pnum} otherwise, if `item` represents a direct base class relationship, then each declaration of the corresponding `$base-specifier$`,
497-
* [#.#.#]{.pnum} otherwise, the each declaration of the entity represented by `item`,
491+
::: addu
492+
* [#.1]{.pnum} if `item` represents a function parameter `$P$` of a function `$F$`, then the declaration of `$P$` in each declaration of `$F$` in `$S$($F$)`,
493+
* [#.#]{.pnum} otherwise, if `item` represents a function `$F$`, then each declaration of `$F$` in `$S$($F$)`,
494+
* [#.#]{.pnum} otherwise, if `item` represents a direct base class relationship (`$D$`, `$B$`), then the corresponding `$base-specifier$` in the definition of `$D$`,
495+
* [#.#]{.pnum} otherwise, the each declaration of the entity represented by `item`,
496+
:::
498497

499-
such that the specified declaration precedes either some point in the evaluation context ([expr.const]) or a point immediately following the `$class-specifier$` of the outermost class for which such a point is in a complete-class context. For any two reflections `@*R*~1~@` and `@*R*~2~@` in the returned `vector`, if the annotation represented by `@*R*~1~@` precedes the annotation represented by `@*R*~2~@`, then `@*R*~1~@` appears before `@*R*~2~@`. If `@*R*~1~@` and `@*R*~2~@` represent annotations from the same translation unit `T`, any element in the returned `vector` between `@*R*~1~@` and `@*R*~2~@` represents an annotation from `T`.
498+
[such that each specified declaration]{.addu} precedes either some point in the evaluation context ([expr.const]) or a point immediately following the `$class-specifier$` of the outermost class for which such a point is in a complete-class context. For any two reflections `@*R*~1~@` and `@*R*~2~@` in the returned `vector`, if the annotation represented by `@*R*~1~@` precedes the annotation represented by `@*R*~2~@`, then `@*R*~1~@` appears before `@*R*~2~@`. If `@*R*~1~@` and `@*R*~2~@` represent annotations from the same translation unit `T`, any element in the returned `vector` between `@*R*~1~@` and `@*R*~2~@` represents an annotation from `T`.
500499

501500
[The order in which two annotations appear is otherwise unspecified.]{.note}
502501

503-
[3]{.pnum} Throws: `meta​::​exception` unless item represents a type, type alias, variable, function, [function parameter,]{.addu} namespace, enumerator, direct base class relationship, [data member description,]{.addu} or non-static data member.
502+
[3]{.pnum} Throws: `meta​::​exception` unless item represents a type, type alias, variable, function, [function parameter,]{.addu} namespace, enumerator, direct base class relationship, or non-static data member.
504503

505504
:::
506505

@@ -574,9 +573,26 @@ consteval void fn() {
574573
- [#.#]{.pnum} `$A$` is either the alignment value held by `options.alignment` or ⊥ if `options.alignment` does not contain a value,
575574
- [#.#]{.pnum} `$W$` is either the value held by `options.bit_width` or ⊥ if `options.bit_width` does not contain a value, [and]{.rm}
576575
- [#.#]{.pnum} `$NUA$` is the value held by `options.no_unique_address`[.]{.rm} [, and]{.addu}
577-
- [#.#]{.pnum} [`$ANN$` is the sequence of annotations in `options.annotations`.]{.addu}
576+
- [#.#]{.pnum} [`$ANN$` is the sequence of reflection values in `options.annotations`.]{.addu}
577+
578+
[The returned reflection value is primarily useful in conjunction with `define_aggregate`; it can also be queried by certain other functions in `std::meta` (e.g., `type_of`, `identifier_of`).]{.note}
579+
580+
[#]{.pnum} *Throws*: `meta::exception` unless the following conditions are met:
578581

579-
[#]{.pnum} [The returned reflection value is primarily useful in conjunction with `define_aggregate`; it can also be queried by certain other functions in `std::meta` (e.g., `type_of`, `identifier_of`).]{.note}
582+
- [#.#]{.pnum} [`dealias(type)`]{.rm} [`dealias(options.type)`]{.addu} represents either an object type or a reference type;
583+
- [#.#]{.pnum} if `options.name` contains a value, then:
584+
- [#.#.#]{.pnum} `holds_alternative<u8string>(options.name->$contents$)` is `true` and `get<u8string>(options.name->$contents$)` contains a valid identifier ([lex.name]) that is not a keyword ([lex.key]) when interpreted with UTF-8, or
585+
- [#.#.#]{.pnum} `holds_alternative<string>(options.name->$contents$)` is `true` and `get<string>(options.name->$contents$)` contains a valid identifier that is not a keyword when interpreted with the ordinary literal encoding;
586+
587+
[The name corresponds to the spelling of an identifier token after phase 6 of translation ([lex.phases]). Lexical constructs like `$universal-character-name$`s [lex.universal.char] are not processed and will cause evaluation to fail. For example, `R"(\u03B1)"` is an invalid identifier and is not interpreted as `"α"`.]{.note}
588+
- [#.#]{.pnum} if `options.name` does not contain a value, then `options.bit_width` contains a value;
589+
- [#.#]{.pnum} if `options.bit_width` contains a value `$V$`, then
590+
- [#.#.#]{.pnum} [`is_integral_type(type) || is_enumeration_type(type)`]{.rm} [`is_integral_type(options.type) || is_enumeration_type(options.type)`]{.addu} is `true`,
591+
- [#.#.#]{.pnum} `options.alignment` does not contain a value,
592+
- [#.#.#]{.pnum} `options.no_unique_address` is `false`, and
593+
- [#.#.#]{.pnum} if `$V$` equals `0` then `options.name` does not contain a value; [and]{.rm}
594+
- [#.#]{.pnum} if `options.alignment` contains a value, it is an alignment value ([basic.align]) not less than [`alignment_of(type)`.]{.rm} [`alignment_of(options.type)`; and]{.addu}
595+
- [#.#]{.pnum} [for every reflection `r` in `options.annotations`, `is_value(r) || is_object(r)` is `true`.]{.addu}
580596

581597
```cpp
582598
template<reflection_range R = initializer_list<info>>
@@ -585,39 +601,22 @@ template<reflection_range R = initializer_list<info>>
585601
586602
[7]{.pnum} Let `$C$` be the class represented by `class_type` and `@$r$~$K$~@` be the `$K$`^th^ reflection value in `mdescrs`. For every `@$r$~$K$~@` in `mdescrs`, let (`@$T$~$K$~@`, `@$N$~$K$~@`, `@$A$~$K$~@`, `@$W$~$K$~@`, `@$NUA$~$K$~@`[, `@$ANN$~$K$~@`]{.addu}) be the corresponding data member description represented by `@$r$~$K$~@`.
587603
604+
[8]{.pnum} *Constant When*: [...]
605+
588606
[9]{.pnum} Produces an injected declaration `$D$` ([expr.const]) that defines `$C$` and has properties as follows:
589607
608+
* [9.1]{.pnum} The target scope of `$D$` is [...]
609+
* [9.2]{.pnum} The locus of `$D$` [...]
610+
* [9.3]{.pnum} The characteristic sequence of `$D$` [...]
611+
* [9.4]{.pnum} If `$C$` is a specialization [...]
590612
* [9.5]{.pnum} For each `@$r$~$K$~@`, there is a corresponding entity `@$M$~$K$~@` belonging to the class scope of `$D$` with the following properties:
591613
592614
- [#.#.#]{.pnum} If `@$N$~$K$~@` is ⊥, `@$M$~$K$~@` is an unnamed bit-field. Otherwise, `@$M$~$K$~@` is a non-static data member whose name is the identifier determined by the character sequence encoded by `@$N$~$K$~@` in UTF-8.
593615
- [#.#.#]{.pnum} The type of `@$M$~$K$~@` is `@$T$~$K$~@`.
594616
- [#.#.#]{.pnum} `@$M$~$K$~@` is declared with the attribute `[[no_unique_address]]` if and only if `@$NUA$~$K$~@` is `true`.
595617
- [#.#.#]{.pnum} If `@$W$~$K$~@` is not ⊥, `@$M$~$K$~@` is a bit-field whose width is that value. Otherwise, `@$M$~$K$~@` is not a bit-field.
596618
- [#.#.#]{.pnum} If `@$A$~$K$~@` is not ⊥, `@$M$~$K$~@` has the `$alignment-specifier$` `alignas(@$A$~$K$~@)`. Otherwise, `@$M$~$K$~@` has no `$alignment-specifier$`.
597-
- [#.#.#]{.pnum} [`@$M$~$K$~@` has the annotations `@$ANN$~$K$~@`.]{.addu}
619+
- [#.#.#]{.pnum} [`@$M$~$K$~@` has an annotation with constant `r` for every reflection `r` in `@$ANN$~$K$~@`.]{.addu}
620+
* [9.6]{.pnum} For every `@$r$~$L$~@` in `mdescrs` such that `$K$ < $L$` [...]
598621
:::
599622
600-
Add the various tuple traits in [meta.reflection.traits]{.sref}:
601-
602-
::: std
603-
```cpp
604-
consteval info tuple_element(size_t index, info type);
605-
```
606-
607-
[9]{.pnum} *Returns*: A reflection representing the type denoted by `tuple_element_t<$I$, $T$>` where `$T$` is the type represented by `dealias(type)` and `$I$` is a constant equal to `index`.
608-
609-
::: addu
610-
```cpp
611-
consteval bool is_applicable_type(info fn, info tuple);
612-
consteval bool is_nothrow_applicable_type(info fn, info tuple);
613-
```
614-
615-
[x]{.pnum} *Returns*: `is_applicable_v<$F$, $T$>` and `is_nothrow_applicable_v<$F$, $T$>`, respectively, where `$F$` and `$T$` are the types represented by `dealias(fn)` and `dealias(tuple)`, respectively.
616-
617-
```cpp
618-
consteval info apply_result(info fn, info tuple);
619-
```
620-
621-
[y]{.pnum} *Returns*: A reflection representing the type denoted by `apply_result_t<$F$, $T$>`, where `$F$` and `$T$` are the types represented by `dealias(fn)` and `dealias(tuple)`, respectively.
622-
:::
623-
:::

0 commit comments

Comments
 (0)