forked from boostorg/beast
Stream traits are in stream_traits.hpp (API Change):
These metafunctions are moved from type_traits.hpp to stream_traits.hpp: - has_get_executor - is_sync_stream - is_sync_read_stream - is_sync_write_stream - is_async_stream - is_async_read_stream - is_async_write_stream Actions Required: * Include the file stream_traits.hpp as needed
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
#include <boost/beast/core/detail/static_const.hpp>
|
||||
#include <boost/beast/core/detail/type_traits.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <boost/beast/core/bind_handler.hpp>
|
||||
#include <boost/beast/core/async_op_base.hpp>
|
||||
#include <boost/beast/core/flat_static_buffer.hpp>
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/asio/basic_stream_socket.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/beast/core/type_traits.hpp>
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef BOOST_BEAST_DETAIL_STREAM_TRAITS_HPP
|
||||
#define BOOST_BEAST_DETAIL_STREAM_TRAITS_HPP
|
||||
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -25,13 +27,11 @@ namespace detail {
|
||||
//
|
||||
|
||||
template <class T>
|
||||
std::false_type has_next_layer_impl(void*) {}
|
||||
std::false_type has_next_layer_impl(void*);
|
||||
|
||||
template <class T>
|
||||
auto has_next_layer_impl(decltype(nullptr)) ->
|
||||
decltype(std::declval<T&>().next_layer(), std::true_type{})
|
||||
{
|
||||
}
|
||||
decltype(std::declval<T&>().next_layer(), std::true_type{});
|
||||
|
||||
template <class T>
|
||||
using has_next_layer = decltype(has_next_layer_impl<T>(nullptr));
|
||||
@@ -73,6 +73,37 @@ get_lowest_layer_impl(
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
template<class BufferType>
|
||||
struct BufferSequence
|
||||
{
|
||||
using value_type = BufferType;
|
||||
using const_iterator = BufferType const*;
|
||||
~BufferSequence();
|
||||
BufferSequence(BufferSequence const&) = default;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
};
|
||||
using ConstBufferSequence =
|
||||
BufferSequence<net::const_buffer>;
|
||||
using MutableBufferSequence =
|
||||
BufferSequence<net::mutable_buffer>;
|
||||
|
||||
//
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
struct StreamHandler
|
||||
{
|
||||
StreamHandler(StreamHandler const&) = default;
|
||||
void operator()(error_code ec, std::size_t);
|
||||
};
|
||||
using ReadHandler = StreamHandler;
|
||||
using WriteHandler = StreamHandler;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
@@ -161,39 +161,6 @@ struct is_contiguous_container<T, E, void_t<
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// buffer concepts
|
||||
//
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
template<class BufferType>
|
||||
struct BufferSequence
|
||||
{
|
||||
using value_type = BufferType;
|
||||
using const_iterator = BufferType const*;
|
||||
~BufferSequence();
|
||||
BufferSequence(BufferSequence const&) = default;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
};
|
||||
using ConstBufferSequence =
|
||||
BufferSequence<net::const_buffer>;
|
||||
using MutableBufferSequence =
|
||||
BufferSequence<net::mutable_buffer>;
|
||||
|
||||
//
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
struct StreamHandler
|
||||
{
|
||||
StreamHandler(StreamHandler const&) = default;
|
||||
void operator()(error_code ec, std::size_t);
|
||||
};
|
||||
using ReadHandler = StreamHandler;
|
||||
using WriteHandler = StreamHandler;
|
||||
|
||||
/* If this static assert goes off, it means that the completion
|
||||
handler you provided to an asynchronous initiating function did
|
||||
not have the right signature. Check the parameter types for your
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -87,6 +87,8 @@ get_lowest_layer(T& t) noexcept
|
||||
t, detail::has_next_layer<T>{});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A trait to determine the return type of get_executor.
|
||||
|
||||
This type alias will be the type of values returned by
|
||||
@@ -110,6 +112,318 @@ using executor_type =
|
||||
decltype(std::declval<T&>().get_executor());
|
||||
#endif
|
||||
|
||||
/** Determine if `T` has the `get_executor` member function.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` has the member
|
||||
function with the correct signature, else type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with tag dispatching:
|
||||
|
||||
@code
|
||||
template<class T>
|
||||
void maybe_hello(T const& t, std::true_type)
|
||||
{
|
||||
net::post(
|
||||
t.get_executor(),
|
||||
[]
|
||||
{
|
||||
std::cout << "Hello, world!" << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void maybe_hello(T const&, std::false_type)
|
||||
{
|
||||
// T does not have get_executor
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void maybe_hello(T const& t)
|
||||
{
|
||||
maybe_hello(t, has_get_executor<T>{});
|
||||
}
|
||||
@endcode
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
struct stream
|
||||
{
|
||||
using executor_type = net::io_context::executor_type;
|
||||
executor_type get_executor() noexcept;
|
||||
};
|
||||
|
||||
static_assert(has_get_executor<stream>::value, "Missing get_executor member");
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct has_get_executor : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct has_get_executor : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct has_get_executor<T, boost::void_t<decltype(
|
||||
std::declval<T&>().get_executor())>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Determine if `T` meets the requirements of @b SyncReadStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
void f(SyncReadStream& stream)
|
||||
{
|
||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
typename std::enable_if<is_sync_read_stream<SyncReadStream>::value>::type
|
||||
f(SyncReadStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_sync_read_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_sync_read_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_sync_read_stream<T, boost::void_t<decltype(
|
||||
std::declval<std::size_t&>() = std::declval<T>().read_some(
|
||||
std::declval<detail::MutableBufferSequence>()),
|
||||
std::declval<std::size_t&>() = std::declval<T>().read_some(
|
||||
std::declval<detail::MutableBufferSequence>(),
|
||||
std::declval<boost::system::error_code&>())
|
||||
)>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b SyncWriteStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
void f(SyncReadStream& stream)
|
||||
{
|
||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
typename std::enable_if<is_sync_read_stream<SyncReadStream>::value>::type
|
||||
f(SyncReadStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_sync_write_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_sync_write_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_sync_write_stream<T, boost::void_t<decltype(
|
||||
(
|
||||
std::declval<std::size_t&>() = std::declval<T&>().write_some(
|
||||
std::declval<detail::ConstBufferSequence>()))
|
||||
,std::declval<std::size_t&>() = std::declval<T&>().write_some(
|
||||
std::declval<detail::ConstBufferSequence>(),
|
||||
std::declval<boost::system::error_code&>())
|
||||
)>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b SyncStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class SyncStream>
|
||||
void f(SyncStream& stream)
|
||||
{
|
||||
static_assert(is_sync_stream<SyncStream>::value,
|
||||
"SyncStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class SyncStream>
|
||||
typename std::enable_if<is_sync_stream<SyncStream>::value>::type
|
||||
f(SyncStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_sync_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T>
|
||||
using is_sync_stream = std::integral_constant<bool,
|
||||
is_sync_read_stream<T>::value && is_sync_write_stream<T>::value>;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Determine if `T` meets the requirements of @b AsyncReadStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class AsyncReadStream>
|
||||
void f(AsyncReadStream& stream)
|
||||
{
|
||||
static_assert(is_async_read_stream<AsyncReadStream>::value,
|
||||
"AsyncReadStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class AsyncReadStream>
|
||||
typename std::enable_if<is_async_read_stream<AsyncReadStream>::value>::type
|
||||
f(AsyncReadStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_async_read_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_async_read_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_async_read_stream<T, boost::void_t<decltype(
|
||||
std::declval<T>().async_read_some(
|
||||
std::declval<detail::MutableBufferSequence>(),
|
||||
std::declval<detail::ReadHandler>())
|
||||
)>> : std::integral_constant<bool,
|
||||
has_get_executor<T>::value
|
||||
> {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b AsyncWriteStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class AsyncWriteStream>
|
||||
void f(AsyncWriteStream& stream)
|
||||
{
|
||||
static_assert(is_async_write_stream<AsyncWriteStream>::value,
|
||||
"AsyncWriteStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class AsyncWriteStream>
|
||||
typename std::enable_if<is_async_write_stream<AsyncWriteStream>::value>::type
|
||||
f(AsyncWriteStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_async_write_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_async_write_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_async_write_stream<T, boost::void_t<decltype(
|
||||
std::declval<T>().async_write_some(
|
||||
std::declval<detail::ConstBufferSequence>(),
|
||||
std::declval<detail::WriteHandler>())
|
||||
)>> : std::integral_constant<bool,
|
||||
has_get_executor<T>::value
|
||||
> {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b AsyncStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class AsyncStream>
|
||||
void f(AsyncStream& stream)
|
||||
{
|
||||
static_assert(is_async_stream<AsyncStream>::value,
|
||||
"AsyncStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class AsyncStream>
|
||||
typename std::enable_if<is_async_stream<AsyncStream>::value>::type
|
||||
f(AsyncStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_async_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T>
|
||||
using is_async_stream = std::integral_constant<bool,
|
||||
is_async_read_stream<T>::value && is_async_write_stream<T>::value>;
|
||||
#endif
|
||||
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
|
||||
@@ -56,320 +56,6 @@ using is_completion_handler = std::integral_constant<bool,
|
||||
detail::is_invocable<T, Signature>::value>;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Stream concepts
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Determine if `T` has the `get_executor` member function.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` has the member
|
||||
function with the correct signature, else type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with tag dispatching:
|
||||
|
||||
@code
|
||||
template<class T>
|
||||
void maybe_hello(T& t, std::true_type)
|
||||
{
|
||||
net::post(
|
||||
t.get_executor(),
|
||||
[]
|
||||
{
|
||||
std::cout << "Hello, world!" << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void maybe_hello(T&, std::false_type)
|
||||
{
|
||||
// T does not have get_executor
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void maybe_hello(T& t)
|
||||
{
|
||||
maybe_hello(t, has_get_executor<T>{});
|
||||
}
|
||||
@endcode
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
struct stream
|
||||
{
|
||||
using executor_type = net::io_context::executor_type;
|
||||
executor_type get_executor() noexcept;
|
||||
};
|
||||
|
||||
static_assert(has_get_executor<stream>::value, "Missing get_executor member");
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct has_get_executor : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct has_get_executor : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct has_get_executor<T, beast::detail::void_t<decltype(
|
||||
std::declval<T&>().get_executor())>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b AsyncReadStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class AsyncReadStream>
|
||||
void f(AsyncReadStream& stream)
|
||||
{
|
||||
static_assert(is_async_read_stream<AsyncReadStream>::value,
|
||||
"AsyncReadStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class AsyncReadStream>
|
||||
typename std::enable_if<is_async_read_stream<AsyncReadStream>::value>::type
|
||||
f(AsyncReadStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_async_read_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_async_read_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_async_read_stream<T, detail::void_t<decltype(
|
||||
std::declval<T>().async_read_some(
|
||||
std::declval<detail::MutableBufferSequence>(),
|
||||
std::declval<detail::ReadHandler>())
|
||||
)>> : std::integral_constant<bool,
|
||||
has_get_executor<T>::value
|
||||
> {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b AsyncWriteStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class AsyncWriteStream>
|
||||
void f(AsyncWriteStream& stream)
|
||||
{
|
||||
static_assert(is_async_write_stream<AsyncWriteStream>::value,
|
||||
"AsyncWriteStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class AsyncWriteStream>
|
||||
typename std::enable_if<is_async_write_stream<AsyncWriteStream>::value>::type
|
||||
f(AsyncWriteStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_async_write_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_async_write_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_async_write_stream<T, detail::void_t<decltype(
|
||||
std::declval<T>().async_write_some(
|
||||
std::declval<detail::ConstBufferSequence>(),
|
||||
std::declval<detail::WriteHandler>())
|
||||
)>> : std::integral_constant<bool,
|
||||
has_get_executor<T>::value
|
||||
> {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b SyncReadStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
void f(SyncReadStream& stream)
|
||||
{
|
||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
typename std::enable_if<is_sync_read_stream<SyncReadStream>::value>::type
|
||||
f(SyncReadStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_sync_read_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_sync_read_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_sync_read_stream<T, detail::void_t<decltype(
|
||||
std::declval<std::size_t&>() = std::declval<T>().read_some(
|
||||
std::declval<detail::MutableBufferSequence>()),
|
||||
std::declval<std::size_t&>() = std::declval<T>().read_some(
|
||||
std::declval<detail::MutableBufferSequence>(),
|
||||
std::declval<boost::system::error_code&>())
|
||||
)>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b SyncWriteStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
void f(SyncReadStream& stream)
|
||||
{
|
||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class SyncReadStream>
|
||||
typename std::enable_if<is_sync_read_stream<SyncReadStream>::value>::type
|
||||
f(SyncReadStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_sync_write_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T, class = void>
|
||||
struct is_sync_write_stream : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_sync_write_stream<T, detail::void_t<decltype(
|
||||
(
|
||||
std::declval<std::size_t&>() = std::declval<T&>().write_some(
|
||||
std::declval<detail::ConstBufferSequence>()))
|
||||
,std::declval<std::size_t&>() = std::declval<T&>().write_some(
|
||||
std::declval<detail::ConstBufferSequence>(),
|
||||
std::declval<boost::system::error_code&>())
|
||||
)>> : std::true_type {};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b AsyncStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class AsyncStream>
|
||||
void f(AsyncStream& stream)
|
||||
{
|
||||
static_assert(is_async_stream<AsyncStream>::value,
|
||||
"AsyncStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class AsyncStream>
|
||||
typename std::enable_if<is_async_stream<AsyncStream>::value>::type
|
||||
f(AsyncStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_async_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T>
|
||||
using is_async_stream = std::integral_constant<bool,
|
||||
is_async_read_stream<T>::value && is_async_write_stream<T>::value>;
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b SyncStream.
|
||||
|
||||
Metafunctions are used to perform compile time checking of template
|
||||
types. This type will be `std::true_type` if `T` meets the requirements,
|
||||
else the type will be `std::false_type`.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<class SyncStream>
|
||||
void f(SyncStream& stream)
|
||||
{
|
||||
static_assert(is_sync_stream<SyncStream>::value,
|
||||
"SyncStream requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<class SyncStream>
|
||||
typename std::enable_if<is_sync_stream<SyncStream>::value>::type
|
||||
f(SyncStream& stream);
|
||||
@endcode
|
||||
*/
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_sync_stream : std::integral_constant<bool, ...>{};
|
||||
#else
|
||||
template<class T>
|
||||
using is_sync_stream = std::integral_constant<bool,
|
||||
is_sync_read_stream<T>::value && is_sync_write_stream<T>::value>;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// File concepts
|
||||
|
||||
Reference in New Issue
Block a user