Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2025 Mohammad Nejati
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/cppalliance/http_proto
9 : //
10 :
11 : #ifndef BOOST_HTTP_PROTO_DETAIL_WORKSPACE_HPP
12 : #define BOOST_HTTP_PROTO_DETAIL_WORKSPACE_HPP
13 :
14 : #include <boost/http_proto/detail/except.hpp>
15 : #include <boost/assert.hpp>
16 : #include <cstdlib>
17 : #include <new>
18 : #include <utility>
19 : #include <stddef.h> // ::max_align_t
20 :
21 : namespace boost {
22 : namespace http_proto {
23 : namespace detail {
24 :
25 : /** A contiguous buffer of storage used by algorithms.
26 :
27 : Objects of this type retain ownership of a
28 : contiguous buffer of storage allocated upon
29 : construction. This storage is divided into
30 : three regions:
31 :
32 : @code
33 : | front | free | acquired | back |
34 : @endcode
35 :
36 : @li The reserved area, which starts at the
37 : beginning of the buffer and can grow
38 : upwards towards the end of the buffer.
39 :
40 : @li The acquired area, which starts at the
41 : end of the buffer and can grow downwards
42 : towards the beginning of the buffer.
43 :
44 : @li The unused area, which starts from the
45 : end of the reserved area and stretches
46 : until the beginning of the acquired area.
47 : */
48 : class workspace
49 : {
50 : unsigned char* begin_ = nullptr;
51 : unsigned char* front_ = nullptr;
52 : unsigned char* head_ = nullptr;
53 : unsigned char* back_ = nullptr;
54 : unsigned char* end_ = nullptr;
55 :
56 : template<class>
57 : struct any_impl;
58 : struct any;
59 : struct undo;
60 :
61 : public:
62 : /** Return the number of aligned bytes required for T
63 : */
64 : template<class T>
65 : static
66 : constexpr
67 : std::size_t
68 : space_needed();
69 :
70 : /** Destructor.
71 : */
72 : ~workspace();
73 :
74 : /** Constructor.
75 :
76 : @param n The number of bytes of storage
77 : to allocate for the internal buffer.
78 : */
79 : explicit
80 : workspace(
81 : std::size_t n);
82 :
83 : /** Constructor.
84 : */
85 : workspace() = default;
86 :
87 : /** Constructor.
88 : */
89 : workspace(workspace&&) noexcept;
90 :
91 : /** Assignment.
92 : */
93 : workspace&
94 : operator=(workspace&&) noexcept;
95 :
96 : /** Allocate internal storage.
97 :
98 : @throw std::logic_error this->size() > 0
99 :
100 : @throw std::invalid_argument n == 0
101 : */
102 : void
103 : allocate(
104 : std::size_t n);
105 :
106 : /** Return a pointer to the unused area.
107 : */
108 : unsigned char*
109 62873 : data() noexcept
110 : {
111 62873 : return front_;
112 : }
113 :
114 : /** Return the size of the unused area.
115 : */
116 : std::size_t
117 39547 : size() const noexcept
118 : {
119 39547 : return head_ - front_;
120 : }
121 :
122 : /** Clear the contents while preserving capacity.
123 : */
124 : BOOST_HTTP_PROTO_DECL
125 : void
126 : clear() noexcept;
127 :
128 : /** Convert unused storage to reserved storage.
129 :
130 : @throw std::invalid_argument n >= this->size()
131 : */
132 : BOOST_HTTP_PROTO_DECL
133 : unsigned char*
134 : reserve_front(
135 : std::size_t n);
136 :
137 : /** Convert unused storage to reserved storage.
138 :
139 : @return nullptr if n >= this->size()
140 : */
141 : BOOST_HTTP_PROTO_DECL
142 : unsigned char*
143 : try_reserve_front(
144 : std::size_t n) noexcept;
145 :
146 : template<class T, class... Args>
147 : typename std::decay<T>::type&
148 : emplace(Args&&... args);
149 :
150 : template<class T>
151 : T*
152 : push_array(
153 : std::size_t n,
154 : T const& t);
155 :
156 : BOOST_HTTP_PROTO_DECL
157 : unsigned char*
158 : reserve_back(
159 : std::size_t n);
160 :
161 : private:
162 : BOOST_HTTP_PROTO_DECL
163 : unsigned char*
164 : bump_down(
165 : std::size_t size,
166 : std::size_t align);
167 : };
168 :
169 : } // detail
170 : } // http_proto
171 : } // boost
172 :
173 : #include <boost/http_proto/detail/impl/workspace.hpp>
174 :
175 : #endif
|