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 1044 : 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 15816 : data() noexcept 104 : { 105 15816 : return front_; 106 : } 107 : 108 : /** Return the size of the unused area. 109 : */ 110 : std::size_t 111 3570 : size() const noexcept 112 : { 113 3570 : 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> 132 : typename std::decay<T>::type& 133 : push(T&& t); 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