GCC Code Coverage Report


Directory: libs/http_proto/
File: boost/http_proto/detail/impl/workspace.hpp
Date: 2024-09-20 16:11:52
Exec Total Coverage
Lines: 47 48 97.9%
Functions: 30 32 93.8%
Branches: 10 16 62.5%

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_HPP
11 #define BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_HPP
12
13 #include <boost/config.hpp>
14
15 namespace boost {
16 namespace http_proto {
17 namespace detail {
18
19 #if defined(BOOST_MSVC)
20 #pragma warning(push)
21 #pragma warning(disable : 4324) /* structure was padded due to __declspec(align()) */
22 #endif
23
24 struct workspace::any
25 {
26 any* next = nullptr;
27
28 BOOST_HTTP_PROTO_DECL
29 virtual ~any() = 0;
30 };
31
32 template<class U>
33 struct alignas(alignof(::max_align_t))
34 workspace::any_impl : any
35 {
36 U u;
37
38 any_impl() = delete;
39 any_impl(any_impl const&) = delete;
40 any_impl(any_impl&&) = delete;
41
42 template<class... Args>
43 836 explicit any_impl(Args&&... args)
44
2/4
✗ Branch 4 not taken.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 48 times.
✗ Branch 7 not taken.
836 : u(std::forward<Args>(args)...)
45 {
46 836 }
47 };
48
49 struct workspace::undo
50 {
51 explicit
52 538 undo(workspace& ws0) noexcept
53 538 : ws_(ws0)
54 538 , head_(ws0.head_)
55 {
56 538 }
57
58 538 ~undo()
59 {
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 538 times.
538 if(head_)
61 ws_.head_ = head_;
62 538 }
63
64 void
65 538 commit() noexcept
66 {
67 538 head_ = nullptr;
68 538 }
69
70 private:
71 workspace& ws_;
72 unsigned char* head_;
73 };
74
75 template<class T>
76 constexpr
77 std::size_t
78 workspace::
79 space_needed()
80 {
81 using U = typename std::decay<T>::type;
82
83 static_assert(
84 alignof(U) <= alignof(::max_align_t),
85 "Overaligned types not supported");
86
87 return sizeof(any_impl<U>);
88 }
89
90 template<class T, class... Args>
91 auto
92 836 workspace::
93 emplace(Args&&... args) ->
94 typename std::decay<T>::type&
95 {
96 static_assert(
97 alignof(T) <= alignof(::max_align_t),
98 "Overaligned types not supported");
99
100 using U = any_impl<typename
101 std::decay<T>::type>;
102
103 836 undo u(*this);
104 836 auto prev_head = head_;
105
1/2
✓ Branch 1 taken 442 times.
✗ Branch 2 not taken.
836 head_ = bump_down(sizeof(U), alignof(U));
106
1/2
✓ Branch 2 taken 395 times.
✗ Branch 3 not taken.
836 auto p = ::new(head_) U(
107 836 std::forward<Args>(args)...);
108 836 u.commit();
109 836 p->next = reinterpret_cast<
110 any*>(prev_head);
111 836 return p->u;
112 836 }
113
114 template<class T>
115 T*
116 96 workspace::
117 push_array(
118 std::size_t n,
119 T const& t)
120 {
121 struct alignas(alignof(::max_align_t))
122 U : any
123 {
124 std::size_t n_ = 0;
125
126 96 U() = default;
127 192 ~U()
128 {
129 192 for(std::size_t i = n_;
130
2/2
✓ Branch 0 taken 686 times.
✓ Branch 1 taken 96 times.
1564 i-- > 0;)
131 1372 data()[i].~T();
132 384 }
133
134 96 U( std::size_t n,
135 T const& t)
136 96 : U()
137 {
138
2/2
✓ Branch 0 taken 686 times.
✓ Branch 1 taken 96 times.
782 while(n_ < n)
139 {
140 686 new(&data()[n_]) T(t);
141 686 ++n_;
142 }
143 96 }
144
145 1468 T* data() noexcept
146 {
147 return reinterpret_cast<
148 1468 T*>(this + 1);
149 }
150 };
151
152 96 undo u(*this);
153 96 auto prev_head = head_;
154 192 head_ = bump_down(
155
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 sizeof(U) + n * sizeof(T),
156 alignof(::max_align_t));
157 96 auto p = ::new(head_) U(n, t);
158 96 u.commit();
159 96 p->next = reinterpret_cast<
160 any*>(prev_head);
161 192 return p->data();
162 96 }
163
164 #if defined(BOOST_MSVC)
165 #pragma warning(pop) /* C4324 */
166 #endif
167
168 } // detail
169 } // http_proto
170 } // boost
171
172 #endif
173