Skip to content

Commit 1dc896a

Browse files
committed
Add API make_proxy_ref
1 parent bcbe0c7 commit 1dc896a

5 files changed

Lines changed: 81 additions & 0 deletions

File tree

docs/spec/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ nav:
3232
- allocate_proxy_shared: allocate_proxy_shared.md
3333
- allocate_proxy: allocate_proxy.md
3434
- make_proxy_inplace: make_proxy_inplace.md
35+
- make_proxy_ref: make_proxy_ref.md
3536
- make_proxy_shared: make_proxy_shared.md
3637
- make_proxy_view: make_proxy_view.md
3738
- make_proxy: make_proxy.md

docs/spec/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ This document provides the API specifications for the C++ library Proxy (version
5252
| [`allocate_proxy_shared`](allocate_proxy_shared.md) | Creates a `proxy` object with shared ownership using an allocator |
5353
| [`allocate_proxy`](allocate_proxy.md) | Creates a `proxy` object with an allocator |
5454
| [`make_proxy_inplace`](make_proxy_inplace.md) | Creates a `proxy` object with strong no-allocation guarantee |
55+
| [`make_proxy_ref`](make_proxy_ref.md) | Creates a `proxy` object with no ownership |
5556
| [`make_proxy_shared`](make_proxy_shared.md) | Creates a `proxy` object with shared ownership |
5657
| [`make_proxy_view`](make_proxy_view.md) | Creates a `proxy_view` object |
5758
| [`make_proxy`](make_proxy.md) | Creates a `proxy` object potentially with heap allocation |

docs/spec/make_proxy_ref.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Function template `make_proxy_ref`
2+
3+
> Header: `proxy.h`
4+
> Module: `proxy`
5+
> Namespace: `pro::inline v4`
6+
> Since: 4.1.0
7+
8+
The definition of `make_proxy_ref` makes use of an exposition-only class template *observer-ptr*. `observer-ptr<T>` contains a raw pointer to an object of type `T`, and provides `operator*` for access with the same qualifiers.
9+
10+
```cpp
11+
template <facade F, class T>
12+
proxy<F> make_proxy_ref(T& value) noexcept;
13+
```
14+
15+
Creates a `proxy<F>` object containing a value `p` of type `observer-ptr<T>`, where `*p` is direct-non-list-initialized with `&value`. If [`proxiable_target<T, F>`](proxiable_target.md) is `false`, the program is ill-formed and diagnostic messages are generated.
16+
17+
## Return Value
18+
19+
The constructed `proxy` object.
20+
21+
## Example
22+
23+
```cpp
24+
#include <iostream>
25+
26+
#include <proxy/proxy.h>
27+
28+
struct Printable : pro::facade_builder //
29+
::add_convention<pro::operator_dispatch<"<<", true>,
30+
std::ostream&(std::ostream&) const> //
31+
::build {};
32+
33+
int main() {
34+
int val = 123;
35+
pro::proxy<Printable> p = pro::make_proxy_ref<Printable>(val);
36+
37+
// Prints "123"
38+
std::cout << *p << "\n";
39+
40+
val = 456;
41+
42+
// Prints "456"
43+
std::cout << *p << "\n";
44+
}
45+
```
46+
47+
## See Also
48+
49+
- [concept `proxiable_target`](proxiable_target.md)
50+
- [function template `make_proxy_view`](make_proxy_view.md)

include/proxy/v4/proxy.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,11 @@ constexpr proxy<F> make_proxy_inplace(T&& value) noexcept(
18181818
std::in_place, std::forward<T>(value)};
18191819
}
18201820

1821+
template <facade F, class T>
1822+
constexpr proxy<F> make_proxy_ref(T& value) noexcept {
1823+
return proxy<F>{details::observer_ptr<T&, const T&, T&&, const T&&>{value}};
1824+
}
1825+
18211826
template <facade F, class T>
18221827
constexpr proxy_view<F> make_proxy_view(T& value) noexcept {
18231828
return proxy_view<F>{

tests/proxy_creation_tests.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,3 +1222,27 @@ TEST(ProxyCreationTests, TestMakeProxyView) {
12221222
p = pro::make_proxy_view<TestFacade>(test_callable);
12231223
ASSERT_EQ((*std::move(std::as_const(p)))(), 3);
12241224
}
1225+
1226+
TEST(ProxyCreationTests, TestMakeProxyRef) {
1227+
struct TestFacade
1228+
: pro::facade_builder //
1229+
::add_convention<pro::operator_dispatch<"()">, int() &, int() const&,
1230+
int() && noexcept, int() const&&> //
1231+
::build {};
1232+
1233+
struct {
1234+
int operator()() & noexcept { return 0; }
1235+
int operator()() const& noexcept { return 1; }
1236+
int operator()() && noexcept { return 2; }
1237+
int operator()() const&& noexcept { return 3; }
1238+
} test_callable;
1239+
1240+
pro::proxy<TestFacade> p = pro::make_proxy_ref<TestFacade>(test_callable);
1241+
static_assert(!noexcept((*p)()));
1242+
static_assert(noexcept((*std::move(p))()));
1243+
ASSERT_EQ((*p)(), 0);
1244+
ASSERT_EQ((*std::as_const(p))(), 1);
1245+
ASSERT_EQ((*std::move(p))(), 2);
1246+
p = pro::make_proxy_ref<TestFacade>(test_callable);
1247+
ASSERT_EQ((*std::move(std::as_const(p)))(), 3);
1248+
}

0 commit comments

Comments
 (0)