GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: pilfer.hpp
Date: 2026-01-02 17:31:41
Exec Total Coverage
Lines: 7 7 100.0%
Functions: 12 12 100.0%
Branches: 0 0 -%

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