GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/detail/impl/workspace.ipp
Date: 2023-02-10 23:49:12
Exec Total Coverage
Lines: 49 64 76.6%
Functions: 6 7 85.7%
Branches: 13 24 54.2%

Line Branch Exec 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/CPPAlliance/http_proto
8 //
9
10 #ifndef BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_IPP
11 #define BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_IPP
12
13 #include <boost/http_proto/detail/workspace.hpp>
14 #include <boost/http_proto/detail/except.hpp>
15 #include <boost/assert.hpp>
16
17 namespace boost {
18 namespace http_proto {
19 namespace detail {
20
21 /* Layout
22
23 The buffer is laid out thusly:
24
25 base_ begin_ head_ end_
26
27 |<- reserved ->|<- unused ->|<- acquired ->|
28 */
29 workspace::
30 any::
31 ~any() = default;
32
33 756 workspace::
34 756 ~workspace()
35 {
36
1/2
✓ Branch 0 taken 756 times.
✗ Branch 1 not taken.
756 if(base_)
37 {
38 756 clear();
39
1/2
✓ Branch 0 taken 756 times.
✗ Branch 1 not taken.
756 delete[] base_;
40 }
41 756 }
42
43 11 workspace::
44 workspace(
45 11 std::size_t n)
46 11 : base_(new unsigned char[n])
47 11 , begin_(base_)
48 11 , head_(base_ + n)
49 11 , end_(head_)
50 {
51 11 }
52
53 workspace::
54 workspace(
55 workspace&& other) noexcept
56 : base_(other.base_)
57 , begin_(other.begin_)
58 , head_(other.end_)
59 , end_(other.end_)
60 {
61 other.base_ = nullptr;
62 other.begin_ = nullptr;
63 other.head_ = nullptr;
64 other.end_ = nullptr;
65 }
66
67 void
68 745 workspace::
69 allocate(
70 std::size_t n)
71 {
72 // n == 0
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 745 times.
745 if(n == 0)
74 detail::throw_invalid_argument();
75
76 // this->size() > 0
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 745 times.
745 if(base_ != nullptr)
78 detail::throw_logic_error();
79
80 745 base_ = new unsigned char[n];
81 745 begin_ = base_;
82 745 head_ = base_ + n;
83 745 end_ = head_;
84 745 }
85
86 void
87 1543 workspace::
88 clear() noexcept
89 {
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1543 times.
1543 BOOST_ASSERT(begin_);
91
92 1543 auto const end =
93 reinterpret_cast<
94 any const*>(end_);
95 1543 auto p =
96 reinterpret_cast<
97 any const*>(head_);
98
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 1543 times.
1580 while(p != end)
99 {
100 37 auto next = p->next;
101 37 p->~any();
102 37 p = next;
103 }
104 1543 head_ = end_;
105 1543 begin_ = base_;
106 1543 }
107
108 void
109 6 workspace::
110 reserve(std::size_t n)
111 {
112 // Requested size exceeds available space.
113 // Note you can never reserve the last byte.
114
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if(n >= size())
115 detail::throw_length_error();
116
117 6 base_ += n ;
118 6 }
119
120 // https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html
121 void*
122 37 workspace::
123 bump_down(
124 std::size_t size,
125 std::size_t align)
126 {
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 BOOST_ASSERT(align > 0);
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 BOOST_ASSERT(
129 (align & (align - 1)) == 0);
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 BOOST_ASSERT(begin_);
131
132 37 auto ip0 = reinterpret_cast<
133 37 std::uintptr_t>(begin_);
134 37 auto ip = reinterpret_cast<
135 37 std::uintptr_t>(head_);
136
137 // If you get an exception here, it
138 // means that a buffer was too small
139 // for your workload. Increase the
140 // buffer size.
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if(size > ip - ip0)
142 detail::throw_bad_alloc();
143
144 37 ip -= size;
145 37 ip &= ~(align - 1);
146
147 // If you get an exception here, it
148 // means that a buffer was too small
149 // for your workload. Increase the
150 // buffer size.
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if(ip < ip0)
152 detail::throw_bad_alloc();
153
154 37 return reinterpret_cast<void*>(ip);
155 }
156
157 } // detail
158 } // http_proto
159 } // boost
160
161 #endif
162