Line data Source code
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 : @code
32 : | front | free | acquired | back |
33 : @endcode
34 :
35 : @li The reserved area, which starts at the
36 : beginning of the buffer and can grow
37 : upwards towards the end of the buffer.
38 :
39 : @li The acquired area, which starts at the
40 : end of the buffer and can grow downwards
41 : towards the beginning of the buffer.
42 :
43 : @li The unused area, which starts from the
44 : end of the reserved area and stretches
45 : until the beginning of the acquired area.
46 : */
47 : class workspace
48 : {
49 : unsigned char* begin_ = nullptr;
50 : unsigned char* front_ = nullptr;
51 : unsigned char* head_ = nullptr;
52 : unsigned char* back_ = nullptr;
53 : unsigned char* end_ = nullptr;
54 :
55 : template<class>
56 : struct any_impl;
57 : struct any;
58 : struct undo;
59 :
60 : public:
61 : /** Return the number of aligned bytes required for T
62 : */
63 : template<class T>
64 : static
65 : constexpr
66 : std::size_t
67 : space_needed();
68 :
69 : /** Destructor.
70 : */
71 : ~workspace();
72 :
73 : /** Constructor.
74 :
75 : @param n The number of bytes of storage
76 : to allocate for the internal buffer.
77 : */
78 : explicit
79 : workspace(
80 : std::size_t n);
81 :
82 : /** Constructor.
83 : */
84 1047 : workspace() = default;
85 :
86 : /** Constructor.
87 : */
88 : workspace(workspace&&) noexcept;
89 :
90 : /** Allocate internal storage.
91 :
92 : @throws std::logic_error this->size() > 0
93 :
94 : @throws std::invalid_argument n == 0
95 : */
96 : void
97 : allocate(
98 : std::size_t n);
99 :
100 : /** Return a pointer to the unused area.
101 : */
102 : unsigned char*
103 64650 : data() noexcept
104 : {
105 64650 : return front_;
106 : }
107 :
108 : /** Return the size of the unused area.
109 : */
110 : std::size_t
111 32451 : size() const noexcept
112 : {
113 32451 : return head_ - front_;
114 : }
115 :
116 : /** Clear the contents while preserving capacity.
117 : */
118 : BOOST_HTTP_PROTO_DECL
119 : void
120 : clear() noexcept;
121 :
122 : /** Convert unused storage to reserved storage.
123 :
124 : @throws std::invalid_argument n >= this->size()
125 : */
126 : BOOST_HTTP_PROTO_DECL
127 : unsigned char*
128 : reserve_front(
129 : std::size_t n);
130 :
131 : template<class T, class... Args>
132 : typename std::decay<T>::type&
133 : emplace(Args&&... args);
134 :
135 : template<class T>
136 : T*
137 : push_array(
138 : std::size_t n,
139 : T const& t);
140 :
141 : BOOST_HTTP_PROTO_DECL
142 : unsigned char*
143 : reserve_back(
144 : std::size_t n);
145 :
146 : private:
147 : BOOST_HTTP_PROTO_DECL
148 : unsigned char*
149 : bump_down(
150 : std::size_t size,
151 : std::size_t align);
152 : };
153 :
154 : } // detail
155 : } // http_proto
156 : } // boost
157 :
158 : #include <boost/http_proto/detail/impl/workspace.hpp>
159 :
160 : #endif
|