Horizon
Loading...
Searching...
No Matches
reference_wrapper.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2013-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13#ifndef RANGES_V3_FUNCTIONAL_REFERENCE_WRAPPER_HPP
14#define RANGES_V3_FUNCTIONAL_REFERENCE_WRAPPER_HPP
15
16#include <type_traits>
17#include <utility>
18
19#include <meta/meta.hpp>
20
21#include <concepts/concepts.hpp>
22
24#include <range/v3/utility/addressof.hpp>
25#include <range/v3/utility/static_const.hpp>
26
27#include <range/v3/detail/prologue.hpp>
28
29namespace ranges
30{
33
35 namespace detail
36 {
37 template<typename T>
38 struct reference_wrapper_
39 {
40 T * t_ = nullptr;
41 constexpr reference_wrapper_() = default;
42 constexpr reference_wrapper_(T & t) noexcept
43 : t_(detail::addressof(t))
44 {}
45 constexpr reference_wrapper_(T &&) = delete;
46 constexpr T & get() const noexcept
47 {
48 return *t_;
49 }
50 };
51 template<typename T>
52 struct reference_wrapper_<T &> : reference_wrapper_<T>
53 {
54 using reference_wrapper_<T>::reference_wrapper_;
55 };
56 template<typename T>
57 struct reference_wrapper_<T &&>
58 {
59 T * t_ = nullptr;
60 constexpr reference_wrapper_() = default;
61 constexpr reference_wrapper_(T && t) noexcept
62 : t_(detail::addressof(t))
63 {}
64 constexpr T && get() const noexcept
65 {
66 return static_cast<T &&>(*t_);
67 }
68 };
69 } // namespace detail
71
72 // Can be used to store rvalue references in addition to lvalue references.
73 // Also, see: https://wg21.link/lwg2993
74 template<typename T>
75 struct reference_wrapper : private detail::reference_wrapper_<T>
76 {
77 private:
78 using base_ = detail::reference_wrapper_<T>;
79 using base_::t_;
80
81 public:
83 using reference = meta::if_<std::is_reference<T>, T, T &>;
84
85 constexpr reference_wrapper() = default;
86 template(typename U)(
87 requires (!same_as<uncvref_t<U>, reference_wrapper>) AND
88 constructible_from<base_, U>)
89 constexpr reference_wrapper(U && u) noexcept(
90 std::is_nothrow_constructible<base_, U>::value)
91 : detail::reference_wrapper_<T>{static_cast<U &&>(u)}
92 {}
93 constexpr reference get() const noexcept
94 {
95 return this->base_::get();
96 }
97 constexpr operator reference() const noexcept
98 {
99 return get();
100 }
101 template(typename...)(
102 requires (!std::is_rvalue_reference<T>::value)) //
103 constexpr operator std::reference_wrapper<type>() const noexcept
104 {
105 return {get()};
106 }
107 // clang-format off
108 template<typename ...Args>
109 constexpr auto CPP_auto_fun(operator())(Args &&...args) (const)
110 (
111 return invoke(static_cast<reference>(*t_), static_cast<Args &&>(args)...)
112 )
113 // clang-format on
114 };
115
116 struct ref_fn
117 {
118 template(typename T)(
119 requires (!is_reference_wrapper_v<T>)) //
120 constexpr reference_wrapper<T> operator()(T & t) const
121 {
122 return {t};
123 }
125 template<typename T>
127 {
128 return t;
129 }
131 template<typename T>
132 constexpr reference_wrapper<T> operator()(std::reference_wrapper<T> t) const
133 {
134 return {t.get()};
135 }
136 };
137
140 RANGES_INLINE_VARIABLE(ref_fn, ref)
141
142 template<typename T>
143 using ref_t = decltype(ref(std::declval<T>()));
144
146 {
147 template<typename T>
148 constexpr T && operator()(T && t) const noexcept
149 {
150 return static_cast<T &&>(t);
151 }
153 template<typename T>
154 constexpr typename reference_wrapper<T>::reference operator()(reference_wrapper<T> t) const
155 noexcept
156 {
157 return t.get();
158 }
160 template<typename T>
161 constexpr T & operator()(std::reference_wrapper<T> t) const noexcept
162 {
163 return t.get();
164 }
166 template<typename T>
167 constexpr T & operator()(ref_view<T> t) const noexcept
168 {
169 return t.base();
170 }
171 };
172
175 RANGES_INLINE_VARIABLE(unwrap_reference_fn, unwrap_reference)
176
177 template<typename T>
178 using unwrap_reference_t = decltype(unwrap_reference(std::declval<T>()));
180} // namespace ranges
181
182#include <range/v3/detail/epilogue.hpp>
183
184#endif
decltype(unwrap_reference(std::declval< T >())) unwrap_reference_t
Definition reference_wrapper.hpp:178
decltype(ref(std::declval< T >())) ref_t
Definition reference_wrapper.hpp:143
typename T::type _t
Type alias for T::type.
Definition meta.hpp:141
_t< detail::_if_< list< Args... > > > if_
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1247
Tiny meta-programming library.
Definition reference_wrapper.hpp:117
constexpr reference_wrapper< T > operator()(reference_wrapper< T > t) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition reference_wrapper.hpp:126
constexpr reference_wrapper< T > operator()(std::reference_wrapper< T > t) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition reference_wrapper.hpp:132
Definition ref.hpp:41
Definition reference_wrapper.hpp:76
Definition reference_wrapper.hpp:146
constexpr reference_wrapper< T >::reference operator()(reference_wrapper< T > t) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition reference_wrapper.hpp:154
constexpr T & operator()(ref_view< T > t) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition reference_wrapper.hpp:167
constexpr T & operator()(std::reference_wrapper< T > t) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition reference_wrapper.hpp:161