]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/json/pilfer.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / json / pilfer.hpp
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/json
8 //
9
10 #ifndef BOOST_JSON_PILFER_HPP
11 #define BOOST_JSON_PILFER_HPP
12
13 #include <boost/json/detail/config.hpp>
14 #include <type_traits>
15 #include <utility>
16
17 /*
18 Implements "pilfering" from P0308R0
19
20 @see
21 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html
22 */
23
24 namespace boost {
25 namespace json {
26
27 /** Tag wrapper to specify pilfer-construction.
28
29 This wrapper is used to specify a pilfer constructor
30 overload.
31
32 @par Example
33
34 A pilfer constructor accepts a single argument
35 of type @ref pilfered and throws nothing:
36
37 @code
38 struct T
39 {
40 T( pilfered<T> ) noexcept;
41 };
42 @endcode
43
44 @note
45
46 The constructor should not be marked explicit.
47
48 @see @ref pilfer, @ref is_pilfer_constructible,
49 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
50 Valueless Variants Considered Harmful</a>
51 */
52 template<class T>
53 class pilfered
54 {
55 T& t_;
56
57 public:
58 /** Constructor
59
60 Construct the wrapper from `t`.
61
62 @param t The pilferable object. Ownership
63 is not transferred.
64 */
65 explicit
66 constexpr
67 pilfered(T&& t) noexcept
68 : t_(t)
69 {
70 }
71
72 /** Return a reference to the pilferable object.
73
74 This returns a reference to the wrapped object.
75 */
76 constexpr T&
77 get() const noexcept
78 {
79 return t_;
80 }
81
82 /** Return a pointer to the pilferable object.
83
84 This returns a pointer to the wrapped object.
85 */
86 constexpr T*
87 operator->() const noexcept
88 {
89 //return std::addressof(t_);
90 return reinterpret_cast<T*>(
91 const_cast<char *>(
92 &reinterpret_cast<
93 const volatile char &>(t_)));
94 }
95 };
96
97 #ifndef BOOST_JSON_DOCS
98 // VFALCO Renamed this to work around an msvc bug
99 namespace detail_pilfer {
100 template<class>
101 struct not_pilfered
102 {
103 };
104 } // detail_pilfer
105 #endif
106
107 /** Metafunction returning `true` if `T` is <em>PilferConstructible</em>
108
109 If `T` can be pilfer constructed, this metafunction is
110 equal to `std::true_type`. Otherwise it is equal to
111 `std::false_type`.
112
113 @see @ref pilfer, @ref pilfered,
114 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
115 Valueless Variants Considered Harmful</a>
116 */
117 template<class T>
118 struct is_pilfer_constructible
119 #ifndef BOOST_JSON_DOCS
120 : std::integral_constant<bool,
121 std::is_nothrow_move_constructible<T>::value ||
122 (
123 std::is_nothrow_constructible<
124 T, pilfered<T> >::value &&
125 ! std::is_nothrow_constructible<
126 T, detail_pilfer::not_pilfered<T> >::value
127 )>
128 #endif
129 {
130 };
131
132 /** Indicate that an object `t` may be pilfered from.
133
134 A <em>pilfer</em> operation is the construction
135 of a new object of type `T` from an existing
136 object `t`. After the construction, the only
137 valid operation on the pilfered-from object is
138 destruction. This permits optimizations beyond
139 those available for a move-construction, as the
140 pilfered-from object is not required to be in
141 a "usable" state.
142 \n
143 This is used similarly to `std::move`.
144
145 @par Example
146
147 A pilfer constructor accepts a single argument
148 of type @ref pilfered and throws nothing:
149
150 @code
151 struct T
152 {
153 T( pilfered<T> ) noexcept;
154 };
155 @endcode
156
157 Pilfer construction is performed using @ref pilfer :
158
159 @code
160 {
161 T t1; // default construction
162 T t2( pilfer( t1 ) ); // pilfer-construct from t1
163
164 // At this point, t1 may only be destroyed
165 }
166 @endcode
167
168 @see @ref pilfered, @ref is_pilfer_constructible,
169 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">
170 Valueless Variants Considered Harmful</a>
171 */
172 template<class T>
173 auto
174 pilfer(T&& t) noexcept ->
175 typename std::conditional<
176 std::is_nothrow_constructible<
177 typename std::remove_reference<T>::type,
178 pilfered<typename
179 std::remove_reference<T>::type> >::value &&
180 ! std::is_nothrow_constructible<
181 typename std::remove_reference<T>::type,
182 detail_pilfer::not_pilfered<typename
183 std::remove_reference<T>::type> >::value,
184 pilfered<typename std::remove_reference<T>::type>,
185 typename std::remove_reference<T>::type&&
186 >::type
187 {
188 using U =
189 typename std::remove_reference<T>::type;
190 static_assert(
191 is_pilfer_constructible<U>::value, "");
192 return typename std::conditional<
193 std::is_nothrow_constructible<
194 U, pilfered<U> >::value &&
195 ! std::is_nothrow_constructible<
196 U, detail_pilfer::not_pilfered<U> >::value,
197 pilfered<U>, U&&
198 >::type(std::move(t));
199 }
200
201 /*
202 template<class T>
203 void
204 relocate(T* dest, T& src) noexcept
205 {
206 static_assert(
207 is_pilfer_constructible<T>::value, "");
208 ::new(dest) T(pilfer(src));
209 src.~T();
210 }
211 */
212
213 } // json
214 } // boost
215
216
217 #endif