Iros
 
Loading...
Searching...
No Matches
reference_wrapper.h
Go to the documentation of this file.
1#pragma once
2
5#include "di/util/addressof.h"
11
12namespace di::util {
13template<typename T>
15private:
16 constexpr static auto get_address(T& value) -> T* { return util::addressof(value); }
17
18public:
19 // Prevent creating reference wrapper's from rvalue (tempory) references.
20 constexpr static void get_address(T&&) = delete;
21
22 using Value = T;
23
24 constexpr explicit ReferenceWrapper(vocab::NullOpt) {}
25
26 template<typename U>
27 requires(!concepts::ReferenceWrapper<meta::Decay<U>> && requires { get_address(util::declval<U>()); })
28 // NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
29 constexpr ReferenceWrapper(U&& value) : m_pointer(get_address(value)) {}
30
31 constexpr ReferenceWrapper(ReferenceWrapper const&) = default;
32 constexpr auto operator=(ReferenceWrapper const&) -> ReferenceWrapper& = default;
33
34 constexpr operator T&() const { return get(); }
35 constexpr auto get() const -> T& { return *m_pointer; }
36
37 template<typename... Args>
38 requires(concepts::Invocable<T&, Args...>)
39 constexpr auto operator()(Args&&... args) const -> meta::InvokeResult<T&, Args...> {
40 return function::invoke(get(), util::forward<Args>(args)...);
41 }
42
43private:
44 // Implement di::vocab::OptionalStorage.
45 constexpr friend auto tag_invoke(types::Tag<vocab::is_nullopt>, ReferenceWrapper const& self) -> bool {
46 return !self.m_pointer;
47 }
48 constexpr friend auto tag_invoke(types::Tag<vocab::get_value>, ReferenceWrapper const& self) -> T& {
49 return *self.m_pointer;
50 }
52 self.m_pointer = nullptr;
53 }
54 constexpr friend void tag_invoke(types::Tag<vocab::set_value>, ReferenceWrapper& self, T& value) {
55 self.m_pointer = util::addressof(value);
56 }
57
58 T* m_pointer { nullptr };
59};
60
61template<typename T>
63
64namespace detail {
66 template<typename T>
67 constexpr auto operator()(T& value) const -> ReferenceWrapper<T> {
68 return ReferenceWrapper<T>(value);
69 }
70
71 template<typename T>
72 constexpr auto operator()(ReferenceWrapper<T> value) const -> ReferenceWrapper<T> {
73 return ReferenceWrapper<T>(value.get());
74 }
75
76 // Prevent construction of reference wrapper's from temporaries.
77 template<typename T>
78 constexpr void operator()(T const&& value) const = delete;
79 };
80
82 template<typename T>
83 constexpr auto operator()(T const& value) const -> ReferenceWrapper<T const> {
84 return ReferenceWrapper<T const>(value);
85 }
86
87 template<typename T>
89 return ReferenceWrapper<T const>(value.get());
90 }
91
92 // Prevent construction of reference wrapper's from temporaries.
93 template<typename T>
94 constexpr void operator()(T const&& value) const = delete;
95 };
96}
97
98constexpr inline auto ref = detail::RefFunction {};
99constexpr inline auto cref = detail::CRefFunction {};
100}
101
102namespace di {
103using util::cref;
104using util::ref;
106}
Definition reference_wrapper.h:14
constexpr ReferenceWrapper(U &&value)
Definition reference_wrapper.h:29
constexpr auto get() const -> T &
Definition reference_wrapper.h:35
constexpr friend void tag_invoke(types::Tag< vocab::set_value >, ReferenceWrapper &self, T &value)
Definition reference_wrapper.h:54
constexpr friend auto tag_invoke(types::Tag< vocab::is_nullopt >, ReferenceWrapper const &self) -> bool
Definition reference_wrapper.h:45
constexpr auto operator=(ReferenceWrapper const &) -> ReferenceWrapper &=default
static constexpr void get_address(T &&)=delete
constexpr ReferenceWrapper(vocab::NullOpt)
Definition reference_wrapper.h:24
constexpr ReferenceWrapper(ReferenceWrapper const &)=default
constexpr friend void tag_invoke(types::Tag< vocab::set_nullopt >, ReferenceWrapper &self)
Definition reference_wrapper.h:51
T Value
Definition reference_wrapper.h:22
constexpr friend auto tag_invoke(types::Tag< vocab::get_value >, ReferenceWrapper const &self) -> T &
Definition reference_wrapper.h:48
Definition invoke.h:58
Definition vocab.h:103
constexpr auto invoke
Definition invoke.h:100
decltype(function::detail::invoke_impl(util::declval< Ts >()...)) InvokeResult
Definition invoke.h:64
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition clamp.h:9
Definition vocab.h:96
constexpr auto ref
Definition reference_wrapper.h:98
auto declval() -> meta::AddRValueReference< T >
Definition declval.h:8
constexpr auto cref
Definition reference_wrapper.h:99
ReferenceWrapper(T &) -> ReferenceWrapper< T >
Definition zstring_parser.h:9
Definition reference_wrapper.h:81
constexpr void operator()(T const &&value) const =delete
constexpr auto operator()(T const &value) const -> ReferenceWrapper< T const >
Definition reference_wrapper.h:83
constexpr auto operator()(ReferenceWrapper< T > value) const -> ReferenceWrapper< T const >
Definition reference_wrapper.h:88
Definition reference_wrapper.h:65
constexpr auto operator()(ReferenceWrapper< T > value) const -> ReferenceWrapper< T >
Definition reference_wrapper.h:72
constexpr void operator()(T const &&value) const =delete
constexpr auto operator()(T &value) const -> ReferenceWrapper< T >
Definition reference_wrapper.h:67
Definition nullopt.h:6