GCC Code Coverage Report


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