GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: impl/monotonic_resource.ipp
Date: 2026-01-02 17:31:41
Exec Total Coverage
Lines: 67 69 97.1%
Functions: 9 10 90.0%
Branches: 13 14 92.9%

Line Branch Exec 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 164 monotonic_resource::
31 max_size()
32 {
33 164 return std::size_t(-1) - sizeof(block);
34 }
35
36 // lowest power of 2 greater than or equal to n
37 std::size_t
38 39 monotonic_resource::
39 round_pow2(
40 std::size_t n) noexcept
41 {
42
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 32 times.
39 if(n & (n - 1))
43 7 return next_pow2(n);
44 32 return n;
45 }
46
47 // lowest power of 2 greater than n
48 std::size_t
49 51 monotonic_resource::
50 next_pow2(
51 std::size_t n) noexcept
52 {
53 51 std::size_t result = min_size_;
54
2/2
✓ Branch 0 taken 163 times.
✓ Branch 1 taken 50 times.
213 while(result <= n)
55 {
56
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 162 times.
163 if(result >= max_size() - result)
57 {
58 // overflow
59 1 result = max_size();
60 1 break;
61 }
62 162 result *= 2;
63 }
64 51 return result;
65 }
66
67 //----------------------------------------------------------
68
69 94 monotonic_resource::
70 94 ~monotonic_resource()
71 {
72 94 release();
73 94 }
74
75 37 monotonic_resource::
76 monotonic_resource(
77 std::size_t initial_size,
78 37 storage_ptr upstream) noexcept
79 37 : buffer_{
80 nullptr, 0, 0, nullptr}
81 74 , next_size_(round_pow2(initial_size))
82 37 , upstream_(std::move(upstream))
83 {
84 37 }
85
86 10 monotonic_resource::
87 monotonic_resource(
88 unsigned char* buffer,
89 std::size_t size,
90 10 storage_ptr upstream) noexcept
91 10 : buffer_{
92 buffer, size, size, nullptr}
93 20 , next_size_(next_pow2(size))
94 10 , upstream_(std::move(upstream))
95 {
96 10 }
97
98 void
99 48 monotonic_resource::
100 release() noexcept
101 {
102 48 auto p = head_;
103
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 48 times.
82 while(p != &buffer_)
104 {
105 34 auto next = p->next;
106 34 upstream_->deallocate(p, p->size);
107 34 p = next;
108 }
109 48 buffer_.p = reinterpret_cast<
110 48 unsigned char*>(buffer_.p) - (
111 48 buffer_.size - buffer_.avail);
112 48 buffer_.avail = buffer_.size;
113 48 head_ = &buffer_;
114 48 }
115
116 void*
117 129498 monotonic_resource::
118 do_allocate(
119 std::size_t n,
120 std::size_t align)
121 {
122 129498 auto p = std::align(align, n, head_->p, head_->avail);
123
2/2
✓ Branch 0 taken 129464 times.
✓ Branch 1 taken 34 times.
129498 if(p)
124 {
125 129464 head_->p = reinterpret_cast<
126 129464 unsigned char*>(p) + n;
127 129464 head_->avail -= n;
128 129464 return p;
129 }
130
131
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 32 times.
34 if(next_size_ < n)
132 2 next_size_ = round_pow2(n);
133 34 auto b = ::new(upstream_->allocate(
134 34 sizeof(block) + next_size_)) block;
135 34 b->p = b + 1;
136 34 b->avail = next_size_;
137 34 b->size = next_size_;
138 34 b->next = head_;
139 34 head_ = b;
140 34 next_size_ = next_pow2(next_size_);
141
142 34 p = std::align(align, n, head_->p, head_->avail);
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 BOOST_ASSERT(p);
144 34 head_->p = reinterpret_cast<
145 34 unsigned char*>(p) + n;
146 34 head_->avail -= n;
147 34 return p;
148 }
149
150 void
151 29 monotonic_resource::
152 do_deallocate(
153 void*,
154 std::size_t,
155 std::size_t)
156 {
157 // do nothing
158 29 }
159
160 bool
161 monotonic_resource::
162 do_is_equal(
163 memory_resource const& mr) const noexcept
164 {
165 return this == &mr;
166 }
167
168 } // namespace json
169 } // namespace boost
170
171 #endif
172