decorator constructor is constrained

This commit is contained in:
Vinnie Falco
2019-04-02 16:31:30 -07:00
parent a4974e18ba
commit 7c084509d6
4 changed files with 69 additions and 1 deletions

View File

@ -1,3 +1,9 @@
Version 245:
* decorator constructor is constrained
--------------------------------------------------------------------------------
Version 244: Version 244:
* Tidy up declval in some traits * Tidy up declval in some traits

View File

@ -25,6 +25,27 @@ namespace beast {
namespace websocket { namespace websocket {
namespace detail { namespace detail {
// VFALCO NOTE: When this is two traits, one for
// request and one for response,
// Visual Studio 2015 fails.
template<class T, class U, class = void>
struct can_invoke_with : std::false_type
{
};
template<class T, class U>
struct can_invoke_with<T, U, boost::void_t<decltype(
std::declval<T&>()(std::declval<U&>()))>>
: std::true_type
{
};
template<class T>
using is_decorator = std::integral_constant<bool,
can_invoke_with<T, request_type>::value ||
can_invoke_with<T, response_type>::value>;
class decorator class decorator
{ {
friend class decorator_test; friend class decorator_test;

View File

@ -14,6 +14,7 @@
#include <boost/beast/websocket/detail/decorator.hpp> #include <boost/beast/websocket/detail/decorator.hpp>
#include <boost/beast/core/role.hpp> #include <boost/beast/core/role.hpp>
#include <chrono> #include <chrono>
#include <type_traits>
namespace boost { namespace boost {
namespace beast { namespace beast {
@ -65,7 +66,13 @@ struct stream_base
@param f An invocable function object. Ownership of @param f An invocable function object. Ownership of
the function object is transferred by decay-copy. the function object is transferred by decay-copy.
*/ */
template<class Decorator> template<class Decorator
#ifndef BOOST_BEAST_DOXYGEN
,class = typename std::enable_if<
detail::is_decorator<
Decorator>::value>::type
#endif
>
decorator(Decorator&& f) decorator(Decorator&& f)
: d_(std::forward<Decorator>(f)) : d_(std::forward<Decorator>(f))
{ {

View File

@ -19,6 +19,40 @@ namespace websocket {
class stream_base_test : public unit_test::suite class stream_base_test : public unit_test::suite
{ {
public: public:
struct T1
{
void operator()(request_type&);
};
struct T2
{
void operator()(response_type&);
};
struct T3
{
void operator()(request_type&);
void operator()(response_type&);
};
struct T4
{
template<class T>
void operator()(T&);
};
struct T5
{
void operator()();
};
BOOST_STATIC_ASSERT(detail::is_decorator<T1>::value);
BOOST_STATIC_ASSERT(detail::is_decorator<T2>::value);
BOOST_STATIC_ASSERT(detail::is_decorator<T3>::value);
BOOST_STATIC_ASSERT(detail::is_decorator<T4>::value);
BOOST_STATIC_ASSERT(! detail::is_decorator<T5>::value);
BOOST_STATIC_ASSERT(! detail::is_decorator<int>::value);
void void
testJavadoc() testJavadoc()
{ {