Skip to content

Commit 28e938e

Browse files
authored
[super! 5/6] Add super facades (#74)
* Add super facades add_facade<F> copied F's conventions and reflections into the built facade. The two facades then shared behavior but had unrelated metadata, so converting a proxy of one to a proxy of the other needed an explicit substitution convention and an indirect call to translate. Give a facade a super_types list. add_facade<F> records F there instead of copying, and the metadata of the built facade embeds the metadata of each super, so const proxy_meta<Derived>& converts to const proxy_meta<Super>&. proxy gains converting constructors and assignment operators guarded on exactly that conversion: the metadata is carried over directly, and only the contained value is copied or relocated. A convention whose overload is a facade_aware_overload_t is the exception to "not copied": its overload depends on the facade it is built into, so it is also checked and made available against the built facade. That is what lets as_view declared on a super yield a proxy_view of the built facade rather than of the super. Accessors are formed from the conventions of the facade and of every super, regrouped per dispatch type, so an overload set spanning a super and the facade that derives from it stays a single overload set. observer_facade and weak_facade map super_types through themselves, so view-ness and weak-ness are preserved across a conversion to a super. add_facade<F, true>, deprecated since 4.1.0, is removed. The second parameter of add_facade, deprecated since 4.1.0, is retained and ignored: a proxy of the built facade already converts to a proxy<F> because F is a super. add_facade_with_substitution and substitution_dispatch are unchanged and still take precedence where both apply; they are addressed in a follow-up. * Reach the trivial copy and relocation by the source facade A converting initialization asked the destination facade whether the copy or the relocation is trivial, but the triviality that licenses a byte copy belongs to the value being moved, which lives in the source. A super is never stricter than the facade converting to it, so the byte copy was missed whenever the derived facade was the stricter of the two, and the value went through the erased invoker instead. Corrected three lines of the specification along the way. The copy assignment is not "as if by auto(rhs).swap(*this)", which is not even formed for a facade that forbids relocation. The converting move assignment loses the contained value on a throwing relocation exactly as the move assignment does. The move constructor is noexcept for trivial relocatability, which its documented signature spelled as an equality.
1 parent a9f488f commit 28e938e

26 files changed

Lines changed: 805 additions & 295 deletions

docs/spec/ProBasicFacade.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
A type `F` meets the *ProBasicFacade* requirements if the following expressions are well-formed and have the specified semantics.
44

5-
| Expressions | Semantics |
6-
| ------------------------------ | ------------------------------------------------------------ |
7-
| `typename F::convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of distinct types `Cs`. Each type `C` in `Cs` shall meet the [*ProBasicConvention* requirements](ProBasicConvention.md). |
8-
| `typename F::reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of distinct types `Rs`. Each type `R` in `Rs` shall meet the [*ProBasicReflection* requirements](ProBasicReflection.md). |
9-
| `F::max_size` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that defines the maximum size of a pointer type. Shall be greater than `0` and a multiple of `F::max_align`. |
10-
| `F::max_align` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that defines the maximum alignment of a pointer type. Shall be a power of `2`. |
11-
| `F::copyability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required copyability of a pointer type. |
12-
| `F::relocatability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required relocatability of a pointer type. |
13-
| `F::destructibility` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required destructibility of a pointer type. |
5+
| Expressions | Semantics |
6+
| ---------------------------------------------- | ------------------------------------------------------------ |
7+
| `typename F::super_types`<br />*(since 5.0.0)* | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of types `Ss`. Each type `S` in `Ss` shall meet the *ProBasicFacade* requirements, and shall be no more conservative than `F`, that is: `F::max_size <= S::max_size`, `F::max_align <= S::max_align`, `F::copyability >= S::copyability`, `F::relocatability >= S::relocatability`, and `F::destructibility >= S::destructibility`. |
8+
| `typename F::convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of types `Cs`. Each type `C` in `Cs` shall meet the [*ProBasicConvention* requirements](ProBasicConvention.md). |
9+
| `typename F::reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of types `Rs`. Each type `R` in `Rs` shall meet the [*ProBasicReflection* requirements](ProBasicReflection.md). |
10+
| `F::max_size` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that defines the maximum size of a pointer type. Shall be greater than `0` and a multiple of `F::max_align`. |
11+
| `F::max_align` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that defines the maximum alignment of a pointer type. Shall be a power of `2`. |
12+
| `F::copyability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required copyability of a pointer type. |
13+
| `F::relocatability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required relocatability of a pointer type. |
14+
| `F::destructibility` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required destructibility of a pointer type. |
1415

1516
Each of `F::copyability`, `F::relocatability`, and `F::destructibility` shall be exactly one of the four enumerators of `constraint_level` (`none`, `nontrivial`, `nothrow`, `trivial`).
1617

docs/spec/ProFacade.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22

33
A type `F` meets the *ProFacade* requirements of a type `P` if `F` meets the [*ProBasicFacade* requirements](ProBasicFacade.md), and the following expressions are well-formed and have the specified semantics.
44

5-
| Expressions | Semantics |
6-
| ------------------------------ | ------------------------------------------------------------ |
7-
| `typename F::convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of distinct types `Cs`. Each type `C` in `Cs` shall meet the [*ProConvention* requirements](ProConvention.md) of `P`. |
8-
| `typename F::reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of distinct types `Rs`. Each type `R` in `Rs` shall meet the [*ProReflection* requirements](ProReflection.md) of `P`. |
9-
| `F::max_size` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that shall be greater than or equal to `sizeof(P)`. |
10-
| `F::max_align` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that shall be greater than or equal to `alignof(P)`. |
11-
| `F::copyability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required copyability of `P`. |
12-
| `F::relocatability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required relocatability of `P`. |
13-
| `F::destructibility` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required destructibility of `P`. |
5+
| Expressions | Semantics |
6+
| ---------------------------------------------- | ------------------------------------------------------------ |
7+
| `typename F::super_types`<br />*(since 5.0.0)* | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of types `Ss`. Each type `S` in `Ss` shall meet the *ProFacade* requirements of `P`. |
8+
| `typename F::convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of types `Cs`. Each type `C` in `Cs` shall meet the [*ProConvention* requirements](ProConvention.md) of `P`. |
9+
| `typename F::reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of types `Rs`. Each type `R` in `Rs` shall meet the [*ProReflection* requirements](ProReflection.md) of `P`. |
10+
| `F::max_size` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that shall be greater than or equal to `sizeof(P)`. |
11+
| `F::max_align` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that shall be greater than or equal to `alignof(P)`. |
12+
| `F::copyability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required copyability of `P`. |
13+
| `F::relocatability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required relocatability of `P`. |
14+
| `F::destructibility` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required destructibility of `P`. |
15+
16+
*Since 5.0.0*: let `Cs` be the conventions of `F` and of every super of `F`, reachable via `typename F::super_types` transitively. Each type `C` in `Cs` whose `typename C::overload_type` is a specialization of [`facade_aware_overload_t`](facade_aware_overload_t.md) shall also meet the [*ProConvention* requirements](ProConvention.md) of `P` with [`substituted-overload`](ProOverload.md)`<typename C::overload_type, F>` in place of `typename C::overload_type`. Among the types in `Cs` sharing `is_direct` and `dispatch_type`, distinct `overload_type`s shall substitute to distinct overloads.
1417

1518
*Since 4.0.2*: `P` shall be a pointer-like type eligible for `proxy`. A type `P` is eligible if the following condition is satisfied:
1619

docs/spec/basic_facade_builder/.pages

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
nav:
22
- basic_facade_builder: README.md
33
- add_convention<br />add_indirect_convention<br />add_direct_convention: add_convention.md
4-
- add_facade_with_substitution: add_facade_with_substitution.md
54
- add_facade: add_facade.md
5+
- add_facade_with_substitution: add_facade_with_substitution.md
66
- add_reflection<br />add_indirect_reflection<br />add_direct_reflection: add_reflection.md
77
- add_skill: add_skill.md
88
- build: build.md

docs/spec/basic_facade_builder/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,20 @@ constexpr constraint_level default-cl = static_cast<constraint_level>(
1515
Given a [facade](../facade.md) type `F`, any meaningful value of `F::max_size` and `F::max_align` is less than *default-size*; any meaningful value of `F::copyability`, `F::relocatability`, and `F::destructibility` is greater than *default-cl*.
1616

1717
```cpp
18-
template <class Cs, class Rs, std::size_t MaxSize, std::size_t MaxAlign,
19-
constraint_level Copyability, constraint_level Relocatability,
20-
constraint_level Destructibility>
18+
template <class Ss, class Cs, class Rs, std::size_t MaxSize,
19+
std::size_t MaxAlign, constraint_level Copyability,
20+
constraint_level Relocatability, constraint_level Destructibility>
2121
class basic_facade_builder;
2222

2323
using facade_builder =
24-
basic_facade_builder<std::tuple<>, std::tuple<>, default-size, default-size,
25-
default-cl, default-cl, default-cl>;
24+
basic_facade_builder<std::tuple<>, std::tuple<>, std::tuple<>, default-size,
25+
default-size, default-cl, default-cl, default-cl>;
2626
```
2727
2828
`basic_facade_builder` provides a member type `build` that compiles the template parameters into a [`facade`](../facade.md) type. The template parameters can be modified via various member alias templates that specify `basic_facade_builder` with the modified template parameters.
2929
30+
*Since 5.0.0*: `Ss` is added to the template parameters, holding the supers accumulated by [`add_facade`](add_facade.md).
31+
3032
## Member Types
3133
3234
| Name | Description |
@@ -38,8 +40,8 @@ using facade_builder =
3840
| Name | Description |
3941
| ------------------------------------------------------------ | ------------------------------------------------------------ |
4042
| [`add_convention`<br />`add_indirect_convention`<br />`add_direct_convention`](add_convention.md) | Adds a convention to the template parameters |
41-
| [`add_facade_with_substitution`](add_facade_with_substitution.md) | Adds a facade to the template parameters, together with [substitution](../substitution_dispatch/README.md) support |
4243
| [`add_facade`](add_facade.md) | Adds a facade to the template parameters |
44+
| [`add_facade_with_substitution`](add_facade_with_substitution.md) | Adds a facade to the template parameters, together with [substitution](../substitution_dispatch/README.md) support |
4345
| [`add_reflection`<br />`add_indirect_reflection`<br />`add_direct_reflection`](add_reflection.md) | Adds a reflection to the template parameters |
4446
| [`add_skill`](add_skill.md) | Adds a custom skill |
4547
| [`restrict_layout`](restrict_layout.md) | Specifies maximum `MaxSize` and `MaxAlign` in the template parameters |

docs/spec/basic_facade_builder/add_convention.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,23 @@ template <class D, class... Os> requires(/* see below */)
1111
using add_direct_convention = basic_facade_builder</* see below */>;
1212
```
1313
14-
The alias templates `add_convention`, `add_indirect_convention`, and `add_direct_convention` of `basic_facade_builder<Cs, Rs, MaxSize, MaxAlign, Copyability, Relocatability, Destructibility>` add convention types to the template parameters. The expression inside `requires` is equivalent to `sizeof...(Os) > 0u` and each type in `Os` meets the [*ProOverload* requirements](../ProOverload.md). Let `F` be a facade type,
14+
The alias templates `add_convention`, `add_indirect_convention`, and `add_direct_convention` of `basic_facade_builder<Ss, Cs, Rs, MaxSize, MaxAlign, Copyability, Relocatability, Destructibility>` add convention types to the template parameters. The expression inside `requires` is equivalent to `sizeof...(Os) > 0u` and each type in `Os` meets the [*ProOverload* requirements](../ProOverload.md).
1515
1616
- `add_convention` is equivalent to `add_indirect_convention`.
17-
- `add_indirect_convention` merges an implementation-defined convention type `IC` into `Cs` for each type `O` in `Os`, where:
17+
- `add_indirect_convention` appends an implementation-defined convention type `IC` to `Cs` for each type `O` in `Os`, where:
1818
- `IC::is_direct` is `false`.
1919
- `typename IC::dispatch_type` is `D`.
2020
- `typename IC::overload_type` is `O`.
21-
- `add_direct_convention` merges an implementation-defined convention type `IC` into `Cs` for each type `O` in `Os`, where:
21+
- `add_direct_convention` appends an implementation-defined convention type `IC` to `Cs` for each type `O` in `Os`, where:
2222
- `IC::is_direct` is `true`.
2323
- `typename IC::dispatch_type` is `D`.
2424
- `typename IC::overload_type` is `O`.
2525
26-
When `Cs` already contains a convention type identical to `IC`, the template parameters shall not change.
27-
28-
Let `F` be a facade type. The accessor a convention contributes to a [`proxy`](../proxy/README.md) of `F` is formed per dispatch type rather than per convention: let `Gs` be the types in `Cs` that share `IC::is_direct` and `typename IC::dispatch_type`, and `GOs` be their `overload_type`s in order of first appearance. The accessor is `typename D::template accessor<proxy_indirect_accessor<F>, D, `[`substituted-overload<GOs, F>`](../ProOverload.md)`...>` when `IC::is_direct` is `false`, or `typename D::template accessor<proxy<F>, D, `[`substituted-overload<GOs, F>`](../ProOverload.md)`...>` when it is `true`, if applicable.
29-
3026
*Since 5.0.0*: each type in `Os` produces its own convention type, rather than one convention type carrying a tuple-like `overload_types`.
3127
3228
## Notes
3329
34-
Adding duplicated combinations of some dispatch type and overload type is well-defined (either directly via `add_convention`, `add_indirect_convention`, `add_direct_convention`, or indirectly via [`add_facade`](add_facade.md)), and does not have side-effects to [`build`](build.md) at either compile-time or runtime.
30+
Adding duplicated combinations of some dispatch type and overload type is well-defined (either directly via `add_convention`, `add_indirect_convention`, `add_direct_convention`, or indirectly via [`add_facade`](add_facade.md)). While such duplicates change the type produced by [`build`](build.md), they do not have side-effects on a [`proxy`](../proxy/README.md) of that facade at either compile-time or runtime.
3531
3632
## Example
3733

0 commit comments

Comments
 (0)