Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

Commit e76e4ac

Browse files
authored
Documentation for 3.0.0 (#160)
* Documentation for Proxy 3 * Remove en-us directory * Update doc for basic_facade_builder::add_facade * readme
1 parent 1902fa2 commit e76e4ac

52 files changed

Lines changed: 2762 additions & 132 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 130 additions & 132 deletions
Large diffs are not rendered by default.

docs/PRO_DEF_FREE_DISPATCH.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Macro `PRO_DEF_FREE_DISPATCH`
2+
3+
```cpp
4+
#define PRO_DEF_FREE_DISPATCH // see below
5+
```
6+
7+
Macro `PRO_DEF_FREE_DISPATCH` defines dispatch types for free function expressions with accessibility. It supports two syntaxes:
8+
9+
```cpp
10+
// (1)
11+
PRO_DEF_FREE_DISPATCH(dispatch_name, func_name);
12+
13+
// (2)
14+
PRO_DEF_FREE_DISPATCH(dispatch_name, func_name, accessibility_func_name);
15+
```
16+
17+
`(1)` Equivalent to `PRO_DEF_FREE_DISPATCH(dispatch_name, func_name, func_name);`
18+
19+
`(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:
20+
21+
```cpp
22+
struct dispatch_name {
23+
template <class T, class... Args>
24+
decltype(auto) operator()(T&& self, Args&&... args)
25+
noexcept(noexcept(func_name(std::forward<T>(self), std::forward<Args>(args)...)))
26+
requires(requires { func_name(std::forward<T>(self), std::forward<Args>(args)...); }) {
27+
return func_name(std::forward<T>(self), std::forward<Args>(args)...);
28+
}
29+
30+
template <class F, class C, class... Os> struct accessor {
31+
accessor() = delete;
32+
};
33+
template <class F, class C, class... Os>
34+
requires(sizeof...(Os) > 1u && (std::is_trivial_v<accessor<F, C, Os>> && ...))
35+
struct accessor<F, C, Os...> : accessor<F, C, Os>... {};
36+
template <class F, class C, class R, class... Args>
37+
struct accessor<F, C, R(Args...) cv ref noex> {
38+
friend R accessibility_func_name(accessor cv ref self, Args... args) noex {
39+
return pro::proxy_invoke<C>(pro::access_proxy<F>(SELF), std::forward<Args>(args)...);
40+
}
41+
};
42+
};
43+
```
44+
45+
## Example
46+
47+
```cpp
48+
#include <iostream>
49+
#include <string>
50+
51+
#include "proxy.h"
52+
53+
PRO_DEF_FREE_DISPATCH(FreeToString, std::to_string, ToString);
54+
55+
struct Stringable : pro::facade_builder
56+
::add_convention<FreeToString, std::string()>
57+
::build {};
58+
59+
int main() {
60+
pro::proxy<Stringable> p = pro::make_proxy<Stringable>(123);
61+
std::cout << ToString(*p) << "\n"; // Prints: "123"
62+
}
63+
```
64+
65+
## See Also
66+
67+
- [macro `PRO_DEF_MEM_DISPATCH`](PRO_DEF_MEM_DISPATCH.md)
68+
- [alias template `basic_facade_builder::add_convention`](basic_facade_builder/add_convention.md)

docs/PRO_DEF_MEM_DISPATCH.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Macro `PRO_DEF_MEM_DISPATCH`
2+
3+
```cpp
4+
#define PRO_DEF_MEM_DISPATCH // see below
5+
```
6+
7+
Macro `PRO_DEF_MEM_DISPATCH` defines dispatch types for member function expressions with accessibility. It supports two syntaxes:
8+
9+
```cpp
10+
// (1)
11+
PRO_DEF_MEM_DISPATCH(dispatch_name, func_name);
12+
13+
// (2)
14+
PRO_DEF_MEM_DISPATCH(dispatch_name, func_name, accessibility_func_name);
15+
```
16+
17+
`(1)` Equivalent to `PRO_DEF_MEM_DISPATCH(dispatch_name, func_name, func_name);`
18+
19+
`(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:
20+
21+
```cpp
22+
struct dispatch_name {
23+
template <class T, class... Args>
24+
decltype(auto) operator()(T&& self, Args&&... args)
25+
noexcept(noexcept(std::forward<T>(self).func_name(std::forward<Args>(args)...)))
26+
requires(requires { std::forward<T>(self).func_name(std::forward<Args>(args)...); }) {
27+
return std::forward<T>(self).func_name(std::forward<Args>(args)...);
28+
}
29+
30+
template <class F, class C, class... Os>
31+
struct accessor {
32+
accessor() = delete;
33+
};
34+
template <class F, class C, class... Os>
35+
requires(sizeof...(Os) > 1u && (std::is_trivial_v<accessor<F, C, Os>> && ...))
36+
struct accessor<F, C, Os...> : accessor<F, C, Os>... {
37+
using accessor<F, C, Os>::accessibility_func_name ...;
38+
};
39+
template <class F, class C, class R, class... Args>
40+
struct accessor<F, C, R(Args...) cv ref noex> {
41+
R accessibility_func_name(Args... args) cv ref noex {
42+
return pro::proxy_invoke<C>(pro::access_proxy<F>(SELF), std::forward<Args>(args)...);
43+
}
44+
};
45+
};
46+
```
47+
48+
## Example
49+
50+
```cpp
51+
#include <iostream>
52+
#include <string>
53+
#include <vector>
54+
55+
#include "proxy.h"
56+
57+
PRO_DEF_MEM_DISPATCH(MemAt, at);
58+
59+
struct Dictionary : pro::facade_builder
60+
::add_convention<MemAt, std::string(int index) const>
61+
::build {};
62+
63+
int main() {
64+
std::vector<const char*> v{"hello", "world"};
65+
pro::proxy<Dictionary> p = &v;
66+
std::cout << p->at(1) << "\n"; // Prints: "world"
67+
}
68+
```
69+
70+
## See Also
71+
72+
- [macro `PRO_DEF_FREE_DISPATCH`](PRO_DEF_FREE_DISPATCH.md)
73+
- [alias template `basic_facade_builder::add_convention`](basic_facade_builder/add_convention.md)

docs/PRO_DEF_WEAK_DISPATCH.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Macro `PRO_DEF_WEAK_DISPATCH`
2+
3+
```cpp
4+
#define PRO_DEF_WEAK_DISPATCH // see below
5+
```
6+
7+
Macro `PRO_DEF_WEAK_DISPATCH` defines a "weak" dispatch type with a default implementation. It supports the following syntax:
8+
9+
```cpp
10+
PRO_DEF_WEAK_DISPATCH(dispatch_name, existing_dispatch, default_func_name);
11+
```
12+
13+
Defines a class named `dispatch_name` that inherits `existing_dispatch` and provides additional overloads of `operator()` calling `default_func_name`. Effectively equivalent to:
14+
15+
```cpp
16+
struct dispatch_name : existing_dispatch {
17+
using existing_dispatch::operator();
18+
template <class... Args>
19+
decltype(auto) operator()(std::nullptr_t, Args&&... args)
20+
noexcept(noexcept(default_func_name(std::forward<Args>(args)...)))
21+
requires(requires { default_func_name(std::forward<Args>(args)...); }) {
22+
return default_func_name(std::forward<Args>(args)...);
23+
}
24+
};
25+
```
26+
27+
## Notes
28+
29+
A weak dispatch can extend an existing dispatch with a default implementation. This is useful when instantiating a `proxy<F>` with a value that does not support some conventions defined by `F`. Similar with [`PRO_DEF_FREE_DISPATCH`](PRO_DEF_FREE_DISPATCH.md), `default_func_name` can be the name of an arbitrary function or anything that supports `()` syntax, including a constructor.
30+
31+
## Example
32+
33+
```cpp
34+
#include <iostream>
35+
#include <string>
36+
#include <vector>
37+
38+
#include "proxy.h"
39+
40+
struct NotImplemented {
41+
explicit NotImplemented(auto&&...) { throw std::runtime_error{ "Not implemented!" }; }
42+
43+
template <class T>
44+
operator T() const noexcept { std::terminate(); } // Or std::unreachable() in C++23
45+
};
46+
47+
PRO_DEF_MEM_DISPATCH(MemAt, at);
48+
PRO_DEF_WEAK_DISPATCH(WeakMemAt, MemAt, NotImplemented);
49+
50+
struct WeakDictionary : pro::facade_builder
51+
::add_convention<WeakMemAt, std::string(int index) const>
52+
::build {};
53+
54+
int main() {
55+
std::vector<const char*> v{"hello", "world"};
56+
pro::proxy<WeakDictionary> p1 = &v;
57+
std::cout << p1->at(1) << "\n"; // Prints: "world"
58+
pro::proxy<WeakDictionary> p2 = pro::make_proxy<WeakDictionary>(123);
59+
try {
60+
p2->at(1);
61+
} catch (const std::runtime_error& e) {
62+
std::cout << e.what() << "\n"; // Prints: "Not implemented!"
63+
}
64+
}
65+
```
66+
67+
## See Also
68+
69+
- [named requirements *ProDispatch*](ProDispatch.md)

docs/ProAccessible.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Named requirements: *ProAccessible*
2+
3+
Given that `F` is a type meeting the [*ProBasicFacade* requirements](ProBasicFacade.md), a type `T` meets the *ProAccessible* requirements of types `F, Args...`, if the following expressions are well-formed and have the specified semantics.
4+
5+
| Expressions | Semantics |
6+
| ------------------------------------------- | ------------------------------------------------------------ |
7+
| `typename T::template accessor<F, Args...>` | A type that provides accessibility to `proxy`. It shall be a trivial class type and not [final](https://en.cppreference.com/w/cpp/language/final). |
8+
9+
## See Also
10+
11+
- [class template `proxy`](proxy.md)

docs/ProBasicConvention.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Named requirements: *ProBasicConvention*
2+
3+
A type `C` meets the *ProBasicConvention* requirements if the following expressions are well-formed and have the specified semantics.
4+
5+
| Expressions | Semantics |
6+
| ---------------------------- | ------------------------------------------------------------ |
7+
| `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`). |
8+
| `typename C::dispatch_type` | A [trivial type](https://en.cppreference.com/w/cpp/named_req/TrivialType) that defines how the calls are forwarded to the concrete types. |
9+
| `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). |
10+
11+
## See Also
12+
13+
- [*ProBasicFacade* requirements](ProBasicFacade.md)
14+
- [*ProConvention* requirements](ProConvention.md)

docs/ProBasicFacade.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Named requirements: *ProBasicFacade*
2+
3+
A type `F` meets the *ProBasicFacade* requirements if the following expressions are well-formed and have the specified semantics.
4+
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 define reflection on pointer types. |
9+
| `F::constraints` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`proxiable_ptr_constraints`](proxiable_ptr_constraints.md) that defines constraints to pointer types. |
10+
11+
## See Also
12+
13+
- [concept `facade`](facade.md)

docs/ProConvention.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Named requirements: *ProConvention*
2+
3+
A type `C` meets the *ProConvention* requirements of a type `P` if `C` meets the [*ProBasicConvention* requirements](ProBasicConvention.md), and the following expressions are well-formed and have the specified semantics.
4+
5+
| Expressions | Semantics |
6+
| ---------------------------- | ------------------------------------------------------------ |
7+
| `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<br />- when `C::is_direct` is `true`, `typename C::dispatch_type` shall meet the [*ProDispatch* requirements](ProDispatch.md) of `P` and `O`, <br />- 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>(qp)` shall be well-formed, and `typename C::dispatch_type` shall meet the [*ProDispatch* requirements](ProDispatch.md) of `decltype(*std::forward<QP>(qp))` and `O`. |
8+
9+
## See Also
10+
11+
- [*ProFacade* requirements](ProFacade.md)

docs/ProDispatch.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Named requirements: *ProDispatch*
2+
3+
A type `D` meets the *ProDispatch* requirements of types `T` and `O` if `D` is a [trivial type](https://en.cppreference.com/w/cpp/named_req/TrivialType), `O` meets the [*ProOverload* requirelemts](ProOverload.md), and the following expressions are well-formed and have the specified semantics (let `R` be return type of `O`, `Args...` be the argument types of `O`. `args...` denotes values of type `Args...`, `v` denotes a value of type `T`, `cv` denotes a value of type `const T`).
4+
5+
| Definitions of `O` | Expressions | Semantics |
6+
| ----------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
7+
| `R(Args...)` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, v, std::forward<Args>(args)...)` | Invokes dispatch type `D` with an lvalue reference of type `T` and `args...`, may throw. |
8+
| `R(Args...) noexcept` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, v, std::forward<Args>(args)...)` | Invokes dispatch type `D` with an lvalue reference of type `T` and `args...`, shall not throw. |
9+
| `R(Args...) &` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, v, std::forward<Args>(args)...)` | Invokes dispatch type `D` with an lvalue reference of type `T` and `args...`, may throw. |
10+
| `R(Args...) & noexcept` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, v, std::forward<Args>(args)...)` | Invokes dispatch type `D` with an lvalue reference of type `T` and `args...`, shall not throw. |
11+
| `R(Args...) &&` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, std::move(v), std::forward<Args>(args)...)` | Invokes dispatch type `D` with a rvalue reference of type `T` and `args...`, may throw. |
12+
| `R(Args...) && noexcept` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, std::move(v), std::forward<Args>(args)...)` | Invokes dispatch type `D` with a rvalue reference of type `T` and `args...`, shall not throw. |
13+
| `R(Args...) const` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, cv, std::forward<Args>(args)...)` | Invokes dispatch type `D` with a const reference of type `T` and `args...`, may throw. |
14+
| `R(Args...) const noexcept` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, cv, std::forward<Args>(args)...)` | Invokes dispatch type `D` with a const reference of type `T` and `args...`, shall not throw. |
15+
| `R(Args...) cosnt&` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, cv, std::forward<Args>(args)...)`, or<br />`d(nullptr, std::forward<Args>(args)...)` | Invokes dispatch type `D` with a const reference of type `T` and `args...`, may throw. |
16+
| `R(Args...) const& noexcept` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, cv, std::forward<Args>(args)...)` | Invokes dispatch type `D` with a const reference of type `T` and `args...`, shall not throw. |
17+
| `R(Args...) const&&` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, std::move(cv), std::forward<Args>(args)...)` | Invokes dispatch type `D` with a const rvalue reference of type `T` and `args...`, may throw. |
18+
| `R(Args...) const&& noexcept` | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, std::move(cv), std::forward<Args>(args)...)` | Invokes dispatch type `D` with a const rvalue reference of type `T` and `args...`, shall not throw. |
19+
20+
Or,
21+
22+
| Definitions of `O` | Expressions | Semantics |
23+
| -------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
24+
| `R(Args...)` *cv ref noex* | [`INVOKE<R>`](https://en.cppreference.com/w/cpp/utility/functional)`(D{}, nullptr, std::forward<Args>(args)...)` | Invokes the dispatch type `D` with `nullptr` and `args...`, may or may not throw depending on `noex`. |
25+
26+
## See Also
27+
28+
- [*ProConvention* requirements](ProConvention.md)

docs/ProFacade.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Named requirements: *ProFacade*
2+
3+
A type `F` meets the *ProFacade* requirements of a type `P` if `F` meets the [*ProBasicFacade* requirements](ProBasicFacade.md), and `P` meets the requirements defined by [`F::constraints`](proxiable_ptr_constraints.md), and the following expressions are well-formed and have the specified semantics.
4+
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+
10+
## See Also
11+
12+
- [concept `proxiable`](proxiable.md)
13+
- [*ProBasicFacade* requirements](ProBasicFacade.md)

0 commit comments

Comments
 (0)