Skip to content

Commit

Permalink
Merge branch 'main' into user/mingxwa/fix-typo
Browse files Browse the repository at this point in the history
  • Loading branch information
mingxwa authored Dec 16, 2024
2 parents fb29624 + a6835a2 commit e926b14
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 143 deletions.
4 changes: 2 additions & 2 deletions docs/PRO_DEF_FREE_AS_MEM_DISPATCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ PRO_DEF_FREE_AS_MEM_DISPATCH(dispatch_name, func_name, accessibility_func_name);

`(1)` Equivalent to `PRO_DEF_FREE_AS_MEM_DISPATCH(dispatch_name, func_name, func_name);`

`(2)` Defines a class named `dispatch_name` of free function call expressions of `func_name` with accessibility via a member function. `dispatch_name` meets the [*ProAccessible*](ProAccessible.md) requirements of types `F`, `C`, and `Os...`, where `F` models concept [`facade`](facade.md), `C` is a tuple element type defined in `typename F::convention_types`, and each type `O` (possibly qualified with *cv ref noex*) in `Os...` is a tuple element type defined in `typename C::overload_types`. The member functions provided by `typename dispatch_name::template accessor<F, C, Os...>` are named `accessibility_func_name`. Let `SELF` be `std::forward<accessor cv ref>(*this)`, effectively equivalent to:
`(2)` Defines a class named `dispatch_name` of free function call expressions of `func_name` with accessibility via a member function. `dispatch_name` meets the [*ProAccessible*](ProAccessible.md) requirements of types `F`, `C`, and `Os...`, where `F` models concept [`facade`](facade.md), `C` is a tuple element type defined in `typename F::convention_types`, and each type `O` (possibly qualified with *cv ref noex*) in `Os...` is a tuple element type defined in `typename C::overload_types`. The member functions provided by `typename dispatch_name::template accessor<F, C, Os...>` are named `accessibility_func_name`. Effectively equivalent to:

```cpp
struct dispatch_name {
Expand All @@ -39,7 +39,7 @@ struct dispatch_name {
template <class F, class C, class R, class... Args>
struct accessor<F, C, R(Args...) cv ref noex> {
R accessibility_func_name(Args... args) cv ref noex {
return pro::proxy_invoke<C, R(Args...) cv ref noex>(pro::access_proxy<F>(SELF), std::forward<Args>(args)...);
return pro::proxy_invoke<C, R(Args...) cv ref noex>(pro::access_proxy<F>(std::forward<accessor cv ref>(*this)), std::forward<Args>(args)...);
}
};
}
Expand Down
6 changes: 3 additions & 3 deletions docs/PRO_DEF_FREE_DISPATCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ PRO_DEF_FREE_DISPATCH(dispatch_name, func_name, accessibility_func_name);

`(1)` Equivalent to `PRO_DEF_FREE_DISPATCH(dispatch_name, func_name, func_name);`

`(2)` Defines a class named `dispatch_name` of free function call expressions of `func_name` with accessibility. `dispatch_name` meets the [*ProAccessible*](ProAccessible.md) requirements of types `F`, `C`, and `Os...`, where `F` models concept [`facade`](facade.md), `C` is a tuple element type defined in `typename F::convention_types`, and each type `O` (possibly qualified with *cv ref noex*) in `Os...` is a tuple element type defined in `typename C::overload_types`. The functions provided by `typename dispatch_name::template accessor<F, C, Os...>` are named `accessibility_func_name` and can be found by [argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl) when `accessor` is an associated class of the arguments. Let `SELF` be `std::forward<accessor cv ref>(self)`, effectively equivalent to:
`(2)` Defines a class named `dispatch_name` of free function call expressions of `func_name` with accessibility. `dispatch_name` meets the [*ProAccessible*](ProAccessible.md) requirements of types `F`, `C`, and `Os...`, where `F` models concept [`facade`](facade.md), `C` is a tuple element type defined in `typename F::convention_types`, and each type `O` (possibly qualified with *cv ref noex*) in `Os...` is a tuple element type defined in `typename C::overload_types`. Let `accessor_arg` be `std::conditional_t<C::is_direct, proxy<F>, proxy_indirect_accessor<F>>`. The functions provided by `typename dispatch_name::template accessor<F, C, Os...>` are named `accessibility_func_name` and can be found by [argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl) when `accessor_arg` is an associated class of the arguments. Effectively equivalent to:

```cpp
struct dispatch_name {
Expand All @@ -35,8 +35,8 @@ struct dispatch_name {
struct accessor<F, C, Os...> : accessor<F, C, Os>... {};
template <class F, class C, class R, class... Args>
struct accessor<F, C, R(Args...) cv ref noex> {
friend R accessibility_func_name(accessor cv ref self, Args... args) noex {
return pro::proxy_invoke<C, R(Args...) cv ref noex>(pro::access_proxy<F>(SELF), std::forward<Args>(args)...);
friend R accessibility_func_name(accessor_arg cv ref self, Args... args) noex {
return pro::proxy_invoke<C, R(Args...) cv ref noex>(pro::access_proxy<F>(std::forward<accessor_arg cv ref>(self)), std::forward<Args>(args)...);
}
};
}
Expand Down
4 changes: 2 additions & 2 deletions docs/PRO_DEF_MEM_DISPATCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ PRO_DEF_MEM_DISPATCH(dispatch_name, func_name, accessibility_func_name);

`(1)` Equivalent to `PRO_DEF_MEM_DISPATCH(dispatch_name, func_name, func_name);`

`(2)` Defines a class named `dispatch_name` of member function call expressions of `func_name` with accessibility. `dispatch_name` meets the [*ProAccessible*](ProAccessible.md) requirements of types `F`, `C`, and `Os...`, where `F` models concept [`facade`](facade.md), `C` is a tuple element type defined in `typename F::convention_types`, and each type `O` (possibly qualified with *cv, ref, noex*) in `Os...` is a tuple element type defined in `typename C::overload_types`. The member functions provided by `typename dispatch_name::template accessor<F, C, Os...>` are named `accessibility_func_name`. Let `SELF` be `std::forward<accessor cv ref>(*this)`, effectively equivalent to:
`(2)` Defines a class named `dispatch_name` of member function call expressions of `func_name` with accessibility. `dispatch_name` meets the [*ProAccessible*](ProAccessible.md) requirements of types `F`, `C`, and `Os...`, where `F` models concept [`facade`](facade.md), `C` is a tuple element type defined in `typename F::convention_types`, and each type `O` (possibly qualified with *cv, ref, noex*) in `Os...` is a tuple element type defined in `typename C::overload_types`. The member functions provided by `typename dispatch_name::template accessor<F, C, Os...>` are named `accessibility_func_name`. Effectively equivalent to:

```cpp
struct dispatch_name {
Expand All @@ -39,7 +39,7 @@ struct dispatch_name {
template <class F, class C, class R, class... Args>
struct accessor<F, C, R(Args...) cv ref noex> {
R accessibility_func_name(Args... args) cv ref noex {
return pro::proxy_invoke<C, R(Args...) cv ref noex>(pro::access_proxy<F>(SELF), std::forward<Args>(args)...);
return pro::proxy_invoke<C, R(Args...) cv ref noex>(pro::access_proxy<F>(std::forward<accessor cv ref>(*this)), std::forward<Args>(args)...);
}
};
}
Expand Down
4 changes: 1 addition & 3 deletions docs/explicit_conversion_dispatch/accessor.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ struct accessor<F, C, T() cv ref noex> {
};
```
Let `SELF` be `std::forward<accessor cv ref>(*this)`.
`(1)` The default implementation of `accessor` is not constructible.
`(2)` When `sizeof...(Os)` is greater than `1`, and `accessor<F, C, Os>...` are default-constructible, inherits all `accessor<F, C, Os>...` types and `using` their `operator return-type-of<Os>`. `return-type-of<O>` denotes the *return type* of the overload type `O`.
`(3)` When `sizeof...(Os)` is `1` and the only type `O` in `Os` is `T() cv ref noex`, provides an explicit `operator T()` with the same *cv ref noex* specifiers. `accessor::operator T()` is equivalent to `return proxy_invoke<C, T() cv ref noex>(access_proxy<F>(SELF))`.
`(3)` When `sizeof...(Os)` is `1` and the only type `O` in `Os` is `T() cv ref noex`, provides an explicit `operator T()` with the same *cv ref noex* specifiers. `accessor::operator T()` is equivalent to `return proxy_invoke<C, T() cv ref noex>(access_proxy<F>(std::forward<accessor cv ref>(*this)))`.
4 changes: 1 addition & 3 deletions docs/implicit_conversion_dispatch/accessor.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ struct accessor<F, C, T() cv ref noex> {
};
```
Let `SELF` be `std::forward<accessor cv ref>(*this)`.
`(1)` The default implementation of `accessor` is not constructible.
`(2)` When `sizeof...(Os)` is greater than `1`, and `accessor<F, C, Os>...` are default-constructible, inherits all `accessor<F, C, Os>...` types and `using` their `operator return-type-of<Os>`. `return-type-of<O>` denotes the *return type* of the overload type `O`.
`(3)` When `sizeof...(Os)` is `1` and the only type `O` in `Os` is `T() cv ref noex`, provides an implicit `operator T()` with the same *cv ref noex* specifiers. `accessor::operator T()` is equivalent to `return proxy_invoke<C, T() cv ref noex>(access_proxy<F>(SELF))`.
`(3)` When `sizeof...(Os)` is `1` and the only type `O` in `Os` is `T() cv ref noex`, provides an implicit `operator T()` with the same *cv ref noex* specifiers. `accessor::operator T()` is equivalent to `return proxy_invoke<C, T() cv ref noex>(access_proxy<F>(std::forward<accessor cv ref>(*this)))`.
18 changes: 9 additions & 9 deletions docs/operator_dispatch/accessor.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct accessor<F, C, Os...> : accessor<F, C, Os>... {

`(2)` When `sizeof...(Os)` is greater than `1`, and `accessor<F, C, Os>...` are default-constructible types, inherits all `accessor<F, C, Os>...` types and `using` their `operator sop`.

When `Rhs` is `false`, the other specializations are defined as follows, where `sizeof...(Os)` is `1` and the only type `O` qualified with `cv ref noex` (let `SELF` be `std::forward<accessor cv ref>(*this)`):
When `Rhs` is `false`, the other specializations are defined as follows, where `sizeof...(Os)` is `1` and the only type `O` qualified with `cv ref noex` (let `ACCESS_PROXY_EXPR` be `access_proxy<F>(std::forward<accessor cv ref>(*this))`):

### Regular SOPs

Expand All @@ -39,7 +39,7 @@ struct accessor<F, C, R(Args...) cv ref noex> {
}
```
`(3)` Provides an `operator sop(Args...)` with the same *cv ref noex* specifiers as of the overload type. `accessor::operator sop(Args...)` is equivalent to `return proxy_invoke<C, R(Args...) cv ref noex>(access_proxy<F>(SELF), std::forward<Args>(args)...)`.
`(3)` Provides an `operator sop(Args...)` with the same *cv ref noex* specifiers as of the overload type. `accessor::operator sop(Args...)` is equivalent to `return proxy_invoke<C, R(Args...) cv ref noex>(ACCESS_PROXY_EXPR, std::forward<Args>(args)...)`.
### `!` and `~`
Expand All @@ -53,7 +53,7 @@ struct accessor<F, C, R() cv ref noex> {
}
```

`(4)` Provides an `operator sop()` with the same *cv ref noex* specifiers as of the overload type. `accessor::operator sop()` is equivalent to `return proxy_invoke<C, R() cv ref noex>(access_proxy<F>(SELF))`.
`(4)` Provides an `operator sop()` with the same *cv ref noex* specifiers as of the overload type. `accessor::operator sop()` is equivalent to `return proxy_invoke<C, R() cv ref noex>(ACCESS_PROXY_EXPR)`.

### Assignment SOPs

Expand All @@ -67,7 +67,7 @@ struct accessor<F, C, R(Arg) cv ref noex> {
}
```
`(4)` Provides an `operator sop(Arg)` with the same *cv ref noex* specifiers as of the overload type. `accessor::operator sop(Arg)` calls `proxy_invoke<C, R(Arg) cv ref noex>(access_proxy<F>(SELF), std::forward<Arg>(arg))` and returns `access_proxy<F>(SELF)` when `C::is_direct` is `true`, or otherwise, returns `*access_proxy<F>(SELF)` when `C::is_direct` is `false`.
`(4)` Provides an `operator sop(Arg)` with the same *cv ref noex* specifiers as of the overload type. `accessor::operator sop(Arg)` calls `proxy_invoke<C, R(Arg) cv ref noex>(ACCESS_PROXY_EXPR, std::forward<Arg>(arg))` and returns `ACCESS_PROXY_EXPR` when `C::is_direct` is `true`, or otherwise, returns `*ACCESS_PROXY_EXPR` when `C::is_direct` is `false`.
## Right-Hand-Side Operand Specializations
Expand All @@ -80,7 +80,7 @@ struct accessor<F, C, Os...> : accessor<F, C, Os>... {};

`(6)` When `sizeof...(Os)` is greater than `1`, and `accessor<F, C, Os>...` are default-constructible types, inherits all `accessor<F, C, Os>...` types.

When `Rhs` is `true`, the other specializations are defined as follows, where `sizeof...(Os)` is `1` and the only type `O` qualified with `cv ref noex` (let `SELF` be `std::forward<accessor cv ref>(self)`):
When `Rhs` is `true`, the other specializations are defined as follows, where `sizeof...(Os)` is `1` and the only type `O` qualified with `cv ref noex` (let `accessor_arg` be `std::conditional_t<C::is_direct, proxy<F>, proxy_indirect_accessor<F>>`, `ACCESS_PROXY_EXPR` be `access_proxy<F>(std::forward<accessor_arg cv ref>(self))`):

### Regular SOPs

Expand All @@ -90,11 +90,11 @@ When `Sign` is one of `"+"`, `"-"`, `"*"`, `"/"`, `"%"`, `"=="`, `"!="`, `">"`,
// (7)
template <class F, class C, class R, class Arg>
struct accessor<F, C, R(Arg) cv ref noex> {
friend R operator sop (Arg arg, accessor cv ref self) noex;
friend R operator sop (Arg arg, accessor_arg cv ref self) noex;
}
```
`(7)` Provides a `friend operator sop(Arg arg, accessor cv ref)` with the same *noex* specifiers as of the overload type. `accessor::operator sop(Arg arg, accessor cv ref)` is equivalent to `return proxy_invoke<C, R(Arg) cv ref noex>(access_proxy<F>(SELF), std::forward<Arg>(arg))`.
`(7)` Provides a `friend operator sop(Arg arg, accessor_arg cv ref self)` with the same *noex* specifiers as of the overload type. `accessor::operator sop(Arg arg, accessor_arg cv ref self)` is equivalent to `return proxy_invoke<C, R(Arg) cv ref noex>(ACCESS_PROXY_EXPR, std::forward<Arg>(arg))`.
### Assignment SOPs
Expand All @@ -104,8 +104,8 @@ When `Sign` is one of `"+="`, `"-="`, `"*="`, `"/="`, `"&="`, `"|="`, `"^="`, `"
// (8)
template <class F, class C, class R, class Arg>
struct accessor<F, C, R(Arg) cv ref noex> {
friend /* see below */ operator sop (Arg arg, accessor cv ref self) noex;
friend /* see below */ operator sop (Arg arg, accessor_arg cv ref self) noex;
}
```

`(8)` Provides a `friend operator sop(Arg arg, accessor cv ref)` with the same *noex* specifiers as of the overload type. `accessor::operator sop(Arg arg, accessor cv ref)` calls `proxy_invoke<C, R(Arg) cv ref noex>(access_proxy<F>(SELF), std::forward<Arg>(arg))` and returns `access_proxy<F>(SELF)` when `C::is_direct` is `true`, or otherwise, returns `*access_proxy<F>(SELF)` when `C::is_direct` is `false`.
`(8)` Provides a `friend operator sop(Arg arg, accessor_arg cv ref self)` with the same *noex* specifiers as of the overload type. `accessor::operator sop(Arg arg, accessor_arg cv ref self)` calls `proxy_invoke<C, R(Arg) cv ref noex>(ACCESS_PROXY_EXPR, std::forward<Arg>(arg))` and returns `ACCESS_PROXY_EXPR` when `C::is_direct` is `true`, or otherwise, returns `*ACCESS_PROXY_EXPR` when `C::is_direct` is `false`.
2 changes: 1 addition & 1 deletion docs/proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class proxy;

Class template `proxy` is a general-purpose polymorphic wrapper for C++ objects. Unlike other polymorphic wrappers in the C++ standard (e.g., [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function), [`std::move_only_function`](https://en.cppreference.com/w/cpp/utility/functional/move_only_function), [`std::any`](https://en.cppreference.com/w/cpp/utility/any), etc.), `proxy` is based on pointer semantics. It supports flexible lifetime management without runtime [garbage collection (GC)](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) at runtime, and offers best-in-class code generation quality, extendibility and accessibility.

To instantiate `proxy<F>`, `F` shall model [concept `facade`](facade.md). As per `facade<F>`, `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 `T` in `Cs` or `Rs`, if `T` meets the [*ProAccessible* requirements](ProAccessible.md) of `F`, `typename T::template accessor<F>` is inherited by `proxy<F>` when `T::is_direct` is `true`. Otherwise, it is inherited by the return type of [`operator*`](proxy/indirection.md) when `T::is_direct` is `false`. Implementation of accessors can call [`access_proxy`](access_proxy.md) to access the `proxy` object. It is recommended to use [`facade_builder`](basic_facade_builder.md) to define a facade type.
To instantiate `proxy<F>`, `F` shall model [concept `facade`](facade.md). As per `facade<F>`, `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 `T` in `Cs` or `Rs`, if `T` meets the [*ProAccessible* requirements](ProAccessible.md) of `F`, `typename T::template accessor<F>` is inherited by `proxy<F>` when `T::is_direct` is `true`. Otherwise, it is inherited by [`proxy_indirect_accessor`](proxy_indirect_accessor.md), the return type of [`operator*`](proxy/indirection.md), when `T::is_direct` is `false`. Implementation of accessors can call [`access_proxy`](access_proxy.md) to access the `proxy` object. It is recommended to use [`facade_builder`](basic_facade_builder.md) to define a facade type.

Any instance of `proxy<F>` at any given point in time either *contains a value* or *does not contain a value*. If a `proxy<F>` *contains a value*, the type of the value shall be a pointer type `P` where [`proxiable<P, F>`](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.

Expand Down
20 changes: 10 additions & 10 deletions docs/proxy/indirection.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
# `proxy::operator->`, `proxy::operator*`

The definitions of `proxy::operator->` and `proxy::operator*` make use of the following exposition-only constant and type alias:
The definitions of `proxy::operator->` and `proxy::operator*` make use of the following exposition-only constant:

```cpp
static constexpr bool has-indirection = see below; // exposition only
using indirect-accessor = see below; // exposition only
```

As per [`facade<F>`](../facade.md), `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`. Let `Cs2` be the types in `Cs` where each type `C` meets the [*ProAccessible* requirements](../ProAccessible.md) of `F` and `C::is_direct` is `false`. *has-indirection* is `true` if `Cs2` contains at least one type; otherwise, it is `false`. *indirect-accessor* is a non-copyable type that inherits from every type in `Cs2`.

```cpp
// (1)
indirect-accessor* operator->() noexcept requires(has-indirection);
const indirect-accessor* operator->() const noexcept requires(has-indirection);
proxy_indirect_accessor<F>* operator->() noexcept requires(has-indirection);
const proxy_indirect_accessor<F>* operator->() const noexcept requires(has-indirection);

// (2)
indirect-accessor& operator*() & noexcept requires(has-indirection);
const indirect-accessor& operator*() const& noexcept requires(has-indirection);
indirect-accessor&& operator*() && noexcept requires(has-indirection);
const indirect-accessor&& operator*() const&& noexcept requires(has-indirection);
proxy_indirect_accessor<F>& operator*() & noexcept requires(has-indirection);
const proxy_indirect_accessor<F>& operator*() const& noexcept requires(has-indirection);
proxy_indirect_accessor<F>&& operator*() && noexcept requires(has-indirection);
const proxy_indirect_accessor<F>&& operator*() const&& noexcept requires(has-indirection);
```
These operators access the accessors of the indirect conventions, as if dereferencing the contained value.
- `(1)` Returns a pointer to the *indirect-accessor*.
- `(2)` Returns a reference to the *indirect-accessor*.
- `(1)` Returns a pointer to the `proxy_indirect_accessor<F>`.
- `(2)` Returns a reference to the `proxy_indirect_accessor<F>`.
The behavior is undefined if `*this` does not contain a value.
Expand Down Expand Up @@ -68,3 +67,4 @@ int main() {

- [function template `access_proxy`](../access_proxy.md)
- [function template `proxy_invoke`](../proxy_invoke.md)
- [class template `proxy_indirect_accessor`](../proxy_indirect_accessor.md)
Loading

0 comments on commit e926b14

Please sign in to comment.