Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.28)

project(msft_proxy4 VERSION 4.0.2 LANGUAGES CXX)
project(msft_proxy4 VERSION 4.1.0 LANGUAGES CXX)
add_library(msft_proxy4 INTERFACE)
set_target_properties(msft_proxy4 PROPERTIES EXPORT_NAME proxy)
add_library(msft_proxy4::proxy ALIAS msft_proxy4)
Expand Down
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module(
name = "proxy",
version = "4.0.2",
version = "4.1.0",
)

bazel_dep(name = "platforms", version = "1.1.0")
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ The "Proxy" library is a self-contained solution for runtime polymorphism in C++
- **Concepts**: To facilitate template programming with "Proxy", 3 concepts are exported from a facade type. Namely, [`proxiable`](https://ngcpp.github.io/proxy/spec/proxiable), [`proxiable_target`](https://ngcpp.github.io/proxy/spec/proxiable_target) and [`inplace_proxiable_target`](https://ngcpp.github.io/proxy/spec/inplace_proxiable_target).
- **Allocator awareness**: [function template `allocate_proxy`](https://ngcpp.github.io/proxy/spec/allocate_proxy) is able to create a `proxy` from a value with any custom allocator. In C++11, [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function) and [`std::packaged_task`](https://en.cppreference.com/w/cpp/thread/packaged_task) had constructors that accepted custom allocators for performance tuning, but these were [removed in C++17](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0302r1.html) because "the semantics are unclear, and there are technical issues with storing an allocator in a type-erased context and then recovering that allocator later for any allocations needed during copy assignment". These issues do not apply to `allocate_proxy`.
- **Configurable constraints**: [`facade_builder`](https://ngcpp.github.io/proxy/spec/basic_facade_builder) provides full support for constraints configuration, including memory layout (by [`restrict_layout`](https://ngcpp.github.io/proxy/spec/basic_facade_builder/restrict_layout)), copyability (by [`support_copy`](https://ngcpp.github.io/proxy/spec/basic_facade_builder/support_copy)), relocatability (by [`support_relocation`](https://ngcpp.github.io/proxy/spec/basic_facade_builder/support_relocation)), and destructibility (by [`support_destruction`](https://ngcpp.github.io/proxy/spec/basic_facade_builder/support_destruction)).
- **Reflection**: `proxy` supports type-based compile-time reflection for runtime queries. Please refer to [`facade_builder::add_reflection`](https://ngcpp.github.io/proxy/spec/basic_facade_builder/add_reflection) and [function template `proxy_reflect`](https://ngcpp.github.io/proxy/spec/proxy_reflect) for more details.
- **Reflection**: `proxy` supports type-based compile-time reflection for runtime queries. Please refer to [`facade_builder::add_reflection`](https://ngcpp.github.io/proxy/spec/basic_facade_builder/add_reflection) and [function template `reflect`](https://ngcpp.github.io/proxy/spec/proxy_indirect_accessor/reflect) for more details.
- **Non-owning proxy**: Although `proxy` can manage the lifetime of an object effectively, similar to a smart pointer, we sometimes want to dereference it before passing to a non-owning context. This has been implemented as an extension since 3.2.0. Please refer to [function template `make_proxy_view`](https://ngcpp.github.io/proxy/spec/make_proxy_view), [alias template `proxy_view`, class template `observer_facade`](https://ngcpp.github.io/proxy/spec/proxy_view) and [`skills::as_view`](https://ngcpp.github.io/proxy/spec/skills_as_view) for more details.
- **RTTI**: [RTTI (run-time type information)](https://en.wikipedia.org/wiki/Run-time_type_information) provides "weak" reflection capability in C++ since the last century. Although it is not as powerful as reflection in some other languages (like `Object.GetType()` in C# or `Object.getClass()` in Java), it offers the basic infrastructure for type-safe casting at runtime. Since 4.0.0, "RTTI for `proxy`" has been implemented as an extension and allows users to opt-in for each facade definition. Please refer to [`skills::rtti`](https://ngcpp.github.io/proxy/spec/skills_rtti) for more details.
- **Shared and weak ownership**: Although `proxy` can be created from a [`std::shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr), extensions are available to create `proxy` objects with shared and weak ownership in a more efficient way since 3.3.0. Please refer to [function template `make_proxy_shared`](https://ngcpp.github.io/proxy/spec/make_proxy_shared), [`allocate_proxy_shared`](https://ngcpp.github.io/proxy/spec/allocate_proxy_shared), [alias template `weak_proxy`, class template `weak_facade`](https://ngcpp.github.io/proxy/spec/weak_proxy) and [`skills::as_weak`](https://ngcpp.github.io/proxy/spec/skills_as_weak) for more details.
Expand All @@ -243,7 +243,7 @@ Fetch via [CPM](https://github.com/cpm-cmake/CPM.cmake) (a thin wrapper over CMa
```cmake
CPMAddPackage(
NAME msft_proxy4
GIT_TAG 4.0.2
GIT_TAG 4.1.0
GIT_REPOSITORY https://github.com/ngcpp/proxy.git
)

Expand All @@ -259,7 +259,7 @@ Place a wrap file at `subprojects/proxy.wrap` and Meson will fetch the source au
```ini
[wrap-git]
url = https://github.com/ngcpp/proxy.git
revision = 4.0.2
revision = 4.1.0

[provide]
dependency_names = msft_proxy4
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ nav:
- is_bitwise_trivially_relocatable: is_bitwise_trivially_relocatable.md
- not_implemented: not_implemented.md
- operator_dispatch: operator_dispatch
- proxy_indirect_accessor: proxy_indirect_accessor.md
- proxy_indirect_accessor: proxy_indirect_accessor
- proxy_view<br />observer_facade: proxy_view.md
- proxy: proxy
- substitution_dispatch: substitution_dispatch
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/PRO_DEF_FREE_AS_MEM_DISPATCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct dispatch_name {
template <class P, class D, class R, class... Args>
struct accessor<P, D, R(Args...) cv ref noex> {
R accessibility_func_name(Args... args) cv ref noex {
return pro::proxy_invoke<D, R(Args...) cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this), std::forward<Args>(args)...);
return invoke<D, R(Args...) cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this), std::forward<Args>(args)...);
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/PRO_DEF_FREE_DISPATCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct dispatch_name {
template <class P, class D, class R, class... Args>
struct accessor<P, D, R(Args...) cv ref noex> {
friend R accessibility_func_name(P cv <ref ? ref : &> self, Args... args) noex {
return pro::proxy_invoke<D, R(Args...) cv ref noex>(static_cast<P cv <ref ? ref : &>>(self), std::forward<Args>(args)...);
return invoke<D, R(Args...) cv ref noex>(static_cast<P cv <ref ? ref : &>>(self), std::forward<Args>(args)...);
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/PRO_DEF_MEM_DISPATCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct dispatch_name {
template <class P, class D, class R, class... Args>
struct accessor<P, D, R(Args...) cv ref noex> {
R accessibility_func_name(Args... args) cv ref noex {
return pro::proxy_invoke<D, R(Args...) cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this), std::forward<Args>(args)...);
return invoke<D, R(Args...) cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this), std::forward<Args>(args)...);
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/ProAccessible.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ A type `T` meets the *ProAccessible* requirements of types `Args...` if the foll
## See Also

- [class template `proxy`](proxy/README.md)
- [class template `proxy_indirect_accessor`](proxy_indirect_accessor.md)
- [class template `proxy_indirect_accessor`](proxy_indirect_accessor/README.md)
6 changes: 3 additions & 3 deletions docs/spec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This document provides the API specifications for the C++ library Proxy (version
| [`is_bitwise_trivially_relocatable`](is_bitwise_trivially_relocatable.md) | Specifies whether a type is bitwise trivially relocatable |
| [`not_implemented` ](not_implemented.md) | Exception thrown by `weak_dispatch` for the default implementation |
| [`operator_dispatch`](operator_dispatch/README.md) | Dispatch type for operator expressions with accessibility |
| [`proxy_indirect_accessor`](proxy_indirect_accessor.md) | Provides indirection accessibility for `proxy` |
| [`proxy_indirect_accessor`](proxy_indirect_accessor/README.md) | Provides indirection accessibility for `proxy` |
| [`proxy_view`<br />`observer_facade`](proxy_view.md) | Non-owning `proxy` optimized for raw pointer types |
| [`proxy`](proxy/README.md) | Wraps a pointer object matching specified facade |
| [`substitution_dispatch`](substitution_dispatch/README.md) | Dispatch type for `proxy` substitution with accessibility |
Expand All @@ -55,8 +55,8 @@ This document provides the API specifications for the C++ library Proxy (version
| [`make_proxy_shared`](make_proxy_shared.md) | Creates a `proxy` object with shared ownership |
| [`make_proxy_view`](make_proxy_view.md) | Creates a `proxy_view` object |
| [`make_proxy`](make_proxy.md) | Creates a `proxy` object potentially with heap allocation |
| [`proxy_invoke`](proxy_invoke.md) | Invokes a `proxy` with a specified convention |
| [`proxy_reflect`](proxy_reflect.md) | Acquires reflection information of a contained type |
| [`proxy_invoke`](proxy_invoke.md) [deprecated] | Invokes a `proxy` with a specified convention |
| [`proxy_reflect`](proxy_reflect.md) [deprecated] | Acquires reflection information of a contained type |

## Header `<proxy_macros.h>`

Expand Down
1 change: 1 addition & 0 deletions docs/spec/basic_facade_builder/.pages
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
nav:
- basic_facade_builder: README.md
- add_convention<br />add_indirect_convention<br />add_direct_convention: add_convention.md
- add_facade_with_substitution: add_facade_with_substitution.md
- add_facade: add_facade.md
- add_reflection<br />add_indirect_reflection<br />add_direct_reflection: add_reflection.md
- add_skill: add_skill.md
Expand Down
1 change: 1 addition & 0 deletions docs/spec/basic_facade_builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ using facade_builder =
| Name | Description |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| [`add_convention`<br />`add_indirect_convention`<br />`add_direct_convention`](add_convention.md) | Adds a convention to the template parameters |
| [`add_facade_with_substitution`](add_facade_with_substitution.md) | Adds a facade to the template parameters, together with [substitution](../substitution_dispatch/README.md) support |
| [`add_facade`](add_facade.md) | Adds a facade to the template parameters |
| [`add_reflection`<br />`add_indirect_reflection`<br />`add_direct_reflection`](add_reflection.md) | Adds a reflection to the template parameters |
| [`add_skill`](add_skill.md) | Adds a custom skill |
Expand Down
9 changes: 6 additions & 3 deletions docs/spec/basic_facade_builder/add_facade.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ The alias template `add_facade` of `basic_facade_builder<Cs, Rs, MaxSize, MaxAli
- sets `Copyability` to `std::max(Copyability, F::copyability)`, and
- sets `Relocatability` to `std::max(Relocatability, F::relocatability)`, and
- sets `Destructibility` to `std::max(Destructibility, F::destructibility)`, and
- optionally, merges a direct convention of [`substitution_dispatch`](../substitution_dispatch/README.md) into `Cs` when `WithSubstitution` is `true`.
- optionally, merges a direct convention of [`substitution_dispatch`](../substitution_dispatch/README.md) into `Cs` when `WithSubstitution` is `true` *(deprecated since 4.1.0: use [`add_facade_with_substitution`](add_facade_with_substitution.md) instead)*.

## Notes

Adding a facade type that contains duplicated convention or reflection types already defined in `Cs` or `Rs` is well-defined and does not have side effects on [`build`](build.md) at either compile-time or runtime. By default, `WithSubstitution` is `false`, which guarantees minimal binary size in code generation. However, substitution is helpful when an API requires backward compatibility. Users can opt-in to this feature by specifying `true` as the second parameter of `add_facade`, at the cost of potentially a slightly larger binary size.
Adding a facade type that contains duplicated convention or reflection types already defined in `Cs` or `Rs` is well-defined and does not have side effects on [`build`](build.md) at either compile-time or runtime. By default, `WithSubstitution` is `false`, which guarantees minimal binary size in code generation. However, substitution is helpful when an API requires backward compatibility. Users can opt-in to this feature via [`add_facade_with_substitution`](add_facade_with_substitution.md), at the cost of potentially a slightly larger binary size.

**Deprecated since 4.1.0**: Specifying the `WithSubstitution` parameter as `true` (i.e., `add_facade<F, true>`) is deprecated. Use [`add_facade_with_substitution`](add_facade_with_substitution.md)`<F>` instead. The single-argument form `add_facade<F>` is not affected.

## Example

Expand Down Expand Up @@ -50,7 +52,7 @@ struct StringDictionary

struct MutableStringDictionary
: pro::facade_builder //
::add_facade<StringDictionary, true> //
::add_facade_with_substitution<StringDictionary> //
::add_convention<MemEmplace, void(std::size_t key, std::string value)> //
::build {};

Expand Down Expand Up @@ -83,4 +85,5 @@ int main() {

## See Also

- [`add_facade_with_substitution`](add_facade_with_substitution.md)
- [`build`](build.md)
53 changes: 53 additions & 0 deletions docs/spec/basic_facade_builder/add_facade_with_substitution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# `basic_facade_builder::add_facade_with_substitution`

> Since: 4.1.0

```cpp
template <facade F>
using add_facade_with_substitution = basic_facade_builder</* see below */>;
```

The alias template `add_facade_with_substitution` of `basic_facade_builder<Cs, Rs, MaxSize, MaxAlign, Copyability, Relocatability, Destructibility>` is equivalent to [`add_facade`](add_facade.md)`<F>`, except that it always merges a direct convention of [`substitution_dispatch`](../substitution_dispatch/README.md) into `Cs`. This convention enables substitution from a `proxy` of the built [facade](../facade.md) to a `proxy<F>`.

## Notes

`add_facade_with_substitution` was introduced in `4.1.0` as a replacement for the deprecated `add_facade<F, true>` syntax.

The substitution convention is helpful when an API requires backward compatibility, at the cost of potentially a slightly larger binary size. When substitution is not required, use [`add_facade`](add_facade.md) to guarantee minimal binary size in code generation.

## Example

```cpp
#include <iostream>
#include <vector>

#include <proxy/proxy.h>

PRO_DEF_MEM_DISPATCH(MemSize, size);
PRO_DEF_MEM_DISPATCH(MemClear, clear);

struct Container : pro::facade_builder //
::add_convention<MemSize, std::size_t() const> //
::build {};

// A proxy<ClearableContainer> can be substituted with a proxy<Container>.
struct ClearableContainer : pro::facade_builder //
::add_facade_with_substitution<Container> //
::add_convention<MemClear, void()> //
::build {};

int main() {
pro::proxy<ClearableContainer> p1 =
pro::make_proxy<ClearableContainer, std::vector<int>>(10);
std::cout << p1->size() << "\n"; // Prints "10"

// Substitution from an rvalue: ClearableContainer -> Container
pro::proxy<Container> p2 = std::move(p1);
std::cout << p2->size() << "\n"; // Prints "10"
}
```

## See Also

- [`add_facade`](add_facade.md)
- [`build`](build.md)
4 changes: 2 additions & 2 deletions docs/spec/basic_facade_builder/add_reflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ public:
template <class P, class R>
struct accessor {
friend std::size_t SizeOf(const P& self) noexcept {
const LayoutReflector& refl = pro::proxy_reflect<R>(self);
const LayoutReflector& refl = reflect<R>(self);
return refl.Size;
}

friend std::size_t AlignOf(const P& self) noexcept {
const LayoutReflector& refl = pro::proxy_reflect<R>(self);
const LayoutReflector& refl = reflect<R>(self);
return refl.Align;
}
};
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/explicit_conversion_dispatch/accessor.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ struct accessor<P, D, T() cv ref noex> {
`(2)` When `sizeof...(Os)` is greater than `1`, and `accessor<P, D, Os>...` are default-constructible, inherits all `accessor<P, D, 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<D, T() cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this))`.
`(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 invoke<D, T() cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this))`.
2 changes: 1 addition & 1 deletion docs/spec/implicit_conversion_dispatch/accessor.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ struct accessor<P, D, T() cv ref noex> {

`(2)` When `sizeof...(Os)` is greater than `1`, and `accessor<P, D, Os>...` are default-constructible, inherits all `accessor<P, D, 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<T() cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this))`.
`(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 invoke<T() cv ref noex>(static_cast<P cv <ref ? ref : &>>(*this))`.
1 change: 1 addition & 0 deletions docs/spec/msft_lib_proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Starting with 3.0.0, Proxy ships a feature-test macro that encodes the library v
| Version | Value of `__msft_lib_proxy` |
| ------- | --------------------------- |
| 4.1.0 | `202606L` |
| 4.0.2 | `202603L` |
| 4.0.1 | `202510L` |
| 4.0.0 | `202508L` |
Expand Down
Loading
Loading