Rename wrap() to bind_executor(). The executor_wrapper class has been temporarily renamed to executor_binder. This name will probably change.
diff --git a/asio/include/Makefile.am b/asio/include/Makefile.am index 9ea794a..cdd5114 100644 --- a/asio/include/Makefile.am +++ b/asio/include/Makefile.am
@@ -18,6 +18,7 @@ asio/basic_streambuf.hpp \ asio/basic_stream_socket.hpp \ asio/basic_waitable_timer.hpp \ + asio/bind_executor.hpp \ asio/buffered_read_stream_fwd.hpp \ asio/buffered_read_stream.hpp \ asio/buffered_stream_fwd.hpp \ @@ -453,7 +454,6 @@ asio/windows/random_access_handle_service.hpp \ asio/windows/stream_handle.hpp \ asio/windows/stream_handle_service.hpp \ - asio/wrap.hpp \ asio/write_at.hpp \ asio/write.hpp \ asio/yield.hpp
diff --git a/asio/include/asio.hpp b/asio/include/asio.hpp index 6224787..06febc6 100644 --- a/asio/include/asio.hpp +++ b/asio/include/asio.hpp
@@ -31,6 +31,7 @@ #include "asio/basic_stream_socket.hpp" #include "asio/basic_streambuf.hpp" #include "asio/basic_waitable_timer.hpp" +#include "asio/bind_executor.hpp" #include "asio/buffer.hpp" #include "asio/buffered_read_stream_fwd.hpp" #include "asio/buffered_read_stream.hpp" @@ -135,7 +136,6 @@ #include "asio/windows/random_access_handle_service.hpp" #include "asio/windows/stream_handle.hpp" #include "asio/windows/stream_handle_service.hpp" -#include "asio/wrap.hpp" #include "asio/write.hpp" #include "asio/write_at.hpp"
diff --git a/asio/include/asio/wrap.hpp b/asio/include/asio/bind_executor.hpp similarity index 65% rename from asio/include/asio/wrap.hpp rename to asio/include/asio/bind_executor.hpp index 505c003..562ce18 100644 --- a/asio/include/asio/wrap.hpp +++ b/asio/include/asio/bind_executor.hpp
@@ -1,6 +1,6 @@ // -// wrap.hpp -// ~~~~~~~~ +// bind_executor.hpp +// ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -8,8 +8,8 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef ASIO_WRAP_HPP -#define ASIO_WRAP_HPP +#ifndef ASIO_BIND_EXECUTOR_HPP +#define ASIO_BIND_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once @@ -29,7 +29,7 @@ namespace detail { template <typename T> -struct executor_wrapper_check +struct executor_binder_check { typedef void type; }; @@ -37,15 +37,15 @@ // Helper to automatically define nested typedef result_type. template <typename T, typename = void> -struct executor_wrapper_result_type +struct executor_binder_result_type { protected: typedef void result_type_or_void; }; template <typename T> -struct executor_wrapper_result_type<T, - typename executor_wrapper_check<typename T::result_type>::type> +struct executor_binder_result_type<T, + typename executor_binder_check<typename T::result_type>::type> { typedef typename T::result_type result_type; protected: @@ -53,7 +53,7 @@ }; template <typename R> -struct executor_wrapper_result_type<R(*)()> +struct executor_binder_result_type<R(*)()> { typedef R result_type; protected: @@ -61,7 +61,7 @@ }; template <typename R> -struct executor_wrapper_result_type<R(&)()> +struct executor_binder_result_type<R(&)()> { typedef R result_type; protected: @@ -69,7 +69,7 @@ }; template <typename R, typename A1> -struct executor_wrapper_result_type<R(*)(A1)> +struct executor_binder_result_type<R(*)(A1)> { typedef R result_type; protected: @@ -77,7 +77,7 @@ }; template <typename R, typename A1> -struct executor_wrapper_result_type<R(&)(A1)> +struct executor_binder_result_type<R(&)(A1)> { typedef R result_type; protected: @@ -85,7 +85,7 @@ }; template <typename R, typename A1, typename A2> -struct executor_wrapper_result_type<R(*)(A1, A2)> +struct executor_binder_result_type<R(*)(A1, A2)> { typedef R result_type; protected: @@ -93,7 +93,7 @@ }; template <typename R, typename A1, typename A2> -struct executor_wrapper_result_type<R(&)(A1, A2)> +struct executor_binder_result_type<R(&)(A1, A2)> { typedef R result_type; protected: @@ -103,23 +103,23 @@ // Helper to automatically define nested typedef argument_type. template <typename T, typename = void> -struct executor_wrapper_argument_type {}; +struct executor_binder_argument_type {}; template <typename T> -struct executor_wrapper_argument_type<T, - typename executor_wrapper_check<typename T::argument_type>::type> +struct executor_binder_argument_type<T, + typename executor_binder_check<typename T::argument_type>::type> { typedef typename T::argument_type argument_type; }; template <typename R, typename A1> -struct executor_wrapper_argument_type<R(*)(A1)> +struct executor_binder_argument_type<R(*)(A1)> { typedef A1 argument_type; }; template <typename R, typename A1> -struct executor_wrapper_argument_type<R(&)(A1)> +struct executor_binder_argument_type<R(&)(A1)> { typedef A1 argument_type; }; @@ -128,25 +128,25 @@ // second_argument_type. template <typename T, typename = void> -struct executor_wrapper_argument_types {}; +struct executor_binder_argument_types {}; template <typename T> -struct executor_wrapper_argument_types<T, - typename executor_wrapper_check<typename T::first_argument_type>::type> +struct executor_binder_argument_types<T, + typename executor_binder_check<typename T::first_argument_type>::type> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type; }; template <typename R, typename A1, typename A2> -struct executor_wrapper_argument_type<R(*)(A1, A2)> +struct executor_binder_argument_type<R(*)(A1, A2)> { typedef A1 first_argument_type; typedef A2 second_argument_type; }; template <typename R, typename A1, typename A2> -struct executor_wrapper_argument_type<R(&)(A1, A2)> +struct executor_binder_argument_type<R(&)(A1, A2)> { typedef A1 first_argument_type; typedef A2 second_argument_type; @@ -154,74 +154,74 @@ // Helper to: // - Apply the empty base optimisation to the executor. -// - Perform uses_executor construction of the wrapped type, if required. +// - Perform uses_executor construction of the target type, if required. template <typename T, typename Executor, bool UsesExecutor> -class executor_wrapper_base; +class executor_binder_base; template <typename T, typename Executor> -class executor_wrapper_base<T, Executor, true> +class executor_binder_base<T, Executor, true> : protected Executor { protected: template <typename E, typename U> - executor_wrapper_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) + executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) : Executor(ASIO_MOVE_CAST(E)(e)), - wrapped_(executor_arg_t(), static_cast<const Executor&>(*this), + target_(executor_arg_t(), static_cast<const Executor&>(*this), ASIO_MOVE_CAST(U)(u)) { } - T wrapped_; + T target_; }; template <typename T, typename Executor> -class executor_wrapper_base<T, Executor, false> +class executor_binder_base<T, Executor, false> : protected Executor { protected: template <typename E, typename U> - executor_wrapper_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) + executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u) : Executor(ASIO_MOVE_CAST(E)(e)), - wrapped_(ASIO_MOVE_CAST(U)(u)) + target_(ASIO_MOVE_CAST(U)(u)) { } - T wrapped_; + T target_; }; // Helper to enable SFINAE on zero-argument operator() below. template <typename T, typename = void> -struct executor_wrapper_result_of0 +struct executor_binder_result_of0 { typedef void type; }; template <typename T> -struct executor_wrapper_result_of0<T, - typename executor_wrapper_check<typename result_of<T()>::type>::type> +struct executor_binder_result_of0<T, + typename executor_binder_check<typename result_of<T()>::type>::type> { typedef typename result_of<T()>::type type; }; } // namespace detail -/// A call wrapper type to associate an object of type @c T with an executor of -/// type @c Executor. +/// A call wrapper type to bind an executor of type @c Executor to an object of +/// type @c T. template <typename T, typename Executor> -class executor_wrapper +class executor_binder #if !defined(GENERATING_DOCUMENTATION) - : public detail::executor_wrapper_result_type<T>, - public detail::executor_wrapper_argument_type<T>, - public detail::executor_wrapper_argument_types<T>, - private detail::executor_wrapper_base< + : public detail::executor_binder_result_type<T>, + public detail::executor_binder_argument_type<T>, + public detail::executor_binder_argument_types<T>, + private detail::executor_binder_base< T, Executor, uses_executor<T, Executor>::value> #endif // !defined(GENERATING_DOCUMENTATION) { public: - /// The type of the wrapped object. - typedef T wrapped_type; + /// The type of the target object. + typedef T target_type; /// The type of the associated executor. typedef Executor executor_type; @@ -294,22 +294,22 @@ * @c U. */ template <typename U> - executor_wrapper(executor_arg_t, const executor_type& e, + executor_binder(executor_arg_t, const executor_type& e, ASIO_MOVE_ARG(U) u) : base_type(e, ASIO_MOVE_CAST(U)(u)) { } /// Copy constructor. - executor_wrapper(const executor_wrapper& other) - : base_type(other.get_executor(), other.unwrap()) + executor_binder(const executor_binder& other) + : base_type(other.get_executor(), other.get()) { } /// Construct a copy, but specify a different executor. - executor_wrapper(executor_arg_t, const executor_type& e, - const executor_wrapper& other) - : base_type(e, other.unwrap()) + executor_binder(executor_arg_t, const executor_type& e, + const executor_binder& other) + : base_type(e, other.get()) { } @@ -320,8 +320,8 @@ * @c U. */ template <typename U, typename OtherExecutor> - executor_wrapper(const executor_wrapper<U, OtherExecutor>& other) - : base_type(other.get_executor(), other.unwrap()) + executor_binder(const executor_binder<U, OtherExecutor>& other) + : base_type(other.get_executor(), other.get()) { } @@ -332,62 +332,62 @@ * @c U. */ template <typename U, typename OtherExecutor> - executor_wrapper(executor_arg_t, const executor_type& e, - const executor_wrapper<U, OtherExecutor>& other) - : base_type(e, other.unwrap()) + executor_binder(executor_arg_t, const executor_type& e, + const executor_binder<U, OtherExecutor>& other) + : base_type(e, other.get()) { } #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. - executor_wrapper(executor_wrapper&& other) + executor_binder(executor_binder&& other) : base_type(ASIO_MOVE_CAST(executor_type)(other.get_executor()), - ASIO_MOVE_CAST(T)(other.unwrap())) + ASIO_MOVE_CAST(T)(other.get())) { } - /// Move construct the wrapped object, but specify a different executor. - executor_wrapper(executor_arg_t, const executor_type& e, - executor_wrapper&& other) - : base_type(e, ASIO_MOVE_CAST(T)(other.unwrap())) + /// Move construct the target object, but specify a different executor. + executor_binder(executor_arg_t, const executor_type& e, + executor_binder&& other) + : base_type(e, ASIO_MOVE_CAST(T)(other.get())) { } /// Move construct from a different executor wrapper type. template <typename U, typename OtherExecutor> - executor_wrapper(executor_wrapper<U, OtherExecutor>&& other) + executor_binder(executor_binder<U, OtherExecutor>&& other) : base_type(ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()), - ASIO_MOVE_CAST(U)(other.unwrap())) + ASIO_MOVE_CAST(U)(other.get())) { } /// Move construct from a different executor wrapper type, but specify a /// different executor. template <typename U, typename OtherExecutor> - executor_wrapper(executor_arg_t, const executor_type& e, - executor_wrapper<U, OtherExecutor>&& other) - : base_type(e, ASIO_MOVE_CAST(U)(other.unwrap())) + executor_binder(executor_arg_t, const executor_type& e, + executor_binder<U, OtherExecutor>&& other) + : base_type(e, ASIO_MOVE_CAST(U)(other.get())) { } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. - ~executor_wrapper() + ~executor_binder() { } - /// Obtain a reference to the wrapped object. - wrapped_type& unwrap() ASIO_NOEXCEPT + /// Obtain a reference to the target object. + target_type& get() ASIO_NOEXCEPT { - return this->wrapped_; + return this->target_; } - /// Obtain a reference to the wrapped object. - const wrapped_type& unwrap() const ASIO_NOEXCEPT + /// Obtain a reference to the target object. + const target_type& get() const ASIO_NOEXCEPT { - return this->wrapped_; + return this->target_; } /// Obtain the associated executor. @@ -408,7 +408,7 @@ typename result_of<T(Args...)>::type operator()( ASIO_MOVE_ARG(Args)... args) { - return this->wrapped_(ASIO_MOVE_CAST(Args)(args)...); + return this->target_(ASIO_MOVE_CAST(Args)(args)...); } /// Forwarding function call operator. @@ -416,98 +416,98 @@ typename result_of<T(Args...)>::type operator()( ASIO_MOVE_ARG(Args)... args) const { - return this->wrapped_(ASIO_MOVE_CAST(Args)(args)...); + return this->target_(ASIO_MOVE_CAST(Args)(args)...); } #elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) - typename detail::executor_wrapper_result_of0<T>::type operator()() + typename detail::executor_binder_result_of0<T>::type operator()() { - return this->wrapped_(); + return this->target_(); } - typename detail::executor_wrapper_result_of0<T>::type operator()() const + typename detail::executor_binder_result_of0<T>::type operator()() const { - return this->wrapped_(); + return this->target_(); } -#define ASIO_PRIVATE_WRAP_CALL_DEF(n) \ +#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \ template <ASIO_VARIADIC_TPARAMS(n)> \ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ - return this->wrapped_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template <ASIO_VARIADIC_TPARAMS(n)> \ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) const \ { \ - return this->wrapped_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ - ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_WRAP_CALL_DEF) -#undef ASIO_PRIVATE_WRAP_CALL_DEF + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF) +#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF #else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) - typedef typename detail::executor_wrapper_result_type<T>::result_type_or_void + typedef typename detail::executor_binder_result_type<T>::result_type_or_void result_type_or_void; result_type_or_void operator()() { - return this->wrapped_(); + return this->target_(); } result_type_or_void operator()() const { - return this->wrapped_(); + return this->target_(); } -#define ASIO_PRIVATE_WRAP_CALL_DEF(n) \ +#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \ template <ASIO_VARIADIC_TPARAMS(n)> \ result_type_or_void operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) \ { \ - return this->wrapped_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template <ASIO_VARIADIC_TPARAMS(n)> \ result_type_or_void operator()( \ ASIO_VARIADIC_MOVE_PARAMS(n)) const \ { \ - return this->wrapped_(ASIO_VARIADIC_MOVE_ARGS(n)); \ + return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ - ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_WRAP_CALL_DEF) -#undef ASIO_PRIVATE_WRAP_CALL_DEF + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF) +#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF #endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) private: - typedef detail::executor_wrapper_base<T, Executor, + typedef detail::executor_binder_base<T, Executor, uses_executor<T, Executor>::value> base_type; }; /// Associate an object of type @c T with an executor of type @c Executor. template <typename Executor, typename T> -inline executor_wrapper<typename decay<T>::type, Executor> -wrap(const Executor& ex, ASIO_MOVE_ARG(T) t, +inline executor_binder<typename decay<T>::type, Executor> +bind_executor(const Executor& ex, ASIO_MOVE_ARG(T) t, typename enable_if<is_executor<Executor>::value>::type* = 0) { - return executor_wrapper<typename decay<T>::type, Executor>( + return executor_binder<typename decay<T>::type, Executor>( executor_arg_t(), ex, ASIO_MOVE_CAST(T)(t)); } /// Associate an object of type @c T with an execution context's executor. template <typename ExecutionContext, typename T> -inline executor_wrapper<typename decay<T>::type, +inline executor_binder<typename decay<T>::type, typename ExecutionContext::executor_type> -wrap(ExecutionContext& ctx, ASIO_MOVE_ARG(T) t, +bind_executor(ExecutionContext& ctx, ASIO_MOVE_ARG(T) t, typename enable_if<is_convertible< ExecutionContext&, execution_context&>::value>::type* = 0) { - return executor_wrapper<typename decay<T>::type, + return executor_binder<typename decay<T>::type, typename ExecutionContext::executor_type>( executor_arg_t(), ctx.get_executor(), ASIO_MOVE_CAST(T)(t)); } @@ -515,57 +515,57 @@ #if !defined(GENERATING_DOCUMENTATION) template <typename T, typename Executor> -struct uses_executor<executor_wrapper<T, Executor>, Executor> +struct uses_executor<executor_binder<T, Executor>, Executor> : true_type {}; template <typename T, typename Executor, typename Signature> -struct handler_type<executor_wrapper<T, Executor>, Signature> +struct handler_type<executor_binder<T, Executor>, Signature> { - typedef executor_wrapper< + typedef executor_binder< typename handler_type<T, Signature>::type, Executor> type; }; template <typename T, typename Executor> -class async_result<executor_wrapper<T, Executor> > +class async_result<executor_binder<T, Executor> > { public: typedef typename async_result<T>::type type; - explicit async_result(executor_wrapper<T, Executor>& w) - : wrapped_(w.unwrap()) + explicit async_result(executor_binder<T, Executor>& b) + : target_(b.get()) { } type get() { - return wrapped_.get(); + return target_.get(); } private: - async_result<T> wrapped_; + async_result<T> target_; }; template <typename T, typename Executor, typename Allocator> -struct associated_allocator<executor_wrapper<T, Executor>, Allocator> +struct associated_allocator<executor_binder<T, Executor>, Allocator> { typedef typename associated_allocator<T, Allocator>::type type; - static type get(const executor_wrapper<T, Executor>& w, + static type get(const executor_binder<T, Executor>& b, const Allocator& a = Allocator()) ASIO_NOEXCEPT { - return associated_allocator<T, Allocator>::get(w.unwrap(), a); + return associated_allocator<T, Allocator>::get(b.get(), a); } }; template <typename T, typename Executor, typename Executor1> -struct associated_executor<executor_wrapper<T, Executor>, Executor1> +struct associated_executor<executor_binder<T, Executor>, Executor1> { typedef Executor type; - static type get(const executor_wrapper<T, Executor>& w, + static type get(const executor_binder<T, Executor>& b, const Executor1& = Executor1()) ASIO_NOEXCEPT { - return w.get_executor(); + return b.get_executor(); } }; @@ -575,4 +575,4 @@ #include "asio/detail/pop_options.hpp" -#endif // ASIO_WRAP_HPP +#endif // ASIO_BIND_EXECUTOR_HPP
diff --git a/asio/include/asio/impl/spawn.hpp b/asio/include/asio/impl/spawn.hpp index 2efc1f9..32561d1 100644 --- a/asio/include/asio/impl/spawn.hpp +++ b/asio/include/asio/impl/spawn.hpp
@@ -19,6 +19,7 @@ #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/async_result.hpp" +#include "asio/bind_executor.hpp" #include "asio/detail/atomic_count.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" @@ -27,7 +28,6 @@ #include "asio/detail/noncopyable.hpp" #include "asio/handler_type.hpp" #include "asio/system_error.hpp" -#include "asio/wrap.hpp" #include "asio/detail/push_options.hpp" @@ -417,7 +417,8 @@ ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes) { - asio::spawn(asio::wrap(ex, &detail::default_spawn_handler), + asio::spawn(asio::bind_executor( + ex, &detail::default_spawn_handler), ASIO_MOVE_CAST(Function)(function), attributes); } @@ -426,7 +427,8 @@ ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes& attributes) { - asio::spawn(asio::wrap(s, &detail::default_spawn_handler), + asio::spawn(asio::bind_executor( + s, &detail::default_spawn_handler), ASIO_MOVE_CAST(Function)(function), attributes); }
diff --git a/asio/include/asio/io_service.hpp b/asio/include/asio/io_service.hpp index 9d7c489..fc6cc60 100644 --- a/asio/include/asio/io_service.hpp +++ b/asio/include/asio/io_service.hpp
@@ -447,7 +447,7 @@ ASIO_INITFN_RESULT_TYPE(CompletionHandler, void ()) post(ASIO_MOVE_ARG(CompletionHandler) handler); - /// (Deprecated: Use asio::wrap().) Create a new handler that + /// (Deprecated: Use asio::bind_executor().) Create a new handler that /// automatically dispatches the wrapped handler on the io_service. /** * This function is used to create a new handler function object that, when
diff --git a/asio/include/asio/io_service_strand.hpp b/asio/include/asio/io_service_strand.hpp index 3123a5e..e8e1c5a 100644 --- a/asio/include/asio/io_service_strand.hpp +++ b/asio/include/asio/io_service_strand.hpp
@@ -286,7 +286,7 @@ } #if !defined(ASIO_NO_DEPRECATED) - /// (Deprecated: Use asio::wrap().) Create a new handler that + /// (Deprecated: Use asio::bind_executor().) Create a new handler that /// automatically dispatches the wrapped handler on the strand. /** * This function is used to create a new handler function object that, when
diff --git a/asio/include/asio/spawn.hpp b/asio/include/asio/spawn.hpp index c21658c..607e703 100644 --- a/asio/include/asio/spawn.hpp +++ b/asio/include/asio/spawn.hpp
@@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include <boost/coroutine/all.hpp> +#include "asio/bind_executor.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/wrapped_handler.hpp" @@ -24,7 +25,6 @@ #include "asio/io_service.hpp" #include "asio/is_executor.hpp" #include "asio/strand.hpp" -#include "asio/wrap.hpp" #include "asio/detail/push_options.hpp" @@ -151,7 +151,7 @@ typedef basic_yield_context<unspecified> yield_context; #else // defined(GENERATING_DOCUMENTATION) typedef basic_yield_context< - executor_wrapper<void(*)(), executor> > yield_context; + executor_binder<void(*)(), executor> > yield_context; #endif // defined(GENERATING_DOCUMENTATION) /**
diff --git a/asio/include/asio/ts/executor.hpp b/asio/include/asio/ts/executor.hpp index ead54cd..3f0759f 100644 --- a/asio/include/asio/ts/executor.hpp +++ b/asio/include/asio/ts/executor.hpp
@@ -21,7 +21,7 @@ #include "asio/execution_context.hpp" #include "asio/is_executor.hpp" #include "asio/associated_executor.hpp" -#include "asio/wrap.hpp" +#include "asio/bind_executor.hpp" #include "asio/executor_work.hpp" #include "asio/system_executor.hpp" #include "asio/executor.hpp"
diff --git a/asio/src/doc/overview/strands.qbk b/asio/src/doc/overview/strands.qbk index 8571030..7e0982b 100644 --- a/asio/src/doc/overview/strands.qbk +++ b/asio/src/doc/overview/strands.qbk
@@ -24,37 +24,60 @@ no possibility of concurrent execution of the handlers. This is an implicit strand. -* An explicit strand is an instance of `io_service::strand`. All event handler - function objects need to be wrapped using `io_service::strand::wrap()` or - otherwise posted/dispatched through the `io_service::strand` object. +* An explicit strand is an instance of `strand<>` or `io_service::strand`. All + event handler function objects need to be bound to the strand using + `asio::bind_executor()` or otherwise posted/dispatched through the strand + object. In the case of composed asynchronous operations, such as `async_read()` or `async_read_until()`, if a completion handler goes through a strand, then all intermediate handlers should also go through the same strand. This is needed to ensure thread safe access for any objects that are shared between the caller and the composed operation (in the case of `async_read()` it's the socket, -which the caller can close() to cancel the operation). This is done by having -hook functions for all intermediate handlers which forward the calls to the -customisable hook associated with the final handler: +which the caller can `close()` to cancel the operation). + +This is done by partially specialising the `asio::ssociated_executor<>` trait +for all intermediate handlers. This trait forwards to the corresponding trait +specialisation for the final handler: struct my_handler { void operator()() { ... } }; - template<class F> - void asio_handler_invoke(F f, my_handler*) - { - // Do custom invocation here. - // Default implementation calls f(); - } + namespace asio { -The `io_service::strand::wrap()` function creates a new completion handler that -defines `asio_handler_invoke` so that the function object is executed through -the strand. + template <class Executor> + struct associated_executor<my_handler, Executor> + { + // Custom implementation of Executor type requirements. + typedef my_executor type; + + // Return a custom executor implementation. + static type get(const my_handler&, const Executor& = Executor()) + { + return my_executor(); + } + }; + + } // namespace asio + +The `asio::bind_executor()` function is a helper to bind a specific executor +object, such as a strand, to a completion handler. This binding automatically +specialises the `associated_executor` trait as shown above. For example, to +bind a strand to a completion handler we would simply write: + + my_socket.async_read_some(my_buffer, + asio::bind_executor(my_strand, + [](error_code ec, size_t length) + { + // ... + })); [heading See Also] +[link asio.reference.bind_executor bind_executor], +[link asio.reference.strand strand], [link asio.reference.io_service__strand io_service::strand], [link asio.tutorial.tuttimer5 tutorial Timer.5], [link asio.examples.cpp03_examples.http_server_3 HTTP server 3 example].
diff --git a/asio/src/doc/quickref.xml b/asio/src/doc/quickref.xml index 5d9d0c7..49f72d3 100644 --- a/asio/src/doc/quickref.xml +++ b/asio/src/doc/quickref.xml
@@ -57,6 +57,7 @@ <member><link linkend="asio.reference.asio_handler_deallocate">asio_handler_deallocate</link></member> <member><link linkend="asio.reference.asio_handler_invoke">asio_handler_invoke</link></member> <member><link linkend="asio.reference.asio_handler_is_continuation">asio_handler_is_continuation</link></member> + <member><link linkend="asio.reference.bind_executor">bind_executor</link></member> <member><link linkend="asio.reference.dispatch">dispatch</link></member> <member><link linkend="asio.reference.defer">defer</link></member> <member><link linkend="asio.reference.get_associated_allocator">get_associated_allocator</link></member> @@ -67,7 +68,6 @@ <member><link linkend="asio.reference.post">post</link></member> <member><link linkend="asio.reference.spawn">spawn</link></member> <member><link linkend="asio.reference.use_service">use_service</link></member> - <member><link linkend="asio.reference.wrap">wrap</link></member> </simplelist> </entry> <entry valign="top">
diff --git a/asio/src/examples/cpp03/http/server3/connection.cpp b/asio/src/examples/cpp03/http/server3/connection.cpp index ea0d2fe..2f30145 100644 --- a/asio/src/examples/cpp03/http/server3/connection.cpp +++ b/asio/src/examples/cpp03/http/server3/connection.cpp
@@ -32,7 +32,7 @@ void connection::start() { socket_.async_read_some(asio::buffer(buffer_), - asio::wrap(strand_, + asio::bind_executor(strand_, boost::bind(&connection::handle_read, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred))); @@ -51,7 +51,7 @@ { request_handler_.handle_request(request_, reply_); asio::async_write(socket_, reply_.to_buffers(), - asio::wrap(strand_, + asio::bind_executor(strand_, boost::bind(&connection::handle_write, shared_from_this(), asio::placeholders::error))); } @@ -59,14 +59,14 @@ { reply_ = reply::stock_reply(reply::bad_request); asio::async_write(socket_, reply_.to_buffers(), - asio::wrap(strand_, + asio::bind_executor(strand_, boost::bind(&connection::handle_write, shared_from_this(), asio::placeholders::error))); } else { socket_.async_read_some(asio::buffer(buffer_), - asio::wrap(strand_, + asio::bind_executor(strand_, boost::bind(&connection::handle_read, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred)));
diff --git a/asio/src/examples/cpp03/tutorial/timer5/timer.cpp b/asio/src/examples/cpp03/tutorial/timer5/timer.cpp index 77c2081..5906748 100644 --- a/asio/src/examples/cpp03/tutorial/timer5/timer.cpp +++ b/asio/src/examples/cpp03/tutorial/timer5/timer.cpp
@@ -22,10 +22,10 @@ timer2_(io, boost::posix_time::seconds(1)), count_(0) { - timer1_.async_wait(asio::wrap(strand_, + timer1_.async_wait(asio::bind_executor(strand_, boost::bind(&printer::print1, this))); - timer2_.async_wait(asio::wrap(strand_, + timer2_.async_wait(asio::bind_executor(strand_, boost::bind(&printer::print2, this))); } @@ -43,7 +43,7 @@ timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1)); - timer1_.async_wait(asio::wrap(strand_, + timer1_.async_wait(asio::bind_executor(strand_, boost::bind(&printer::print1, this))); } } @@ -57,7 +57,7 @@ timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1)); - timer2_.async_wait(asio::wrap(strand_, + timer2_.async_wait(asio::bind_executor(strand_, boost::bind(&printer::print2, this))); } }
diff --git a/asio/src/examples/cpp03/tutorial/timer_dox.txt b/asio/src/examples/cpp03/tutorial/timer_dox.txt index 30aa20f..56fabdb 100644 --- a/asio/src/examples/cpp03/tutorial/timer_dox.txt +++ b/asio/src/examples/cpp03/tutorial/timer_dox.txt
@@ -331,22 +331,23 @@ constructor initialises the <tt>strand_</tt> member, an object of type asio::io_service::strand. -An asio::io_service::strand guarantees that, for those handlers that are -dispatched through it, an executing handler will be allowed to complete before -the next one is started. This is guaranteed irrespective of the number of -threads that are calling asio::io_service::run(). Of course, the handlers may -still execute concurrently with other handlers that were <b>not</b> dispatched -through an asio::io_service::strand, or were dispatched through a different -asio::io_service::strand object. +An asio::io_service::strand is an executor that guarantees that, for those +handlers that are dispatched through it, an executing handler will be allowed +to complete before the next one is started. This is guaranteed irrespective of +the number of threads that are calling asio::io_service::run(). Of course, the +handlers may still execute concurrently with other handlers that were +<b>not</b> dispatched through an asio::io_service::strand, or were dispatched +through a different asio::io_service::strand object. \until { -When initiating the asynchronous operations, each callback handler is "wrapped" -using the asio::io_service::strand object. The asio::io_service::strand::wrap() -function returns a new handler that automatically dispatches its contained -handler through the asio::io_service::strand object. By wrapping the handlers -using the same asio::io_service::strand, we are ensuring that they cannot -execute concurrently. +When initiating the asynchronous operations, each callback handler is "bound" +to an asio::io_service::strand object. The +asio::io_service::strand::bind_executor() function returns a new handler that +automatically dispatches its contained handler through the +asio::io_service::strand object. By binding the handlers to the same +asio::io_service::strand, we are ensuring that they cannot execute +concurrently. \until } \until }
diff --git a/asio/src/examples/cpp11/executors/pipeline.cpp b/asio/src/examples/cpp11/executors/pipeline.cpp index 098565b..4bfa169 100644 --- a/asio/src/examples/cpp11/executors/pipeline.cpp +++ b/asio/src/examples/cpp11/executors/pipeline.cpp
@@ -1,9 +1,9 @@ #include <asio/associated_executor.hpp> +#include <asio/bind_executor.hpp> #include <asio/execution_context.hpp> #include <asio/package.hpp> #include <asio/post.hpp> #include <asio/system_executor.hpp> -#include <asio/wrap.hpp> #include <condition_variable> #include <future> #include <memory> @@ -13,7 +13,7 @@ #include <vector> using asio::execution_context; -using asio::executor_wrapper; +using asio::executor_binder; using asio::get_associated_executor; using asio::package; using asio::post; @@ -202,7 +202,7 @@ std::future<void> pipeline(queue_back<T> in, F f, Tail... t) { // Determine the output queue type. - typedef typename executor_wrapper<F, thread_executor>::second_argument_type::value_type output_value_type; + typedef typename executor_binder<F, thread_executor>::second_argument_type::value_type output_value_type; // Create the output queue and its implementation. auto out_impl = std::make_shared<queue_impl<output_value_type>>(); @@ -228,7 +228,7 @@ std::future<void> pipeline(F f, Tail... t) { // Determine the output queue type. - typedef typename executor_wrapper<F, thread_executor>::argument_type::value_type output_value_type; + typedef typename executor_binder<F, thread_executor>::argument_type::value_type output_value_type; // Create the output queue and its implementation. auto out_impl = std::make_shared<queue_impl<output_value_type>>(); @@ -255,8 +255,8 @@ #include <iostream> #include <string> +using asio::bind_executor; using asio::thread_pool; -using asio::wrap; void reader(queue_front<std::string> out) { @@ -297,6 +297,6 @@ { thread_pool pool; - auto f = pipeline(reader, filter, wrap(pool, upper), writer); + auto f = pipeline(reader, filter, bind_executor(pool, upper), writer); f.wait(); }
diff --git a/asio/src/examples/cpp14/executors/async_1.cpp b/asio/src/examples/cpp14/executors/async_1.cpp index 5317551..2a78894 100644 --- a/asio/src/examples/cpp14/executors/async_1.cpp +++ b/asio/src/examples/cpp14/executors/async_1.cpp
@@ -3,11 +3,11 @@ #include <iostream> #include <string> +using asio::bind_executor; using asio::dispatch; using asio::make_work; using asio::post; using asio::thread_pool; -using asio::wrap; // A function to asynchronously read a single line from an input stream. template <class Handler> @@ -38,7 +38,7 @@ std::cout << "Enter a line: "; async_getline(std::cin, - wrap(pool, [](std::string line) + bind_executor(pool, [](std::string line) { std::cout << "Line: " << line << "\n"; }));
diff --git a/asio/src/examples/cpp14/executors/async_2.cpp b/asio/src/examples/cpp14/executors/async_2.cpp index 6fa0360..4d7695f 100644 --- a/asio/src/examples/cpp14/executors/async_2.cpp +++ b/asio/src/examples/cpp14/executors/async_2.cpp
@@ -3,12 +3,12 @@ #include <iostream> #include <string> +using asio::bind_executor; using asio::dispatch; using asio::get_associated_executor; using asio::make_work; using asio::post; using asio::thread_pool; -using asio::wrap; // A function to asynchronously read a single line from an input stream. template <class Handler> @@ -41,7 +41,7 @@ // Use the associated executor for each operation in the composition. async_getline(is, - wrap(ex, + bind_executor(ex, [&is, lines=std::move(init), handler=std::move(handler)] (std::string line) mutable { @@ -59,7 +59,7 @@ std::cout << "Enter text, terminating with a blank line:\n"; async_getlines(std::cin, "", - wrap(pool, [](std::string lines) + bind_executor(pool, [](std::string lines) { std::cout << "Lines:\n" << lines << "\n"; }));
diff --git a/asio/src/examples/cpp14/executors/pipeline.cpp b/asio/src/examples/cpp14/executors/pipeline.cpp index 0610b3f..484b959 100644 --- a/asio/src/examples/cpp14/executors/pipeline.cpp +++ b/asio/src/examples/cpp14/executors/pipeline.cpp
@@ -8,7 +8,7 @@ #include <vector> using asio::execution_context; -using asio::executor_wrapper; +using asio::executor_binder; using asio::get_associated_executor; using asio::package; using asio::post; @@ -197,7 +197,7 @@ std::future<void> pipeline(queue_back<T> in, F f, Tail... t) { // Determine the output queue type. - typedef typename executor_wrapper<F, thread_executor>::second_argument_type::value_type output_value_type; + typedef typename executor_binder<F, thread_executor>::second_argument_type::value_type output_value_type; // Create the output queue and its implementation. auto out_impl = std::make_shared<queue_impl<output_value_type>>(); @@ -223,7 +223,7 @@ std::future<void> pipeline(F f, Tail... t) { // Determine the output queue type. - typedef typename executor_wrapper<F, thread_executor>::argument_type::value_type output_value_type; + typedef typename executor_binder<F, thread_executor>::argument_type::value_type output_value_type; // Create the output queue and its implementation. auto out_impl = std::make_shared<queue_impl<output_value_type>>(); @@ -250,8 +250,8 @@ #include <iostream> #include <string> +using asio::bind_executor; using asio::thread_pool; -using asio::wrap; void reader(queue_front<std::string> out) { @@ -292,6 +292,6 @@ { thread_pool pool; - auto f = pipeline(reader, filter, wrap(pool, upper), writer); + auto f = pipeline(reader, filter, bind_executor(pool, upper), writer); f.wait(); }
diff --git a/asio/src/tests/performance/client.cpp b/asio/src/tests/performance/client.cpp index 13b3a57..dfd71dc 100644 --- a/asio/src/tests/performance/client.cpp +++ b/asio/src/tests/performance/client.cpp
@@ -77,7 +77,8 @@ void start(asio::ip::tcp::resolver::results_type endpoints) { asio::async_connect(socket_, endpoints, - asio::wrap(strand_,boost::bind(&session::handle_connect, this, + asio::bind_executor(strand_, + boost::bind(&session::handle_connect, this, asio::placeholders::error))); } @@ -98,13 +99,13 @@ { ++unwritten_count_; async_write(socket_, asio::buffer(write_data_, block_size_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(write_allocator_, boost::bind(&session::handle_write, this, asio::placeholders::error, asio::placeholders::bytes_transferred)))); socket_.async_read_some(asio::buffer(read_data_, block_size_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(read_allocator_, boost::bind(&session::handle_read, this, asio::placeholders::error, @@ -125,13 +126,13 @@ { std::swap(read_data_, write_data_); async_write(socket_, asio::buffer(write_data_, read_data_length_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(write_allocator_, boost::bind(&session::handle_write, this, asio::placeholders::error, asio::placeholders::bytes_transferred)))); socket_.async_read_some(asio::buffer(read_data_, block_size_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(read_allocator_, boost::bind(&session::handle_read, this, asio::placeholders::error, @@ -151,13 +152,13 @@ { std::swap(read_data_, write_data_); async_write(socket_, asio::buffer(write_data_, read_data_length_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(write_allocator_, boost::bind(&session::handle_write, this, asio::placeholders::error, asio::placeholders::bytes_transferred)))); socket_.async_read_some(asio::buffer(read_data_, block_size_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(read_allocator_, boost::bind(&session::handle_read, this, asio::placeholders::error,
diff --git a/asio/src/tests/performance/server.cpp b/asio/src/tests/performance/server.cpp index c21255a..9b8a124 100644 --- a/asio/src/tests/performance/server.cpp +++ b/asio/src/tests/performance/server.cpp
@@ -51,7 +51,7 @@ { ++op_count_; socket_.async_read_some(asio::buffer(read_data_, block_size_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(read_allocator_, boost::bind(&session::handle_read, this, asio::placeholders::error, @@ -76,12 +76,12 @@ op_count_ += 2; std::swap(read_data_, write_data_); async_write(socket_, asio::buffer(write_data_, read_data_length_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(write_allocator_, boost::bind(&session::handle_write, this, asio::placeholders::error)))); socket_.async_read_some(asio::buffer(read_data_, block_size_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(read_allocator_, boost::bind(&session::handle_read, this, asio::placeholders::error, @@ -105,12 +105,12 @@ op_count_ += 2; std::swap(read_data_, write_data_); async_write(socket_, asio::buffer(write_data_, read_data_length_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(write_allocator_, boost::bind(&session::handle_write, this, asio::placeholders::error)))); socket_.async_read_some(asio::buffer(read_data_, block_size_), - asio::wrap(strand_, + asio::bind_executor(strand_, make_custom_alloc_handler(read_allocator_, boost::bind(&session::handle_read, this, asio::placeholders::error,