Optimize for size on buffers_cat preconditions:

When BOOST_BEAST_TESTS is not defined, violations of
buffers_cat preconditions will assert instead of throwing
exceptions. This reduces the size of the emitted code
and improves performance.
This commit is contained in:
Vinnie Falco
2018-12-15 12:51:34 -08:00
parent fa14af2696
commit 9d27f2659f
6 changed files with 63 additions and 31 deletions

View File

@@ -10,6 +10,7 @@ Version 200
* Add const and mutable buffer sequence traits * Add const and mutable buffer sequence traits
* Add buffers_iterator_type trait * Add buffers_iterator_type trait
* Use new buffer traits, remove old unused traits * Use new buffer traits, remove old unused traits
* Optimize for size on buffers_cat preconditions
API Changes: API Changes:

View File

@@ -14,7 +14,6 @@
#include <boost/beast/core/detail/type_traits.hpp> #include <boost/beast/core/detail/type_traits.hpp>
#include <boost/beast/core/detail/variant.hpp> #include <boost/beast/core/detail/variant.hpp>
#include <boost/asio/buffer.hpp> #include <boost/asio/buffer.hpp>
#include <boost/throw_exception.hpp>
#include <cstdint> #include <cstdint>
#include <iterator> #include <iterator>
#include <new> #include <new>
@@ -24,6 +23,45 @@
namespace boost { namespace boost {
namespace beast { namespace beast {
#if defined(_MSC_VER) && ! defined(__clang__)
# define BOOST_BEAST_UNREACHABLE() __assume(false)
# define BOOST_BEAST_UNREACHABLE_RETURN(v) __assume(false)
#else
# define BOOST_BEAST_UNREACHABLE() __builtin_unreachable()
# define BOOST_BEAST_UNREACHABLE_RETURN(v) \
do { __builtin_unreachable(); return v; } while(false)
#endif
#ifdef BOOST_BEAST_TESTS
#define BOOST_BEAST_LOGIC_ERROR(s) \
do { \
BOOST_THROW_EXCEPTION(std::logic_error((s))); \
BOOST_BEAST_UNREACHABLE(); \
} while(false)
#define BOOST_BEAST_LOGIC_ERROR_RETURN(v, s) \
do { \
BOOST_THROW_EXCEPTION(std::logic_error(s)); \
BOOST_BEAST_UNREACHABLE_RETURN(v); \
} while(false)
#else
#define BOOST_BEAST_LOGIC_ERROR(s) \
do { \
BOOST_ASSERT_MSG(false, s); \
BOOST_BEAST_UNREACHABLE(); \
} while(false)
#define BOOST_BEAST_LOGIC_ERROR_RETURN(v, s) \
do { \
BOOST_ASSERT_MSG(false, (s)); \
BOOST_BEAST_UNREACHABLE_RETURN(v); \
} while(false)
#endif
namespace detail { namespace detail {
struct buffers_cat_view_iterator_base struct buffers_cat_view_iterator_base
@@ -35,9 +73,8 @@ struct buffers_cat_view_iterator_base
net::mutable_buffer net::mutable_buffer
operator*() const operator*() const
{ {
// Dereferencing a one-past-the-end iterator BOOST_BEAST_LOGIC_ERROR_RETURN({},
BOOST_THROW_EXCEPTION(std::logic_error{ "Dereferencing a one-past-the-end iterator");
"invalid iterator"});
} }
operator bool() const noexcept operator bool() const noexcept
@@ -115,13 +152,11 @@ private:
{ {
const_iterator const& self; const_iterator const& self;
[[noreturn]]
reference reference
operator()(mp11::mp_size_t<0>) operator()(mp11::mp_size_t<0>)
{ {
// Dereferencing a default-constructed iterator BOOST_BEAST_LOGIC_ERROR_RETURN({},
BOOST_THROW_EXCEPTION(std::logic_error{ "Dereferencing a default-constructed iterator");
"invalid iterator"});
} }
template<class I> template<class I>
@@ -135,13 +170,11 @@ private:
{ {
const_iterator& self; const_iterator& self;
[[noreturn]]
void void
operator()(mp11::mp_size_t<0>) operator()(mp11::mp_size_t<0>)
{ {
// Incrementing a default-constructed iterator BOOST_BEAST_LOGIC_ERROR(
BOOST_THROW_EXCEPTION(std::logic_error{ "Incrementing a default-constructed iterator");
"invalid iterator"});
} }
template<std::size_t I> template<std::size_t I>
@@ -198,13 +231,11 @@ private:
self.it_.template emplace<I+1>(); self.it_.template emplace<I+1>();
} }
[[noreturn]]
void void
operator()(mp11::mp_size_t<sizeof...(Bn)+1>) operator()(mp11::mp_size_t<sizeof...(Bn)+1>)
{ {
// Incrementing a one-past-the-end iterator BOOST_BEAST_LOGIC_ERROR(
BOOST_THROW_EXCEPTION(std::logic_error{ "Incrementing a one-past-the-end iterator");
"invalid iterator"});
} }
}; };
@@ -212,13 +243,11 @@ private:
{ {
const_iterator& self; const_iterator& self;
[[noreturn]]
void void
operator()(mp11::mp_size_t<0>) operator()(mp11::mp_size_t<0>)
{ {
// Decrementing a default-constructed iterator BOOST_BEAST_LOGIC_ERROR(
BOOST_THROW_EXCEPTION(std::logic_error{ "Decrementing a default-constructed iterator");
"invalid iterator"});
} }
void void
@@ -232,9 +261,8 @@ private:
if(it == net::buffer_sequence_begin( if(it == net::buffer_sequence_begin(
detail::get<I-1>(*self.bn_))) detail::get<I-1>(*self.bn_)))
{ {
// Decrementing an iterator to the beginning BOOST_BEAST_LOGIC_ERROR(
BOOST_THROW_EXCEPTION(std::logic_error{ "Decrementing an iterator to the beginning");
"invalid iterator"});
} }
--it; --it;
if(net::const_buffer(*it).size() > 0) if(net::const_buffer(*it).size() > 0)

View File

@@ -22,6 +22,7 @@ project /boost/beast/test
] ]
<include>./extern <include>./extern
<define>BOOST_BEAST_ALLOW_DEPRECATED <define>BOOST_BEAST_ALLOW_DEPRECATED
<define>BOOST_BEAST_TESTS
<define>BOOST_ASIO_SEPARATE_COMPILATION <define>BOOST_ASIO_SEPARATE_COMPILATION
; ;

View File

@@ -8,6 +8,8 @@
# #
add_definitions (-DBOOST_BEAST_ALLOW_DEPRECATED) add_definitions (-DBOOST_BEAST_ALLOW_DEPRECATED)
add_definitions (-DBOOST_BEAST_TESTS)
add_subdirectory (core) add_subdirectory (core)
add_subdirectory (experimental) add_subdirectory (experimental)

View File

@@ -14,18 +14,18 @@ alias run-tests :
[ compile websocket.cpp ] [ compile websocket.cpp ]
[ compile zlib.cpp ] [ compile zlib.cpp ]
core//run-tests core//run-tests
experimental//run-tests
http//run-tests http//run-tests
websocket//run-tests websocket//run-tests
zlib//run-tests zlib//run-tests
experimental//run-tests
; ;
alias fat-tests : alias fat-tests :
core//fat-tests core//fat-tests
experimental//fat-tests
http//fat-tests http//fat-tests
websocket//fat-tests websocket//fat-tests
zlib//fat-tests zlib//fat-tests
experimental//fat-tests
; ;
explicit fat-tests ; explicit fat-tests ;

View File

@@ -119,26 +119,27 @@ public:
net::const_buffer b3{" world!", 7}; net::const_buffer b3{" world!", 7};
auto const b = beast::buffers_cat(b1, b2, b3); auto const b = beast::buffers_cat(b1, b2, b3);
using type = decltype(b);
// Dereferencing a default-constructed iterator // Dereferencing a default-constructed iterator
checkException( checkException(
[] []
{ {
*(decltype(b)::const_iterator{}); *(type::const_iterator{});
}); });
// Incrementing a default-constructed iterator // Incrementing a default-constructed iterator
checkException( checkException(
[] []
{ {
++(decltype(b)::const_iterator{}); ++(type::const_iterator{});
}); });
// Decrementing a default-constructed iterator // Decrementing a default-constructed iterator
checkException( checkException(
[] []
{ {
--(decltype(b)::const_iterator{}); --(type::const_iterator{});
}); });
// Decrementing an iterator to the beginning // Decrementing an iterator to the beginning
@@ -270,11 +271,10 @@ public:
net::const_buffer{"lo", 2}, net::const_buffer{"lo", 2},
e1, e1,
net::const_buffer{", ", 2} }}; net::const_buffer{", ", 2} }};
auto b3 = std::array<net::const_buffer, 3>{ auto b3 = std::array<net::const_buffer, 3>{{
net::const_buffer{"w", 1}, net::const_buffer{"w", 1},
net::const_buffer{"orld!", 5}, net::const_buffer{"orld!", 5},
e1 e1 }};
};
{ {
auto const b = beast::buffers_cat( auto const b = beast::buffers_cat(
e2, b1, e2, b2, e2, b3, e2); e2, b1, e2, b2, e2, b3, e2);