diff --git a/CHANGELOG.md b/CHANGELOG.md index 937b2bdf..831ae945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Version 245: + +* decorator constructor is constrained + +-------------------------------------------------------------------------------- + Version 244: * Tidy up declval in some traits diff --git a/include/boost/beast/websocket/detail/decorator.hpp b/include/boost/beast/websocket/detail/decorator.hpp index e09b2c5d..cab7f9a2 100644 --- a/include/boost/beast/websocket/detail/decorator.hpp +++ b/include/boost/beast/websocket/detail/decorator.hpp @@ -25,6 +25,27 @@ namespace beast { namespace websocket { namespace detail { +// VFALCO NOTE: When this is two traits, one for +// request and one for response, +// Visual Studio 2015 fails. + +template +struct can_invoke_with : std::false_type +{ +}; + +template +struct can_invoke_with()(std::declval()))>> + : std::true_type +{ +}; + +template +using is_decorator = std::integral_constant::value || + can_invoke_with::value>; + class decorator { friend class decorator_test; diff --git a/include/boost/beast/websocket/stream_base.hpp b/include/boost/beast/websocket/stream_base.hpp index c25df25a..47d98d3d 100644 --- a/include/boost/beast/websocket/stream_base.hpp +++ b/include/boost/beast/websocket/stream_base.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace boost { namespace beast { @@ -65,7 +66,13 @@ struct stream_base @param f An invocable function object. Ownership of the function object is transferred by decay-copy. */ - template + template::value>::type +#endif + > decorator(Decorator&& f) : d_(std::forward(f)) { diff --git a/test/beast/websocket/stream_base.cpp b/test/beast/websocket/stream_base.cpp index f435dbd3..e61a51ed 100644 --- a/test/beast/websocket/stream_base.cpp +++ b/test/beast/websocket/stream_base.cpp @@ -19,6 +19,40 @@ namespace websocket { class stream_base_test : public unit_test::suite { 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 + void operator()(T&); + }; + + struct T5 + { + void operator()(); + }; + + BOOST_STATIC_ASSERT(detail::is_decorator::value); + BOOST_STATIC_ASSERT(detail::is_decorator::value); + BOOST_STATIC_ASSERT(detail::is_decorator::value); + BOOST_STATIC_ASSERT(detail::is_decorator::value); + BOOST_STATIC_ASSERT(! detail::is_decorator::value); + BOOST_STATIC_ASSERT(! detail::is_decorator::value); + void testJavadoc() {