diff --git a/docs/spec/ProBasicConvention.md b/docs/spec/ProBasicConvention.md index 1b4dc248..6786e1fc 100644 --- a/docs/spec/ProBasicConvention.md +++ b/docs/spec/ProBasicConvention.md @@ -2,11 +2,11 @@ A type `C` meets the *ProBasicConvention* requirements if the following expressions are well-formed and have the specified semantics. -| Expressions | Semantics | -| ---------------------------- | ------------------------------------------------------------ | -| `C::is_direct` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `bool`, specifying whether the convention applies to a pointer type itself (`true`), or the element type of a pointer type (`false`). | -| `typename C::dispatch_type` | A type that defines how the calls are forwarded to the concrete types. Shall be *nothrow-default-constructible* and *nothrow-destructible*. | -| `typename C::overload_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type of one or more distinct types `Os`. Each type `O` in `Os` shall meet the [*ProOverload* requirements](ProOverload.md). | +| Expressions | Semantics | +| ------------------------------------------------ | ------------------------------------------------------------ | +| `C::is_direct` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `bool`, specifying whether the convention applies to a pointer type itself (`true`), or the element type of a pointer type (`false`). | +| `typename C::dispatch_type` | A type that defines how the calls are forwarded to the concrete types. Shall be *nothrow-default-constructible* and *nothrow-destructible*. | +| `typename C::overload_type`
*(since 5.0.0)* | A type that meets the [*ProOverload* requirements](ProOverload.md). | ## See Also diff --git a/docs/spec/ProConvention.md b/docs/spec/ProConvention.md index 65734671..2d2ac7c3 100644 --- a/docs/spec/ProConvention.md +++ b/docs/spec/ProConvention.md @@ -4,7 +4,7 @@ A type `C` meets the *ProConvention* requirements of a type `P` if `C` meets the | Expressions | Semantics | | ---------------------------- | ------------------------------------------------------------ | -| `typename C::overload_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains one or more distinct types `Os`. Each type `O` in `Os` shall meet the [*ProOverload* requirements](ProOverload.md), and
- when `C::is_direct` is `true`, `typename C::dispatch_type` shall meet the [*ProDispatch* requirements](ProDispatch.md) of `P` and `O`,
- or otherwise, when `C::is_direct` is `false`, let `QP` be a qualified reference type of `P` with the *cv ref* qualifiers defined by `O` (`QP` is an lvalue reference type if `O` does not define a *ref* qualifier), `qp` be a value of `QP`, `*std::forward(qp)` shall be well-formed, and `typename C::dispatch_type` shall meet the [*ProDispatch* requirements](ProDispatch.md) of `decltype(*std::forward(qp))` and `O`. | +| `typename C::overload_type` | A type `O` that meets the [*ProOverload* requirements](ProOverload.md), where
- when `C::is_direct` is `true`, `typename C::dispatch_type` shall meet the [*ProDispatch* requirements](ProDispatch.md) of `P` and `O`,
- or otherwise, when `C::is_direct` is `false`, let `QP` be a qualified reference type of `P` with the *cv ref* qualifiers defined by `O` (`QP` is an lvalue reference type if `O` does not define a *ref* qualifier), `qp` be a value of `QP`, `*std::forward(qp)` shall be well-formed, and `typename C::dispatch_type` shall meet the [*ProDispatch* requirements](ProDispatch.md) of `decltype(*std::forward(qp))` and `O`. | ## See Also diff --git a/docs/spec/basic_facade_builder/add_convention.md b/docs/spec/basic_facade_builder/add_convention.md index 0797eeca..c432c9d6 100644 --- a/docs/spec/basic_facade_builder/add_convention.md +++ b/docs/spec/basic_facade_builder/add_convention.md @@ -14,18 +14,20 @@ using add_direct_convention = basic_facade_builder; The alias templates `add_convention`, `add_indirect_convention`, and `add_direct_convention` of `basic_facade_builder` 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, - `add_convention` is equivalent to `add_indirect_convention`. -- `add_indirect_convention` merges an implementation-defined convention type `IC` into `Cs`, where: +- `add_indirect_convention` merges an implementation-defined convention type `IC` into `Cs` for each type `O` in `Os`, where: - `IC::is_direct` is `false`. - `typename IC::dispatch_type` is `D`. - - `typename IC::overload_types` is a [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type of distinct types in `Os`. - - `typename IC::template accessor` is `typename D::template accessor, D, `[`substituted-overload`](../ProOverload.md)`...>` if applicable. -- `add_direct_convention` merges an implementation-defined convention type `IC` into `Cs`, where: + - `typename IC::overload_type` is `O`. +- `add_direct_convention` merges an implementation-defined convention type `IC` into `Cs` for each type `O` in `Os`, where: - `IC::is_direct` is `true`. - `typename IC::dispatch_type` is `D`. - - `typename IC::overload_types` is a [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type of distinct types in `Os`. - - `typename IC::template accessor` is `typename D::template accessor, D, `[`substituted-overload`](../ProOverload.md)`...>` if applicable. + - `typename IC::overload_type` is `O`. -When `Cs` already contains a convention type `IC2` where `IC2::is_direct == IC::is_direct && std::is_same_v` is `true`, `Os` merges with `typename IC2::overload_types` and removes duplicates, and `std::tuple_size_v` shall not change. +When `Cs` already contains a convention type identical to `IC`, the template parameters shall not change. + +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, D, `[`substituted-overload`](../ProOverload.md)`...>` when `IC::is_direct` is `false`, or `typename D::template accessor, D, `[`substituted-overload`](../ProOverload.md)`...>` when it is `true`, if applicable. + +*Since 5.0.0*: each type in `Os` produces its own convention type, rather than one convention type carrying a tuple-like `overload_types`. ## Notes diff --git a/docs/spec/proxy/README.md b/docs/spec/proxy/README.md index 5e56583f..c32fc567 100644 --- a/docs/spec/proxy/README.md +++ b/docs/spec/proxy/README.md @@ -15,9 +15,11 @@ Any instance of `proxy` at any given point in time either *contains a value* As per `facade`, `typename F::convention_types` shall be a [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type containing any number of distinct types `Cs`, and `typename F::reflection_types` shall be a [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type containing any number of distinct types `Rs`. -- For each type `C` in `Cs`, if `C::is_direct` is `true` and `typename C::dispatch_type` meets the [*ProAccessible* requirements](../ProAccessible.md) of `proxy, typename C::dispatch_type, substituted-overload-types...`, `typename C::dispatch_type::template accessor, typename C::dispatch_type, substituted-overload-types...>` is inherited by `proxy`. Let `Os...` be the element types of `typename C::overload_types`, `substituted-overload-types...` is [`substituted-overload...`](../ProOverload.md). +- For each distinct dispatch type `D` among the types `C` in `Cs` where `C::is_direct` is `true`, let `Os...` be the overload types of those conventions with duplicates removed, and `substituted-overload-types...` be [`substituted-overload...`](../ProOverload.md). If `D` meets the [*ProAccessible* requirements](../ProAccessible.md) of `proxy, D, substituted-overload-types...`, `typename D::template accessor, D, substituted-overload-types...>` is inherited by `proxy`. - For each type `R` in `Rs`, if `R::is_direct` is `true` and `typename R::reflector_type` meets the [*ProAccessible* requirements](../ProAccessible.md) of `proxy, typename R::reflector_type`, `typename R::reflector_type::template accessor, typename R::reflector_type` is inherited by `proxy`. +*Since 5.0.0*: the accessor of a dispatch type is formed from the overload types of every convention in `Cs` sharing that dispatch type, rather than from a single convention. + ## Member Types | Name | Description | diff --git a/docs/spec/proxy/friend_invoke.md b/docs/spec/proxy/friend_invoke.md index be6fd290..8b8aff89 100644 --- a/docs/spec/proxy/friend_invoke.md +++ b/docs/spec/proxy/friend_invoke.md @@ -21,7 +21,7 @@ There shall be a convention type `Conv` defined in `typename F::convention_types - `Conv::is_direct` is `true`, and - `typename Conv::dispatch_type` is `D`, and -- there shall be an overload type `O1` defined in `typename Conv::overload_types` where [`substituted-overload`](../ProOverload.md)`` is `O`. +- [`substituted-overload`](../ProOverload.md)`` is `O`. This function is not visible to ordinary [unqualified](https://en.cppreference.com/w/cpp/language/unqualified_lookup) or [qualified lookup](https://en.cppreference.com/w/cpp/language/qualified_lookup). It can only be found by [argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl) when `proxy` is an associated class of the arguments. diff --git a/docs/spec/proxy_indirect_accessor/README.md b/docs/spec/proxy_indirect_accessor/README.md index fbab8dca..fff00f44 100644 --- a/docs/spec/proxy_indirect_accessor/README.md +++ b/docs/spec/proxy_indirect_accessor/README.md @@ -12,9 +12,11 @@ class proxy_indirect_accessor; Class template `proxy_indirect_accessor` provides indirection accessibility for `proxy`. As per `facade`, `typename F::convention_types` shall be a [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type containing any number of distinct types `Cs`, and `typename F::reflection_types` shall be a [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type containing any number of distinct types `Rs`. -- For each type `C` in `Cs`, if `C::is_direct` is `false` and `typename C::dispatch_type` meets the [*ProAccessible* requirements](../ProAccessible.md) of `proxy_indirect_accessor, typename C::dispatch_type, substituted-overload-types...`, `typename C::dispatch_type::template accessor, typename C::dispatch_type, substituted-overload-types...>` is inherited by `proxy_indirect_accessor`. Let `Os...` be the element types of `typename C::overload_types`, `substituted-overload-types...` is [`substituted-overload...`](../ProOverload.md). +- For each distinct dispatch type `D` among the types `C` in `Cs` where `C::is_direct` is `false`, let `Os...` be the overload types of those conventions with duplicates removed, and `substituted-overload-types...` be [`substituted-overload...`](../ProOverload.md). If `D` meets the [*ProAccessible* requirements](../ProAccessible.md) of `proxy_indirect_accessor, D, substituted-overload-types...`, `typename D::template accessor, D, substituted-overload-types...>` is inherited by `proxy_indirect_accessor`. - For each type `R` in `Rs`, if `R::is_direct` is `false` and `typename R::reflector_type` meets the [*ProAccessible* requirements](../ProAccessible.md) of `proxy_indirect_accessor, typename R::reflector_type`, `typename R::reflector_type::template accessor, typename R::reflector_type` is inherited by `proxy_indirect_accessor`. +*Since 5.0.0*: the accessor of a dispatch type is formed from the overload types of every convention in `Cs` sharing that dispatch type, rather than from a single convention. + ## Member Functions | Name | Description | diff --git a/docs/spec/proxy_indirect_accessor/friend_invoke.md b/docs/spec/proxy_indirect_accessor/friend_invoke.md index 0a5e9f1c..f57877f2 100644 --- a/docs/spec/proxy_indirect_accessor/friend_invoke.md +++ b/docs/spec/proxy_indirect_accessor/friend_invoke.md @@ -21,7 +21,7 @@ There shall be a convention type `Conv` defined in `typename F::convention_types - `Conv::is_direct` is `false`, and - `typename Conv::dispatch_type` is `D`, and -- there shall be an overload type `O1` defined in `typename Conv::overload_types` where [`substituted-overload`](../ProOverload.md)`` is `O`. +- [`substituted-overload`](../ProOverload.md)`` is `O`. This function is not visible to ordinary [unqualified](https://en.cppreference.com/w/cpp/language/unqualified_lookup) or [qualified lookup](https://en.cppreference.com/w/cpp/language/qualified_lookup). It can only be found by [argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl) when `proxy_indirect_accessor` is an associated class of the arguments. diff --git a/include/proxy/v4/detail/core.h b/include/proxy/v4/detail/core.h index 00b87943..0cd9f41f 100644 --- a/include/proxy/v4/detail/core.h +++ b/include/proxy/v4/detail/core.h @@ -77,19 +77,44 @@ struct inapplicable_traits { static constexpr bool applicable = false; }; -template