Coverage Report

Created: 2026-02-07 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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/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
    pilfered(T&& t) noexcept
69
2.80M
        : t_(t)
70
2.80M
    {
71
2.80M
    }
boost::json::pilfered<boost::json::value>::pilfered(boost::json::value&&)
Line
Count
Source
69
2.80M
        : t_(t)
70
2.80M
    {
71
2.80M
    }
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&&)
72
73
    /** Return a reference to the pilferable object.
74
75
        This returns a reference to the wrapped object.
76
    */
77
    constexpr T&
78
    get() const noexcept
79
4.21M
    {
80
4.21M
        return t_;
81
4.21M
    }
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
79
4.21M
    {
80
4.21M
        return t_;
81
4.21M
    }
Unexecuted instantiation: boost::json::pilfered<boost::json::key_value_pair>::get() const
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
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
2.84M
{
189
2.84M
    using U =
190
2.84M
        typename std::remove_reference<T>::type;
191
2.84M
    BOOST_CORE_STATIC_ASSERT( is_pilfer_constructible<U>::value );
192
2.84M
    return typename std::conditional<
193
2.84M
        std::is_nothrow_constructible<
194
2.84M
            U, pilfered<U> >::value &&
195
2.84M
        ! std::is_nothrow_constructible<
196
2.84M
            U, detail_pilfer::not_pilfered<U> >::value,
197
2.84M
        pilfered<U>, U&&
198
2.84M
            >::type(std::move(t));
199
2.84M
}
_ZN5boost4json6pilferIRNS0_5valueEEENSt3__111conditionalIXaasr3std24is_nothrow_constructibleINS4_16remove_referenceIT_E4typeENS0_8pilferedIS9_EEEE5valuentsr3std24is_nothrow_constructibleIS9_NS0_13detail_pilfer12not_pilferedIS9_EEEE5valueESB_OS9_E4typeEOS7_
Line
Count
Source
188
2.80M
{
189
2.80M
    using U =
190
2.80M
        typename std::remove_reference<T>::type;
191
2.80M
    BOOST_CORE_STATIC_ASSERT( is_pilfer_constructible<U>::value );
192
2.80M
    return typename std::conditional<
193
2.80M
        std::is_nothrow_constructible<
194
2.80M
            U, pilfered<U> >::value &&
195
2.80M
        ! std::is_nothrow_constructible<
196
2.80M
            U, detail_pilfer::not_pilfered<U> >::value,
197
2.80M
        pilfered<U>, U&&
198
2.80M
            >::type(std::move(t));
199
2.80M
}
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
188
35.8k
{
189
35.8k
    using U =
190
35.8k
        typename std::remove_reference<T>::type;
191
35.8k
    BOOST_CORE_STATIC_ASSERT( is_pilfer_constructible<U>::value );
192
35.8k
    return typename std::conditional<
193
35.8k
        std::is_nothrow_constructible<
194
35.8k
            U, pilfered<U> >::value &&
195
35.8k
        ! std::is_nothrow_constructible<
196
35.8k
            U, detail_pilfer::not_pilfered<U> >::value,
197
35.8k
        pilfered<U>, U&&
198
35.8k
            >::type(std::move(t));
199
35.8k
}
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