2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_EXAMPLE_FIELDS_ALLOC_HPP
11 #define BOOST_BEAST_EXAMPLE_FIELDS_ALLOC_HPP
13 #include <boost/throw_exception.hpp>
23 std::size_t refs_ = 1;
24 std::size_t count_ = 0;
30 return reinterpret_cast<char*>(this+1) + size_;
34 static_pool(std::size_t size)
36 , p_(reinterpret_cast<char*>(this+1))
43 construct(std::size_t size)
45 auto p = new char[sizeof(static_pool) + size];
46 return *(new(p) static_pool{size});
62 delete[] reinterpret_cast<char*>(this);
70 BOOST_THROW_EXCEPTION(std::bad_alloc{});
82 p_ = reinterpret_cast<char*>(this+1);
88 /** A non-thread-safe allocator optimized for @ref basic_fields.
90 This allocator obtains memory from a pre-allocated memory block
91 of a given size. It does nothing in deallocate until all
92 previously allocated blocks are deallocated, upon which it
93 resets the internal memory block for re-use.
95 To use this allocator declare an instance persistent to the
96 connection or session, and construct with the block size.
97 A good rule of thumb is 20% more than the maximum allowed
98 header size. For example if the application only allows up
99 to an 8,000 byte header, the block size could be 9,600.
101 Then, for every instance of `message` construct the header
102 with a copy of the previously declared allocator instance.
107 detail::static_pool& pool_;
110 using value_type = T;
111 using is_always_equal = std::false_type;
113 using reference = T&;
114 using const_pointer = T const*;
115 using const_reference = T const&;
116 using size_type = std::size_t;
117 using difference_type = std::ptrdiff_t;
122 using other = fields_alloc<U>;
126 fields_alloc(std::size_t size)
127 : pool_(detail::static_pool::construct(size))
131 fields_alloc(fields_alloc const& other)
132 : pool_(other.pool_.share())
137 fields_alloc(fields_alloc<U> const& other)
138 : pool_(other.pool_.share())
148 allocate(size_type n)
150 return static_cast<value_type*>(
151 pool_.alloc(n * sizeof(T)));
155 deallocate(value_type*, size_type)
160 #if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
161 template<class U, class... Args>
163 construct(U* ptr, Args&&... args)
165 ::new((void*)ptr) U(std::forward<Args>(args)...);
180 fields_alloc const& lhs,
181 fields_alloc<U> const& rhs)
183 return &lhs.pool_ == &rhs.pool_;
190 fields_alloc const& lhs,
191 fields_alloc<U> const& rhs)
193 return ! (lhs == rhs);