GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/detail/workspace.hpp
Date: 2023-02-02 18:17:22
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 class workspace
25 {
26 74 struct any
27 {
28 any* next = nullptr;
29
30 BOOST_HTTP_PROTO_DECL
31 virtual ~any() = 0;
32 };
33
34 unsigned char* begin_ = nullptr;
35 unsigned char* end_;
36 unsigned char* head_;
37
38 public:
39 ~workspace();
40
41 745 workspace() = default;
42 workspace(workspace&&) noexcept;
43 workspace& operator=(
44 workspace&&) noexcept;
45
46 explicit
47 workspace(
48 std::size_t n);
49
50 void*
51 7952 data() noexcept
52 {
53 7952 return begin_;
54 }
55
56 std::size_t
57 14 size() const noexcept
58 {
59 14 return head_ - begin_;
60 }
61
62 BOOST_HTTP_PROTO_DECL
63 void
64 clear() noexcept;
65
66 BOOST_HTTP_PROTO_DECL
67 void*
68 reserve(std::size_t n);
69
70 template<class T>
71 auto
72 push(T&& t) ->
73 typename std::decay<T>::type&;
74
75 template<class T>
76 T*
77 push_array(
78 std::size_t n,
79 T const& t);
80
81 private:
82 BOOST_HTTP_PROTO_DECL
83 void*
84 bump_down(
85 std::size_t size,
86 std::size_t align);
87 };
88
89 template<class T>
90 auto
91 26 workspace::
92 push(T&& t) ->
93 typename std::decay<T>::type&
94 {
95 struct alignas(alignof(::max_align_t))
96 U : any
97 {
98 typename std::decay<T>::type v_;
99
100 U() = delete;
101 U(U&&) = default;
102
103 13 explicit U(T&& t)
104 13 : v_(std::move(t))
105 {
106 }
107 };
108
109 26 auto p = ::new(bump_down(
110 sizeof(U), alignof(U))) U(
111 26 std::forward<T>(t));
112 26 p->next = reinterpret_cast<
113 26 any*>(head_);
114 26 head_ = reinterpret_cast<
115 unsigned char*>(p);
116 26 return p->v_;
117 }
118
119 template<class T>
120 T*
121 24 workspace::
122 push_array(
123 std::size_t n,
124 T const& t)
125 {
126 struct alignas(alignof(::max_align_t))
127 24 U : any
128 {
129 std::size_t n_ = 0;
130
131 U() = default;
132 48 ~U()
133 {
134 140 for(std::size_t i = n_;
135
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 24 times.
140 i-- > 0;)
136 92 data()[i].~T();
137 }
138
139 24 U( std::size_t n,
140 T const& t)
141 24 : U()
142 {
143
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 24 times.
70 while(n_ < n)
144 {
145 46 new(&data()[n_]) T(t);
146 46 ++n_;
147 }
148 24 }
149
150 116 T* data() noexcept
151 {
152 return reinterpret_cast<
153 116 T*>(this + 1);
154 }
155 };
156
157 24 auto p = ::new(bump_down(
158 24 sizeof(U) + n * sizeof(T),
159 alignof(::max_align_t))) U(n, t);
160 24 p->next = reinterpret_cast<
161 24 any*>(head_);
162 24 head_ = reinterpret_cast<
163 unsigned char*>(p);
164 24 return p->data();
165 }
166
167 } // detail
168 } // http_proto
169 } // boost
170
171 #endif
172