Tidy up basic_fields exception specifiers

fix #894

Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
Damian Jarek
2017-11-18 19:50:57 +01:00
committed by Vinnie Falco
parent 7ac24d77be
commit 190d20e3a8
4 changed files with 83 additions and 22 deletions

View File

@@ -3,6 +3,10 @@ Version 147:
* Don't use boost::string_ref
* Use iterator wrapper in detail::buffers_range
HTTP:
* Tidy up basic_fields exception specifiers
WebSocket:
* control callback is copied or moved

View File

@@ -188,6 +188,19 @@ private:
boost::intrusive::constant_time_size<true>,
boost::intrusive::compare<key_compare>>::type;
using align_type = typename
boost::type_with_alignment<alignof(value_type)>::type;
using rebind_type = typename
beast::detail::allocator_traits<Allocator>::
template rebind_alloc<align_type>;
using alloc_traits =
beast::detail::allocator_traits<rebind_type>;
using size_type = typename
beast::detail::allocator_traits<Allocator>::size_type;
public:
/// Destructor
@@ -201,14 +214,14 @@ public:
@param alloc The allocator to use.
*/
explicit
basic_fields(Allocator const& alloc);
basic_fields(Allocator const& alloc) noexcept;
/** Move constructor.
The state of the moved-from object is
as if constructed using the same allocator.
*/
basic_fields(basic_fields&&);
basic_fields(basic_fields&&) noexcept;
/** Move constructor.
@@ -245,7 +258,8 @@ public:
The state of the moved-from object is
as if constructed using the same allocator.
*/
basic_fields& operator=(basic_fields&&);
basic_fields& operator=(basic_fields&&) noexcept(
alloc_traits::propagate_on_container_move_assignment::value);
/// Copy assignment.
basic_fields& operator=(basic_fields const&);
@@ -690,19 +704,6 @@ private:
template<class OtherAlloc>
friend class basic_fields;
using align_type = typename
boost::type_with_alignment<alignof(value_type)>::type;
using rebind_type = typename
beast::detail::allocator_traits<Allocator>::
template rebind_alloc<align_type>;
using alloc_traits =
beast::detail::allocator_traits<rebind_type>;
using size_type = typename
beast::detail::allocator_traits<Allocator>::size_type;
value_type&
new_element(field name,
string_view sname, string_view value);

View File

@@ -349,14 +349,14 @@ basic_fields<Allocator>::
template<class Allocator>
basic_fields<Allocator>::
basic_fields(Allocator const& alloc)
basic_fields(Allocator const& alloc) noexcept
: beast::detail::empty_base_optimization<Allocator>(alloc)
{
}
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields&& other)
basic_fields(basic_fields&& other) noexcept
: beast::detail::empty_base_optimization<Allocator>(
std::move(other.member()))
, set_(std::move(other.set_))
@@ -426,9 +426,12 @@ basic_fields(basic_fields<OtherAlloc> const& other,
template<class Allocator>
auto
basic_fields<Allocator>::
operator=(basic_fields&& other) ->
basic_fields&
operator=(basic_fields&& other) noexcept(
alloc_traits::propagate_on_container_move_assignment::value)
-> basic_fields&
{
static_assert(is_nothrow_move_assignable<Allocator>::value,
"Allocator must be noexcept assignable.");
if(this == &other)
return *this;
move_assign(other, std::integral_constant<bool,

View File

@@ -21,11 +21,64 @@ namespace boost {
namespace beast {
namespace http {
BOOST_STATIC_ASSERT(is_fields<fields>::value);
class fields_test : public beast::unit_test::suite
{
public:
template <class T>
class test_allocator
{
public:
using value_type = T;
test_allocator() noexcept(false) {}
template <typename U, typename = typename std::enable_if<!std::is_same<test_allocator, U>::value>::type>
test_allocator(test_allocator<U> const&) noexcept {}
value_type*
allocate(std::size_t n)
{
return static_cast<value_type*>(::operator new (n*sizeof(value_type)));
}
void
deallocate(value_type* p, std::size_t) noexcept
{
::operator delete(p);
}
template <class U>
friend
bool
operator==(test_allocator<T> const&, test_allocator<U> const&) noexcept
{
return true;
}
template <class U>
friend
bool
operator!=(test_allocator<T> const& x, test_allocator<U> const& y) noexcept
{
return !(x == y);
}
};
using test_fields = basic_fields<test_allocator<char>>;
BOOST_STATIC_ASSERT(is_fields<fields>::value);
BOOST_STATIC_ASSERT(is_fields<test_fields>::value);
// std::allocator is noexcept movable, fields should satisfy
// these constraints as well.
BOOST_STATIC_ASSERT(std::is_nothrow_move_constructible<fields>::value);
BOOST_STATIC_ASSERT(std::is_nothrow_move_assignable<fields>::value);
// Check if basic_fields respects throw-constructibility and
// propagate_on_container_move_assignment of the allocator.
BOOST_STATIC_ASSERT(std::is_nothrow_move_constructible<test_fields>::value);
BOOST_STATIC_ASSERT(!std::is_nothrow_move_assignable<test_fields>::value);
template<class Allocator>
using fa_t = basic_fields<Allocator>;