GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/detail/impl/workspace.hpp
Date: 2023-12-22 17:54:30
Exec Total Coverage
Lines: 47 48 97.9%
Functions: 25 25 100.0%
Branches: 7 10 70.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_HPP
11 #define BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_HPP
12
13 namespace boost {
14 namespace http_proto {
15 namespace detail {
16
17 672 struct workspace::any
18 {
19 any* next = nullptr;
20
21 BOOST_HTTP_PROTO_DECL
22 virtual ~any() = 0;
23 };
24
25 template<class U>
26 struct alignas(alignof(::max_align_t))
27 workspace::any_impl : any
28 {
29 U u;
30
31 any_impl() = delete;
32 any_impl(any_impl&&) = default;
33
34 template<class U_>
35 624 explicit any_impl(U_&& u_)
36 624 : u(std::move(u_))
37 {
38 624 }
39 };
40
41 struct workspace::undo
42 {
43 explicit
44 336 undo(workspace& ws0) noexcept
45 336 : ws_(ws0)
46 336 , head_(ws0.head_)
47 {
48 336 }
49
50 336 ~undo()
51 336 {
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
336 if(head_)
53 ws_.head_ = head_;
54 336 }
55
56 void
57 336 commit() noexcept
58 {
59 336 head_ = nullptr;
60 336 }
61
62 private:
63 workspace& ws_;
64 unsigned char* head_;
65 };
66
67 template<class T>
68 constexpr
69 std::size_t
70 workspace::
71 space_needed()
72 {
73 using U = typename std::decay<T>::type;
74
75 static_assert(
76 alignof(U) <= alignof(::max_align_t),
77 "Overaligned types not supported");
78
79 return sizeof(any_impl<U>);
80 }
81
82 template<class T>
83 auto
84 325 workspace::
85 push(T&& t) ->
86 typename std::decay<T>::type&
87 {
88 static_assert(
89 alignof(T) <= alignof(::max_align_t),
90 "Overaligned types not supported");
91
92 using U = any_impl<typename
93 std::decay<T>::type>;
94
95 325 undo u(*this);
96
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
325 auto p = ::new(bump_down(
97 sizeof(U), alignof(U))) U(
98 325 std::forward<T>(t));
99 325 u.commit();
100 325 p->next = reinterpret_cast<
101 325 any*>(head_);
102 325 head_ = reinterpret_cast<
103 unsigned char*>(p);
104 650 return p->u;
105 }
106
107 template<class T>
108 T*
109 24 workspace::
110 push_array(
111 std::size_t n,
112 T const& t)
113 {
114 struct alignas(alignof(::max_align_t))
115 24 U : any
116 {
117 std::size_t n_ = 0;
118
119 U() = default;
120 48 ~U()
121 {
122 140 for(std::size_t i = n_;
123
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 24 times.
140 i-- > 0;)
124 92 data()[i].~T();
125 96 }
126
127 24 U( std::size_t n,
128 T const& t)
129 24 : U()
130 {
131
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 24 times.
70 while(n_ < n)
132 {
133 46 new(&data()[n_]) T(t);
134 46 ++n_;
135 }
136 24 }
137
138 116 T* data() noexcept
139 {
140 return reinterpret_cast<
141 116 T*>(this + 1);
142 }
143 };
144
145 48 undo u(*this);
146 24 auto p = ::new(bump_down(
147
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 sizeof(U) + n * sizeof(T),
148 alignof(::max_align_t))) U(n, t);
149 24 u.commit();
150 24 p->next = reinterpret_cast<
151 24 any*>(head_);
152 24 head_ = reinterpret_cast<
153 unsigned char*>(p);
154 48 return p->data();
155 }
156
157 } // detail
158 } // http_proto
159 } // boost
160
161 #endif
162