mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Remove unused and obsolete classes and tidy up:
Many classes required to support type-erasure of handlers and boost::asio types are now obsolete, so these classes and files are removed: HTTPClientType, FixedInputBuffer, PeerRole, socket_wrapper, client_session, basic_url, abstract_socket, buffer_sequence, memory_buffer, enable_wait_for_async, shared_handler, wrap_handler, streambuf, ContentBodyBuffer, SSLContext, completion-handler based handshake detectors. These structural changes are made: * Some missing includes added to headers * asio module directory flattened
This commit is contained in:
@@ -22,11 +22,5 @@
|
||||
#endif
|
||||
|
||||
#include <beast/asio/impl/IPAddressConversion.cpp>
|
||||
|
||||
#include <beast/asio/tests/wrap_handler.test.cpp>
|
||||
#include <beast/asio/tests/bind_handler.test.cpp>
|
||||
#include <beast/asio/tests/enable_wait_for_async.test.cpp>
|
||||
#include <beast/asio/tests/shared_handler.test.cpp>
|
||||
|
||||
#include <beast/asio/abstract_socket.cpp> // TEMPORARY!
|
||||
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/asio/abstract_socket.h>
|
||||
#include <beast/asio/bind_handler.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
#if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void* abstract_socket::this_layer_ptr (char const*) const
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool abstract_socket::native_handle (char const*, void*)
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
boost::asio::io_service& abstract_socket::get_io_service ()
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void*
|
||||
abstract_socket::lowest_layer_ptr (char const*) const
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::cancel (boost::system::error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::shutdown (shutdown_type, boost::system::error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::close (boost::system::error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
auto
|
||||
abstract_socket::accept (abstract_socket&, error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_accept (abstract_socket&, error_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::size_t
|
||||
abstract_socket::read_some (mutable_buffers, error_code& ec)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
abstract_socket::write_some (const_buffers, error_code& ec)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_read_some (mutable_buffers, transfer_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_write_some (const_buffers, transfer_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void*
|
||||
abstract_socket::next_layer_ptr (char const*) const
|
||||
{
|
||||
pure_virtual_called ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
abstract_socket::needs_handshake ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::set_verify_mode (int)
|
||||
{
|
||||
pure_virtual_called ();
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::handshake (handshake_type, error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_handshake (handshake_type, error_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::handshake (handshake_type, const_buffers, error_code& ec) ->
|
||||
error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_handshake (handshake_type, const_buffers,
|
||||
transfer_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
auto
|
||||
abstract_socket::shutdown (error_code& ec) -> error_code
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
void
|
||||
abstract_socket::async_shutdown (error_handler handler)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,404 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED
|
||||
#define BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED
|
||||
|
||||
#include <beast/asio/buffer_sequence.h>
|
||||
#include <beast/asio/shared_handler.h>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/socket_base.hpp>
|
||||
#include <boost/asio/ssl/stream_base.hpp>
|
||||
|
||||
// Checking overrides replaces unimplemented stubs with pure virtuals
|
||||
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
# define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
|
||||
#endif
|
||||
|
||||
#if BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
# define BEAST_SOCKET_VIRTUAL = 0
|
||||
#else
|
||||
# define BEAST_SOCKET_VIRTUAL
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** A high level socket abstraction.
|
||||
|
||||
This combines the capabilities of multiple socket interfaces such
|
||||
as listening, connecting, streaming, and handshaking. It brings
|
||||
everything together into a single abstract interface.
|
||||
|
||||
When member functions are called and the underlying implementation does
|
||||
not support the operation, a fatal error is generated.
|
||||
*/
|
||||
class abstract_socket
|
||||
: public boost::asio::ssl::stream_base
|
||||
, public boost::asio::socket_base
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
typedef asio::shared_handler <void (void)> post_handler;
|
||||
|
||||
typedef asio::shared_handler <void (error_code)> error_handler;
|
||||
|
||||
typedef asio::shared_handler <
|
||||
void (error_code, std::size_t)> transfer_handler;
|
||||
|
||||
static
|
||||
void
|
||||
pure_virtual_called()
|
||||
{
|
||||
throw std::runtime_error ("pure virtual called");
|
||||
}
|
||||
|
||||
static
|
||||
error_code
|
||||
pure_virtual_error ()
|
||||
{
|
||||
pure_virtual_called();
|
||||
return boost::system::errc::make_error_code (
|
||||
boost::system::errc::function_not_supported);
|
||||
}
|
||||
|
||||
static
|
||||
error_code
|
||||
pure_virtual_error (error_code& ec)
|
||||
{
|
||||
return ec = pure_virtual_error();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
throw_if (error_code const& ec)
|
||||
{
|
||||
if (ec)
|
||||
throw boost::system::system_error (ec);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~abstract_socket ()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// abstract_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the underlying object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& this_layer ()
|
||||
{
|
||||
Object* object (this->this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& this_layer () const
|
||||
{
|
||||
Object const* object (this->this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* this_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->this_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* this_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->this_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* this_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the native representation of the object.
|
||||
|
||||
Since we dont know the return type, and because almost every
|
||||
asio implementation passes the result by value, you need to provide
|
||||
a pointer to a default-constructed object of the matching type.
|
||||
|
||||
@note If the type doesn't match, an exception is thrown.
|
||||
*/
|
||||
template <typename Handle>
|
||||
void native_handle (Handle* dest)
|
||||
{
|
||||
if (! native_handle (typeid (Handle).name (), dest))
|
||||
throw std::bad_cast ();
|
||||
}
|
||||
|
||||
virtual bool native_handle (char const* type_name, void* dest)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual boost::asio::io_service& get_io_service ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the lowest layer object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& lowest_layer ()
|
||||
{
|
||||
Object* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& lowest_layer () const
|
||||
{
|
||||
Object const* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* lowest_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->lowest_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* lowest_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->lowest_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* lowest_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void cancel ()
|
||||
{
|
||||
error_code ec;
|
||||
cancel (ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code cancel (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void shutdown (shutdown_type what)
|
||||
{
|
||||
error_code ec;
|
||||
shutdown (what, ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code shutdown (shutdown_type what,
|
||||
error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void close ()
|
||||
{
|
||||
error_code ec;
|
||||
close (ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code close (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual error_code accept (abstract_socket& peer, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_accept (abstract_socket& peer, error_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual std::size_t read_some (mutable_buffers buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual std::size_t write_some (const_buffers buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_read_some (mutable_buffers buffers,
|
||||
transfer_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_write_some (const_buffers buffers,
|
||||
transfer_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the next layer object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& next_layer ()
|
||||
{
|
||||
Object* object (this->next_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& next_layer () const
|
||||
{
|
||||
Object const* object (this->next_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
throw std::bad_cast ();
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* next_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->next_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* next_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->next_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* next_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
/** Determines if the underlying stream requires a handshake.
|
||||
|
||||
If needs_handshake is true, it will be necessary to call handshake or
|
||||
async_handshake after the connection is established. Furthermore it
|
||||
will be necessary to call the shutdown member from the
|
||||
HandshakeInterface to close the connection. Do not close the underlying
|
||||
socket or else the closure will not be graceful. Only one side should
|
||||
initiate the handshaking shutdon. The other side should observe it.
|
||||
Which side does what is up to the user.
|
||||
|
||||
The default version returns false.
|
||||
*/
|
||||
virtual bool needs_handshake ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void set_verify_mode (int verify_mode)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void handshake (handshake_type type)
|
||||
{
|
||||
error_code ec;
|
||||
handshake (type, ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code handshake (handshake_type type, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_handshake (handshake_type type, error_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual error_code handshake (handshake_type type,
|
||||
const_buffers buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_handshake (handshake_type type,
|
||||
const_buffers buffers, transfer_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void shutdown ()
|
||||
{
|
||||
error_code ec;
|
||||
shutdown (ec);
|
||||
throw_if (ec);
|
||||
}
|
||||
|
||||
virtual error_code shutdown (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
virtual void async_shutdown (error_handler handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,126 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_BUFFER_SEQUENCE_H_INCLUDED
|
||||
#define BEAST_ASIO_BUFFER_SEQUENCE_H_INCLUDED
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <class Buffer>
|
||||
class buffer_sequence
|
||||
{
|
||||
private:
|
||||
typedef std::vector <Buffer> sequence_type;
|
||||
|
||||
public:
|
||||
typedef Buffer value_type;
|
||||
typedef typename sequence_type::const_iterator const_iterator;
|
||||
|
||||
private:
|
||||
sequence_type m_buffers;
|
||||
|
||||
template <class FwdIter>
|
||||
void assign (FwdIter first, FwdIter last)
|
||||
{
|
||||
m_buffers.clear();
|
||||
m_buffers.reserve (std::distance (first, last));
|
||||
for (;first != last; ++first)
|
||||
m_buffers.push_back (*first);
|
||||
}
|
||||
|
||||
public:
|
||||
buffer_sequence ()
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
class BufferSequence,
|
||||
class = std::enable_if_t <std::is_constructible <
|
||||
Buffer, typename BufferSequence::value_type>::value>
|
||||
>
|
||||
buffer_sequence (BufferSequence const& s)
|
||||
{
|
||||
assign (std::begin (s), std::end (s));
|
||||
}
|
||||
|
||||
template <
|
||||
class FwdIter,
|
||||
class = std::enable_if_t <std::is_constructible <
|
||||
Buffer, typename std::iterator_traits <
|
||||
FwdIter>::value_type>::value>
|
||||
>
|
||||
buffer_sequence (FwdIter first, FwdIter last)
|
||||
{
|
||||
assign (first, last);
|
||||
}
|
||||
|
||||
template <class BufferSequence>
|
||||
std::enable_if_t <std::is_constructible <
|
||||
Buffer, typename BufferSequence::value_type>::value,
|
||||
buffer_sequence&
|
||||
>
|
||||
operator= (BufferSequence const& s)
|
||||
{
|
||||
return assign (s);
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin () const noexcept
|
||||
{
|
||||
return m_buffers.begin ();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end () const noexcept
|
||||
{
|
||||
return m_buffers.end ();
|
||||
}
|
||||
|
||||
#if 0
|
||||
template <class ConstBufferSequence>
|
||||
void
|
||||
assign (ConstBufferSequence const& buffers)
|
||||
{
|
||||
auto const n (std::distance (
|
||||
std::begin (buffers), std::end (buffers)));
|
||||
|
||||
for (int i = 0, auto iter (std::begin (buffers));
|
||||
iter != std::end (buffers); ++iter, ++i)
|
||||
m_buffers[i] = Buffer (boost::asio::buffer_cast <void*> (
|
||||
*iter), boost::asio::buffer_size (*iter));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef buffer_sequence <boost::asio::const_buffer> const_buffers;
|
||||
typedef buffer_sequence <boost::asio::mutable_buffer> mutable_buffers;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,369 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||
#define BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||
|
||||
#include <beast/asio/wrap_handler.h>
|
||||
#include <beast/utility/is_call_possible.h>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Owner, class Handler>
|
||||
class ref_counted_wrapped_handler
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
|
||||
"Owner cannot be a const or reference type");
|
||||
|
||||
Handler m_handler;
|
||||
std::reference_wrapper <Owner> m_owner;
|
||||
bool m_continuation;
|
||||
|
||||
public:
|
||||
~ref_counted_wrapped_handler();
|
||||
|
||||
ref_counted_wrapped_handler (Owner& owner,
|
||||
Handler&& handler, bool continuation);
|
||||
|
||||
ref_counted_wrapped_handler (Owner& owner,
|
||||
Handler const& handler, bool continuation);
|
||||
|
||||
ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler const& other);
|
||||
|
||||
ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler&& other);
|
||||
|
||||
ref_counted_wrapped_handler& operator= (
|
||||
ref_counted_wrapped_handler const&) = delete;
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args)
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function& f,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function const& f,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (std::size_t size,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (void* p, std::size_t size,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (ref_counted_wrapped_handler* h)
|
||||
{
|
||||
return h->m_continuation;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::~ref_counted_wrapped_handler()
|
||||
{
|
||||
m_owner.get().decrement();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
Owner& owner, Handler&& handler, bool continuation)
|
||||
: m_handler (std::move (handler))
|
||||
, m_owner (owner)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
Owner& owner, Handler const& handler, bool continuation)
|
||||
: m_handler (handler)
|
||||
, m_owner (owner)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler const& other)
|
||||
: m_handler (other.m_handler)
|
||||
, m_owner (other.m_owner)
|
||||
, m_continuation (other.m_continuation)
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
ref_counted_wrapped_handler<Owner, Handler>::ref_counted_wrapped_handler (
|
||||
ref_counted_wrapped_handler&& other)
|
||||
: m_handler (std::move (other.m_handler))
|
||||
, m_owner (other.m_owner)
|
||||
, m_continuation (other.m_continuation)
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Facilitates blocking until no completion handlers are remaining.
|
||||
If Derived has this member function:
|
||||
|
||||
@code
|
||||
void on_wait_for_async (void)
|
||||
@endcode
|
||||
|
||||
Then it will be called every time the number of pending completion
|
||||
handlers transitions to zero from a non-zero value. The call is made
|
||||
while holding the internal mutex.
|
||||
*/
|
||||
template <class Derived>
|
||||
class enable_wait_for_async
|
||||
{
|
||||
private:
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(
|
||||
has_on_wait_for_async,on_wait_for_async);
|
||||
|
||||
void increment()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
++m_count;
|
||||
}
|
||||
|
||||
void notify (std::true_type)
|
||||
{
|
||||
static_cast <Derived*> (this)->on_wait_for_async();
|
||||
}
|
||||
|
||||
void notify (std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
--m_count;
|
||||
if (m_count == 0)
|
||||
{
|
||||
m_cond.notify_all();
|
||||
notify (std::integral_constant <bool,
|
||||
has_on_wait_for_async<Derived, void(void)>::value>());
|
||||
}
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
friend class detail::ref_counted_wrapped_handler;
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cond;
|
||||
std::size_t m_count;
|
||||
|
||||
public:
|
||||
/** Blocks if there are any pending completion handlers. */
|
||||
void
|
||||
wait_for_async()
|
||||
{
|
||||
std::unique_lock <decltype (m_mutex)> lock (m_mutex);
|
||||
while (m_count != 0)
|
||||
m_cond.wait (lock);
|
||||
}
|
||||
|
||||
protected:
|
||||
enable_wait_for_async()
|
||||
: m_count (0)
|
||||
{
|
||||
}
|
||||
|
||||
~enable_wait_for_async()
|
||||
{
|
||||
assert (m_count == 0);
|
||||
}
|
||||
|
||||
/** Wraps the specified handler so it can be counted. */
|
||||
/** @{ */
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <
|
||||
enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>
|
||||
>
|
||||
wrap_with_counter (Handler&& handler, bool continuation = false)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>> (*this,
|
||||
std::forward <Handler> (handler), continuation);
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <
|
||||
enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>
|
||||
>
|
||||
wrap_with_counter (continuation_t, Handler&& handler)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>> (*this,
|
||||
std::forward <Handler> (handler), true);
|
||||
}
|
||||
/** @} */
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A waitable event object that blocks when handlers are pending. */
|
||||
class pending_handlers
|
||||
{
|
||||
private:
|
||||
std::size_t count_ = 0;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
|
||||
template <class Owner, class Handler>
|
||||
friend class detail::ref_counted_wrapped_handler;
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
increment();
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
decrement();
|
||||
|
||||
public:
|
||||
~pending_handlers()
|
||||
{
|
||||
assert (count_ == 0);
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
wait();
|
||||
|
||||
/** Returns a handler that causes wait to block until completed.
|
||||
The returned handler provides the same execution
|
||||
guarantees as the passed handler.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>>
|
||||
wrap (Handler&& handler,
|
||||
bool continuation = false)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>> (*this,
|
||||
std::forward<Handler>(handler), continuation);
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>>
|
||||
wrap (continuation_t, Handler&& handler)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <pending_handlers,
|
||||
std::remove_reference_t<Handler>> (*this,
|
||||
std::forward<Handler>(handler), true);
|
||||
}
|
||||
/** @} */
|
||||
};
|
||||
|
||||
template <class>
|
||||
void
|
||||
pending_handlers::increment()
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
++count_;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
pending_handlers::decrement()
|
||||
{
|
||||
std::lock_guard <std::mutex> lock (mutex_);
|
||||
if (--count_ == 0)
|
||||
cond_.notify_all();
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
pending_handlers::wait()
|
||||
{
|
||||
std::unique_lock <std::mutex> lock (mutex_);
|
||||
while (count_ != 0)
|
||||
cond_.wait (lock);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,426 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
|
||||
#define BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
|
||||
|
||||
#include <beast/utility/empty_base_optimization.h>
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <
|
||||
class T,
|
||||
class Alloc = std::allocator <T>
|
||||
>
|
||||
class memory_buffer
|
||||
: private empty_base_optimization <Alloc>
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_same <char, T>::value ||
|
||||
std::is_same <unsigned char, T>::value,
|
||||
"memory_buffer only works with char and unsigned char");
|
||||
|
||||
typedef empty_base_optimization <Alloc> Base;
|
||||
|
||||
using AllocTraits = std::allocator_traits <Alloc>;
|
||||
|
||||
T* m_base;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef Alloc allocator_type;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef std::reverse_iterator <iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator <const_iterator> const_reverse_iterator;
|
||||
|
||||
memory_buffer ()
|
||||
: m_base (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
memory_buffer (memory_buffer&& other)
|
||||
: Base (std::move (other))
|
||||
, m_base (other.m_base)
|
||||
, m_size (other.m_size)
|
||||
{
|
||||
other.m_base = nullptr;
|
||||
other.m_size = 0;
|
||||
}
|
||||
|
||||
explicit memory_buffer (size_type n)
|
||||
: m_base (AllocTraits::allocate (Base::member(), n))
|
||||
, m_size (n)
|
||||
{
|
||||
}
|
||||
|
||||
explicit memory_buffer (Alloc const& alloc)
|
||||
: Base (alloc)
|
||||
, m_base (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
memory_buffer (size_type n, Alloc const& alloc)
|
||||
: Base (alloc)
|
||||
, m_base (AllocTraits::allocate (Base::member(), n))
|
||||
, m_size (n)
|
||||
{
|
||||
}
|
||||
|
||||
~memory_buffer()
|
||||
{
|
||||
if (m_base != nullptr)
|
||||
AllocTraits::deallocate (Base::member(), m_base, m_size);
|
||||
}
|
||||
|
||||
memory_buffer& operator= (memory_buffer const&) = delete;
|
||||
|
||||
allocator_type
|
||||
get_allocator() const
|
||||
{
|
||||
return Base::member;
|
||||
}
|
||||
|
||||
//
|
||||
// asio support
|
||||
//
|
||||
|
||||
boost::asio::mutable_buffer
|
||||
buffer()
|
||||
{
|
||||
return boost::asio::mutable_buffer (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::const_buffer
|
||||
buffer() const
|
||||
{
|
||||
return boost::asio::const_buffer (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::mutable_buffers_1
|
||||
buffers()
|
||||
{
|
||||
return boost::asio::mutable_buffers_1 (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::const_buffers_1
|
||||
buffers() const
|
||||
{
|
||||
return boost::asio::const_buffers_1 (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
operator boost::asio::mutable_buffer()
|
||||
{
|
||||
return buffer();
|
||||
}
|
||||
|
||||
operator boost::asio::const_buffer() const
|
||||
{
|
||||
return buffer();
|
||||
}
|
||||
|
||||
operator boost::asio::mutable_buffers_1()
|
||||
{
|
||||
return buffers();
|
||||
}
|
||||
|
||||
operator boost::asio::const_buffers_1() const
|
||||
{
|
||||
return buffers();
|
||||
}
|
||||
|
||||
//
|
||||
// Element access
|
||||
//
|
||||
|
||||
reference
|
||||
at (size_type pos)
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
at (size_type pos) const
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
operator[] (size_type pos) noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
operator[] (size_type pos) const noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
back() noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
const_reference
|
||||
back() const noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
reference
|
||||
front() noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
pointer
|
||||
data() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_pointer
|
||||
data() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
//
|
||||
// Iterators
|
||||
//
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator (end());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rend() noexcept
|
||||
{
|
||||
return reverse_iterator (begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
//
|
||||
// Capacity
|
||||
//
|
||||
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
size_type
|
||||
size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
size_type
|
||||
max_size() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type
|
||||
capacity() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type bytes() const
|
||||
{
|
||||
return m_size * sizeof(T);
|
||||
}
|
||||
|
||||
//
|
||||
// Modifiers
|
||||
//
|
||||
|
||||
template <class U, class A>
|
||||
friend
|
||||
void
|
||||
swap (memory_buffer <U, A>& lhs,
|
||||
memory_buffer <U, A>& rhs) noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T, class Alloc>
|
||||
void
|
||||
swap (memory_buffer <T, Alloc>& lhs,
|
||||
memory_buffer <T, Alloc>& rhs) noexcept
|
||||
{
|
||||
std::swap (lhs.m_base, rhs.m_base);
|
||||
std::swap (lhs.m_size, rhs.m_size);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator== (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return std::equal (lhs.cbegin(), lhs.cend(),
|
||||
rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator!= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator< (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return std::lexicographical_compare (
|
||||
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator>= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (lhs < rhs);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator> (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator<= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (rhs < lhs);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,475 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
||||
#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <beast/utility/is_call_possible.h>
|
||||
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
|
||||
#ifndef BEAST_ASIO_NO_ALLOCATE_SHARED
|
||||
#define BEAST_ASIO_NO_ALLOCATE_SHARED 0
|
||||
#endif
|
||||
|
||||
#ifndef BEAST_ASIO_NO_HANDLER_RESULT_OF
|
||||
#define BEAST_ASIO_NO_HANDLER_RESULT_OF 1
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class shared_handler_wrapper_base
|
||||
{
|
||||
public:
|
||||
virtual ~shared_handler_wrapper_base()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void invoke (std::function <void (void)> f) = 0;
|
||||
virtual void* allocate (std::size_t size) = 0;
|
||||
virtual void deallocate (void* p, std::size_t size) = 0;
|
||||
virtual bool is_continuation () = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Signature>
|
||||
class shared_handler_wrapper_func
|
||||
: public shared_handler_wrapper_base
|
||||
{
|
||||
private:
|
||||
std::function <Signature> m_func;
|
||||
|
||||
public:
|
||||
template <class Handler>
|
||||
explicit shared_handler_wrapper_func (Handler&& handler)
|
||||
: m_func (std::ref (std::forward <Handler> (handler)))
|
||||
{
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
|
||||
void
|
||||
#else
|
||||
std::result_of_t <std::function <Signature> (Args...)>
|
||||
#endif
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
return m_func (std::forward <Args> (args)...);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <class Signature, class Handler>
|
||||
class shared_handler_wrapper
|
||||
: private boost::base_from_member <Handler>
|
||||
, public shared_handler_wrapper_func <Signature>
|
||||
{
|
||||
private:
|
||||
typedef boost::base_from_member <Handler> Base;
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_is_continuation, is_continuation);
|
||||
|
||||
public:
|
||||
shared_handler_wrapper (Handler&& handler)
|
||||
: boost::base_from_member <Handler> (std::move (handler))
|
||||
, shared_handler_wrapper_func <Signature> (Base::member)
|
||||
{
|
||||
}
|
||||
|
||||
shared_handler_wrapper (Handler const& handler)
|
||||
: boost::base_from_member <Handler> (handler)
|
||||
, shared_handler_wrapper_func <Signature> (Base::member)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
invoke (std::function <void (void)> f) override
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::
|
||||
invoke (f, Base::member);
|
||||
}
|
||||
|
||||
void*
|
||||
allocate (std::size_t size) override
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, Base::member);
|
||||
}
|
||||
|
||||
void
|
||||
deallocate (void* p, std::size_t size) override
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, Base::member);
|
||||
}
|
||||
|
||||
bool
|
||||
is_continuation () override
|
||||
{
|
||||
return is_continuation (std::integral_constant <bool,
|
||||
has_is_continuation <Handler, bool(void)>::value>());
|
||||
}
|
||||
|
||||
bool
|
||||
is_continuation (std::true_type)
|
||||
{
|
||||
return Base::member.is_continuation();
|
||||
}
|
||||
|
||||
bool
|
||||
is_continuation (std::false_type)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation (Base::member);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct is_shared_handler : public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T, class Handler>
|
||||
class handler_allocator
|
||||
{
|
||||
private:
|
||||
// We want a partial template specialization as a friend
|
||||
// but that isn't allowed so we friend all versions. This
|
||||
// should produce a compile error if Handler is not constructible
|
||||
// from H.
|
||||
//
|
||||
template <class U, class H>
|
||||
friend class handler_allocator;
|
||||
|
||||
Handler m_handler;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
public:
|
||||
typedef handler_allocator <U, Handler> other;
|
||||
};
|
||||
|
||||
handler_allocator() = delete;
|
||||
|
||||
handler_allocator (Handler const& handler)
|
||||
: m_handler (handler)
|
||||
{
|
||||
}
|
||||
|
||||
template <class U>
|
||||
handler_allocator (
|
||||
handler_allocator <U, Handler> const& other)
|
||||
: m_handler (other.m_handler)
|
||||
{
|
||||
}
|
||||
|
||||
handler_allocator&
|
||||
operator= (handler_allocator const&) = delete;
|
||||
|
||||
pointer
|
||||
allocate (std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
return static_cast <pointer> (
|
||||
boost_asio_handler_alloc_helpers::allocate (
|
||||
size, m_handler));
|
||||
}
|
||||
|
||||
void
|
||||
deallocate (pointer p, std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
boost_asio_handler_alloc_helpers::deallocate (
|
||||
p, size, m_handler);
|
||||
}
|
||||
|
||||
// Work-around for MSVC not using allocator_traits
|
||||
// in the implementation of shared_ptr
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
void
|
||||
destroy (T* t)
|
||||
{
|
||||
t->~T();
|
||||
}
|
||||
#endif
|
||||
|
||||
friend
|
||||
bool
|
||||
operator== (handler_allocator const& lhs, handler_allocator const& rhs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator!= (handler_allocator const& lhs, handler_allocator const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Handler shared reference that provides io_service execution guarantees. */
|
||||
template <class Signature>
|
||||
class shared_handler
|
||||
{
|
||||
private:
|
||||
template <class T>
|
||||
friend class shared_handler_allocator;
|
||||
|
||||
typedef shared_handler_wrapper_func <
|
||||
Signature> wrapper_type;
|
||||
|
||||
typedef std::shared_ptr <wrapper_type> ptr_type;
|
||||
|
||||
ptr_type m_ptr;
|
||||
|
||||
public:
|
||||
shared_handler()
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
class DeducedHandler,
|
||||
class = std::enable_if_t <
|
||||
! detail::is_shared_handler <
|
||||
std::decay_t <DeducedHandler>>::value &&
|
||||
std::is_constructible <std::function <Signature>,
|
||||
std::decay_t <DeducedHandler>>::value
|
||||
>
|
||||
>
|
||||
shared_handler (DeducedHandler&& handler)
|
||||
{
|
||||
typedef std::remove_reference_t <DeducedHandler> Handler;
|
||||
|
||||
#if BEAST_ASIO_NO_ALLOCATE_SHARED
|
||||
m_ptr = std::make_shared <detail::shared_handler_wrapper <
|
||||
Signature, Handler>> (std::forward <DeducedHandler> (handler));
|
||||
#else
|
||||
m_ptr = std::allocate_shared <detail::shared_handler_wrapper <
|
||||
Signature, Handler>> (detail::handler_allocator <char, Handler> (
|
||||
handler), std::forward <DeducedHandler> (handler));
|
||||
#endif
|
||||
}
|
||||
|
||||
shared_handler (shared_handler&& other)
|
||||
: m_ptr (std::move (other.m_ptr))
|
||||
{
|
||||
}
|
||||
|
||||
shared_handler (shared_handler const& other)
|
||||
: m_ptr (other.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
shared_handler&
|
||||
operator= (std::nullptr_t)
|
||||
{
|
||||
m_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_handler&
|
||||
operator= (shared_handler const& rhs)
|
||||
{
|
||||
m_ptr = rhs.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_handler&
|
||||
operator= (shared_handler&& rhs)
|
||||
{
|
||||
m_ptr = std::move (rhs.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit
|
||||
operator bool() const noexcept
|
||||
{
|
||||
return m_ptr.operator bool();
|
||||
}
|
||||
|
||||
void
|
||||
reset()
|
||||
{
|
||||
m_ptr.reset();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
|
||||
void
|
||||
#else
|
||||
std::result_of_t <std::function <Signature> (Args...)>
|
||||
#endif
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
return (*m_ptr)(std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function&& f, shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->invoke (f);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (
|
||||
std::size_t size, shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->allocate (size);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (
|
||||
void* p, std::size_t size, shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->deallocate (p, size);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (
|
||||
shared_handler* h)
|
||||
{
|
||||
return h->m_ptr->is_continuation ();
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <
|
||||
class Signature
|
||||
>
|
||||
struct is_shared_handler <
|
||||
shared_handler <Signature>
|
||||
> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
class shared_handler_allocator
|
||||
{
|
||||
private:
|
||||
template <class U>
|
||||
friend class shared_handler_allocator;
|
||||
|
||||
std::shared_ptr <shared_handler_wrapper_base> m_ptr;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
|
||||
shared_handler_allocator() = delete;
|
||||
|
||||
template <class Signature>
|
||||
shared_handler_allocator (
|
||||
shared_handler <Signature> const& handler)
|
||||
: m_ptr (handler.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
template <class U>
|
||||
shared_handler_allocator (
|
||||
shared_handler_allocator <U> const& other)
|
||||
: m_ptr (other.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
pointer
|
||||
allocate (std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
return static_cast <pointer> (
|
||||
m_ptr->allocate (size));
|
||||
}
|
||||
|
||||
void
|
||||
deallocate (pointer p, std::ptrdiff_t n)
|
||||
{
|
||||
auto const size (n * sizeof (T));
|
||||
m_ptr->deallocate (p, size);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator== (shared_handler_allocator const& lhs,
|
||||
shared_handler_allocator const& rhs)
|
||||
{
|
||||
return lhs.m_ptr == rhs.m_ptr;
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator!= (shared_handler_allocator const& lhs,
|
||||
shared_handler_allocator const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,826 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_SOCKET_WRAPPER_H_INCLUDED
|
||||
#define BEAST_ASIO_SOCKET_WRAPPER_H_INCLUDED
|
||||
|
||||
#include <beast/asio/abstract_socket.h>
|
||||
#include <beast/asio/bind_handler.h>
|
||||
|
||||
#include <beast/utility/noexcept.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Wraps a reference to any object and exports all availble interfaces.
|
||||
|
||||
If the object does not support an interface, calling those
|
||||
member functions will behave as if a pure virtual was called.
|
||||
|
||||
Note that only a reference to the underlying is stored. Management
|
||||
of the lifetime of the object is controlled by the caller.
|
||||
|
||||
Examples of the type of Object:
|
||||
|
||||
asio::ip::tcp::socket
|
||||
asio::ip::tcp::socket&
|
||||
asio::ssl::stream <asio::ip::tcp::socket>
|
||||
asio::ssl::stream <asio::ip::tcp::socket&>
|
||||
explain arg must be an io_context
|
||||
explain socket_wrapper will create and take ownership of the tcp::socket
|
||||
explain this_layer_type will be tcp::socket
|
||||
explain next_layer () returns a asio::ip::tcp::socket&
|
||||
explain lowest_layer () returns a asio::ip::tcp::socket&
|
||||
|
||||
asio::ssl::stream <asio::buffered_stream <asio::ip::tcp::socket> > >
|
||||
This makes my head explode
|
||||
*/
|
||||
template <typename Object>
|
||||
class socket_wrapper : public abstract_socket
|
||||
{
|
||||
private:
|
||||
Object m_object;
|
||||
|
||||
public:
|
||||
template <class... Args>
|
||||
explicit socket_wrapper (Args&&... args)
|
||||
: m_object (std::forward <Args> (args)...)
|
||||
{
|
||||
}
|
||||
|
||||
socket_wrapper (socket_wrapper const&) = delete;
|
||||
socket_wrapper& operator= (socket_wrapper const&) = delete;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// socket_wrapper
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** The type of the object being wrapped. */
|
||||
typedef typename boost::remove_reference <Object>::type this_layer_type;
|
||||
|
||||
/** Get a reference to this layer. */
|
||||
this_layer_type& this_layer () noexcept
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
/** Get a const reference to this layer. */
|
||||
this_layer_type const& this_layer () const noexcept
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// abstract_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void* this_layer_ptr (char const* type_name) const override
|
||||
{
|
||||
char const* const name (typeid (this_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_get_io_service, get_io_service);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_lowest_layer, lowest_layer);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_cancel, cancel);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_shutdown, shutdown);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_close, close);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_accept, accept);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_accept, async_accept);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_read_some, read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_write_some, write_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_read_some, async_read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_write_some, async_write_some);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_set_verify_mode, set_verify_mode);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_handshake, handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_handshake, async_handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_shutdown, async_shutdown);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class Cond>
|
||||
struct Enabled : public std::integral_constant <bool, Cond::value>
|
||||
{
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
// This is a potential work-around for the problem with
|
||||
// the has_type_native_handle_type template, but requires
|
||||
// Boost 1.54 or later.
|
||||
//
|
||||
// This include will be needed:
|
||||
//
|
||||
// boost/tti/has_type.hpp
|
||||
//
|
||||
//
|
||||
BOOST_TTI_HAS_TYPE(native_handle_type)
|
||||
|
||||
#else
|
||||
template <class T>
|
||||
struct has_type_native_handle_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::native_handle_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(
|
||||
has_type_native_handle_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T,
|
||||
bool Exists = has_type_native_handle_type <T>::value
|
||||
>
|
||||
struct extract_native_handle_type
|
||||
{
|
||||
typedef typename T::native_handle_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_native_handle_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if native_handle_type doesn't exist in Object
|
||||
typedef typename extract_native_handle_type <
|
||||
this_layer_type>::type native_handle_type;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool native_handle (char const* type_name, void* dest) override
|
||||
{
|
||||
return native_handle (type_name, dest,
|
||||
Enabled <has_type_native_handle_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
bool native_handle (char const* type_name, void* dest,
|
||||
std::true_type)
|
||||
{
|
||||
char const* const name (typeid (
|
||||
typename this_layer_type::native_handle_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
{
|
||||
native_handle_type* const p (reinterpret_cast <
|
||||
native_handle_type*> (dest));
|
||||
*p = m_object.native_handle ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool native_handle (char const*, void*,
|
||||
std::false_type)
|
||||
{
|
||||
pure_virtual_called();
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::asio::io_service& get_io_service () override
|
||||
{
|
||||
return get_io_service (
|
||||
Enabled <has_get_io_service <this_layer_type,
|
||||
boost::asio::io_service&()> > ());
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service (
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.get_io_service ();
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service (
|
||||
std::false_type)
|
||||
{
|
||||
pure_virtual_called();
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
To forward the lowest_layer_type type, we need to make sure it
|
||||
exists in Object. This is a little more tricky than just figuring
|
||||
out if Object has a particular member function.
|
||||
|
||||
The problem is boost::asio::basic_socket_acceptor, which doesn't
|
||||
have lowest_layer () or lowest_layer_type ().
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
struct has_type_lowest_layer_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::lowest_layer_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_lowest_layer_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T, bool Exists = has_type_lowest_layer_type <T>::value >
|
||||
struct extract_lowest_layer_type
|
||||
{
|
||||
typedef typename T::lowest_layer_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_lowest_layer_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if lowest_layer_type doesn't exist in Object
|
||||
typedef typename extract_lowest_layer_type <this_layer_type>::type lowest_layer_type;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void* lowest_layer_ptr (char const* type_name) const override
|
||||
{
|
||||
return lowest_layer_ptr (type_name,
|
||||
Enabled <has_type_lowest_layer_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
void* lowest_layer_ptr (char const* type_name,
|
||||
std::true_type) const
|
||||
{
|
||||
char const* const name (typeid (typename this_layer_type::lowest_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object.lowest_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* lowest_layer_ptr (char const*,
|
||||
std::false_type) const
|
||||
{
|
||||
pure_virtual_called();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code cancel (error_code& ec) override
|
||||
{
|
||||
return cancel (ec,
|
||||
Enabled <has_cancel <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code cancel (error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.cancel (ec);
|
||||
}
|
||||
|
||||
error_code cancel (error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code shutdown (shutdown_type what, error_code& ec) override
|
||||
{
|
||||
return shutdown (what, ec,
|
||||
Enabled <has_shutdown <this_layer_type,
|
||||
error_code (shutdown_type, error_code&)> > ());
|
||||
}
|
||||
|
||||
|
||||
error_code shutdown (shutdown_type what, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.shutdown (what, ec);
|
||||
}
|
||||
|
||||
error_code shutdown (shutdown_type, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code close (error_code& ec) override
|
||||
{
|
||||
return close (ec,
|
||||
Enabled <has_close <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code close (error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.close (ec);
|
||||
}
|
||||
|
||||
error_code close (error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Extracts the underlying socket type from the protocol of another asio object
|
||||
template <typename T, typename Enable = void>
|
||||
struct native_socket
|
||||
{
|
||||
typedef void* socket_type;
|
||||
inline native_socket (abstract_socket&)
|
||||
: m_socket (nullptr)
|
||||
{
|
||||
abstract_socket::pure_virtual_called();
|
||||
}
|
||||
inline socket_type& get ()
|
||||
{
|
||||
abstract_socket::pure_virtual_called();
|
||||
return m_socket;
|
||||
}
|
||||
inline socket_type& operator-> ()
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
private:
|
||||
socket_type m_socket;
|
||||
};
|
||||
|
||||
// Enabled if T::protocol_type::socket exists as a type
|
||||
template <typename T>
|
||||
struct native_socket <T, typename boost::enable_if <boost::is_class <
|
||||
typename T::protocol_type::socket> >::type>
|
||||
{
|
||||
typedef typename T::protocol_type::socket socket_type;
|
||||
inline native_socket (abstract_socket& peer)
|
||||
: m_socket_ptr (&peer.this_layer <socket_type> ())
|
||||
{
|
||||
}
|
||||
inline socket_type& get () noexcept
|
||||
{
|
||||
return *m_socket_ptr;
|
||||
}
|
||||
inline socket_type& operator-> () noexcept
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
private:
|
||||
socket_type* m_socket_ptr;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code accept (abstract_socket& peer, error_code& ec) override
|
||||
{
|
||||
typedef typename native_socket <this_layer_type>::socket_type socket_type;
|
||||
return accept (peer, ec,
|
||||
Enabled <has_accept <this_layer_type,
|
||||
error_code (socket_type&, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code accept (abstract_socket& peer, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.accept (
|
||||
native_socket <this_layer_type> (peer).get (), ec);
|
||||
}
|
||||
|
||||
error_code accept (abstract_socket&, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_accept (abstract_socket& peer, error_handler handler) override
|
||||
{
|
||||
typedef typename native_socket <this_layer_type>::socket_type socket_type;
|
||||
async_accept (peer, handler,
|
||||
Enabled <has_async_accept <this_layer_type,
|
||||
void (socket_type&, error_handler)> > ());
|
||||
}
|
||||
|
||||
void async_accept (abstract_socket& peer, error_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_accept (
|
||||
native_socket <this_layer_type> (peer).get (), handler);
|
||||
}
|
||||
|
||||
void async_accept (abstract_socket&, error_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t
|
||||
read_some (mutable_buffers buffers, error_code& ec) override
|
||||
{
|
||||
return read_some (buffers, ec,
|
||||
Enabled <has_read_some <this_layer_type,
|
||||
std::size_t (mutable_buffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
read_some (mutable_buffers const& buffers, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.read_some (buffers, ec);
|
||||
}
|
||||
|
||||
std::size_t read_some (mutable_buffers const&, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t
|
||||
write_some (const_buffers buffers, error_code& ec) override
|
||||
{
|
||||
return write_some (buffers, ec,
|
||||
Enabled <has_write_some <this_layer_type,
|
||||
std::size_t (const_buffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
write_some (const_buffers const& buffers, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
write_some (const_buffers const&, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_read_some (mutable_buffers buffers,
|
||||
transfer_handler handler) override
|
||||
{
|
||||
async_read_some (buffers, handler,
|
||||
Enabled <has_async_read_some <this_layer_type,
|
||||
void (mutable_buffers const&, transfer_handler const&)> > ());
|
||||
}
|
||||
|
||||
void
|
||||
async_read_some (mutable_buffers const& buffers,
|
||||
transfer_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_read_some (buffers, handler);
|
||||
}
|
||||
|
||||
void
|
||||
async_read_some (mutable_buffers const&,
|
||||
transfer_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
async_write_some (const_buffers buffers,
|
||||
transfer_handler handler) override
|
||||
{
|
||||
async_write_some (buffers, handler,
|
||||
Enabled <has_async_write_some <this_layer_type,
|
||||
void (const_buffers const&, transfer_handler const&)> > ());
|
||||
}
|
||||
|
||||
void
|
||||
async_write_some (const_buffers const& buffers,
|
||||
transfer_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_write_some (buffers, handler);
|
||||
}
|
||||
|
||||
void
|
||||
async_write_some (const_buffers const&,
|
||||
transfer_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
struct has_type_next_layer_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::next_layer_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_next_layer_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T, bool Exists = has_type_next_layer_type <T>::value >
|
||||
struct extract_next_layer_type
|
||||
{
|
||||
typedef typename T::next_layer_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_next_layer_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if next_layer_type doesn't exist in Object
|
||||
typedef typename extract_next_layer_type <this_layer_type>::type next_layer_type;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void* next_layer_ptr (char const* type_name) const override
|
||||
{
|
||||
return next_layer_ptr (type_name,
|
||||
Enabled <has_type_next_layer_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
void* next_layer_ptr (char const* type_name,
|
||||
std::true_type) const
|
||||
{
|
||||
char const* const name (typeid (typename this_layer_type::next_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object.next_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* next_layer_ptr (char const*,
|
||||
std::false_type) const
|
||||
{
|
||||
pure_virtual_called();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool needs_handshake () override
|
||||
{
|
||||
return
|
||||
has_handshake <this_layer_type,
|
||||
error_code (handshake_type, error_code&)>::value ||
|
||||
has_async_handshake <this_layer_type,
|
||||
void (handshake_type, error_handler)>::value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void set_verify_mode (int verify_mode) override
|
||||
{
|
||||
set_verify_mode (verify_mode,
|
||||
Enabled <has_set_verify_mode <this_layer_type,
|
||||
void (int)> > ());
|
||||
|
||||
}
|
||||
|
||||
void set_verify_mode (int verify_mode,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.set_verify_mode (verify_mode);
|
||||
}
|
||||
|
||||
void set_verify_mode (int,
|
||||
std::false_type)
|
||||
{
|
||||
pure_virtual_called();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, error_code& ec) override
|
||||
{
|
||||
return handshake (type, ec,
|
||||
Enabled <has_handshake <this_layer_type,
|
||||
error_code (handshake_type, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.handshake (type, ec);
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type, error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_handshake (handshake_type type, error_handler handler) override
|
||||
{
|
||||
async_handshake (type, handler,
|
||||
Enabled <has_async_handshake <this_layer_type,
|
||||
void (handshake_type, error_handler)> > ());
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type type, error_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_handshake (type, handler);
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type, error_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, const_buffers buffers,
|
||||
error_code& ec) override
|
||||
{
|
||||
return handshake (type, buffers, ec,
|
||||
Enabled <has_handshake <this_layer_type,
|
||||
error_code (handshake_type, const_buffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type type, const_buffers const& buffers,
|
||||
error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.handshake (type, buffers, ec);
|
||||
}
|
||||
|
||||
error_code
|
||||
handshake (handshake_type, const_buffers const&,
|
||||
error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_handshake (handshake_type type,
|
||||
const_buffers buffers, transfer_handler handler) override
|
||||
{
|
||||
async_handshake (type, buffers, handler,
|
||||
Enabled <has_async_handshake <this_layer_type,
|
||||
void (handshake_type, const_buffers const&,
|
||||
transfer_handler)> > ());
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type type, const_buffers const& buffers,
|
||||
transfer_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_handshake (type, buffers, handler);
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type, const_buffers const&,
|
||||
transfer_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error(), 0));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code shutdown (error_code& ec) override
|
||||
{
|
||||
return shutdown (ec,
|
||||
Enabled <has_shutdown <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code shutdown (error_code& ec,
|
||||
std::true_type)
|
||||
{
|
||||
return m_object.shutdown (ec);
|
||||
}
|
||||
|
||||
error_code shutdown (error_code& ec,
|
||||
std::false_type)
|
||||
{
|
||||
return pure_virtual_error (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_shutdown (error_handler handler) override
|
||||
{
|
||||
async_shutdown (handler,
|
||||
Enabled <has_async_shutdown <this_layer_type,
|
||||
void (error_handler)> > ());
|
||||
}
|
||||
|
||||
void async_shutdown (error_handler const& handler,
|
||||
std::true_type)
|
||||
{
|
||||
m_object.async_shutdown (handler);
|
||||
}
|
||||
|
||||
void async_shutdown (error_handler const& handler,
|
||||
std::false_type)
|
||||
{
|
||||
get_io_service ().post (bind_handler (
|
||||
handler, pure_virtual_error()));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_BASIC_STREAMBUF_H_INCLUDED
|
||||
#define BEAST_ASIO_BASIC_STREAMBUF_H_INCLUDED
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <class Alloc = std::allocator <char>>
|
||||
class basic_streambuf : private Alloc
|
||||
{
|
||||
private:
|
||||
typedef std::allocator_traits <Alloc> alloc_traits;
|
||||
std::vector <boost::asio::mutable_buffer> bufs_;
|
||||
|
||||
public:
|
||||
~basic_streambuf()
|
||||
{
|
||||
for (auto const& buf : bufs_)
|
||||
alloc_traits::deallocate (
|
||||
boost::asio::buffer_cast<char const*>(buf));
|
||||
}
|
||||
}
|
||||
|
||||
} // asio
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,105 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/asio/bind_handler.h>
|
||||
#include <beast/asio/enable_wait_for_async.h>
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class enable_wait_for_async_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
void test()
|
||||
{
|
||||
struct handler
|
||||
{
|
||||
void operator()(error_code)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct owner : asio::enable_wait_for_async <owner>
|
||||
{
|
||||
bool notified;
|
||||
|
||||
owner()
|
||||
: notified (false)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
ios.post (asio::bind_handler (handler(),
|
||||
error_code()));
|
||||
ios.run();
|
||||
ios.reset();
|
||||
wait_for_async();
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
ios.post (wrap_with_counter (asio::bind_handler (
|
||||
handler(), error_code())));
|
||||
ios.run();
|
||||
wait_for_async();
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
handler h;
|
||||
ios.post (wrap_with_counter (std::bind (
|
||||
&handler::operator(), &h,
|
||||
error_code())));
|
||||
ios.run();
|
||||
wait_for_async();
|
||||
}
|
||||
}
|
||||
|
||||
void on_wait_for_async()
|
||||
{
|
||||
notified = true;
|
||||
}
|
||||
};
|
||||
|
||||
owner o;
|
||||
o();
|
||||
expect (o.notified);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
test();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(enable_wait_for_async,asio,beast);
|
||||
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/asio/shared_handler.h>
|
||||
|
||||
// Disables is_constructible tests for std::function
|
||||
// Visual Studio std::function fails the is_constructible tests
|
||||
#ifndef BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
|
||||
# ifdef _MSC_VER
|
||||
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 1
|
||||
# else
|
||||
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
|
||||
class shared_handler_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
struct test_results
|
||||
{
|
||||
bool call;
|
||||
bool invoke;
|
||||
bool alloc;
|
||||
bool dealloc;
|
||||
bool cont;
|
||||
|
||||
test_results ()
|
||||
: call (false)
|
||||
, invoke (false)
|
||||
, alloc (false)
|
||||
, dealloc (false)
|
||||
, cont (false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct test_handler
|
||||
{
|
||||
std::reference_wrapper <test_results> results;
|
||||
|
||||
explicit test_handler (test_results& results_)
|
||||
: results (results_)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
results.get().call = true;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function const& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
friend void* asio_handler_allocate (
|
||||
std::size_t size, test_handler* h)
|
||||
{
|
||||
h->results.get().alloc = true;
|
||||
return boost::asio::asio_handler_allocate (size);
|
||||
}
|
||||
|
||||
friend void asio_handler_deallocate (
|
||||
void* p, std::size_t size, test_handler* h)
|
||||
{
|
||||
h->results.get().dealloc = true;
|
||||
boost::asio::asio_handler_deallocate (p, size);
|
||||
}
|
||||
|
||||
friend bool asio_handler_is_continuation (
|
||||
test_handler* h)
|
||||
{
|
||||
h->results.get().cont = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct test_invokable
|
||||
{
|
||||
bool call;
|
||||
|
||||
test_invokable ()
|
||||
: call (false)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
call = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Handler>
|
||||
bool async_op (Handler&& handler)
|
||||
{
|
||||
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
|
||||
handler();
|
||||
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
|
||||
return boost_asio_handler_cont_helpers::is_continuation (handler);
|
||||
}
|
||||
|
||||
void virtual_async_op (asio::shared_handler <void(void)> handler)
|
||||
{
|
||||
async_op (handler);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
#if ! BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
|
||||
static_assert (! std::is_constructible <
|
||||
std::function <void(void)>, int&&>::value,
|
||||
"Cannot construct std::function from int&&");
|
||||
|
||||
static_assert (! std::is_constructible <
|
||||
std::function <void(void)>, int>::value,
|
||||
"Cannot construct std::function from int");
|
||||
|
||||
static_assert (! std::is_constructible <
|
||||
asio::shared_handler <void(void)>, int>::value,
|
||||
"Cannot construct shared_handler from int");
|
||||
#endif
|
||||
|
||||
static_assert (std::is_constructible <
|
||||
asio::shared_handler <void(int)>,
|
||||
asio::shared_handler <void(int)>>::value,
|
||||
"Should construct <void(int)> from <void(int)>");
|
||||
|
||||
static_assert (! std::is_constructible <
|
||||
asio::shared_handler <void(int)>,
|
||||
asio::shared_handler <void(void)>>::value,
|
||||
"Can't construct <void(int)> from <void(void)>");
|
||||
|
||||
// Hooks called when using the raw handler
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
|
||||
async_op (h);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Use of std::function shows the hooks not getting called
|
||||
{
|
||||
test_results r;
|
||||
std::function <void(void)> fh ((test_handler) (r));
|
||||
|
||||
async_op (fh);
|
||||
expect (r.call);
|
||||
unexpected (r.alloc);
|
||||
unexpected (r.dealloc);
|
||||
unexpected (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), fh);
|
||||
unexpected (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Make sure shared_handler calls the hooks
|
||||
{
|
||||
test_results r;
|
||||
asio::shared_handler <void(void)> sh ((test_handler)(r));
|
||||
|
||||
async_op (sh);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), sh);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Make sure shared_handler via implicit conversion calls hooks
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
|
||||
virtual_async_op ((test_handler) (r));
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(shared_handler,asio,beast);
|
||||
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/asio/wrap_handler.h>
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Displays the order of destruction of parameters in the bind wrapper
|
||||
//
|
||||
class boost_bind_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
struct Result
|
||||
{
|
||||
std::string text;
|
||||
|
||||
void push_back (std::string const& s)
|
||||
{
|
||||
if (! text.empty())
|
||||
text += ", ";
|
||||
text += s;
|
||||
}
|
||||
};
|
||||
|
||||
struct Payload
|
||||
{
|
||||
std::reference_wrapper <Result> m_result;
|
||||
std::string m_name;
|
||||
|
||||
explicit Payload (Result& result, std::string const& name)
|
||||
: m_result (result)
|
||||
, m_name (name)
|
||||
{
|
||||
}
|
||||
|
||||
~Payload ()
|
||||
{
|
||||
m_result.get().push_back (m_name);
|
||||
}
|
||||
};
|
||||
|
||||
struct Arg
|
||||
{
|
||||
std::shared_ptr <Payload> m_payload;
|
||||
|
||||
Arg (Result& result, std::string const& name)
|
||||
: m_payload (std::make_shared <Payload> (result, name))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static void foo (Arg const&, Arg const&, Arg const&)
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
{
|
||||
Result r;
|
||||
{
|
||||
boost::bind (&foo,
|
||||
Arg (r, "one"),
|
||||
Arg (r, "two"),
|
||||
Arg (r, "three"));
|
||||
}
|
||||
log <<
|
||||
std::string ("boost::bind (") + r.text + ")";
|
||||
}
|
||||
|
||||
{
|
||||
Result r;
|
||||
{
|
||||
std::bind (&foo,
|
||||
Arg (r, "one"),
|
||||
Arg (r, "two"),
|
||||
Arg (r, "three"));
|
||||
}
|
||||
|
||||
log <<
|
||||
std::string ("std::bind (") + r.text + ")";
|
||||
}
|
||||
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(boost_bind,asio,beast);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class wrap_handler_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
struct test_results
|
||||
{
|
||||
bool call;
|
||||
bool invoke;
|
||||
bool alloc;
|
||||
bool dealloc;
|
||||
bool cont;
|
||||
|
||||
test_results ()
|
||||
: call (false)
|
||||
, invoke (false)
|
||||
, alloc (false)
|
||||
, dealloc (false)
|
||||
, cont (false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct test_handler
|
||||
{
|
||||
std::reference_wrapper <test_results> results;
|
||||
|
||||
explicit test_handler (test_results& results_)
|
||||
: results (results_)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
results.get().call = true;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend void asio_handler_invoke (
|
||||
Function const& f, test_handler* h)
|
||||
{
|
||||
h->results.get().invoke = true;
|
||||
f();
|
||||
}
|
||||
|
||||
friend void* asio_handler_allocate (
|
||||
std::size_t, test_handler* h)
|
||||
{
|
||||
h->results.get().alloc = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
friend void asio_handler_deallocate (
|
||||
void*, std::size_t, test_handler* h)
|
||||
{
|
||||
h->results.get().dealloc = true;
|
||||
}
|
||||
|
||||
friend bool asio_handler_is_continuation (
|
||||
test_handler* h)
|
||||
{
|
||||
h->results.get().cont = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct test_invokable
|
||||
{
|
||||
bool call;
|
||||
|
||||
test_invokable ()
|
||||
: call (false)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
call = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Handler>
|
||||
bool async_op (Handler&& handler)
|
||||
{
|
||||
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
|
||||
(handler)();
|
||||
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
|
||||
return boost_asio_handler_cont_helpers::is_continuation (handler);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
// Hooks called when using the raw handler
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
|
||||
async_op (h);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Use of boost::bind shows the hooks not getting called
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
auto b (std::bind (&test_handler::operator(), &h));
|
||||
|
||||
async_op (b);
|
||||
expect (r.call);
|
||||
unexpected (r.alloc);
|
||||
unexpected (r.dealloc);
|
||||
unexpected (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), b);
|
||||
unexpected (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
|
||||
// Make sure the wrapped handler calls the hooks
|
||||
{
|
||||
test_results r;
|
||||
test_handler h (r);
|
||||
auto w (wrap_handler (
|
||||
std::bind (&test_handler::operator(), test_handler(r)), h));
|
||||
|
||||
async_op (w);
|
||||
expect (r.call);
|
||||
expect (r.alloc);
|
||||
expect (r.dealloc);
|
||||
expect (r.cont);
|
||||
|
||||
test_invokable f;
|
||||
boost_asio_handler_invoke_helpers::invoke (std::ref (f), w);
|
||||
expect (r.invoke);
|
||||
expect (f.call);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(wrap_handler,asio,beast);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_WRAP_HANDLER_H_INCLUDED
|
||||
#define BEAST_ASIO_WRAP_HANDLER_H_INCLUDED
|
||||
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** A handler which wraps another handler using a specfic context.
|
||||
The handler is invoked with the same io_service execution guarantees
|
||||
as the provided context.
|
||||
@note A copy of Context is made.
|
||||
*/
|
||||
template <class Handler, class Context>
|
||||
class wrapped_handler
|
||||
{
|
||||
private:
|
||||
Handler m_handler;
|
||||
Context m_context;
|
||||
bool m_continuation;
|
||||
|
||||
// If this goes off, consider carefully what the intent is.
|
||||
static_assert (! std::is_reference <Handler>::value,
|
||||
"Handler should not be a reference type");
|
||||
|
||||
public:
|
||||
wrapped_handler (bool continuation, Handler&& handler, Context context)
|
||||
: m_handler (std::move (handler))
|
||||
, m_context (context)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (context))
|
||||
{
|
||||
}
|
||||
|
||||
wrapped_handler (bool continuation, Handler const& handler, Context context)
|
||||
: m_handler (handler)
|
||||
, m_context (context)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (context))
|
||||
{
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args)
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function& f, wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_context);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function const& f, wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_context);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (std::size_t size, wrapped_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, h->m_context);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (void* p, std::size_t size, wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, h->m_context);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (wrapped_handler* h)
|
||||
{
|
||||
return h->m_continuation;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Tag for dispatching wrap_handler with is_continuation == true
|
||||
enum continuation_t
|
||||
{
|
||||
continuation
|
||||
};
|
||||
|
||||
/** Returns a wrapped handler so it executes within another context.
|
||||
The handler is invoked with the same io_service execution guarantees
|
||||
as the provided context. The handler will be copied if necessary.
|
||||
@note A copy of Context is made.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class DeducedHandler, class Context>
|
||||
detail::wrapped_handler <
|
||||
std::remove_reference_t <DeducedHandler>,
|
||||
Context
|
||||
>
|
||||
wrap_handler (DeducedHandler&& handler, Context const& context,
|
||||
bool continuation = false)
|
||||
{
|
||||
typedef std::remove_reference_t <DeducedHandler> Handler;
|
||||
return detail::wrapped_handler <Handler, Context> (continuation,
|
||||
std::forward <DeducedHandler> (handler), context);
|
||||
}
|
||||
|
||||
template <class DeducedHandler, class Context>
|
||||
detail::wrapped_handler <
|
||||
std::remove_reference_t <DeducedHandler>,
|
||||
Context
|
||||
>
|
||||
wrap_handler (continuation_t, DeducedHandler&& handler,
|
||||
Context const& context)
|
||||
{
|
||||
typedef std::remove_reference_t <DeducedHandler> Handler;
|
||||
return detail::wrapped_handler <Handler, Context> (true,
|
||||
std::forward <DeducedHandler> (handler), context);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user