Coverage Report

Created: 2026-03-09 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boost/boost/json/impl/monotonic_resource.ipp
Line
Count
Source
1
//
2
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3
// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
4
//
5
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
//
8
// Official repository: https://github.com/boostorg/json
9
//
10
11
#ifndef BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
12
#define BOOST_JSON_IMPL_MONOTONIC_RESOURCE_IPP
13
14
#include <boost/json/monotonic_resource.hpp>
15
#include <boost/json/detail/except.hpp>
16
#include <boost/core/max_align.hpp>
17
18
#include <memory>
19
20
namespace boost {
21
namespace json {
22
23
struct alignas(core::max_align_t)
24
    monotonic_resource::block : block_base
25
{
26
};
27
28
constexpr
29
std::size_t
30
monotonic_resource::
31
max_size()
32
7.48k
{
33
7.48k
    return std::size_t(-1) - sizeof(block);
34
7.48k
}
35
36
// lowest power of 2 greater than or equal to n
37
std::size_t
38
monotonic_resource::
39
round_pow2(
40
    std::size_t n) noexcept
41
4.52k
{
42
4.52k
    if(n & (n - 1))
43
463
        return next_pow2(n);
44
4.06k
    return n;
45
4.52k
}
46
47
// lowest power of 2 greater than n
48
std::size_t
49
monotonic_resource::
50
next_pow2(
51
    std::size_t n) noexcept
52
2.08k
{
53
2.08k
    std::size_t result = min_size_;
54
9.57k
    while(result <= n)
55
7.48k
    {
56
7.48k
        if(result >= max_size() - result)
57
0
        {
58
            // overflow
59
0
            result = max_size();
60
0
            break;
61
0
        }
62
7.48k
        result *= 2;
63
7.48k
    }
64
2.08k
    return result;
65
2.08k
}
66
67
//----------------------------------------------------------
68
69
monotonic_resource::
70
~monotonic_resource()
71
4.05k
{
72
4.05k
    release();
73
4.05k
}
74
75
monotonic_resource::
76
monotonic_resource(
77
    std::size_t initial_size,
78
    storage_ptr upstream) noexcept
79
4.05k
    : buffer_{
80
4.05k
        nullptr, 0, 0, nullptr}
81
4.05k
    , next_size_(round_pow2(initial_size))
82
4.05k
    , upstream_(std::move(upstream))
83
4.05k
{
84
4.05k
}
85
86
monotonic_resource::
87
monotonic_resource(
88
    unsigned char* buffer,
89
    std::size_t size,
90
    storage_ptr upstream) noexcept
91
0
    : buffer_{
92
0
        buffer, size, size, nullptr}
93
0
    , next_size_(next_pow2(size))
94
0
    , upstream_(std::move(upstream))
95
0
{
96
0
}
97
98
void
99
monotonic_resource::
100
release() noexcept
101
4.05k
{
102
4.05k
    auto p = head_;
103
5.67k
    while(p != &buffer_)
104
1.62k
    {
105
1.62k
        auto next = p->next;
106
1.62k
        upstream_->deallocate(p, p->size);
107
1.62k
        p = next;
108
1.62k
    }
109
4.05k
    buffer_.p = reinterpret_cast<
110
4.05k
        unsigned char*>(buffer_.p) - (
111
4.05k
            buffer_.size - buffer_.avail);
112
4.05k
    buffer_.avail = buffer_.size;
113
4.05k
    head_ = &buffer_;
114
4.05k
}
115
116
void*
117
monotonic_resource::
118
do_allocate(
119
    std::size_t n,
120
    std::size_t align)
121
32.5k
{
122
32.5k
    auto p = std::align(align, n, head_->p, head_->avail);
123
32.5k
    if(p)
124
30.8k
    {
125
30.8k
        head_->p = reinterpret_cast<
126
30.8k
            unsigned char*>(p) + n;
127
30.8k
        head_->avail -= n;
128
30.8k
        return p;
129
30.8k
    }
130
131
1.62k
    if(next_size_ < n)
132
468
        next_size_ = round_pow2(n);
133
1.62k
    auto b = ::new(upstream_->allocate(
134
1.62k
        sizeof(block) + next_size_)) block;
135
1.62k
    b->p = b + 1;
136
1.62k
    b->avail = next_size_;
137
1.62k
    b->size = next_size_;
138
1.62k
    b->next = head_;
139
1.62k
    head_ = b;
140
1.62k
    next_size_ = next_pow2(next_size_);
141
142
1.62k
    p = std::align(align, n, head_->p, head_->avail);
143
1.62k
    BOOST_ASSERT(p);
144
1.62k
    head_->p = reinterpret_cast<
145
1.62k
        unsigned char*>(p) + n;
146
1.62k
    head_->avail -= n;
147
1.62k
    return p;
148
32.5k
}
149
150
void
151
monotonic_resource::
152
do_deallocate(
153
    void*,
154
    std::size_t,
155
    std::size_t)
156
305
{
157
    // do nothing
158
305
}
159
160
bool
161
monotonic_resource::
162
do_is_equal(
163
    memory_resource const& mr) const noexcept
164
0
{
165
0
    return this == &mr;
166
0
}
167
168
} // namespace json
169
} // namespace boost
170
171
#endif