GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/detail/impl/workspace.ipp
Date: 2023-02-02 18:17:22
Exec Total Coverage
Lines: 42 61 68.9%
Functions: 5 7 71.4%
Branches: 12 24 50.0%

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