` *contains a value*, the type of the value shall be a pointer type `P` where [`proxiable`](../proxiable.md) is `true`, and the value is guaranteed to be allocated as part of the `proxy` object footprint, i.e. no dynamic memory allocation occurs. However, `P` may allocate during its construction, depending on its implementation.
-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`.
+Let `Cs` be the convention types of `F` and of every super of `F`, reachable via `typename F::super_types` transitively, and `Rs` be the reflection types of `F` and of every such super.
- 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.
+*Since 5.0.0*: `Cs` and `Rs` include the conventions and reflections of the supers of `F`, and 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
diff --git a/docs/spec/proxy/assignment.md b/docs/spec/proxy/assignment.md
index 8934ce1..2792569 100644
--- a/docs/spec/proxy/assignment.md
+++ b/docs/spec/proxy/assignment.md
@@ -24,7 +24,24 @@ proxy& operator=(proxy&& rhs)
F::destructibility >= constraint_level::nontrivial &&
F::copyability != constraint_level::trivial);
-// (4)
+// (4) (since 5.0.0)
+template
+proxy& operator=(const proxy& rhs)
+ noexcept(F::copyability >= constraint_level::nothrow &&
+ F::destructibility >= constraint_level::nothrow)
+ requires(F::copyability >= constraint_level::nontrivial &&
+ F::destructibility >= constraint_level::nontrivial);
+
+// (5) (since 5.0.0)
+template
+proxy& operator=(proxy&& rhs)
+ noexcept(F::relocatability >= constraint_level::nothrow &&
+ F::destructibility >= constraint_level::nothrow)
+ requires(F::relocatability >= constraint_level::nontrivial &&
+ F::destructibility >= constraint_level::nontrivial &&
+ F::copyability != constraint_level::trivial);
+
+// (6)
template
proxy& operator=(P&& ptr)
noexcept(std::is_nothrow_constructible_v, P> &&
@@ -38,7 +55,9 @@ Assigns a new value to `proxy` or destroys the contained value.
- `(1)` Destroys the current contained value if it exists. After the call, `*this` does not contain a value.
- `(2)` Copy assignment operator copies the contained value of `rhs` to `*this`. If `rhs` does not contain a value, it destroys the contained value of `*this` (if any) as if by `auto(rhs).swap(*this)`. The copy assignment is trivial when `F::copyability == constraint_level::trivial` is `true`.
- `(3)` Move assignment operator moves the contained value of `rhs` to `*this`. If `rhs` does not contain a value, it destroys the contained value of `*this` (if any). If the move construction throws when `F::relocatability == constraint_level::nontrivial`, `*this` does not contain a value. After move assignment, `rhs` is in a valid state with an unspecified value. The move assignment operator does not participate in overload resolution when `F::copyability == constraint_level::trivial`, falling back to the trivial copy assignment operator.
-- `(4)` Let `VP` be `std::decay_t`. Sets the contained value to an object of type `VP`, direct-non-list-initialized with `std::forward
(ptr)`. Participates in overload resolution only if `VP` is not a specialization of `proxy` and is a pointer-like type eligible for `proxy` (see [*ProFacade* requirements](../ProFacade.md)). *Since 3.3.0*: If [`proxiable`](../proxiable.md) is `false`, the program is ill-formed and a diagnostic is generated.
+- `(4)` Converting copy assignment operator copies the contained value of `rhs` to `*this`, as if by constructing a `proxy` from `rhs` and assigning it. If `rhs` does not contain a value, it destroys the contained value of `*this` (if any). Participates in overload resolution only if `F2` is not `F` and `F` is a super of `F2`, reachable via `typename F2::super_types` transitively.
+- `(5)` Converting move assignment operator moves the contained value of `rhs` to `*this`. If `rhs` does not contain a value, it destroys the contained value of `*this` (if any). After the assignment, `rhs` does not contain a value. Participates in overload resolution only if `F2` is not `F` and `F` is a super of `F2`, reachable via `typename F2::super_types` transitively. The converting move assignment operator does not participate in overload resolution when `F::copyability == constraint_level::trivial`, falling back to `(4)`.
+- `(6)` Let `VP` be `std::decay_t`. Sets the contained value to an object of type `VP`, direct-non-list-initialized with `std::forward
(ptr)`. Participates in overload resolution only if `VP` is not a specialization of `proxy` and is a pointer-like type eligible for `proxy` (see [*ProFacade* requirements](../ProFacade.md)). *Since 3.3.0*: If [`proxiable`](../proxiable.md) is `false`, the program is ill-formed and a diagnostic is generated.
## Return Value
diff --git a/docs/spec/proxy/constructor.md b/docs/spec/proxy/constructor.md
index 922bf8f..d05846c 100644
--- a/docs/spec/proxy/constructor.md
+++ b/docs/spec/proxy/constructor.md
@@ -19,18 +19,31 @@ proxy(proxy&& rhs)
requires(F::relocatability >= constraint_level::nontrivial &&
F::copyability != constraint_level::trivial);
-// (4)
+// (4) (since 5.0.0)
+template
+proxy(const proxy& rhs)
+ noexcept(F::copyability >= constraint_level::nothrow)
+ requires(F::copyability >= constraint_level::nontrivial);
+
+// (5) (since 5.0.0)
+template
+proxy(proxy&& rhs)
+ noexcept(F::relocatability >= constraint_level::nothrow)
+ requires(F::relocatability >= constraint_level::nontrivial &&
+ F::copyability != constraint_level::trivial);
+
+// (6)
template
proxy(P&& ptr) noexcept(std::is_nothrow_constructible_v, P>)
requires(std::is_constructible_v, P>);
-// (5)
+// (7)
template
explicit proxy(std::in_place_type_t, Args&&... args)
noexcept(std::is_nothrow_constructible_v
)
requires(std::is_constructible_v
);
-// (6)
+// (8)
template
explicit proxy(std::in_place_type_t, std::initializer_list il,
Args&&... args)
@@ -44,11 +57,13 @@ Creates a new `proxy`.
- `(1)` Default constructor and the constructor taking `nullptr` construct a `proxy` that does not contain a value.
- `(2)` Copy constructor constructs a `proxy` whose contained value is that of `rhs` if `rhs` contains a value, or otherwise, constructs a `proxy` that does not contain a value. As per the `requires` clause, the copy constructor is trivial when `F::copyability == constraint_level::trivial`.
- `(3)` Move constructor constructs a `proxy` whose contained value is that of `rhs` if `rhs` contains a value, or otherwise, constructs a `proxy` that does not contain a value. `rhs` is in a valid but unspecified state after move construction. As per the `requires` clause, the move constructor does not participate in overload resolution when `F::copyability == constraint_level::trivial`, so that a move construction falls back to the trivial copy constructor.
-- `(4)` Let `VP` be `std::decay_t
`. Constructs a `proxy` whose contained value is of type `VP`, direct-non-list-initialized with `std::forward
(ptr)`. Participates in overload resolution only if `VP` is not a specialization of `proxy` and is a pointer-like type eligible for `proxy` (see [*ProFacade* requirements](../ProFacade.md)).
-- `(5)` Constructs a `proxy` whose contained value is of type `P`, direct-non-list-initialized with `std::forward(args)...`. Participates in overload resolution only if `P` is a pointer-like type eligible for `proxy`.
-- `(6)` Constructs a `proxy` whose contained value is of type `P`, direct-non-list-initialized with `il, std::forward(args)...`. Participates in overload resolution only if `P` is a pointer-like type eligible for `proxy`.
+- `(4)` Converting copy constructor constructs a `proxy` whose contained value is a copy of that of `rhs` if `rhs` contains a value, or otherwise, constructs a `proxy` that does not contain a value. Participates in overload resolution only if `F2` is not `F` and `F` is a super of `F2`, reachable via `typename F2::super_types` transitively.
+- `(5)` Converting move constructor constructs a `proxy` whose contained value is that of `rhs` if `rhs` contains a value, or otherwise, constructs a `proxy` that does not contain a value. `rhs` does not contain a value after the conversion. Participates in overload resolution only if `F2` is not `F` and `F` is a super of `F2`, reachable via `typename F2::super_types` transitively. As per the `requires` clause, the converting move constructor does not participate in overload resolution when `F::copyability == constraint_level::trivial`, so that a conversion from an rvalue falls back to `(4)`.
+- `(6)` Let `VP` be `std::decay_t`. Constructs a `proxy` whose contained value is of type `VP`, direct-non-list-initialized with `std::forward
(ptr)`. Participates in overload resolution only if `VP` is not a specialization of `proxy` and is a pointer-like type eligible for `proxy` (see [*ProFacade* requirements](../ProFacade.md)).
+- `(7)` Constructs a `proxy` whose contained value is of type `P`, direct-non-list-initialized with `std::forward(args)...`. Participates in overload resolution only if `P` is a pointer-like type eligible for `proxy`.
+- `(8)` Constructs a `proxy` whose contained value is of type `P`, direct-non-list-initialized with `il, std::forward(args)...`. Participates in overload resolution only if `P` is a pointer-like type eligible for `proxy`.
-*Since 3.3.0*: For `(4-6)`, if [`proxiable, F>`](../proxiable.md) is `false`, the program is ill-formed and diagnostic messages are generated.
+*Since 3.3.0*: For `(6-8)`, if [`proxiable, F>`](../proxiable.md) is `false`, the program is ill-formed and diagnostic messages are generated.
## Comparing with Other Standard Polymorphic Wrappers
diff --git a/docs/spec/proxy/friend_invoke.md b/docs/spec/proxy/friend_invoke.md
index 2facfe6..ead4193 100644
--- a/docs/spec/proxy/friend_invoke.md
+++ b/docs/spec/proxy/friend_invoke.md
@@ -17,7 +17,7 @@ Invokes a `proxy` with a specified dispatch type `D`, an overload type `O`, a
Let `ptr` be the contained value of `p` with the same cv ref-qualifiers. Equivalent to [`INVOKE`](https://en.cppreference.com/w/cpp/utility/functional)`(D(), ptr, static_cast(args)...)`. The behavior is undefined if `p` does not contain a value.
-There shall be a convention type `Conv` defined in `typename F::convention_types` where
+There shall be a convention type `Conv` defined in the convention types of `F` or of any super of `F`, reachable via `typename F::super_types` transitively, where
- `Conv::is_direct` is `true`, and
- `typename Conv::dispatch_type` is `D`, and
diff --git a/docs/spec/proxy/friend_reflect.md b/docs/spec/proxy/friend_reflect.md
index bf74787..9bf04cd 100644
--- a/docs/spec/proxy/friend_reflect.md
+++ b/docs/spec/proxy/friend_reflect.md
@@ -11,7 +11,7 @@ Acquires reflection information of the contained type of a `proxy`, through a
Let `P` be the contained type of `p`. Returns a `const` reference of `R` direct-non-list-initialized with [`std::in_place_type`](https://en.cppreference.com/w/cpp/utility/in_place). The behavior is undefined if `p` does not contain a value.
-There shall be a reflection type `Refl` defined in `typename F::reflection_types` where
+There shall be a reflection type `Refl` defined in the reflection types of `F` or of any super of `F`, reachable via `typename F::super_types` transitively, where
- `Refl::is_direct` is `true`, and
- `typename Refl::reflector_type` is `R`.
diff --git a/docs/spec/proxy_indirect_accessor/README.md b/docs/spec/proxy_indirect_accessor/README.md
index e510dd2..9f2f81c 100644
--- a/docs/spec/proxy_indirect_accessor/README.md
+++ b/docs/spec/proxy_indirect_accessor/README.md
@@ -10,12 +10,12 @@ template
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`.
+Class template `proxy_indirect_accessor` provides indirection accessibility for `proxy`. Let `Cs` be the convention types of `F` and of every super of `F`, reachable via `typename F::super_types` transitively, and `Rs` be the reflection types of `F` and of every such super.
- 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.
+*Since 5.0.0*: `Cs` and `Rs` include the conventions and reflections of the supers of `F`, and 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
diff --git a/docs/spec/proxy_indirect_accessor/friend_invoke.md b/docs/spec/proxy_indirect_accessor/friend_invoke.md
index fb8b015..ebfbfab 100644
--- a/docs/spec/proxy_indirect_accessor/friend_invoke.md
+++ b/docs/spec/proxy_indirect_accessor/friend_invoke.md
@@ -17,7 +17,7 @@ Invokes a `proxy_indirect_accessor` with a specified dispatch type `D`, an ov
Let `ptr` be the contained value of the `proxy` object associated to `p` with the same cv ref-qualifiers. Equivalent to [`INVOKE`](https://en.cppreference.com/w/cpp/utility/functional)`(D(), *ptr, static_cast(args)...)`.
-There shall be a convention type `Conv` defined in `typename F::convention_types` where
+There shall be a convention type `Conv` defined in the convention types of `F` or of any super of `F`, reachable via `typename F::super_types` transitively, where
- `Conv::is_direct` is `false`, and
- `typename Conv::dispatch_type` is `D`, and
diff --git a/docs/spec/proxy_indirect_accessor/friend_reflect.md b/docs/spec/proxy_indirect_accessor/friend_reflect.md
index 70630c7..900bad3 100644
--- a/docs/spec/proxy_indirect_accessor/friend_reflect.md
+++ b/docs/spec/proxy_indirect_accessor/friend_reflect.md
@@ -11,7 +11,7 @@ Acquires reflection information of the contained type of the associated `proxy`,
Let `P` be the contained type of the `proxy` object associated to `p`. Returns a `const` reference of `R` direct-non-list-initialized with [`std::in_place_type::element_type>`](https://en.cppreference.com/w/cpp/utility/in_place).
-There shall be a reflection type `Refl` defined in `typename F::reflection_types` where
+There shall be a reflection type `Refl` defined in the reflection types of `F` or of any super of `F`, reachable via `typename F::super_types` transitively, where
- `Refl::is_direct` is `false`, and
- `typename Refl::reflector_type` is `R`.
diff --git a/docs/spec/proxy_invoke.md b/docs/spec/proxy_invoke.md
index dda3a2d..dd84873 100644
--- a/docs/spec/proxy_invoke.md
+++ b/docs/spec/proxy_invoke.md
@@ -33,11 +33,11 @@ Invokes a `proxy` with a specified dispatch type, an overload type, and argument
- `(1)` Let `ptr` be the contained value of the `proxy` object associated to `p` with the same cv ref-qualifiers. Equivalent to [`INVOKE`](https://en.cppreference.com/w/cpp/utility/functional)`(D(), *ptr, static_cast(args)...)`.
- `(2)` Let `ptr` be the contained value of `p` with the same cv ref-qualifiers. Equivalent to [`INVOKE`](https://en.cppreference.com/w/cpp/utility/functional)`(D(), ptr, static_cast(args)...)`. The behavior is undefined if `p` does not contain a value.
-There shall be a convention type `Conv` defined in `typename F::convention_types` where
+There shall be a convention type `Conv` defined in the convention types of `F` or of any super of `F`, reachable via `typename F::super_types` transitively, where
- `Conv::is_direct` is `false` (for `(1)`) or `true` (for `(2)`), 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`.
## Notes
diff --git a/docs/spec/proxy_view.md b/docs/spec/proxy_view.md
index 2f81c5d..15aa656 100644
--- a/docs/spec/proxy_view.md
+++ b/docs/spec/proxy_view.md
@@ -15,14 +15,15 @@ using proxy_view = proxy>;
`proxy_view` is a non-owning, trivially copyable, trivially relocatable view of an object that models [`proxiable_target`](proxiable_target.md). It behaves like a `proxy` except that it never owns the lifetime of the underlying object.
-`observer_facade` adapts an existing [facade](facade.md) `F` for this non-owning use. The adaptation preserves only those parts of `F` that remain semantically valid when the storage is reduced to a single pointer and modifies substitution conversions so that view-ness is preserved (substitution that would have produced an owning `proxy` instead produces a `proxy_view`).
+`observer_facade` adapts an existing [facade](facade.md) `F` for this non-owning use. The adaptation preserves only those parts of `F` that remain semantically valid when the storage is reduced to a single pointer. Each super of `F` is adapted in the same way, so that view-ness is preserved when converting to a `proxy` of a super: a `proxy_view` converts to a `proxy_view` for every super `G` of `F`.
## Member Types of `observer_facade`
-| Name | Description |
-| ------------------ | ------------------------------------------------------------ |
-| `convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type transformed from `typename F::convention_types`. Specifically, for each convention `C` in `typename F::convention_types`:
- If `C::is_direct` is `false`, include `C` unchanged.
- Otherwise, if `typename C::dispatch_type` is [`substitution_dispatch`](./substitution_dispatch/README.md), include a transformed convention `C'` whose
* `is_direct` is `true` and `dispatch_type` is still `substitution_dispatch`.
* For every overload `O` in `typename C::overload_types` with signature (after cv/ref/noexcept qualifiers) returning a `proxy`, replace its return type with `proxy_view` while preserving qualifiers and `noexcept`.
- Otherwise `C` is discarded. |
-| `reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type transformed from `typename F::reflection_types`. Specifically, for each reflection type `R` in `typename F::reflection_types`, `R` is included when `R::is_direct` is `false`, or otherwise discarded. |
+| Name | Description |
+| ---------------------------------- | ------------------------------------------------------------ |
+| `super_types`
*(since 5.0.0)* | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type transformed from `typename F::super_types`. Specifically, for each super `G` in `typename F::super_types`, `observer_facade` is included. |
+| `convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type transformed from `typename F::convention_types`. Specifically, for each convention `C` in `typename F::convention_types`:
- If `C::is_direct` is `false`, include `C` unchanged.
- Otherwise, if `typename C::dispatch_type` is [`substitution_dispatch`](./substitution_dispatch/README.md), include a transformed convention `C'` whose `is_direct` is `true`, `dispatch_type` is still `substitution_dispatch`, and whose `overload_type` is `typename C::overload_type` with a return type of `proxy` replaced by `proxy_view` and qualifiers replaced by `const noexcept`.
- Otherwise `C` is discarded. Duplicates are removed. |
+| `reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type transformed from `typename F::reflection_types`. Specifically, for each reflection type `R` in `typename F::reflection_types`, `R` is included when `R::is_direct` is `false`, or otherwise discarded. |
## Member Constants of `observer_facade`
diff --git a/docs/spec/weak_proxy.md b/docs/spec/weak_proxy.md
index 64456e7..0c71ce3 100644
--- a/docs/spec/weak_proxy.md
+++ b/docs/spec/weak_proxy.md
@@ -18,15 +18,16 @@ using weak_proxy = proxy>;
`weak_facade` adapts the original [facade](facade.md) `F` so that:
* A `lock()` member (direct convention) is provided, returning a `proxy` that contains a value if and only if the referenced object is still alive at the time of the call.
-* All direct substitution conversions that would have produced a `proxy` become conversions that produce a `weak_proxy` instead (so that "weak-ness" is preserved across facade-substitution).
+* Each super of `F` is adapted in the same way, so that "weak-ness" is preserved when converting to a `proxy` of a super: a `weak_proxy` converts to a `weak_proxy` for every super `G` of `F`.
* No reflections from `F` are preserved.
## Member Types of `weak_facade`
-| Name | Description |
-| ---- | ----------- |
-| `convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type transformed from `typename F::convention_types`. Specifically:
- It always prepends a direct convention whose dispatch type denotes the member function `lock` and whose single overload has signature `proxy() const noexcept`. Calling this overload attempts to obtain a strong `proxy`; it returns an empty `proxy` if the object has expired.
- For any direct convention `C` in `F` whose `dispatch_type` is `substitution_dispatch`, a transformed convention `C'` is included, whose
* `is_direct` is `true` and `dispatch_type` is still `substitution_dispatch`.
* For every overload `O` in `typename C::overload_types` with signature (after cv/ref/noexcept qualifiers) returning a `proxy`, replace its return type with `weak_proxy` while preserving qualifiers and `noexcept`.
- All other conventions from `F` are discarded. |
-| `reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains no types. |
+| Name | Description |
+| ---------------------------------- | ----------- |
+| `super_types`
*(since 5.0.0)* | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type transformed from `typename F::super_types`. Specifically, for each super `S` in `typename F::super_types`, `weak_facade` is included. |
+| `convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that always contains a direct convention whose dispatch type denotes the member function `lock` and whose overload has signature `proxy() const noexcept`. Calling this overload attempts to obtain a strong `proxy`; it returns an empty `proxy` if the object has expired. For each direct convention `C` in `typename F::convention_types` whose `dispatch_type` is [`substitution_dispatch`](./substitution_dispatch/README.md), a transformed convention `C'` is also included, whose `is_direct` is `true`, `dispatch_type` is still `substitution_dispatch`, and whose `overload_type` is `typename C::overload_type` with a return type of `proxy` replaced by `weak_proxy`, preserving qualifiers. All other conventions from `F` are discarded. |
+| `reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains no types. |
## Member Constants of `weak_facade`
diff --git a/include/proxy/v4/detail/core.h b/include/proxy/v4/detail/core.h
index 4262904..897cb63 100644
--- a/include/proxy/v4/detail/core.h
+++ b/include/proxy/v4/detail/core.h
@@ -39,9 +39,8 @@ namespace detail {
template
struct basic_facade_traits;
-
template
-struct proxy_meta;
+struct facade_traits;
} // namespace detail
@@ -95,6 +94,13 @@ struct specialization_type_traits, Args...>
template class T, class TL, class... Args>
using specialization_t = specialization_type_traits::type;
+template class TT>
+struct specialization_traits : inapplicable_traits {};
+template class TT, class... Args>
+struct specialization_traits, TT> : applicable_traits {};
+template class TT>
+concept specialization_of = specialization_traits::applicable;
+
template class R, class... Args>
struct reduction_t;
template
@@ -255,6 +261,14 @@ struct proxy_helper {
static const M& get_meta(const proxy_indirect_accessor& p) noexcept {
return get_meta(as_proxy(p));
}
+ template
+ static proxy make_relocated(void* src) noexcept {
+ proxy ret;
+ std::uninitialized_copy_n(static_cast(src), sizeof(P),
+ ret.ptr_);
+ ret.meta_ = decltype(ret.meta_){std::in_place_type};
+ return ret;
+ }
template
static void* get_ptr(proxy& p) noexcept {
return p.ptr_;
@@ -271,14 +285,6 @@ struct proxy_helper {
static const void* get_ptr(const proxy_indirect_accessor& p) noexcept {
return get_ptr(as_proxy(p));
}
- template
- static proxy make_relocated(void* src) noexcept {
- proxy ret;
- std::uninitialized_copy_n(static_cast(src), sizeof(P),
- ret.ptr_);
- ret.meta_ = decltype(ret.meta_){std::in_place_type};
- return ret;
- }
};
template
@@ -482,13 +488,6 @@ using substituted_overload_t =
template
concept extended_overload = overload_traits::applicable ||
overload_substitution_traits::applicable;
-template
-consteval void diagnose_proxiable_required_convention_not_implemented() {
- static_assert(overload_traits::applicable &&
- overload_traits::template applicable_ptr,
- "not proxiable due to a required convention not implemented");
-}
-
template
consteval bool is_is_direct_well_formed() {
if constexpr (requires {
@@ -523,6 +522,11 @@ concept basic_reflection = requires {
typename R::reflector_type;
} && is_is_direct_well_formed() && basic_meta;
+template
+concept pointer_like = (std::is_pointer_v ||
+ requires { typename T::element_type; } || requires(T val) { *val; }) &&
+ requires { typename std::pointer_traits::element_type; };
+
template
struct a11y_traits_impl
: std::conditional &&
@@ -538,41 +542,6 @@ struct a11y_traits>, T,
template
using accessor_t = a11y_traits::type;
-template
-struct conv_group;
-template
-struct conv_accessor_traits;
-template
-struct conv_accessor_traits, P, F>
- : std::type_identity...>> {};
-
-template
-struct conv_group_match_traits : inapplicable_traits {};
-template
-struct conv_group_match_traits, D> : applicable_traits {};
-
-template
-struct conv_group_merge_traits : std::type_identity {};
-template
-struct conv_group_merge_traits, conv_group>
- : specialization_type_traits<
- conv_group, merge_tuples_t, std::tuple>,
- D> {};
-
-template
-struct conv_groups_reduction;
-template
- requires(conv_group_match_traits::applicable || ...)
-struct conv_groups_reduction, conv_group>
- : std::type_identity>::type...>> {};
-template
-struct conv_groups_reduction, I>
- : std::type_identity> {};
-template
-using conv_groups_merge_t =
- flattening_merge_t, Gss...>;
-
template
struct reflection_meta {
reflection_meta() = default;
@@ -603,12 +572,6 @@ consteval bool is_reflector_well_formed() {
}
return false;
}
-template
-consteval void diagnose_proxiable_required_reflection_not_implemented() {
- static_assert(is_reflector_well_formed(),
- "not proxiable due to a required reflection not implemented");
-}
-
struct copy_dispatch {
template
PRO4D_STATIC_CALL(void, const T& self, void* rhs) noexcept(
@@ -636,27 +599,49 @@ using lifetime_meta_t = lifetime_meta_traits::type;
template
struct PRO4D_ENFORCE_EBO composite_accessor : As... {};
+template
+using refl_accessors_t =
+ composite_t,
+ accessor_t...>;
+
+template
+struct conv_group;
+template
+struct conv_accessor_traits;
+template
+struct conv_accessor_traits, P, F>
+ : std::type_identity...>> {};
template
using conv_accessors_t =
composite_t,
typename conv_accessor_traits::type...>;
-template
-using refl_accessors_t =
- composite_t,
- accessor_t...>;
+template
+struct conv_group_match_traits : inapplicable_traits {};
+template
+struct conv_group_match_traits, D> : applicable_traits {};
-template
-concept pointer_like = (std::is_pointer_v ||
- requires { typename T::element_type; } || requires(T val) { *val; }) &&
- requires { typename std::pointer_traits::element_type; };
+template
+struct conv_group_merge_traits : std::type_identity {};
+template
+struct conv_group_merge_traits, conv_group>
+ : specialization_type_traits<
+ conv_group, merge_tuples_t, std::tuple>,
+ D> {};
-template class TT>
-struct specialization_traits : inapplicable_traits {};
-template class TT, class... Args>
-struct specialization_traits, TT> : applicable_traits {};
-template class TT>
-concept specialization_of = specialization_traits::applicable;
+template
+struct conv_groups_reduction;
+template
+ requires(conv_group_match_traits::applicable || ...)
+struct conv_groups_reduction, conv_group>
+ : std::type_identity>::type...>> {};
+template
+struct conv_groups_reduction, I>
+ : std::type_identity> {};
+template
+using conv_groups_merge_t =
+ flattening_merge_t