GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/detail/workspace.hpp
Date: 2023-02-10 23:49:12
Exec Total Coverage
Lines: 35 35 100.0%
Functions: 16 16 100.0%
Branches: 4 4 100.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_WORKSPACE_HPP
11 #define BOOST_HTTP_PROTO_DETAIL_WORKSPACE_HPP
12
13 #include <boost/http_proto/detail/except.hpp>
14 #include <boost/assert.hpp>
15 #include <cstdlib>
16 #include <new>
17 #include <utility>
18 #include <stddef.h> // ::max_align_t
19
20 namespace boost {
21 namespace http_proto {
22 namespace detail {
23
24 /** A contiguous buffer of storage used by algorithms.
25
26 Objects of this type retain ownership of a
27 contiguous buffer of storage allocated upon
28 construction. This storage is divided into
29 three regions:
30
31 @li The reserved area, which starts at the
32 beginning of the buffer and can grow
33 upwards towards the end of the buffer.
34
35 @li The acquired area, which starts at the
36 end of the buffer and can grow downwards
37 towards the beginning of the buffer.
38
39 @li The unused area, which starts from the
40 end of the reserved area and stretches
41 until the beginning of the acquired area.
42 */
43 class workspace
44 {
45 74 struct any
46 {
47 any* next = nullptr;
48
49 BOOST_HTTP_PROTO_DECL
50 virtual ~any() = 0;
51 };
52
53 unsigned char* base_ = nullptr;
54 unsigned char* begin_ = nullptr;
55 unsigned char* head_ = nullptr;
56 unsigned char* end_ = nullptr;
57
58 public:
59 /** Destructor.
60 */
61 ~workspace();
62
63 /** Constructor.
64
65 @param n The number of bytes of storage
66 to allocate for the internal buffer.
67 */
68 explicit
69 workspace(
70 std::size_t n);
71
72 /** Constructor.
73 */
74 745 workspace() = default;
75
76 /** Constructor.
77 */
78 workspace(workspace&&) noexcept;
79
80 /** Allocate internal storage.
81
82 @throws std::logic_error this->size() > 0
83
84 @throws std::invalid_argument n == 0
85 */
86 void
87 allocate(
88 std::size_t n);
89
90 /** Return a pointer to the unused area.
91 */
92 void*
93 7958 data() noexcept
94 {
95 7958 return begin_;
96 }
97
98 /** Return the size of the unused area.
99 */
100 std::size_t
101 20 size() const noexcept
102 {
103 20 return head_ - begin_;
104 }
105
106 /** Clear the contents while preserving capacity.
107 */
108 BOOST_HTTP_PROTO_DECL
109 void
110 clear() noexcept;
111
112 /** Convert unused storage to reserved storage.
113
114 @throws std::invalid_argument n >= this->size()
115 */
116 BOOST_HTTP_PROTO_DECL
117 void
118 reserve(std::size_t n);
119
120 template<class T>
121 auto
122 push(T&& t) ->
123 typename std::decay<T>::type&;
124
125 template<class T>
126 T*
127 push_array(
128 std::size_t n,
129 T const& t);
130
131 private:
132 BOOST_HTTP_PROTO_DECL
133 void*
134 bump_down(
135 std::size_t size,
136 std::size_t align);
137 };
138
139 template<class T>
140 auto
141 26 workspace::
142 push(T&& t) ->
143 typename std::decay<T>::type&
144 {
145 struct alignas(alignof(::max_align_t))
146 U : any
147 {
148 typename std::decay<T>::type v_;
149
150 U() = delete;
151 U(U&&) = default;
152
153 13 explicit U(T&& t)
154 13 : v_(std::move(t))
155 {
156 }
157 };
158
159 26 auto p = ::new(bump_down(
160 sizeof(U), alignof(U))) U(
161 26 std::forward<T>(t));
162 26 p->next = reinterpret_cast<
163 26 any*>(head_);
164 26 head_ = reinterpret_cast<
165 unsigned char*>(p);
166 26 return p->v_;
167 }
168
169 template<class T>
170 T*
171 24 workspace::
172 push_array(
173 std::size_t n,
174 T const& t)
175 {
176 struct alignas(alignof(::max_align_t))
177 24 U : any
178 {
179 std::size_t n_ = 0;
180
181 U() = default;
182 48 ~U()
183 {
184 140 for(std::size_t i = n_;
185
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 24 times.
140 i-- > 0;)
186 92 data()[i].~T();
187 }
188
189 24 U( std::size_t n,
190 T const& t)
191 24 : U()
192 {
193
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 24 times.
70 while(n_ < n)
194 {
195 46 new(&data()[n_]) T(t);
196 46 ++n_;
197 }
198 24 }
199
200 116 T* data() noexcept
201 {
202 return reinterpret_cast<
203 116 T*>(this + 1);
204 }
205 };
206
207 24 auto p = ::new(bump_down(
208 24 sizeof(U) + n * sizeof(T),
209 alignof(::max_align_t))) U(n, t);
210 24 p->next = reinterpret_cast<
211 24 any*>(head_);
212 24 head_ = reinterpret_cast<
213 unsigned char*>(p);
214 24 return p->data();
215 }
216
217 } // detail
218 } // http_proto
219 } // boost
220
221 #endif
222