Coverage Report

Created: 2025-06-13 06:26

/src/boost/boost/json/pilfer.hpp
Line
Count
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/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
1.81M
        : t_(t)
69
1.81M
    {
70
1.81M
    }
boost::json::pilfered<boost::json::value>::pilfered(boost::json::value&&)
Line
Count
Source
68
1.81M
        : t_(t)
69
1.81M
    {
70
1.81M
    }
Unexecuted instantiation: boost::json::pilfered<boost::json::array>::pilfered(boost::json::array&&)
Unexecuted instantiation: boost::json::pilfered<boost::json::object>::pilfered(boost::json::object&&)
Unexecuted instantiation: boost::json::pilfered<boost::json::key_value_pair>::pilfered(boost::json::key_value_pair&&)
Unexecuted instantiation: boost::json::pilfered<boost::json::string>::pilfered(boost::json::string&&)
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
2.73M
    {
79
2.73M
        return t_;
80
2.73M
    }
Unexecuted instantiation: boost::json::pilfered<boost::json::array>::get() const
Unexecuted instantiation: boost::json::pilfered<boost::json::object>::get() const
Unexecuted instantiation: boost::json::pilfered<boost::json::string>::get() const
boost::json::pilfered<boost::json::value>::get() const
Line
Count
Source
78
2.73M
    {
79
2.73M
        return t_;
80
2.73M
    }
Unexecuted instantiation: boost::json::pilfered<boost::json::key_value_pair>::get() const
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
1.83M
{
188
1.83M
    using U =
189
1.83M
        typename std::remove_reference<T>::type;
190
1.83M
    static_assert(
191
1.83M
        is_pilfer_constructible<U>::value, "");
192
1.83M
    return typename std::conditional<
193
1.83M
        std::is_nothrow_constructible<
194
1.83M
            U, pilfered<U> >::value &&
195
1.83M
        ! std::is_nothrow_constructible<
196
1.83M
            U, detail_pilfer::not_pilfered<U> >::value,
197
1.83M
        pilfered<U>, U&&
198
1.83M
            >::type(std::move(t));
199
1.83M
}
_ZN5boost4json6pilferIRNS0_5valueEEENSt3__111conditionalIXaasr3std24is_nothrow_constructibleINS4_16remove_referenceIT_E4typeENS0_8pilferedIS9_EEEE5valuentsr3std24is_nothrow_constructibleIS9_NS0_13detail_pilfer12not_pilferedIS9_EEEE5valueESB_OS9_E4typeEOS7_
Line
Count
Source
187
1.81M
{
188
1.81M
    using U =
189
1.81M
        typename std::remove_reference<T>::type;
190
1.81M
    static_assert(
191
1.81M
        is_pilfer_constructible<U>::value, "");
192
1.81M
    return typename std::conditional<
193
1.81M
        std::is_nothrow_constructible<
194
1.81M
            U, pilfered<U> >::value &&
195
1.81M
        ! std::is_nothrow_constructible<
196
1.81M
            U, detail_pilfer::not_pilfered<U> >::value,
197
1.81M
        pilfered<U>, U&&
198
1.81M
            >::type(std::move(t));
199
1.81M
}
Unexecuted instantiation: _ZN5boost4json6pilferIRNS0_5arrayEEENSt3__111conditionalIXaasr3std24is_nothrow_constructibleINS4_16remove_referenceIT_E4typeENS0_8pilferedIS9_EEEE5valuentsr3std24is_nothrow_constructibleIS9_NS0_13detail_pilfer12not_pilferedIS9_EEEE5valueESB_OS9_E4typeEOS7_
Unexecuted instantiation: _ZN5boost4json6pilferIRNS0_6objectEEENSt3__111conditionalIXaasr3std24is_nothrow_constructibleINS4_16remove_referenceIT_E4typeENS0_8pilferedIS9_EEEE5valuentsr3std24is_nothrow_constructibleIS9_NS0_13detail_pilfer12not_pilferedIS9_EEEE5valueESB_OS9_E4typeEOS7_
Unexecuted instantiation: _ZN5boost4json6pilferIRNS0_14key_value_pairEEENSt3__111conditionalIXaasr3std24is_nothrow_constructibleINS4_16remove_referenceIT_E4typeENS0_8pilferedIS9_EEEE5valuentsr3std24is_nothrow_constructibleIS9_NS0_13detail_pilfer12not_pilferedIS9_EEEE5valueESB_OS9_E4typeEOS7_
Unexecuted instantiation: _ZN5boost4json6pilferIRNS0_6stringEEENSt3__111conditionalIXaasr3std24is_nothrow_constructibleINS4_16remove_referenceIT_E4typeENS0_8pilferedIS9_EEEE5valuentsr3std24is_nothrow_constructibleIS9_NS0_13detail_pilfer12not_pilferedIS9_EEEE5valueESB_OS9_E4typeEOS7_
_ZN5boost4json6pilferIRNS0_11storage_ptrEEENSt3__111conditionalIXaasr3std24is_nothrow_constructibleINS4_16remove_referenceIT_E4typeENS0_8pilferedIS9_EEEE5valuentsr3std24is_nothrow_constructibleIS9_NS0_13detail_pilfer12not_pilferedIS9_EEEE5valueESB_OS9_E4typeEOS7_
Line
Count
Source
187
13.4k
{
188
13.4k
    using U =
189
13.4k
        typename std::remove_reference<T>::type;
190
13.4k
    static_assert(
191
13.4k
        is_pilfer_constructible<U>::value, "");
192
13.4k
    return typename std::conditional<
193
13.4k
        std::is_nothrow_constructible<
194
13.4k
            U, pilfered<U> >::value &&
195
13.4k
        ! std::is_nothrow_constructible<
196
13.4k
            U, detail_pilfer::not_pilfered<U> >::value,
197
13.4k
        pilfered<U>, U&&
198
13.4k
            >::type(std::move(t));
199
13.4k
}
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