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