Tidy up tests and docs:

* Add handler_ptr test and increase coverage
* Add test for prepare_buffer
* Move is_call_possible tests to a .cpp file
* Tidy up docs and declarations
This commit is contained in:
Vinnie Falco
2017-02-06 10:56:37 -05:00
parent 7ef72b6ebc
commit 51aa614a10
19 changed files with 372 additions and 136 deletions

View File

@@ -1,5 +1,7 @@
1.0.0-b27 1.0.0-b27
* Tidy up tests and docs
API Changes: API Changes:
* Invoke callback on pings and pongs * Invoke callback on pings and pongs

View File

@@ -29,15 +29,16 @@
[def __asio_handler_invoke__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_invoke.html `asio_handler_invoke`]] [def __asio_handler_invoke__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_invoke.html `asio_handler_invoke`]]
[def __asio_handler_allocate__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_allocate.html `asio_handler_allocate`]] [def __asio_handler_allocate__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_allocate.html `asio_handler_allocate`]]
[def __void_or_deduced__ [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]] [def __void_or_deduced__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]]
[def __AsyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]] [def __AsyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]]
[def __AsyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]] [def __AsyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]]
[def __CompletionHandler__ [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]] [def __CompletionHandler__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]]
[def __ConstBufferSequence__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]] [def __ConstBufferSequence__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]]
[def __Handler__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/Handler.html [*Handler]]]
[def __MutableBufferSequence__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]] [def __MutableBufferSequence__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]]
[def __SyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]] [def __SyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]]
[def __SyncWriteStream__ [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]] [def __SyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]]
[def __Body__ [link beast.ref.Body [*`Body`]]] [def __Body__ [link beast.ref.Body [*`Body`]]]
[def __DynamicBuffer__ [link beast.ref.DynamicBuffer [*DynamicBuffer]]] [def __DynamicBuffer__ [link beast.ref.DynamicBuffer [*DynamicBuffer]]]

View File

@@ -1580,6 +1580,9 @@
<xsl:when test="declname = 'DynamicBuffer' or type = 'class DynamicBuffer'"> <xsl:when test="declname = 'DynamicBuffer' or type = 'class DynamicBuffer'">
<xsl:text>class ``[link beast.ref.DynamicBuffer [*DynamicBuffer]]``</xsl:text> <xsl:text>class ``[link beast.ref.DynamicBuffer [*DynamicBuffer]]``</xsl:text>
</xsl:when> </xsl:when>
<xsl:when test="declname = 'Handler' or type = 'class Handler'">
<xsl:text>class __Handler__</xsl:text>
</xsl:when>
<xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'"> <xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'">
<xsl:text>class __MutableBufferSequence__</xsl:text> <xsl:text>class __MutableBufferSequence__</xsl:text>
</xsl:when> </xsl:when>

View File

@@ -15,21 +15,23 @@
namespace beast { namespace beast {
/** Bind parameters to a completion handler, creating a wrapped handler. /** Bind parameters to a completion handler, creating a new handler.
This function creates a new handler which, when invoked with no This function creates a new handler which, when invoked with no
parameters, calls the original handler with the list of bound arguments. parameters, calls the original handler with the list of bound
The passed handler and arguments are forwarded into the returned handler, arguments. The passed handler and arguments are forwarded into
which provides the same `io_service` execution guarantees as the original the returned handler, which provides the same `io_service`
handler. execution guarantees as the original handler.
Unlike `io_service::wrap`, the returned handler can be used in a Unlike `io_service::wrap`, the returned handler can be used in
subsequent call to `io_service::post` instead of `io_service::dispatch`, a subsequent call to `io_service::post` instead of
to ensure that the handler will not be invoked immediately by the `io_service::dispatch`, to ensure that the handler will not be
calling function. invoked immediately by the calling function.
Example: Example:
@code @code
template<class AsyncReadStream, class ReadHandler> template<class AsyncReadStream, class ReadHandler>
void void
do_cancel(AsyncReadStream& stream, ReadHandler&& handler) do_cancel(AsyncReadStream& stream, ReadHandler&& handler)
@@ -38,6 +40,7 @@ namespace beast {
bind_handler(std::forward<ReadHandler>(handler), bind_handler(std::forward<ReadHandler>(handler),
boost::asio::error::operation_aborted, 0)); boost::asio::error::operation_aborted, 0));
} }
@endcode @endcode
@param handler The handler to wrap. @param handler The handler to wrap.
@@ -45,22 +48,21 @@ namespace beast {
@param args A list of arguments to bind to the handler. The @param args A list of arguments to bind to the handler. The
arguments are forwarded into the returned object. arguments are forwarded into the returned object.
*/ */
template<class CompletionHandler, class... Args> template<class Handler, class... Args>
#if GENERATING_DOCS #if GENERATING_DOCS
implementation_defined implementation_defined
#else #else
detail::bound_handler< detail::bound_handler<
typename std::decay<CompletionHandler>::type, Args...> typename std::decay<Handler>::type, Args...>
#endif #endif
bind_handler(CompletionHandler&& handler, Args&&... args) bind_handler(Handler&& handler, Args&&... args)
{ {
static_assert(is_CompletionHandler< static_assert(is_CompletionHandler<
CompletionHandler, void(Args...)>::value, Handler, void(Args...)>::value,
"CompletionHandler requirements not met"); "Handler requirements not met");
return detail::bound_handler<typename std::decay< return detail::bound_handler<typename std::decay<
CompletionHandler>::type, Args...>(std::forward< Handler>::type, Args...>(std::forward<
CompletionHandler>(handler), Handler>(handler), std::forward<Args>(args)...);
std::forward<Args>(args)...);
} }
} // beast } // beast

View File

@@ -24,8 +24,9 @@ namespace beast {
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 application object does not take ownership of the underlying memory. The
is still responsible for managing the lifetime of the referenced memory. application is still responsible for managing the lifetime of the
referenced memory.
@param buffers The list of buffer sequences to concatenate. @param buffers The list of buffer sequences to concatenate.

View File

@@ -30,12 +30,6 @@ namespace beast {
is still responsible for managing its lifetime. is still responsible for managing its lifetime.
@tparam BufferSequence The buffer sequence to wrap. @tparam BufferSequence The buffer sequence to wrap.
@tparam ValueType The type of buffer of the final buffer sequence. This
can be different from the buffer type of the wrapped sequence. For
example, a `MutableBufferSequence` can be transformed into a
consumable `ConstBufferSequence`. Violations of buffer const safety
are not permitted, and will result in a compile error.
*/ */
template<class BufferSequence> template<class BufferSequence>
class consuming_buffers class consuming_buffers
@@ -45,6 +39,7 @@ class consuming_buffers
BufferSequence bs_; BufferSequence bs_;
iter_type begin_; iter_type begin_;
iter_type end_;
std::size_t skip_ = 0; std::size_t skip_ = 0;
template<class Deduced> template<class Deduced>
@@ -56,13 +51,23 @@ class consuming_buffers
} }
public: public:
/// The type for each element in the list of buffers. /** The type for each element in the list of buffers.
If the buffers in the underlying sequence are convertible to
`boost::asio::mutable_buffer`, then this type will be
`boost::asio::mutable_buffer`, else this type will be
`boost::asio::const_buffer`.
*/
#if GENERATING_DOCS
using value_type = ...;
#else
using value_type = typename std::conditional< using value_type = typename std::conditional<
std::is_convertible<typename std::is_convertible<typename
std::iterator_traits<iter_type>::value_type, std::iterator_traits<iter_type>::value_type,
boost::asio::mutable_buffer>::value, boost::asio::mutable_buffer>::value,
boost::asio::mutable_buffer, boost::asio::mutable_buffer,
boost::asio::const_buffer>::type; boost::asio::const_buffer>::type;
#endif
#if GENERATING_DOCS #if GENERATING_DOCS
/// A bidirectional iterator type that may be used to read elements. /// A bidirectional iterator type that may be used to read elements.

View File

@@ -42,7 +42,8 @@ public:
template<class DeducedHandler> template<class DeducedHandler>
explicit explicit
bound_handler(DeducedHandler&& handler, Args&&... args) bound_handler(
DeducedHandler&& handler, Args&&... args)
: h_(std::forward<DeducedHandler>(handler)) : h_(std::forward<DeducedHandler>(handler))
, args_(std::forward<Args>(args)...) , args_(std::forward<Args>(args)...)
{ {
@@ -102,9 +103,11 @@ public:
} // beast } // beast
#include <functional> #include <functional>
namespace std { namespace std {
template<class Handler, class... Args> template<class Handler, class... Args>
void bind(beast::detail::bound_handler< void
bind(beast::detail::bound_handler<
Handler, Args...>, ...) = delete; Handler, Args...>, ...) = delete;
} // std } // std

View File

@@ -26,8 +26,12 @@ std::false_type
is_call_possible_test(C&& c, long, A&& ...a); is_call_possible_test(C&& c, long, A&& ...a);
/** Metafunction returns `true` if F callable as R(A...) /** Metafunction returns `true` if F callable as R(A...)
Example: Example:
@code
is_call_possible<T, void(std::string)> is_call_possible<T, void(std::string)>
@endcode
*/ */
/** @{ */ /** @{ */
template<class C, class F> template<class C, class F>
@@ -44,49 +48,6 @@ struct is_call_possible<C, R(A...)>
}; };
/** @} */ /** @} */
namespace test {
struct is_call_possible_udt1
{
void operator()(int) const;
};
struct is_call_possible_udt2
{
int operator()(int) const;
};
struct is_call_possible_udt3
{
int operator()(int);
};
#ifndef __INTELLISENSE__
// VFALCO Fails to compile with Intellisense
static_assert(is_call_possible<
is_call_possible_udt1, void(int)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt1, void(void)>::value, "");
static_assert(is_call_possible<
is_call_possible_udt2, int(int)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt2, int(void)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt2, void(void)>::value, "");
static_assert(is_call_possible<
is_call_possible_udt3, int(int)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt3 const, int(int)>::value, "");
#endif
} // test
} // detail } // detail
} // beast } // beast

View File

@@ -179,13 +179,7 @@ public:
return sb_; return sb_;
} }
/** Access the internal buffer. /// Access the internal buffer
The internal buffer is returned. It is possible for the
caller to break invariants with this function. For example,
by causing the internal buffer size to increase beyond
the caller defined maximum.
*/
DynamicBuffer const& DynamicBuffer const&
buffer() const buffer() const
{ {
@@ -213,8 +207,83 @@ public:
capacity_ = size; capacity_ = size;
} }
/// Write the given data to the stream. Returns the number of bytes written. /** Read some data from the stream.
/// Throws an exception on failure.
This function is used to read data from the stream.
The function call will block until one or more bytes of
data has been read successfully, or until an error occurs.
@param buffers One or more buffers into which the data will be read.
@return The number of bytes read.
@throws system_error Thrown on failure.
*/
template<class MutableBufferSequence>
std::size_t
read_some(MutableBufferSequence const& buffers);
/** Read some data from the stream.
This function is used to read data from the stream.
The function call will block until one or more bytes of
data has been read successfully, or until an error occurs.
@param buffers One or more buffers into which the data will be read.
@param ec Set to the error, if any occurred.
@return The number of bytes read, or 0 on error.
*/
template<class MutableBufferSequence>
std::size_t
read_some(MutableBufferSequence const& buffers,
error_code& ec);
/** Start an asynchronous read.
This function is used to asynchronously read data from
the stream. The function call always returns immediately.
@param buffers One or more buffers into which the data
will be read. Although the buffers object may be copied
as necessary, ownership of the underlying memory blocks
is retained by the caller, which must guarantee that they
remain valid until the handler is called.
@param handler The handler to be called when the operation
completes. Copies will be made of the handler as required.
The equivalent function signature of the handler must be:
@code void handler(
error_code const& error, // result of operation
std::size_t bytes_transferred // number of bytes transferred
); @endcode
Regardless of whether the asynchronous operation completes
immediately or not, the handler will not be invoked from within
this function. Invocation of the handler will be performed in a
manner equivalent to using `boost::asio::io_service::post`.
*/
template<class MutableBufferSequence, class ReadHandler>
#if GENERATING_DOCS
void_or_deduced
#else
typename async_completion<ReadHandler, void(error_code)>::result_type
#endif
async_read_some(MutableBufferSequence const& buffers,
ReadHandler&& handler);
/** Write some data to the stream.
This function is used to write data to the stream.
The function call will block until one or more bytes of the
data has been written successfully, or until an error occurs.
@param buffers One or more data buffers to be written to the stream.
@return The number of bytes written.
@throws system_error Thrown on failure.
*/
template<class ConstBufferSequence> template<class ConstBufferSequence>
std::size_t std::size_t
write_some(ConstBufferSequence const& buffers) write_some(ConstBufferSequence const& buffers)
@@ -224,8 +293,18 @@ public:
return next_layer_.write_some(buffers); return next_layer_.write_some(buffers);
} }
/// Write the given data to the stream. Returns the number of bytes written, /** Write some data to the stream.
/// or 0 if an error occurred.
This function is used to write data to the stream.
The function call will block until one or more bytes of the
data has been written successfully, or until an error occurs.
@param buffers One or more data buffers to be written to the stream.
@param ec Set to the error, if any occurred.
@return The number of bytes written.
*/
template<class ConstBufferSequence> template<class ConstBufferSequence>
std::size_t std::size_t
write_some(ConstBufferSequence const& buffers, write_some(ConstBufferSequence const& buffers,
@@ -236,8 +315,29 @@ public:
return next_layer_.write_some(buffers, ec); return next_layer_.write_some(buffers, ec);
} }
/// Start an asynchronous write. The data being written must be valid for the /** Start an asynchronous write.
/// lifetime of the asynchronous operation.
This function is used to asynchronously write data from
the stream. The function call always returns immediately.
@param buffers One or more data buffers to be written to
the stream. Although the buffers object may be copied as
necessary, ownership of the underlying memory blocks is
retained by the caller, which must guarantee that they
remain valid until the handler is called.
@param handler The handler to be called when the operation
completes. Copies will be made of the handler as required.
The equivalent function signature of the handler must be:
@code void handler(
error_code const& error, // result of operation
std::size_t bytes_transferred // number of bytes transferred
); @endcode
Regardless of whether the asynchronous operation completes
immediately or not, the handler will not be invoked from within
this function. Invocation of the handler will be performed in a
manner equivalent to using `boost::asio::io_service::post`.
*/
template<class ConstBufferSequence, class WriteHandler> template<class ConstBufferSequence, class WriteHandler>
#if GENERATING_DOCS #if GENERATING_DOCS
void_or_deduced void_or_deduced
@@ -246,30 +346,6 @@ public:
#endif #endif
async_write_some(ConstBufferSequence const& buffers, async_write_some(ConstBufferSequence const& buffers,
WriteHandler&& handler); WriteHandler&& handler);
/// Read some data from the stream. Returns the number of bytes read.
/// Throws an exception on failure.
template<class MutableBufferSequence>
std::size_t
read_some(MutableBufferSequence const& buffers);
/// Read some data from the stream. Returns the number of bytes read
/// or 0 if an error occurred.
template<class MutableBufferSequence>
std::size_t
read_some(MutableBufferSequence const& buffers,
error_code& ec);
/// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation.
template<class MutableBufferSequence, class ReadHandler>
#if GENERATING_DOCS
void_or_deduced
#else
typename async_completion<ReadHandler, void(error_code)>::result_type
#endif
async_read_some(MutableBufferSequence const& buffers,
ReadHandler&& handler);
}; };
} // beast } // beast

View File

@@ -28,28 +28,29 @@ namespace beast {
@tparam T The type of objects allocated by the allocator. @tparam T The type of objects allocated by the allocator.
@tparam CompletionHandler The type of handler. @tparam Handler The type of handler.
@note Memory allocated by this allocator must be freed before @note Memory allocated by this allocator must be freed before
the handler is invoked or undefined behavior results. the handler is invoked or undefined behavior results. This behavior
is described as the "deallocate before invocation" Asio guarantee.
*/ */
#if GENERATING_DOCS #if GENERATING_DOCS
template<class T, class CompletionHandler> template<class T, class Handler>
class handler_alloc; class handler_alloc;
#else #else
template<class T, class CompletionHandler> template<class T, class Handler>
class handler_alloc class handler_alloc
{ {
private: private:
// We want a partial template specialization as a friend // We want a partial template specialization as a friend
// but that isn't allowed so we friend all versions. This // but that isn't allowed so we friend all versions. This
// should produce a compile error if CompletionHandler is not // should produce a compile error if Handler is not
// constructible from H. // constructible from H.
// //
template<class U, class H> template<class U, class H>
friend class handler_alloc; friend class handler_alloc;
CompletionHandler& h_; Handler& h_;
public: public:
using value_type = T; using value_type = T;
@@ -58,7 +59,7 @@ public:
template<class U> template<class U>
struct rebind struct rebind
{ {
using other = handler_alloc<U, CompletionHandler>; using other = handler_alloc<U, Handler>;
}; };
handler_alloc() = delete; handler_alloc() = delete;
@@ -73,7 +74,7 @@ public:
remain valid for at least the lifetime of the allocator. remain valid for at least the lifetime of the allocator.
*/ */
explicit explicit
handler_alloc(CompletionHandler& h) handler_alloc(Handler& h)
: h_(h) : h_(h)
{ {
} }
@@ -81,7 +82,7 @@ public:
/// Copy constructor /// Copy constructor
template<class U> template<class U>
handler_alloc( handler_alloc(
handler_alloc<U, CompletionHandler> const& other) handler_alloc<U, Handler> const& other)
: h_(other.h_) : h_(other.h_)
{ {
} }
@@ -118,7 +119,7 @@ public:
friend friend
bool bool
operator==(handler_alloc const& lhs, operator==(handler_alloc const& lhs,
handler_alloc<U, CompletionHandler> const& rhs) handler_alloc<U, Handler> const& rhs)
{ {
return true; return true;
} }
@@ -127,7 +128,7 @@ public:
friend friend
bool bool
operator!=(handler_alloc const& lhs, operator!=(handler_alloc const& lhs,
handler_alloc<U, CompletionHandler> const& rhs) handler_alloc<U, Handler> const& rhs)
{ {
return ! (lhs == rhs); return ! (lhs == rhs);
} }

View File

@@ -21,9 +21,9 @@ static auto const bytes_transferred (std::placeholders::_2);
static auto const iterator (std::placeholders::_2); static auto const iterator (std::placeholders::_2);
static auto const signal_number (std::placeholders::_2); static auto const signal_number (std::placeholders::_2);
} }
} } // placeholders
} } // asio
} } // beast
#endif #endif

View File

@@ -28,6 +28,7 @@ unit-test core-tests :
core/handler_concepts.cpp core/handler_concepts.cpp
core/handler_ptr.cpp core/handler_ptr.cpp
core/placeholders.cpp core/placeholders.cpp
core/prepare_buffer.cpp
core/prepare_buffers.cpp core/prepare_buffers.cpp
core/static_streambuf.cpp core/static_streambuf.cpp
core/static_string.cpp core/static_string.cpp
@@ -38,6 +39,7 @@ unit-test core-tests :
core/base64.cpp core/base64.cpp
core/empty_base_optimization.cpp core/empty_base_optimization.cpp
core/get_lowest_layer.cpp core/get_lowest_layer.cpp
core/is_call_possible.cpp
core/sha1.cpp core/sha1.cpp
; ;

View File

@@ -22,6 +22,7 @@ add_executable (core-tests
handler_concepts.cpp handler_concepts.cpp
handler_ptr.cpp handler_ptr.cpp
placeholders.cpp placeholders.cpp
prepare_buffer.cpp
prepare_buffers.cpp prepare_buffers.cpp
static_streambuf.cpp static_streambuf.cpp
static_string.cpp static_string.cpp
@@ -32,6 +33,7 @@ add_executable (core-tests
base64.cpp base64.cpp
empty_base_optimization.cpp empty_base_optimization.cpp
get_lowest_layer.cpp get_lowest_layer.cpp
is_call_possible.cpp
sha1.cpp sha1.cpp
) )

View File

@@ -16,15 +16,17 @@ namespace beast {
class bind_handler_test : public unit_test::suite class bind_handler_test : public unit_test::suite
{ {
public: public:
static void foo (int) void
callback(int v)
{ {
BEAST_EXPECT(v == 42);
} }
void run() void run()
{ {
auto f (bind_handler ( auto f = bind_handler(std::bind(
std::bind (&foo, std::placeholders::_1), &bind_handler_test::callback, this,
42)); std::placeholders::_1), 42);
f(); f();
pass(); pass();
} }

View File

@@ -6,23 +6,44 @@
// //
// Test that header file is self-contained. // Test that header file is self-contained.
#include <beast/core/to_string.hpp> #include <beast/core/handler_alloc.hpp>
#include <beast/unit_test/suite.hpp> #include <beast/unit_test/suite.hpp>
#include <boost/asio/buffer.hpp> #include <vector>
namespace beast { namespace beast {
class to_string_test : public beast::unit_test::suite class handler_alloc_test : public beast::unit_test::suite
{ {
public: public:
void run() struct handler
{
void
operator()() const
{ {
BEAST_EXPECT(to_string(boost::asio::const_buffers_1("x", 1)) == "x");
} }
}; };
BEAST_DEFINE_TESTSUITE(to_string,core,beast); void
run() override
{
handler h;
handler h2;
handler_alloc<char, handler> a1{h};
handler_alloc<char, handler> a2{h2};
BEAST_EXPECT(a2 == a1);
auto a3 = a1;
BEAST_EXPECT(a3 == a1);
{
std::vector<char,
handler_alloc<char, handler>> v(a1);
v.reserve(32);
v.resize(10);
}
}
};
BEAST_DEFINE_TESTSUITE(handler_alloc,core,beast);
} // beast } // beast

View File

@@ -7,3 +7,74 @@
// Test that header file is self-contained. // Test that header file is self-contained.
#include <beast/core/handler_ptr.hpp> #include <beast/core/handler_ptr.hpp>
#include <beast/unit_test/suite.hpp>
#include <exception>
#include <utility>
namespace beast {
class handler_ptr_test : public beast::unit_test::suite
{
public:
struct handler
{
handler() = default;
handler(handler const&) = default;
void
operator()(bool& b) const
{
b = true;
}
};
struct T
{
T(handler&)
{
}
~T()
{
}
};
struct U
{
U(handler&)
{
throw std::exception{};
}
};
void
run() override
{
handler h;
handler_ptr<T, handler> p1{h};
handler_ptr<T, handler> p2{p1};
try
{
handler_ptr<U, handler> p3{h};
fail();
}
catch(std::exception const&)
{
pass();
}
catch(...)
{
fail();
}
handler_ptr<T, handler> p4{std::move(h)};
bool b = false;
p4.invoke(std::ref(b));
BEAST_EXPECT(b);
}
};
BEAST_DEFINE_TESTSUITE(handler_ptr,core,beast);
} // beast

View File

@@ -0,0 +1,56 @@
//
// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Test that header file is self-contained.
#include <beast/core/detail/is_call_possible.hpp>
namespace beast {
namespace detail {
namespace {
struct is_call_possible_udt1
{
void operator()(int) const;
};
struct is_call_possible_udt2
{
int operator()(int) const;
};
struct is_call_possible_udt3
{
int operator()(int);
};
#ifndef __INTELLISENSE__
// VFALCO Fails to compile with Intellisense
static_assert(is_call_possible<
is_call_possible_udt1, void(int)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt1, void(void)>::value, "");
static_assert(is_call_possible<
is_call_possible_udt2, int(int)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt2, int(void)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt2, void(void)>::value, "");
static_assert(is_call_possible<
is_call_possible_udt3, int(int)>::value, "");
static_assert(! is_call_possible<
is_call_possible_udt3 const, int(int)>::value, "");
#endif
}
} // detail
} // beast

View File

@@ -0,0 +1,9 @@
//
// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Test that header file is self-contained.
#include <beast/core/prepare_buffer.hpp>

View File

@@ -8,3 +8,21 @@
// Test that header file is self-contained. // Test that header file is self-contained.
#include <beast/core/to_string.hpp> #include <beast/core/to_string.hpp>
#include <beast/unit_test/suite.hpp>
#include <boost/asio/buffer.hpp>
namespace beast {
class to_string_test : public beast::unit_test::suite
{
public:
void run()
{
BEAST_EXPECT(to_string(boost::asio::const_buffers_1("x", 1)) == "x");
}
};
BEAST_DEFINE_TESTSUITE(to_string,core,beast);
} // beast