Coverage Report

Created: 2026-02-07 06:45

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
8.05k
{
33
8.05k
    return std::size_t(-1) - sizeof(block);
34
8.05k
}
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.60k
{
42
4.60k
    if(n & (n - 1))
43
509
        return next_pow2(n);
44
4.09k
    return n;
45
4.60k
}
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.24k
{
53
2.24k
    std::size_t result = min_size_;
54
10.2k
    while(result <= n)
55
8.05k
    {
56
8.05k
        if(result >= max_size() - result)
57
0
        {
58
            // overflow
59
0
            result = max_size();
60
0
            break;
61
0
        }
62
8.05k
        result *= 2;
63
8.05k
    }
64
2.24k
    return result;
65
2.24k
}
66
67
//----------------------------------------------------------
68
69
monotonic_resource::
70
~monotonic_resource()
71
4.09k
{
72
4.09k
    release();
73
4.09k
}
74
75
monotonic_resource::
76
monotonic_resource(
77
    std::size_t initial_size,
78
    storage_ptr upstream) noexcept
79
4.09k
    : buffer_{
80
4.09k
        nullptr, 0, 0, nullptr}
81
4.09k
    , next_size_(round_pow2(initial_size))
82
4.09k
    , upstream_(std::move(upstream))
83
4.09k
{
84
4.09k
}
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.09k
{
102
4.09k
    auto p = head_;
103
5.82k
    while(p != &buffer_)
104
1.73k
    {
105
1.73k
        auto next = p->next;
106
1.73k
        upstream_->deallocate(p, p->size);
107
1.73k
        p = next;
108
1.73k
    }
109
4.09k
    buffer_.p = reinterpret_cast<
110
4.09k
        unsigned char*>(buffer_.p) - (
111
4.09k
            buffer_.size - buffer_.avail);
112
4.09k
    buffer_.avail = buffer_.size;
113
4.09k
    head_ = &buffer_;
114
4.09k
}
115
116
void*
117
monotonic_resource::
118
do_allocate(
119
    std::size_t n,
120
    std::size_t align)
121
75.5k
{
122
75.5k
    auto p = std::align(align, n, head_->p, head_->avail);
123
75.5k
    if(p)
124
73.7k
    {
125
73.7k
        head_->p = reinterpret_cast<
126
73.7k
            unsigned char*>(p) + n;
127
73.7k
        head_->avail -= n;
128
73.7k
        return p;
129
73.7k
    }
130
131
1.73k
    if(next_size_ < n)
132
514
        next_size_ = round_pow2(n);
133
1.73k
    auto b = ::new(upstream_->allocate(
134
1.73k
        sizeof(block) + next_size_)) block;
135
1.73k
    b->p = b + 1;
136
1.73k
    b->avail = next_size_;
137
1.73k
    b->size = next_size_;
138
1.73k
    b->next = head_;
139
1.73k
    head_ = b;
140
1.73k
    next_size_ = next_pow2(next_size_);
141
142
1.73k
    p = std::align(align, n, head_->p, head_->avail);
143
1.73k
    BOOST_ASSERT(p);
144
1.73k
    head_->p = reinterpret_cast<
145
1.73k
        unsigned char*>(p) + n;
146
1.73k
    head_->avail -= n;
147
1.73k
    return p;
148
75.5k
}
149
150
void
151
monotonic_resource::
152
do_deallocate(
153
    void*,
154
    std::size_t,
155
    std::size_t)
156
316
{
157
    // do nothing
158
316
}
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