mirror of
https://github.com/boostorg/beast.git
synced 2025-08-03 14:54:32 +02:00
allocator_traits::construct
is used for user-defined types:
It should only be called when constructing a user-provided type. Close #1332 Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@ Version 256:
|
||||
* Remove redundant template in service_base
|
||||
* Expand CI matrix using Azure Pipelines
|
||||
* Make chat websocket javascript client more user friendly
|
||||
* `allocator_traits::construct` is used for user-defined types
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@@ -19,7 +19,6 @@ namespace boost {
|
||||
namespace beast {
|
||||
|
||||
/** A buffer sequence representing a concatenation of buffer sequences.
|
||||
|
||||
@see buffers_cat
|
||||
*/
|
||||
template<class... Buffers>
|
||||
@@ -29,7 +28,6 @@ class buffers_cat_view
|
||||
|
||||
public:
|
||||
/** The type of buffer returned when dereferencing an iterator.
|
||||
|
||||
If every buffer sequence in the view is a <em>MutableBufferSequence</em>,
|
||||
then `value_type` will be `net::mutable_buffer`.
|
||||
Otherwise, `value_type` will be `net::const_buffer`.
|
||||
@@ -50,7 +48,6 @@ public:
|
||||
buffers_cat_view& operator=(buffers_cat_view const&) = default;
|
||||
|
||||
/** Constructor
|
||||
|
||||
@param buffers The list of buffer sequences to concatenate.
|
||||
Copies of the arguments will be maintained for the lifetime
|
||||
of the concatenated sequence; however, the ownership of the
|
||||
@@ -63,28 +60,24 @@ public:
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
/// Returns an iterator to one past the last buffer in the sequence
|
||||
/// Returns an iterator to one past the last buffer in the sequence
|
||||
const_iterator
|
||||
end() const;
|
||||
};
|
||||
|
||||
/** Concatenate 2 or more buffer sequences.
|
||||
|
||||
This function returns a constant or mutable buffer sequence which,
|
||||
when iterated, efficiently concatenates the input buffer sequences.
|
||||
Copies of the arguments passed will be made; however, the returned
|
||||
object does not take ownership of the underlying memory. The
|
||||
application is still responsible for managing the lifetime of the
|
||||
referenced memory.
|
||||
|
||||
@param buffers The list of buffer sequences to concatenate.
|
||||
|
||||
@return A new buffer sequence that represents the concatenation of
|
||||
the input buffer sequences. This buffer sequence will be a
|
||||
<em>MutableBufferSequence</em> if each of the passed buffer sequences is
|
||||
also a <em>MutableBufferSequence</em>; otherwise the returned buffer
|
||||
sequence will be a <em>ConstBufferSequence</em>.
|
||||
|
||||
@see buffers_cat_view
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
|
@@ -42,8 +42,9 @@ struct allocate_stable_state final
|
||||
allocate_stable_state>;
|
||||
|
||||
A a(this->get());
|
||||
detail::allocator_traits<A>::destroy(a, this);
|
||||
detail::allocator_traits<A>::deallocate(a, this, 1);
|
||||
auto* p = this;
|
||||
p->~allocate_stable_state();
|
||||
a.deallocate(p, 1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -118,33 +119,30 @@ allocate_stable(
|
||||
{
|
||||
using allocator_type = typename stable_async_base<
|
||||
Handler, Executor1, Allocator>::allocator_type;
|
||||
|
||||
using state = detail::allocate_stable_state<
|
||||
State, allocator_type>;
|
||||
using A = typename detail::allocator_traits<
|
||||
allocator_type>::template rebind_alloc<
|
||||
detail::allocate_stable_state<
|
||||
State, allocator_type>>;
|
||||
allocator_type>::template rebind_alloc<state>;
|
||||
|
||||
struct deleter
|
||||
{
|
||||
allocator_type alloc;
|
||||
detail::allocate_stable_state<
|
||||
State, allocator_type>* ptr;
|
||||
state* ptr;
|
||||
|
||||
~deleter()
|
||||
{
|
||||
if(ptr)
|
||||
{
|
||||
A a(alloc);
|
||||
detail::allocator_traits<A>::deallocate(a, ptr, 1);
|
||||
a.deallocate(ptr, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
A a(base.get_allocator());
|
||||
deleter d{base.get_allocator(), nullptr};
|
||||
d.ptr = detail::allocator_traits<A>::allocate(a, 1);
|
||||
detail::allocator_traits<A>::construct(a, d.ptr,
|
||||
d.alloc, std::forward<Args>(args)...);
|
||||
deleter d{base.get_allocator(), a.allocate(1)};
|
||||
::new(static_cast<void*>(d.ptr))
|
||||
state(d.alloc, std::forward<Args>(args)...);
|
||||
d.ptr->next_ = base.list_;
|
||||
base.list_ = d.ptr;
|
||||
return boost::exchange(d.ptr, nullptr)->value;
|
||||
|
@@ -302,6 +302,21 @@ public:
|
||||
buffers_cat(buffers_prefix(i, buffers), cb));
|
||||
}
|
||||
|
||||
void
|
||||
testSingleBuffer()
|
||||
{
|
||||
char c[1] = {};
|
||||
auto b = net::const_buffer(c, 1);
|
||||
auto bs = buffers_cat(net::const_buffer(c, 1));
|
||||
auto first = net::buffer_sequence_begin(bs);
|
||||
auto last = net::buffer_sequence_end(bs);
|
||||
BOOST_ASSERT(first != last);
|
||||
BEAST_EXPECT(std::distance(first, last) == 1);
|
||||
net::const_buffer b2(*first);
|
||||
BEAST_EXPECT(b.data() == b2.data());
|
||||
BEAST_EXPECT(b.size() == b2.size());
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testBufferSequence();
|
||||
@@ -309,6 +324,7 @@ public:
|
||||
testEmpty();
|
||||
testGccWarning1();
|
||||
testGccWarning2();
|
||||
testSingleBuffer();
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user