?????????? ????????? - ??????????????? - /home/agenciai/public_html/cd38d8/asio.zip
???????
PK q��[2 2 placeholders.hppnu �[��� // // placeholders.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_PLACEHOLDERS_HPP #define BOOST_ASIO_PLACEHOLDERS_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_BOOST_BIND) # include <boost/bind/arg.hpp> #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace placeholders { #if defined(GENERATING_DOCUMENTATION) /// An argument placeholder, for use with boost::bind(), that corresponds to /// the error argument of a handler for any of the asynchronous functions. unspecified error; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the bytes_transferred argument of a handler for asynchronous functions such /// as boost::asio::basic_stream_socket::async_write_some or /// boost::asio::async_write. unspecified bytes_transferred; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the iterator argument of a handler for asynchronous functions such as /// boost::asio::async_connect. unspecified iterator; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the results argument of a handler for asynchronous functions such as /// boost::asio::basic_resolver::async_resolve. unspecified results; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the results argument of a handler for asynchronous functions such as /// boost::asio::async_connect. unspecified endpoint; /// An argument placeholder, for use with boost::bind(), that corresponds to /// the signal_number argument of a handler for asynchronous functions such as /// boost::asio::signal_set::async_wait. unspecified signal_number; #elif defined(BOOST_ASIO_HAS_BOOST_BIND) # if defined(__BORLANDC__) || defined(__GNUC__) inline boost::arg<1> error() { return boost::arg<1>(); } inline boost::arg<2> bytes_transferred() { return boost::arg<2>(); } inline boost::arg<2> iterator() { return boost::arg<2>(); } inline boost::arg<2> results() { return boost::arg<2>(); } inline boost::arg<2> endpoint() { return boost::arg<2>(); } inline boost::arg<2> signal_number() { return boost::arg<2>(); } # else namespace detail { template <int Number> struct placeholder { static boost::arg<Number>& get() { static boost::arg<Number> result; return result; } }; } # if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC < 1400) static boost::arg<1>& error = boost::asio::placeholders::detail::placeholder<1>::get(); static boost::arg<2>& bytes_transferred = boost::asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& iterator = boost::asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& results = boost::asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& endpoint = boost::asio::placeholders::detail::placeholder<2>::get(); static boost::arg<2>& signal_number = boost::asio::placeholders::detail::placeholder<2>::get(); # else namespace { boost::arg<1>& error = boost::asio::placeholders::detail::placeholder<1>::get(); boost::arg<2>& bytes_transferred = boost::asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& iterator = boost::asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& results = boost::asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& endpoint = boost::asio::placeholders::detail::placeholder<2>::get(); boost::arg<2>& signal_number = boost::asio::placeholders::detail::placeholder<2>::get(); } // namespace # endif # endif #endif } // namespace placeholders } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_PLACEHOLDERS_HPP PK q��[7�P� � associated_executor.hppnu �[��� // // associated_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP #define BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/is_executor.hpp> #include <boost/asio/system_executor.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { template <typename T, typename E, typename = void> struct associated_executor_impl { typedef void asio_associated_executor_is_unspecialised; typedef E type; static type get(const T&, const E& e = E()) BOOST_ASIO_NOEXCEPT { return e; } }; template <typename T, typename E> struct associated_executor_impl<T, E, typename void_type<typename T::executor_type>::type> { typedef typename T::executor_type type; static type get(const T& t, const E& = E()) BOOST_ASIO_NOEXCEPT { return t.get_executor(); } }; } // namespace detail /// Traits type used to obtain the executor associated with an object. /** * A program may specialise this traits type if the @c T template parameter in * the specialisation is a user-defined type. The template parameter @c * Executor shall be a type meeting the Executor requirements. * * Specialisations shall meet the following requirements, where @c t is a const * reference to an object of type @c T, and @c e is an object of type @c * Executor. * * @li Provide a nested typedef @c type that identifies a type meeting the * Executor requirements. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t) and with return type @c type. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t,e) and with return type @c type. */ template <typename T, typename Executor = system_executor> struct associated_executor #if !defined(GENERATING_DOCUMENTATION) : detail::associated_executor_impl<T, Executor> #endif // !defined(GENERATING_DOCUMENTATION) { #if defined(GENERATING_DOCUMENTATION) /// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>. /// Otherwise @c Executor. typedef see_below type; /// If @c T has a nested type @c executor_type, returns /// <tt>t.get_executor()</tt>. Otherwise returns @c ex. static type get(const T& t, const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; /// Helper function to obtain an object's associated executor. /** * @returns <tt>associated_executor<T>::get(t)</tt> */ template <typename T> inline typename associated_executor<T>::type get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT { return associated_executor<T>::get(t); } /// Helper function to obtain an object's associated executor. /** * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt> */ template <typename T, typename Executor> inline typename associated_executor<T, Executor>::type get_associated_executor(const T& t, const Executor& ex, typename enable_if< is_executor<Executor>::value || execution::is_executor<Executor>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return associated_executor<T, Executor>::get(t, ex); } /// Helper function to obtain an object's associated executor. /** * @returns <tt>associated_executor<T, typename * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt> */ template <typename T, typename ExecutionContext> inline typename associated_executor<T, typename ExecutionContext::executor_type>::type get_associated_executor(const T& t, ExecutionContext& ctx, typename enable_if<is_convertible<ExecutionContext&, execution_context&>::value>::type* = 0) BOOST_ASIO_NOEXCEPT { return associated_executor<T, typename ExecutionContext::executor_type>::get(t, ctx.get_executor()); } #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) template <typename T, typename Executor = system_executor> using associated_executor_t = typename associated_executor<T, Executor>::type; #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) namespace detail { template <typename T, typename E, typename = void> struct associated_executor_forwarding_base { }; template <typename T, typename E> struct associated_executor_forwarding_base<T, E, typename enable_if< is_same< typename associated_executor<T, E>::asio_associated_executor_is_unspecialised, void >::value >::type> { typedef void asio_associated_executor_is_unspecialised; }; } // namespace detail } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP PK q��[%���D D local/connect_pair.hppnu �[��� // // local/connect_pair.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_LOCAL_CONNECT_PAIR_HPP #define BOOST_ASIO_LOCAL_CONNECT_PAIR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_socket.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/local/basic_endpoint.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace local { /// Create a pair of connected sockets. template <typename Protocol, typename Executor1, typename Executor2> void connect_pair(basic_socket<Protocol, Executor1>& socket1, basic_socket<Protocol, Executor2>& socket2); /// Create a pair of connected sockets. template <typename Protocol, typename Executor1, typename Executor2> BOOST_ASIO_SYNC_OP_VOID connect_pair(basic_socket<Protocol, Executor1>& socket1, basic_socket<Protocol, Executor2>& socket2, boost::system::error_code& ec); template <typename Protocol, typename Executor1, typename Executor2> inline void connect_pair(basic_socket<Protocol, Executor1>& socket1, basic_socket<Protocol, Executor2>& socket2) { boost::system::error_code ec; connect_pair(socket1, socket2, ec); boost::asio::detail::throw_error(ec, "connect_pair"); } template <typename Protocol, typename Executor1, typename Executor2> inline BOOST_ASIO_SYNC_OP_VOID connect_pair( basic_socket<Protocol, Executor1>& socket1, basic_socket<Protocol, Executor2>& socket2, boost::system::error_code& ec) { // Check that this function is only being used with a UNIX domain socket. boost::asio::local::basic_endpoint<Protocol>* tmp = static_cast<typename Protocol::endpoint*>(0); (void)tmp; Protocol protocol; boost::asio::detail::socket_type sv[2]; if (boost::asio::detail::socket_ops::socketpair(protocol.family(), protocol.type(), protocol.protocol(), sv, ec) == boost::asio::detail::socket_error_retval) BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); socket1.assign(protocol, sv[0], ec); if (ec) { boost::system::error_code temp_ec; boost::asio::detail::socket_ops::state_type state[2] = { 0, 0 }; boost::asio::detail::socket_ops::close(sv[0], state[0], true, temp_ec); boost::asio::detail::socket_ops::close(sv[1], state[1], true, temp_ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } socket2.assign(protocol, sv[1], ec); if (ec) { boost::system::error_code temp_ec; socket1.close(temp_ec); boost::asio::detail::socket_ops::state_type state = 0; boost::asio::detail::socket_ops::close(sv[1], state, true, temp_ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); } } // namespace local } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // BOOST_ASIO_LOCAL_CONNECT_PAIR_HPP PK q��[f��"E E local/basic_endpoint.hppnu �[��� // // local/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // 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) // #ifndef BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP #define BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include <boost/asio/local/detail/endpoint.hpp> #if !defined(BOOST_ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(BOOST_ASIO_NO_IOSTREAM) #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace local { /// Describes an endpoint for a UNIX socket. /** * The boost::asio::local::basic_endpoint class template describes an endpoint * that may be associated with a particular UNIX socket. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. * * @par Concepts: * Endpoint. */ template <typename Protocol> class basic_endpoint { public: /// The protocol type associated with the endpoint. typedef Protocol protocol_type; /// The type of the endpoint structure. This type is dependent on the /// underlying implementation of the socket layer. #if defined(GENERATING_DOCUMENTATION) typedef implementation_defined data_type; #else typedef boost::asio::detail::socket_addr_type data_type; #endif /// Default constructor. basic_endpoint() BOOST_ASIO_NOEXCEPT { } /// Construct an endpoint using the specified path name. basic_endpoint(const char* path_name) : impl_(path_name) { } /// Construct an endpoint using the specified path name. basic_endpoint(const std::string& path_name) : impl_(path_name) { } #if defined(BOOST_ASIO_HAS_STRING_VIEW) /// Construct an endpoint using the specified path name. basic_endpoint(string_view path_name) : impl_(path_name) { } #endif // defined(BOOST_ASIO_HAS_STRING_VIEW) /// Copy constructor. basic_endpoint(const basic_endpoint& other) : impl_(other.impl_) { } #if defined(BOOST_ASIO_HAS_MOVE) /// Move constructor. basic_endpoint(basic_endpoint&& other) : impl_(other.impl_) { } #endif // defined(BOOST_ASIO_HAS_MOVE) /// Assign from another endpoint. basic_endpoint& operator=(const basic_endpoint& other) { impl_ = other.impl_; return *this; } #if defined(BOOST_ASIO_HAS_MOVE) /// Move-assign from another endpoint. basic_endpoint& operator=(basic_endpoint&& other) { impl_ = other.impl_; return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) /// The protocol associated with the endpoint. protocol_type protocol() const { return protocol_type(); } /// Get the underlying endpoint in the native type. data_type* data() { return impl_.data(); } /// Get the underlying endpoint in the native type. const data_type* data() const { return impl_.data(); } /// Get the underlying size of the endpoint in the native type. std::size_t size() const { return impl_.size(); } /// Set the underlying size of the endpoint in the native type. void resize(std::size_t new_size) { impl_.resize(new_size); } /// Get the capacity of the endpoint in the native type. std::size_t capacity() const { return impl_.capacity(); } /// Get the path associated with the endpoint. std::string path() const { return impl_.path(); } /// Set the path associated with the endpoint. void path(const char* p) { impl_.path(p); } /// Set the path associated with the endpoint. void path(const std::string& p) { impl_.path(p); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { return !(e1.impl_ == e2.impl_); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint<Protocol>& e1, const basic_endpoint<Protocol>& e2) { return !(e1 < e2); } private: // The underlying UNIX domain endpoint. boost::asio::local::detail::endpoint impl_; }; /// Output an endpoint as a string. /** * Used to output a human-readable string for a specified endpoint. * * @param os The output stream to which the string will be written. * * @param endpoint The endpoint to be written. * * @return The output stream. * * @relates boost::asio::local::basic_endpoint */ template <typename Elem, typename Traits, typename Protocol> std::basic_ostream<Elem, Traits>& operator<<( std::basic_ostream<Elem, Traits>& os, const basic_endpoint<Protocol>& endpoint) { os << endpoint.path(); return os; } } // namespace local } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP PK q��[Ӗ�� � local/detail/impl/endpoint.ippnu �[��� // // local/detail/impl/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // 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) // #ifndef BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP #define BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) #include <cstring> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> #include <boost/asio/local/detail/endpoint.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace local { namespace detail { endpoint::endpoint() { init("", 0); } endpoint::endpoint(const char* path_name) { using namespace std; // For strlen. init(path_name, strlen(path_name)); } endpoint::endpoint(const std::string& path_name) { init(path_name.data(), path_name.length()); } #if defined(BOOST_ASIO_HAS_STRING_VIEW) endpoint::endpoint(string_view path_name) { init(path_name.data(), path_name.length()); } #endif // defined(BOOST_ASIO_HAS_STRING_VIEW) void endpoint::resize(std::size_t new_size) { if (new_size > sizeof(boost::asio::detail::sockaddr_un_type)) { boost::system::error_code ec(boost::asio::error::invalid_argument); boost::asio::detail::throw_error(ec); } else if (new_size == 0) { path_length_ = 0; } else { path_length_ = new_size - offsetof(boost::asio::detail::sockaddr_un_type, sun_path); // The path returned by the operating system may be NUL-terminated. if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0) --path_length_; } } std::string endpoint::path() const { return std::string(data_.local.sun_path, path_length_); } void endpoint::path(const char* p) { using namespace std; // For strlen. init(p, strlen(p)); } void endpoint::path(const std::string& p) { init(p.data(), p.length()); } bool operator==(const endpoint& e1, const endpoint& e2) { return e1.path() == e2.path(); } bool operator<(const endpoint& e1, const endpoint& e2) { return e1.path() < e2.path(); } void endpoint::init(const char* path_name, std::size_t path_length) { if (path_length > sizeof(data_.local.sun_path) - 1) { // The buffer is not large enough to store this address. boost::system::error_code ec(boost::asio::error::name_too_long); boost::asio::detail::throw_error(ec); } using namespace std; // For memcpy. data_.local = boost::asio::detail::sockaddr_un_type(); data_.local.sun_family = AF_UNIX; if (path_length > 0) memcpy(data_.local.sun_path, path_name, path_length); path_length_ = path_length; // NUL-terminate normal path names. Names that start with a NUL are in the // UNIX domain protocol's "abstract namespace" and are not NUL-terminated. if (path_length > 0 && data_.local.sun_path[0] == 0) data_.local.sun_path[path_length] = 0; } } // namespace detail } // namespace local } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) #endif // BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP PK q��[���� � local/detail/endpoint.hppnu �[��� // // local/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // 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) // #ifndef BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP #define BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) #include <cstddef> #include <string> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/string_view.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace local { namespace detail { // Helper class for implementing a UNIX domain endpoint. class endpoint { public: // Default constructor. BOOST_ASIO_DECL endpoint(); // Construct an endpoint using the specified path name. BOOST_ASIO_DECL endpoint(const char* path_name); // Construct an endpoint using the specified path name. BOOST_ASIO_DECL endpoint(const std::string& path_name); #if defined(BOOST_ASIO_HAS_STRING_VIEW) // Construct an endpoint using the specified path name. BOOST_ASIO_DECL endpoint(string_view path_name); #endif // defined(BOOST_ASIO_HAS_STRING_VIEW) // Copy constructor. endpoint(const endpoint& other) : data_(other.data_), path_length_(other.path_length_) { } // Assign from another endpoint. endpoint& operator=(const endpoint& other) { data_ = other.data_; path_length_ = other.path_length_; return *this; } // Get the underlying endpoint in the native type. boost::asio::detail::socket_addr_type* data() { return &data_.base; } // Get the underlying endpoint in the native type. const boost::asio::detail::socket_addr_type* data() const { return &data_.base; } // Get the underlying size of the endpoint in the native type. std::size_t size() const { return path_length_ + offsetof(boost::asio::detail::sockaddr_un_type, sun_path); } // Set the underlying size of the endpoint in the native type. BOOST_ASIO_DECL void resize(std::size_t size); // Get the capacity of the endpoint in the native type. std::size_t capacity() const { return sizeof(boost::asio::detail::sockaddr_un_type); } // Get the path associated with the endpoint. BOOST_ASIO_DECL std::string path() const; // Set the path associated with the endpoint. BOOST_ASIO_DECL void path(const char* p); // Set the path associated with the endpoint. BOOST_ASIO_DECL void path(const std::string& p); // Compare two endpoints for equality. BOOST_ASIO_DECL friend bool operator==( const endpoint& e1, const endpoint& e2); // Compare endpoints for ordering. BOOST_ASIO_DECL friend bool operator<( const endpoint& e1, const endpoint& e2); private: // The underlying UNIX socket address. union data_union { boost::asio::detail::socket_addr_type base; boost::asio::detail::sockaddr_un_type local; } data_; // The length of the path associated with the endpoint. std::size_t path_length_; // Initialise with a specified path. BOOST_ASIO_DECL void init(const char* path, std::size_t path_length); }; } // namespace detail } // namespace local } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #if defined(BOOST_ASIO_HEADER_ONLY) # include <boost/asio/local/detail/impl/endpoint.ipp> #endif // defined(BOOST_ASIO_HEADER_ONLY) #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) #endif // BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP PK q��[`���[ [ local/stream_protocol.hppnu �[��� // // local/stream_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_HPP #define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_socket_acceptor.hpp> #include <boost/asio/basic_socket_iostream.hpp> #include <boost/asio/basic_stream_socket.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/local/basic_endpoint.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace local { /// Encapsulates the flags needed for stream-oriented UNIX sockets. /** * The boost::asio::local::stream_protocol class contains flags necessary for * stream-oriented UNIX domain sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class stream_protocol { public: /// Obtain an identifier for the type of the protocol. int type() const BOOST_ASIO_NOEXCEPT { return SOCK_STREAM; } /// Obtain an identifier for the protocol. int protocol() const BOOST_ASIO_NOEXCEPT { return 0; } /// Obtain an identifier for the protocol family. int family() const BOOST_ASIO_NOEXCEPT { return AF_UNIX; } /// The type of a UNIX domain endpoint. typedef basic_endpoint<stream_protocol> endpoint; /// The UNIX domain socket type. typedef basic_stream_socket<stream_protocol> socket; /// The UNIX domain acceptor type. typedef basic_socket_acceptor<stream_protocol> acceptor; #if !defined(BOOST_ASIO_NO_IOSTREAM) /// The UNIX domain iostream type. typedef basic_socket_iostream<stream_protocol> iostream; #endif // !defined(BOOST_ASIO_NO_IOSTREAM) }; } // namespace local } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_HPP PK q��[{� local/datagram_protocol.hppnu �[��� // // local/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP #define BOOST_ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ || defined(GENERATING_DOCUMENTATION) #include <boost/asio/basic_datagram_socket.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/local/basic_endpoint.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace local { /// Encapsulates the flags needed for datagram-oriented UNIX sockets. /** * The boost::asio::local::datagram_protocol class contains flags necessary for * datagram-oriented UNIX domain sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Safe. * * @par Concepts: * Protocol. */ class datagram_protocol { public: /// Obtain an identifier for the type of the protocol. int type() const BOOST_ASIO_NOEXCEPT { return SOCK_DGRAM; } /// Obtain an identifier for the protocol. int protocol() const BOOST_ASIO_NOEXCEPT { return 0; } /// Obtain an identifier for the protocol family. int family() const BOOST_ASIO_NOEXCEPT { return AF_UNIX; } /// The type of a UNIX domain endpoint. typedef basic_endpoint<datagram_protocol> endpoint; /// The UNIX domain socket type. typedef basic_datagram_socket<datagram_protocol> socket; }; } // namespace local } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) // || defined(GENERATING_DOCUMENTATION) #endif // BOOST_ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP PK q��[t� packaged_task.hppnu �[��� // // packaged_task.hpp // ~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_PACKAGED_TASK_HPP #define BOOST_ASIO_PACKAGED_TASK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/future.hpp> #if defined(BOOST_ASIO_HAS_STD_FUTURE_CLASS) \ || defined(GENERATING_DOCUMENTATION) #include <boost/asio/async_result.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/variadic_templates.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \ || defined(GENERATING_DOCUMENTATION) /// Partial specialisation of @c async_result for @c std::packaged_task. template <typename Result, typename... Args, typename Signature> class async_result<std::packaged_task<Result(Args...)>, Signature> { public: /// The packaged task is the concrete completion handler type. typedef std::packaged_task<Result(Args...)> completion_handler_type; /// The return type of the initiating function is the future obtained from /// the packaged task. typedef std::future<Result> return_type; /// The constructor extracts the future from the packaged task. explicit async_result(completion_handler_type& h) : future_(h.get_future()) { } /// Returns the packaged task's future. return_type get() { return std::move(future_); } private: return_type future_; }; #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) template <typename Result, typename Signature> struct async_result<std::packaged_task<Result()>, Signature> { typedef std::packaged_task<Result()> completion_handler_type; typedef std::future<Result> return_type; explicit async_result(completion_handler_type& h) : future_(h.get_future()) { } return_type get() { return std::move(future_); } private: return_type future_; }; #define BOOST_ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \ template <typename Result, \ BOOST_ASIO_VARIADIC_TPARAMS(n), typename Signature> \ class async_result< \ std::packaged_task<Result(BOOST_ASIO_VARIADIC_TARGS(n))>, Signature> \ { \ public: \ typedef std::packaged_task< \ Result(BOOST_ASIO_VARIADIC_TARGS(n))> \ completion_handler_type; \ \ typedef std::future<Result> return_type; \ \ explicit async_result(completion_handler_type& h) \ : future_(h.get_future()) \ { \ } \ \ return_type get() \ { \ return std::move(future_); \ } \ \ private: \ return_type future_; \ }; \ /**/ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_RESULT_DEF) #undef BOOST_ASIO_PRIVATE_ASYNC_RESULT_DEF #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // defined(BOOST_ASIO_HAS_STD_FUTURE_CLASS) // || defined(GENERATING_DOCUMENTATION) #endif // BOOST_ASIO_PACKAGED_TASK_HPP PK q��[_5��6E 6E buffer.hppnu �[��� // // buffer.hpp // ~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_BUFFER_HPP #define BOOST_ASIO_BUFFER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <cstddef> #include <cstring> #include <limits> #include <stdexcept> #include <string> #include <vector> #include <boost/asio/detail/array_fwd.hpp> #include <boost/asio/detail/memory.hpp> #include <boost/asio/detail/string_view.hpp> #include <boost/asio/detail/throw_exception.hpp> #include <boost/asio/detail/type_traits.hpp> #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700) # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0) # if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) # define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING # endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) # endif // defined(_HAS_ITERATOR_DEBUGGING) #endif // defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700) #if defined(__GNUC__) # if defined(_GLIBCXX_DEBUG) # if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) # define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING # endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING) # endif // defined(_GLIBCXX_DEBUG) #endif // defined(__GNUC__) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) # include <boost/asio/detail/functional.hpp> #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING #if defined(BOOST_ASIO_HAS_BOOST_WORKAROUND) # include <boost/detail/workaround.hpp> # if !defined(__clang__) # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) # define BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND # endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) # elif BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) # define BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND # endif // BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) #endif // defined(BOOST_ASIO_HAS_BOOST_WORKAROUND) #if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) # include <boost/asio/detail/type_traits.hpp> #endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { class mutable_buffer; class const_buffer; /// Holds a buffer that can be modified. /** * The mutable_buffer class provides a safe representation of a buffer that can * be modified. It does not own the underlying data, and so is cheap to copy or * assign. * * @par Accessing Buffer Contents * * The contents of a buffer may be accessed using the @c data() and @c size() * member functions: * * @code boost::asio::mutable_buffer b1 = ...; * std::size_t s1 = b1.size(); * unsigned char* p1 = static_cast<unsigned char*>(b1.data()); * @endcode * * The @c data() member function permits violations of type safety, so uses of * it in application code should be carefully considered. */ class mutable_buffer { public: /// Construct an empty buffer. mutable_buffer() BOOST_ASIO_NOEXCEPT : data_(0), size_(0) { } /// Construct a buffer to represent a given memory range. mutable_buffer(void* data, std::size_t size) BOOST_ASIO_NOEXCEPT : data_(data), size_(size) { } #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) mutable_buffer(void* data, std::size_t size, boost::asio::detail::function<void()> debug_check) : data_(data), size_(size), debug_check_(debug_check) { } const boost::asio::detail::function<void()>& get_debug_check() const { return debug_check_; } #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING /// Get a pointer to the beginning of the memory range. void* data() const BOOST_ASIO_NOEXCEPT { #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) if (size_ && debug_check_) debug_check_(); #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING return data_; } /// Get the size of the memory range. std::size_t size() const BOOST_ASIO_NOEXCEPT { return size_; } /// Move the start of the buffer by the specified number of bytes. mutable_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT { std::size_t offset = n < size_ ? n : size_; data_ = static_cast<char*>(data_) + offset; size_ -= offset; return *this; } private: void* data_; std::size_t size_; #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) boost::asio::detail::function<void()> debug_check_; #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING }; #if !defined(BOOST_ASIO_NO_DEPRECATED) /// (Deprecated: Use mutable_buffer.) Adapts a single modifiable buffer so that /// it meets the requirements of the MutableBufferSequence concept. class mutable_buffers_1 : public mutable_buffer { public: /// The type for each element in the list of buffers. typedef mutable_buffer value_type; /// A random-access iterator type that may be used to read elements. typedef const mutable_buffer* const_iterator; /// Construct to represent a given memory range. mutable_buffers_1(void* data, std::size_t size) BOOST_ASIO_NOEXCEPT : mutable_buffer(data, size) { } #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) mutable_buffers_1(void* data, std::size_t size, boost::asio::detail::function<void()> debug_check) : mutable_buffer(data, size, debug_check) { } #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING /// Construct to represent a single modifiable buffer. explicit mutable_buffers_1(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT : mutable_buffer(b) { } /// Get a random-access iterator to the first element. const_iterator begin() const BOOST_ASIO_NOEXCEPT { return this; } /// Get a random-access iterator for one past the last element. const_iterator end() const BOOST_ASIO_NOEXCEPT { return begin() + 1; } }; #endif // !defined(BOOST_ASIO_NO_DEPRECATED) /// Holds a buffer that cannot be modified. /** * The const_buffer class provides a safe representation of a buffer that cannot * be modified. It does not own the underlying data, and so is cheap to copy or * assign. * * @par Accessing Buffer Contents * * The contents of a buffer may be accessed using the @c data() and @c size() * member functions: * * @code boost::asio::const_buffer b1 = ...; * std::size_t s1 = b1.size(); * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data()); * @endcode * * The @c data() member function permits violations of type safety, so uses of * it in application code should be carefully considered. */ class const_buffer { public: /// Construct an empty buffer. const_buffer() BOOST_ASIO_NOEXCEPT : data_(0), size_(0) { } /// Construct a buffer to represent a given memory range. const_buffer(const void* data, std::size_t size) BOOST_ASIO_NOEXCEPT : data_(data), size_(size) { } /// Construct a non-modifiable buffer from a modifiable one. const_buffer(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT : data_(b.data()), size_(b.size()) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , debug_check_(b.get_debug_check()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING { } #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) const_buffer(const void* data, std::size_t size, boost::asio::detail::function<void()> debug_check) : data_(data), size_(size), debug_check_(debug_check) { } const boost::asio::detail::function<void()>& get_debug_check() const { return debug_check_; } #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING /// Get a pointer to the beginning of the memory range. const void* data() const BOOST_ASIO_NOEXCEPT { #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) if (size_ && debug_check_) debug_check_(); #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING return data_; } /// Get the size of the memory range. std::size_t size() const BOOST_ASIO_NOEXCEPT { return size_; } /// Move the start of the buffer by the specified number of bytes. const_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT { std::size_t offset = n < size_ ? n : size_; data_ = static_cast<const char*>(data_) + offset; size_ -= offset; return *this; } private: const void* data_; std::size_t size_; #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) boost::asio::detail::function<void()> debug_check_; #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING }; #if !defined(BOOST_ASIO_NO_DEPRECATED) /// (Deprecated: Use const_buffer.) Adapts a single non-modifiable buffer so /// that it meets the requirements of the ConstBufferSequence concept. class const_buffers_1 : public const_buffer { public: /// The type for each element in the list of buffers. typedef const_buffer value_type; /// A random-access iterator type that may be used to read elements. typedef const const_buffer* const_iterator; /// Construct to represent a given memory range. const_buffers_1(const void* data, std::size_t size) BOOST_ASIO_NOEXCEPT : const_buffer(data, size) { } #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) const_buffers_1(const void* data, std::size_t size, boost::asio::detail::function<void()> debug_check) : const_buffer(data, size, debug_check) { } #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING /// Construct to represent a single non-modifiable buffer. explicit const_buffers_1(const const_buffer& b) BOOST_ASIO_NOEXCEPT : const_buffer(b) { } /// Get a random-access iterator to the first element. const_iterator begin() const BOOST_ASIO_NOEXCEPT { return this; } /// Get a random-access iterator for one past the last element. const_iterator end() const BOOST_ASIO_NOEXCEPT { return begin() + 1; } }; #endif // !defined(BOOST_ASIO_NO_DEPRECATED) /// (Deprecated: Use the socket/descriptor wait() and async_wait() member /// functions.) An implementation of both the ConstBufferSequence and /// MutableBufferSequence concepts to represent a null buffer sequence. class null_buffers { public: /// The type for each element in the list of buffers. typedef mutable_buffer value_type; /// A random-access iterator type that may be used to read elements. typedef const mutable_buffer* const_iterator; /// Get a random-access iterator to the first element. const_iterator begin() const BOOST_ASIO_NOEXCEPT { return &buf_; } /// Get a random-access iterator for one past the last element. const_iterator end() const BOOST_ASIO_NOEXCEPT { return &buf_; } private: mutable_buffer buf_; }; /** @defgroup buffer_sequence_begin boost::asio::buffer_sequence_begin * * @brief The boost::asio::buffer_sequence_begin function returns an iterator * pointing to the first element in a buffer sequence. */ /*@{*/ /// Get an iterator to the first element in a buffer sequence. template <typename MutableBuffer> inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b, typename enable_if< is_convertible<const MutableBuffer*, const mutable_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return static_cast<const mutable_buffer*>(detail::addressof(b)); } /// Get an iterator to the first element in a buffer sequence. template <typename ConstBuffer> inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b, typename enable_if< is_convertible<const ConstBuffer*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return static_cast<const const_buffer*>(detail::addressof(b)); } #if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /// Get an iterator to the first element in a buffer sequence. template <typename C> inline auto buffer_sequence_begin(C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin()) { return c.begin(); } /// Get an iterator to the first element in a buffer sequence. template <typename C> inline auto buffer_sequence_begin(const C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin()) { return c.begin(); } #else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) template <typename C> inline typename C::iterator buffer_sequence_begin(C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return c.begin(); } template <typename C> inline typename C::const_iterator buffer_sequence_begin(const C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return c.begin(); } #endif // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /*@}*/ /** @defgroup buffer_sequence_end boost::asio::buffer_sequence_end * * @brief The boost::asio::buffer_sequence_end function returns an iterator * pointing to one past the end element in a buffer sequence. */ /*@{*/ /// Get an iterator to one past the end element in a buffer sequence. template <typename MutableBuffer> inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b, typename enable_if< is_convertible<const MutableBuffer*, const mutable_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1; } /// Get an iterator to one past the end element in a buffer sequence. template <typename ConstBuffer> inline const const_buffer* buffer_sequence_end(const ConstBuffer& b, typename enable_if< is_convertible<const ConstBuffer*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return static_cast<const const_buffer*>(detail::addressof(b)) + 1; } #if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /// Get an iterator to one past the end element in a buffer sequence. template <typename C> inline auto buffer_sequence_end(C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end()) { return c.end(); } /// Get an iterator to one past the end element in a buffer sequence. template <typename C> inline auto buffer_sequence_end(const C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end()) { return c.end(); } #else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) template <typename C> inline typename C::iterator buffer_sequence_end(C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return c.end(); } template <typename C> inline typename C::const_iterator buffer_sequence_end(const C& c, typename enable_if< !is_convertible<const C*, const mutable_buffer*>::value && !is_convertible<const C*, const const_buffer*>::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return c.end(); } #endif // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) /*@}*/ namespace detail { // Tag types used to select appropriately optimised overloads. struct one_buffer {}; struct multiple_buffers {}; // Helper trait to detect single buffers. template <typename BufferSequence> struct buffer_sequence_cardinality : conditional< is_same<BufferSequence, mutable_buffer>::value #if !defined(BOOST_ASIO_NO_DEPRECATED) || is_same<BufferSequence, mutable_buffers_1>::value || is_same<BufferSequence, const_buffers_1>::value #endif // !defined(BOOST_ASIO_NO_DEPRECATED) || is_same<BufferSequence, const_buffer>::value, one_buffer, multiple_buffers>::type {}; template <typename Iterator> inline std::size_t buffer_size(one_buffer, Iterator begin, Iterator) BOOST_ASIO_NOEXCEPT { return const_buffer(*begin).size(); } template <typename Iterator> inline std::size_t buffer_size(multiple_buffers, Iterator begin, Iterator end) BOOST_ASIO_NOEXCEPT { std::size_t total_buffer_size = 0; Iterator iter = begin; for (; iter != end; ++iter) { const_buffer b(*iter); total_buffer_size += b.size(); } return total_buffer_size; } } // namespace detail /// Get the total number of bytes in a buffer sequence. /** * The @c buffer_size function determines the total size of all buffers in the * buffer sequence, as if computed as follows: * * @code size_t total_size = 0; * auto i = boost::asio::buffer_sequence_begin(buffers); * auto end = boost::asio::buffer_sequence_end(buffers); * for (; i != end; ++i) * { * const_buffer b(*i); * total_size += b.size(); * } * return total_size; @endcode * * The @c BufferSequence template parameter may meet either of the @c * ConstBufferSequence or @c MutableBufferSequence type requirements. */ template <typename BufferSequence> inline std::size_t buffer_size(const BufferSequence& b) BOOST_ASIO_NOEXCEPT { return detail::buffer_size( detail::buffer_sequence_cardinality<BufferSequence>(), boost::asio::buffer_sequence_begin(b), boost::asio::buffer_sequence_end(b)); } #if !defined(BOOST_ASIO_NO_DEPRECATED) /** @defgroup buffer_cast boost::asio::buffer_cast * * @brief (Deprecated: Use the @c data() member function.) The * boost::asio::buffer_cast function is used to obtain a pointer to the * underlying memory region associated with a buffer. * * @par Examples: * * To access the memory of a non-modifiable buffer, use: * @code boost::asio::const_buffer b1 = ...; * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1); * @endcode * * To access the memory of a modifiable buffer, use: * @code boost::asio::mutable_buffer b2 = ...; * unsigned char* p2 = boost::asio::buffer_cast<unsigned char*>(b2); * @endcode * * The boost::asio::buffer_cast function permits violations of type safety, so * uses of it in application code should be carefully considered. */ /*@{*/ /// Cast a non-modifiable buffer to a specified pointer to POD type. template <typename PointerToPodType> inline PointerToPodType buffer_cast(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT { return static_cast<PointerToPodType>(b.data()); } /// Cast a non-modifiable buffer to a specified pointer to POD type. template <typename PointerToPodType> inline PointerToPodType buffer_cast(const const_buffer& b) BOOST_ASIO_NOEXCEPT { return static_cast<PointerToPodType>(b.data()); } /*@}*/ #endif // !defined(BOOST_ASIO_NO_DEPRECATED) /// Create a new modifiable buffer that is offset from the start of another. /** * @relates mutable_buffer */ inline mutable_buffer operator+(const mutable_buffer& b, std::size_t n) BOOST_ASIO_NOEXCEPT { std::size_t offset = n < b.size() ? n : b.size(); char* new_data = static_cast<char*>(b.data()) + offset; std::size_t new_size = b.size() - offset; return mutable_buffer(new_data, new_size #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that is offset from the start of another. /** * @relates mutable_buffer */ inline mutable_buffer operator+(std::size_t n, const mutable_buffer& b) BOOST_ASIO_NOEXCEPT { return b + n; } /// Create a new non-modifiable buffer that is offset from the start of another. /** * @relates const_buffer */ inline const_buffer operator+(const const_buffer& b, std::size_t n) BOOST_ASIO_NOEXCEPT { std::size_t offset = n < b.size() ? n : b.size(); const char* new_data = static_cast<const char*>(b.data()) + offset; std::size_t new_size = b.size() - offset; return const_buffer(new_data, new_size #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that is offset from the start of another. /** * @relates const_buffer */ inline const_buffer operator+(std::size_t n, const const_buffer& b) BOOST_ASIO_NOEXCEPT { return b + n; } #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) namespace detail { template <typename Iterator> class buffer_debug_check { public: buffer_debug_check(Iterator iter) : iter_(iter) { } ~buffer_debug_check() { #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400) // MSVC 8's string iterator checking may crash in a std::string::iterator // object's destructor when the iterator points to an already-destroyed // std::string object, unless the iterator is cleared first. iter_ = Iterator(); #endif // defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400) } void operator()() { (void)*iter_; } private: Iterator iter_; }; } // namespace detail #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING /** @defgroup buffer boost::asio::buffer * * @brief The boost::asio::buffer function is used to create a buffer object to * represent raw memory, an array of POD elements, a vector of POD elements, * or a std::string. * * A buffer object represents a contiguous region of memory as a 2-tuple * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*, * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a * tuple of the form <tt>{const void*, size_t}</tt> specifies a const * (non-modifiable) region of memory. These two forms correspond to the classes * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the * opposite conversion is not permitted. * * The simplest use case involves reading or writing a single buffer of a * specified size: * * @code sock.send(boost::asio::buffer(data, size)); @endcode * * In the above example, the return value of boost::asio::buffer meets the * requirements of the ConstBufferSequence concept so that it may be directly * passed to the socket's write function. A buffer created for modifiable * memory also meets the requirements of the MutableBufferSequence concept. * * An individual buffer may be created from a builtin array, std::vector, * std::array or boost::array of POD elements. This helps prevent buffer * overruns by automatically determining the size of the buffer: * * @code char d1[128]; * size_t bytes_transferred = sock.receive(boost::asio::buffer(d1)); * * std::vector<char> d2(128); * bytes_transferred = sock.receive(boost::asio::buffer(d2)); * * std::array<char, 128> d3; * bytes_transferred = sock.receive(boost::asio::buffer(d3)); * * boost::array<char, 128> d4; * bytes_transferred = sock.receive(boost::asio::buffer(d4)); @endcode * * In all three cases above, the buffers created are exactly 128 bytes long. * Note that a vector is @e never automatically resized when creating or using * a buffer. The buffer size is determined using the vector's <tt>size()</tt> * member function, and not its capacity. * * @par Accessing Buffer Contents * * The contents of a buffer may be accessed using the @c data() and @c size() * member functions: * * @code boost::asio::mutable_buffer b1 = ...; * std::size_t s1 = b1.size(); * unsigned char* p1 = static_cast<unsigned char*>(b1.data()); * * boost::asio::const_buffer b2 = ...; * std::size_t s2 = b2.size(); * const void* p2 = b2.data(); @endcode * * The @c data() member function permits violations of type safety, so * uses of it in application code should be carefully considered. * * For convenience, a @ref buffer_size function is provided that works with * both buffers and buffer sequences (that is, types meeting the * ConstBufferSequence or MutableBufferSequence type requirements). In this * case, the function returns the total size of all buffers in the sequence. * * @par Buffer Copying * * The @ref buffer_copy function may be used to copy raw bytes between * individual buffers and buffer sequences. * * In particular, when used with the @ref buffer_size function, the @ref * buffer_copy function can be used to linearise a sequence of buffers. For * example: * * @code vector<const_buffer> buffers = ...; * * vector<unsigned char> data(boost::asio::buffer_size(buffers)); * boost::asio::buffer_copy(boost::asio::buffer(data), buffers); @endcode * * Note that @ref buffer_copy is implemented in terms of @c memcpy, and * consequently it cannot be used to copy between overlapping memory regions. * * @par Buffer Invalidation * * A buffer object does not have any ownership of the memory it refers to. It * is the responsibility of the application to ensure the memory region remains * valid until it is no longer required for an I/O operation. When the memory * is no longer available, the buffer is said to have been invalidated. * * For the boost::asio::buffer overloads that accept an argument of type * std::vector, the buffer objects returned are invalidated by any vector * operation that also invalidates all references, pointers and iterators * referring to the elements in the sequence (C++ Std, 23.2.4) * * For the boost::asio::buffer overloads that accept an argument of type * std::basic_string, the buffer objects returned are invalidated according to * the rules defined for invalidation of references, pointers and iterators * referring to elements of the sequence (C++ Std, 21.3). * * @par Buffer Arithmetic * * Buffer objects may be manipulated using simple arithmetic in a safe way * which helps prevent buffer overruns. Consider an array initialised as * follows: * * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode * * A buffer object @c b1 created using: * * @code b1 = boost::asio::buffer(a); @endcode * * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An * optional second argument to the boost::asio::buffer function may be used to * limit the size, in bytes, of the buffer: * * @code b2 = boost::asio::buffer(a, 3); @endcode * * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the * size argument exceeds the actual size of the array, the size of the buffer * object created will be limited to the array size. * * An offset may be applied to an existing buffer to create a new one: * * @code b3 = b1 + 2; @endcode * * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset * exceeds the size of the existing buffer, the newly created buffer will be * empty. * * Both an offset and size may be specified to create a buffer that corresponds * to a specific range of bytes within an existing buffer: * * @code b4 = boost::asio::buffer(b1 + 1, 3); @endcode * * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>. * * @par Buffers and Scatter-Gather I/O * * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple * buffer objects may be assigned into a container that supports the * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts: * * @code * char d1[128]; * std::vector<char> d2(128); * boost::array<char, 128> d3; * * boost::array<mutable_buffer, 3> bufs1 = { * boost::asio::buffer(d1), * boost::asio::buffer(d2), * boost::asio::buffer(d3) }; * bytes_transferred = sock.receive(bufs1); * * std::vector<const_buffer> bufs2; * bufs2.push_back(boost::asio::buffer(d1)); * bufs2.push_back(boost::asio::buffer(d2)); * bufs2.push_back(boost::asio::buffer(d3)); * bytes_transferred = sock.send(bufs2); @endcode */ /*@{*/ #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) # define BOOST_ASIO_MUTABLE_BUFFER mutable_buffer # define BOOST_ASIO_CONST_BUFFER const_buffer #else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) # define BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_1 # define BOOST_ASIO_CONST_BUFFER const_buffers_1 #endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer from an existing buffer. /** * @returns <tt>mutable_buffer(b)</tt>. */ inline BOOST_ASIO_MUTABLE_BUFFER buffer( const mutable_buffer& b) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(b); } /// Create a new modifiable buffer from an existing buffer. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * b.data(), * min(b.size(), max_size_in_bytes)); @endcode */ inline BOOST_ASIO_MUTABLE_BUFFER buffer(const mutable_buffer& b, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER( mutable_buffer(b.data(), b.size() < max_size_in_bytes ? b.size() : max_size_in_bytes #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING )); } /// Create a new non-modifiable buffer from an existing buffer. /** * @returns <tt>const_buffer(b)</tt>. */ inline BOOST_ASIO_CONST_BUFFER buffer( const const_buffer& b) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(b); } /// Create a new non-modifiable buffer from an existing buffer. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * b.data(), * min(b.size(), max_size_in_bytes)); @endcode */ inline BOOST_ASIO_CONST_BUFFER buffer(const const_buffer& b, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(b.data(), b.size() < max_size_in_bytes ? b.size() : max_size_in_bytes #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , b.get_debug_check() #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given memory range. /** * @returns <tt>mutable_buffer(data, size_in_bytes)</tt>. */ inline BOOST_ASIO_MUTABLE_BUFFER buffer(void* data, std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data, size_in_bytes); } /// Create a new non-modifiable buffer that represents the given memory range. /** * @returns <tt>const_buffer(data, size_in_bytes)</tt>. */ inline BOOST_ASIO_CONST_BUFFER buffer(const void* data, std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data, size_in_bytes); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * static_cast<void*>(data), * N * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N]) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType)); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * static_cast<void*>(data), * min(N * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N], std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType) < max_size_in_bytes ? N * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * static_cast<const void*>(data), * N * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer( const PodType (&data)[N]) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data, N * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * static_cast<const void*>(data), * min(N * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer(const PodType (&data)[N], std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data, N * sizeof(PodType) < max_size_in_bytes ? N * sizeof(PodType) : max_size_in_bytes); } #if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) // Borland C++ and Sun Studio think the overloads: // // unspecified buffer(boost::array<PodType, N>& array ...); // // and // // unspecified buffer(boost::array<const PodType, N>& array ...); // // are ambiguous. This will be worked around by using a buffer_types traits // class that contains typedefs for the appropriate buffer and container // classes, based on whether PodType is const or non-const. namespace detail { template <bool IsConst> struct buffer_types_base; template <> struct buffer_types_base<false> { typedef mutable_buffer buffer_type; typedef BOOST_ASIO_MUTABLE_BUFFER container_type; }; template <> struct buffer_types_base<true> { typedef const_buffer buffer_type; typedef BOOST_ASIO_CONST_BUFFER container_type; }; template <typename PodType> struct buffer_types : public buffer_types_base<is_const<PodType>::value> { }; } // namespace detail template <typename PodType, std::size_t N> inline typename detail::buffer_types<PodType>::container_type buffer(boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT { typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type buffer_type; typedef typename boost::asio::detail::buffer_types<PodType>::container_type container_type; return container_type( buffer_type(data.c_array(), data.size() * sizeof(PodType))); } template <typename PodType, std::size_t N> inline typename detail::buffer_types<PodType>::container_type buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type buffer_type; typedef typename boost::asio::detail::buffer_types<PodType>::container_type container_type; return container_type( buffer_type(data.c_array(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes)); } #else // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_MUTABLE_BUFFER buffer( boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER( data.c_array(), data.size() * sizeof(PodType)); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_MUTABLE_BUFFER buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data.c_array(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer( boost::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer(boost::array<const PodType, N>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } #endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND) /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer( const boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer(const boost::array<PodType, N>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } #if defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_MUTABLE_BUFFER buffer( std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new modifiable buffer that represents the given POD array. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::array<PodType, N>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer( std::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer(std::array<const PodType, N>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * data.size() * sizeof(PodType)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer( const std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType)); } /// Create a new non-modifiable buffer that represents the given POD array. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode */ template <typename PodType, std::size_t N> inline BOOST_ASIO_CONST_BUFFER buffer(const std::array<PodType, N>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes); } #endif // defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer that represents the given POD vector. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * data.size() * sizeof(PodType)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template <typename PodType, typename Allocator> inline BOOST_ASIO_MUTABLE_BUFFER buffer( std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER( data.size() ? &data[0] : 0, data.size() * sizeof(PodType) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector<PodType, Allocator>::iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given POD vector. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template <typename PodType, typename Allocator> inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector<PodType, Allocator>::iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given POD vector. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.size() ? &data[0] : 0, * data.size() * sizeof(PodType)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template <typename PodType, typename Allocator> inline BOOST_ASIO_CONST_BUFFER buffer( const std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER( data.size() ? &data[0] : 0, data.size() * sizeof(PodType) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector<PodType, Allocator>::const_iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given POD vector. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any vector operation that would also * invalidate iterators. */ template <typename PodType, typename Allocator> inline BOOST_ASIO_CONST_BUFFER buffer( const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(PodType) < max_size_in_bytes ? data.size() * sizeof(PodType) : max_size_in_bytes #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::vector<PodType, Allocator>::const_iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given string. /** * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0, * data.size() * sizeof(Elem))</tt>. * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template <typename Elem, typename Traits, typename Allocator> inline BOOST_ASIO_MUTABLE_BUFFER buffer( std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string<Elem, Traits, Allocator>::iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new modifiable buffer that represents the given string. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template <typename Elem, typename Traits, typename Allocator> inline BOOST_ASIO_MUTABLE_BUFFER buffer( std::basic_string<Elem, Traits, Allocator>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) < max_size_in_bytes ? data.size() * sizeof(Elem) : max_size_in_bytes #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string<Elem, Traits, Allocator>::iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given string. /** * @returns <tt>const_buffer(data.data(), data.size() * sizeof(Elem))</tt>. * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template <typename Elem, typename Traits, typename Allocator> inline BOOST_ASIO_CONST_BUFFER buffer( const std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string<Elem, Traits, Allocator>::const_iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given string. /** * @returns A const_buffer value equivalent to: * @code const_buffer( * data.data(), * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ template <typename Elem, typename Traits, typename Allocator> inline BOOST_ASIO_CONST_BUFFER buffer( const std::basic_string<Elem, Traits, Allocator>& data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem) < max_size_in_bytes ? data.size() * sizeof(Elem) : max_size_in_bytes #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename std::basic_string<Elem, Traits, Allocator>::const_iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } #if defined(BOOST_ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION) /// Create a new modifiable buffer that represents the given string_view. /** * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0, * data.size() * sizeof(Elem))</tt>. */ template <typename Elem, typename Traits> inline BOOST_ASIO_CONST_BUFFER buffer( basic_string_view<Elem, Traits> data) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename basic_string_view<Elem, Traits>::iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } /// Create a new non-modifiable buffer that represents the given string. /** * @returns A mutable_buffer value equivalent to: * @code mutable_buffer( * data.size() ? &data[0] : 0, * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode */ template <typename Elem, typename Traits> inline BOOST_ASIO_CONST_BUFFER buffer( basic_string_view<Elem, Traits> data, std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT { return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0, data.size() * sizeof(Elem) < max_size_in_bytes ? data.size() * sizeof(Elem) : max_size_in_bytes #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING) , detail::buffer_debug_check< typename basic_string_view<Elem, Traits>::iterator >(data.begin()) #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING ); } #endif // defined(BOOST_ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION) /*@}*/ /// Adapt a basic_string to the DynamicBuffer requirements. /** * Requires that <tt>sizeof(Elem) == 1</tt>. */ template <typename Elem, typename Traits, typename Allocator> class dynamic_string_buffer { public: /// The type used to represent a sequence of constant buffers that refers to /// the underlying memory. typedef BOOST_ASIO_CONST_BUFFER const_buffers_type; /// The type used to represent a sequence of mutable buffers that refers to /// the underlying memory. typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type; /// Construct a dynamic buffer from a string. /** * @param s The string to be used as backing storage for the dynamic buffer. * The object stores a reference to the string and the user is responsible * for ensuring that the string object remains valid while the * dynamic_string_buffer object, and copies of the object, are in use. * * @b DynamicBuffer_v1: Any existing data in the string is treated as the * dynamic buffer's input sequence. * * @param maximum_size Specifies a maximum size for the buffer, in bytes. */ explicit dynamic_string_buffer(std::basic_string<Elem, Traits, Allocator>& s, std::size_t maximum_size = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT : string_(s), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) size_((std::numeric_limits<std::size_t>::max)()), #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(maximum_size) { } /// @b DynamicBuffer_v2: Copy construct a dynamic buffer. dynamic_string_buffer(const dynamic_string_buffer& other) BOOST_ASIO_NOEXCEPT : string_(other.string_), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move construct a dynamic buffer. dynamic_string_buffer(dynamic_string_buffer&& other) BOOST_ASIO_NOEXCEPT : string_(other.string_), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// @b DynamicBuffer_v1: Get the size of the input sequence. /// @b DynamicBuffer_v2: Get the current size of the underlying memory. /** * @returns @b DynamicBuffer_v1 The current size of the input sequence. * @b DynamicBuffer_v2: The current size of the underlying string if less than * max_size(). Otherwise returns max_size(). */ std::size_t size() const BOOST_ASIO_NOEXCEPT { #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits<std::size_t>::max)()) return size_; #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) return (std::min)(string_.size(), max_size()); } /// Get the maximum size of the dynamic buffer. /** * @returns The allowed maximum size of the underlying memory. */ std::size_t max_size() const BOOST_ASIO_NOEXCEPT { return max_size_; } /// Get the maximum size that the buffer may grow to without triggering /// reallocation. /** * @returns The current capacity of the underlying string if less than * max_size(). Otherwise returns max_size(). */ std::size_t capacity() const BOOST_ASIO_NOEXCEPT { return (std::min)(string_.capacity(), max_size()); } #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the input /// sequence. /** * @returns An object of type @c const_buffers_type that satisfies * ConstBufferSequence requirements, representing the basic_string memory in * the input sequence. * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that resizes or erases the string. */ const_buffers_type data() const BOOST_ASIO_NOEXCEPT { return const_buffers_type(boost::asio::buffer(string_, size_)); } #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing the basic_string memory. * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that resizes or erases the string. */ mutable_buffers_type data(std::size_t pos, std::size_t n) BOOST_ASIO_NOEXCEPT { return mutable_buffers_type(boost::asio::buffer( boost::asio::buffer(string_, max_size_) + pos, n)); } /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that resizes or erases the string. */ const_buffers_type data(std::size_t pos, std::size_t n) const BOOST_ASIO_NOEXCEPT { return const_buffers_type(boost::asio::buffer( boost::asio::buffer(string_, max_size_) + pos, n)); } #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the output /// sequence, with the given size. /** * Ensures that the output sequence can accommodate @c n bytes, resizing the * basic_string object as necessary. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing basic_string memory * at the start of the output sequence of size @c n. * * @throws std::length_error If <tt>size() + n > max_size()</tt>. * * @note The returned object is invalidated by any @c dynamic_string_buffer * or @c basic_string member function that modifies the input sequence or * output sequence. */ mutable_buffers_type prepare(std::size_t n) { if (size() > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_string_buffer too long"); boost::asio::detail::throw_exception(ex); } if (size_ == (std::numeric_limits<std::size_t>::max)()) size_ = string_.size(); // Enable v1 behaviour. string_.resize(size_ + n); return boost::asio::buffer(boost::asio::buffer(string_) + size_, n); } /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input /// sequence. /** * @param n The number of bytes to append from the start of the output * sequence to the end of the input sequence. The remainder of the output * sequence is discarded. * * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and * no intervening operations that modify the input or output sequence. * * @note If @c n is greater than the size of the output sequence, the entire * output sequence is moved to the input sequence and no error is issued. */ void commit(std::size_t n) { size_ += (std::min)(n, string_.size() - size_); string_.resize(size_); } #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of /// bytes. /** * Resizes the string to accommodate an additional @c n bytes at the end. * * @throws std::length_error If <tt>size() + n > max_size()</tt>. */ void grow(std::size_t n) { if (size() > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_string_buffer too long"); boost::asio::detail::throw_exception(ex); } string_.resize(size() + n); } /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number /// of bytes. /** * Erases @c n bytes from the end of the string by resizing the basic_string * object. If @c n is greater than the current size of the string, the string * is emptied. */ void shrink(std::size_t n) { string_.resize(n > size() ? 0 : size() - n); } /// @b DynamicBuffer_v1: Remove characters from the input sequence. /// @b DynamicBuffer_v2: Consume the specified number of bytes from the /// beginning of the underlying memory. /** * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the * input sequence. @note If @c n is greater than the size of the input * sequence, the entire input sequence is consumed and no error is issued. * * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string. * If @c n is greater than the current size of the string, the string is * emptied. */ void consume(std::size_t n) { #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits<std::size_t>::max)()) { std::size_t consume_length = (std::min)(n, size_); string_.erase(0, consume_length); size_ -= consume_length; return; } #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) string_.erase(0, n); } private: std::basic_string<Elem, Traits, Allocator>& string_; #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) std::size_t size_; #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) const std::size_t max_size_; }; /// Adapt a vector to the DynamicBuffer requirements. /** * Requires that <tt>sizeof(Elem) == 1</tt>. */ template <typename Elem, typename Allocator> class dynamic_vector_buffer { public: /// The type used to represent a sequence of constant buffers that refers to /// the underlying memory. typedef BOOST_ASIO_CONST_BUFFER const_buffers_type; /// The type used to represent a sequence of mutable buffers that refers to /// the underlying memory. typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type; /// Construct a dynamic buffer from a vector. /** * @param v The vector to be used as backing storage for the dynamic buffer. * The object stores a reference to the vector and the user is responsible * for ensuring that the vector object remains valid while the * dynamic_vector_buffer object, and copies of the object, are in use. * * @param maximum_size Specifies a maximum size for the buffer, in bytes. */ explicit dynamic_vector_buffer(std::vector<Elem, Allocator>& v, std::size_t maximum_size = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT : vector_(v), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) size_((std::numeric_limits<std::size_t>::max)()), #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(maximum_size) { } /// @b DynamicBuffer_v2: Copy construct a dynamic buffer. dynamic_vector_buffer(const dynamic_vector_buffer& other) BOOST_ASIO_NOEXCEPT : vector_(other.vector_), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move construct a dynamic buffer. dynamic_vector_buffer(dynamic_vector_buffer&& other) BOOST_ASIO_NOEXCEPT : vector_(other.vector_), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) size_(other.size_), #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) max_size_(other.max_size_) { } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// @b DynamicBuffer_v1: Get the size of the input sequence. /// @b DynamicBuffer_v2: Get the current size of the underlying memory. /** * @returns @b DynamicBuffer_v1 The current size of the input sequence. * @b DynamicBuffer_v2: The current size of the underlying vector if less than * max_size(). Otherwise returns max_size(). */ std::size_t size() const BOOST_ASIO_NOEXCEPT { #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits<std::size_t>::max)()) return size_; #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) return (std::min)(vector_.size(), max_size()); } /// Get the maximum size of the dynamic buffer. /** * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed * maximum size of the underlying memory. */ std::size_t max_size() const BOOST_ASIO_NOEXCEPT { return max_size_; } /// Get the maximum size that the buffer may grow to without triggering /// reallocation. /** * @returns @b DynamicBuffer_v1: The current total capacity of the buffer, * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2: * The current capacity of the underlying vector if less than max_size(). * Otherwise returns max_size(). */ std::size_t capacity() const BOOST_ASIO_NOEXCEPT { return (std::min)(vector_.capacity(), max_size()); } #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the input /// sequence. /** * @returns An object of type @c const_buffers_type that satisfies * ConstBufferSequence requirements, representing the vector memory in the * input sequence. * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that modifies the input sequence or output * sequence. */ const_buffers_type data() const BOOST_ASIO_NOEXCEPT { return const_buffers_type(boost::asio::buffer(vector_, size_)); } #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing the vector memory. * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that resizes or erases the vector. */ mutable_buffers_type data(std::size_t pos, std::size_t n) BOOST_ASIO_NOEXCEPT { return mutable_buffers_type(boost::asio::buffer( boost::asio::buffer(vector_, max_size_) + pos, n)); } /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the /// underlying memory. /** * @param pos Position of the first byte to represent in the buffer sequence * * @param n The number of bytes to return in the buffer sequence. If the * underlying memory is shorter, the buffer sequence represents as many bytes * as are available. * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that resizes or erases the vector. */ const_buffers_type data(std::size_t pos, std::size_t n) const BOOST_ASIO_NOEXCEPT { return const_buffers_type(boost::asio::buffer( boost::asio::buffer(vector_, max_size_) + pos, n)); } #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v1: Get a list of buffers that represents the output /// sequence, with the given size. /** * Ensures that the output sequence can accommodate @c n bytes, resizing the * vector object as necessary. * * @returns An object of type @c mutable_buffers_type that satisfies * MutableBufferSequence requirements, representing vector memory at the * start of the output sequence of size @c n. * * @throws std::length_error If <tt>size() + n > max_size()</tt>. * * @note The returned object is invalidated by any @c dynamic_vector_buffer * or @c vector member function that modifies the input sequence or output * sequence. */ mutable_buffers_type prepare(std::size_t n) { if (size () > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_vector_buffer too long"); boost::asio::detail::throw_exception(ex); } if (size_ == (std::numeric_limits<std::size_t>::max)()) size_ = vector_.size(); // Enable v1 behaviour. vector_.resize(size_ + n); return boost::asio::buffer(boost::asio::buffer(vector_) + size_, n); } /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input /// sequence. /** * @param n The number of bytes to append from the start of the output * sequence to the end of the input sequence. The remainder of the output * sequence is discarded. * * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and * no intervening operations that modify the input or output sequence. * * @note If @c n is greater than the size of the output sequence, the entire * output sequence is moved to the input sequence and no error is issued. */ void commit(std::size_t n) { size_ += (std::min)(n, vector_.size() - size_); vector_.resize(size_); } #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of /// bytes. /** * Resizes the vector to accommodate an additional @c n bytes at the end. * * @throws std::length_error If <tt>size() + n > max_size()</tt>. */ void grow(std::size_t n) { if (size() > max_size() || max_size() - size() < n) { std::length_error ex("dynamic_vector_buffer too long"); boost::asio::detail::throw_exception(ex); } vector_.resize(size() + n); } /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number /// of bytes. /** * Erases @c n bytes from the end of the vector by resizing the vector * object. If @c n is greater than the current size of the vector, the vector * is emptied. */ void shrink(std::size_t n) { vector_.resize(n > size() ? 0 : size() - n); } /// @b DynamicBuffer_v1: Remove characters from the input sequence. /// @b DynamicBuffer_v2: Consume the specified number of bytes from the /// beginning of the underlying memory. /** * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the * input sequence. @note If @c n is greater than the size of the input * sequence, the entire input sequence is consumed and no error is issued. * * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector. * If @c n is greater than the current size of the vector, the vector is * emptied. */ void consume(std::size_t n) { #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) if (size_ != (std::numeric_limits<std::size_t>::max)()) { std::size_t consume_length = (std::min)(n, size_); vector_.erase(vector_.begin(), vector_.begin() + consume_length); size_ -= consume_length; return; } #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n)); } private: std::vector<Elem, Allocator>& vector_; #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) std::size_t size_; #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) const std::size_t max_size_; }; /** @defgroup dynamic_buffer boost::asio::dynamic_buffer * * @brief The boost::asio::dynamic_buffer function is used to create a * dynamically resized buffer from a @c std::basic_string or @c std::vector. */ /*@{*/ /// Create a new dynamic buffer that represents the given string. /** * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data)</tt>. */ template <typename Elem, typename Traits, typename Allocator> inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer( std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT { return dynamic_string_buffer<Elem, Traits, Allocator>(data); } /// Create a new dynamic buffer that represents the given string. /** * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data, * max_size)</tt>. */ template <typename Elem, typename Traits, typename Allocator> inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer( std::basic_string<Elem, Traits, Allocator>& data, std::size_t max_size) BOOST_ASIO_NOEXCEPT { return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size); } /// Create a new dynamic buffer that represents the given vector. /** * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>. */ template <typename Elem, typename Allocator> inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer( std::vector<Elem, Allocator>& data) BOOST_ASIO_NOEXCEPT { return dynamic_vector_buffer<Elem, Allocator>(data); } /// Create a new dynamic buffer that represents the given vector. /** * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>. */ template <typename Elem, typename Allocator> inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer( std::vector<Elem, Allocator>& data, std::size_t max_size) BOOST_ASIO_NOEXCEPT { return dynamic_vector_buffer<Elem, Allocator>(data, max_size); } /*@}*/ /** @defgroup buffer_copy boost::asio::buffer_copy * * @brief The boost::asio::buffer_copy function is used to copy bytes from a * source buffer (or buffer sequence) to a target buffer (or buffer sequence). * * The @c buffer_copy function is available in two forms: * * @li A 2-argument form: @c buffer_copy(target, source) * * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy) * * Both forms return the number of bytes actually copied. The number of bytes * copied is the lesser of: * * @li @c buffer_size(target) * * @li @c buffer_size(source) * * @li @c If specified, @c max_bytes_to_copy. * * This prevents buffer overflow, regardless of the buffer sizes used in the * copy operation. * * Note that @ref buffer_copy is implemented in terms of @c memcpy, and * consequently it cannot be used to copy between overlapping memory regions. */ /*@{*/ namespace detail { inline std::size_t buffer_copy_1(const mutable_buffer& target, const const_buffer& source) { using namespace std; // For memcpy. std::size_t target_size = target.size(); std::size_t source_size = source.size(); std::size_t n = target_size < source_size ? target_size : source_size; if (n > 0) memcpy(target.data(), source.data(), n); return n; } template <typename TargetIterator, typename SourceIterator> inline std::size_t buffer_copy(one_buffer, one_buffer, TargetIterator target_begin, TargetIterator, SourceIterator source_begin, SourceIterator) BOOST_ASIO_NOEXCEPT { return (buffer_copy_1)(*target_begin, *source_begin); } template <typename TargetIterator, typename SourceIterator> inline std::size_t buffer_copy(one_buffer, one_buffer, TargetIterator target_begin, TargetIterator, SourceIterator source_begin, SourceIterator, std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT { return (buffer_copy_1)(*target_begin, boost::asio::buffer(*source_begin, max_bytes_to_copy)); } template <typename TargetIterator, typename SourceIterator> std::size_t buffer_copy(one_buffer, multiple_buffers, TargetIterator target_begin, TargetIterator, SourceIterator source_begin, SourceIterator source_end, std::size_t max_bytes_to_copy = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; SourceIterator source_iter = source_begin; for (mutable_buffer target_buffer( boost::asio::buffer(*target_begin, max_bytes_to_copy)); target_buffer.size() && source_iter != source_end; ++source_iter) { const_buffer source_buffer(*source_iter); std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); total_bytes_copied += bytes_copied; target_buffer += bytes_copied; } return total_bytes_copied; } template <typename TargetIterator, typename SourceIterator> std::size_t buffer_copy(multiple_buffers, one_buffer, TargetIterator target_begin, TargetIterator target_end, SourceIterator source_begin, SourceIterator, std::size_t max_bytes_to_copy = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; TargetIterator target_iter = target_begin; for (const_buffer source_buffer( boost::asio::buffer(*source_begin, max_bytes_to_copy)); source_buffer.size() && target_iter != target_end; ++target_iter) { mutable_buffer target_buffer(*target_iter); std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); total_bytes_copied += bytes_copied; source_buffer += bytes_copied; } return total_bytes_copied; } template <typename TargetIterator, typename SourceIterator> std::size_t buffer_copy(multiple_buffers, multiple_buffers, TargetIterator target_begin, TargetIterator target_end, SourceIterator source_begin, SourceIterator source_end) BOOST_ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; TargetIterator target_iter = target_begin; std::size_t target_buffer_offset = 0; SourceIterator source_iter = source_begin; std::size_t source_buffer_offset = 0; while (target_iter != target_end && source_iter != source_end) { mutable_buffer target_buffer = mutable_buffer(*target_iter) + target_buffer_offset; const_buffer source_buffer = const_buffer(*source_iter) + source_buffer_offset; std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer); total_bytes_copied += bytes_copied; if (bytes_copied == target_buffer.size()) { ++target_iter; target_buffer_offset = 0; } else target_buffer_offset += bytes_copied; if (bytes_copied == source_buffer.size()) { ++source_iter; source_buffer_offset = 0; } else source_buffer_offset += bytes_copied; } return total_bytes_copied; } template <typename TargetIterator, typename SourceIterator> std::size_t buffer_copy(multiple_buffers, multiple_buffers, TargetIterator target_begin, TargetIterator target_end, SourceIterator source_begin, SourceIterator source_end, std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT { std::size_t total_bytes_copied = 0; TargetIterator target_iter = target_begin; std::size_t target_buffer_offset = 0; SourceIterator source_iter = source_begin; std::size_t source_buffer_offset = 0; while (total_bytes_copied != max_bytes_to_copy && target_iter != target_end && source_iter != source_end) { mutable_buffer target_buffer = mutable_buffer(*target_iter) + target_buffer_offset; const_buffer source_buffer = const_buffer(*source_iter) + source_buffer_offset; std::size_t bytes_copied = (buffer_copy_1)( target_buffer, boost::asio::buffer(source_buffer, max_bytes_to_copy - total_bytes_copied)); total_bytes_copied += bytes_copied; if (bytes_copied == target_buffer.size()) { ++target_iter; target_buffer_offset = 0; } else target_buffer_offset += bytes_copied; if (bytes_copied == source_buffer.size()) { ++source_iter; source_buffer_offset = 0; } else source_buffer_offset += bytes_copied; } return total_bytes_copied; } } // namespace detail /// Copies bytes from a source buffer sequence to a target buffer sequence. /** * @param target A modifiable buffer sequence representing the memory regions to * which the bytes will be copied. * * @param source A non-modifiable buffer sequence representing the memory * regions from which the bytes will be copied. * * @returns The number of bytes copied. * * @note The number of bytes copied is the lesser of: * * @li @c buffer_size(target) * * @li @c buffer_size(source) * * This function is implemented in terms of @c memcpy, and consequently it * cannot be used to copy between overlapping memory regions. */ template <typename MutableBufferSequence, typename ConstBufferSequence> inline std::size_t buffer_copy(const MutableBufferSequence& target, const ConstBufferSequence& source) BOOST_ASIO_NOEXCEPT { return detail::buffer_copy( detail::buffer_sequence_cardinality<MutableBufferSequence>(), detail::buffer_sequence_cardinality<ConstBufferSequence>(), boost::asio::buffer_sequence_begin(target), boost::asio::buffer_sequence_end(target), boost::asio::buffer_sequence_begin(source), boost::asio::buffer_sequence_end(source)); } /// Copies a limited number of bytes from a source buffer sequence to a target /// buffer sequence. /** * @param target A modifiable buffer sequence representing the memory regions to * which the bytes will be copied. * * @param source A non-modifiable buffer sequence representing the memory * regions from which the bytes will be copied. * * @param max_bytes_to_copy The maximum number of bytes to be copied. * * @returns The number of bytes copied. * * @note The number of bytes copied is the lesser of: * * @li @c buffer_size(target) * * @li @c buffer_size(source) * * @li @c max_bytes_to_copy * * This function is implemented in terms of @c memcpy, and consequently it * cannot be used to copy between overlapping memory regions. */ template <typename MutableBufferSequence, typename ConstBufferSequence> inline std::size_t buffer_copy(const MutableBufferSequence& target, const ConstBufferSequence& source, std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT { return detail::buffer_copy( detail::buffer_sequence_cardinality<MutableBufferSequence>(), detail::buffer_sequence_cardinality<ConstBufferSequence>(), boost::asio::buffer_sequence_begin(target), boost::asio::buffer_sequence_end(target), boost::asio::buffer_sequence_begin(source), boost::asio::buffer_sequence_end(source), max_bytes_to_copy); } /*@}*/ } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #include <boost/asio/detail/is_buffer_sequence.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { /// Trait to determine whether a type satisfies the MutableBufferSequence /// requirements. template <typename T> struct is_mutable_buffer_sequence #if defined(GENERATING_DOCUMENTATION) : integral_constant<bool, automatically_determined> #else // defined(GENERATING_DOCUMENTATION) : boost::asio::detail::is_buffer_sequence<T, mutable_buffer> #endif // defined(GENERATING_DOCUMENTATION) { }; /// Trait to determine whether a type satisfies the ConstBufferSequence /// requirements. template <typename T> struct is_const_buffer_sequence #if defined(GENERATING_DOCUMENTATION) : integral_constant<bool, automatically_determined> #else // defined(GENERATING_DOCUMENTATION) : boost::asio::detail::is_buffer_sequence<T, const_buffer> #endif // defined(GENERATING_DOCUMENTATION) { }; #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// Trait to determine whether a type satisfies the DynamicBuffer_v1 /// requirements. template <typename T> struct is_dynamic_buffer_v1 #if defined(GENERATING_DOCUMENTATION) : integral_constant<bool, automatically_determined> #else // defined(GENERATING_DOCUMENTATION) : boost::asio::detail::is_dynamic_buffer_v1<T> #endif // defined(GENERATING_DOCUMENTATION) { }; #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) /// Trait to determine whether a type satisfies the DynamicBuffer_v2 /// requirements. template <typename T> struct is_dynamic_buffer_v2 #if defined(GENERATING_DOCUMENTATION) : integral_constant<bool, automatically_determined> #else // defined(GENERATING_DOCUMENTATION) : boost::asio::detail::is_dynamic_buffer_v2<T> #endif // defined(GENERATING_DOCUMENTATION) { }; /// Trait to determine whether a type satisfies the DynamicBuffer requirements. /** * If @c BOOST_ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the * type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c * BOOST_ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type * satisfies the DynamicBuffer_v2 requirements. */ template <typename T> struct is_dynamic_buffer #if defined(GENERATING_DOCUMENTATION) : integral_constant<bool, automatically_determined> #elif defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) : boost::asio::is_dynamic_buffer_v2<T> #else // defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) : boost::asio::is_dynamic_buffer_v1<T> #endif // defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) { }; } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_BUFFER_HPP PK q��[���6 �6 buffers_iterator.hppnu �[��� // // buffers_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_BUFFERS_ITERATOR_HPP #define BOOST_ASIO_BUFFERS_ITERATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <cstddef> #include <iterator> #include <boost/asio/buffer.hpp> #include <boost/asio/detail/assert.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { template <bool IsMutable> struct buffers_iterator_types_helper; template <> struct buffers_iterator_types_helper<false> { typedef const_buffer buffer_type; template <typename ByteType> struct byte_type { typedef typename add_const<ByteType>::type type; }; }; template <> struct buffers_iterator_types_helper<true> { typedef mutable_buffer buffer_type; template <typename ByteType> struct byte_type { typedef ByteType type; }; }; template <typename BufferSequence, typename ByteType> struct buffers_iterator_types { enum { is_mutable = is_convertible< typename BufferSequence::value_type, mutable_buffer>::value }; typedef buffers_iterator_types_helper<is_mutable> helper; typedef typename helper::buffer_type buffer_type; typedef typename helper::template byte_type<ByteType>::type byte_type; typedef typename BufferSequence::const_iterator const_iterator; }; template <typename ByteType> struct buffers_iterator_types<mutable_buffer, ByteType> { typedef mutable_buffer buffer_type; typedef ByteType byte_type; typedef const mutable_buffer* const_iterator; }; template <typename ByteType> struct buffers_iterator_types<const_buffer, ByteType> { typedef const_buffer buffer_type; typedef typename add_const<ByteType>::type byte_type; typedef const const_buffer* const_iterator; }; #if !defined(BOOST_ASIO_NO_DEPRECATED) template <typename ByteType> struct buffers_iterator_types<mutable_buffers_1, ByteType> { typedef mutable_buffer buffer_type; typedef ByteType byte_type; typedef const mutable_buffer* const_iterator; }; template <typename ByteType> struct buffers_iterator_types<const_buffers_1, ByteType> { typedef const_buffer buffer_type; typedef typename add_const<ByteType>::type byte_type; typedef const const_buffer* const_iterator; }; #endif // !defined(BOOST_ASIO_NO_DEPRECATED) } /// A random access iterator over the bytes in a buffer sequence. template <typename BufferSequence, typename ByteType = char> class buffers_iterator { private: typedef typename detail::buffers_iterator_types< BufferSequence, ByteType>::buffer_type buffer_type; typedef typename detail::buffers_iterator_types<BufferSequence, ByteType>::const_iterator buffer_sequence_iterator_type; public: /// The type used for the distance between two iterators. typedef std::ptrdiff_t difference_type; /// The type of the value pointed to by the iterator. typedef ByteType value_type; #if defined(GENERATING_DOCUMENTATION) /// The type of the result of applying operator->() to the iterator. /** * If the buffer sequence stores buffer objects that are convertible to * mutable_buffer, this is a pointer to a non-const ByteType. Otherwise, a * pointer to a const ByteType. */ typedef const_or_non_const_ByteType* pointer; #else // defined(GENERATING_DOCUMENTATION) typedef typename detail::buffers_iterator_types< BufferSequence, ByteType>::byte_type* pointer; #endif // defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION) /// The type of the result of applying operator*() to the iterator. /** * If the buffer sequence stores buffer objects that are convertible to * mutable_buffer, this is a reference to a non-const ByteType. Otherwise, a * reference to a const ByteType. */ typedef const_or_non_const_ByteType& reference; #else // defined(GENERATING_DOCUMENTATION) typedef typename detail::buffers_iterator_types< BufferSequence, ByteType>::byte_type& reference; #endif // defined(GENERATING_DOCUMENTATION) /// The iterator category. typedef std::random_access_iterator_tag iterator_category; /// Default constructor. Creates an iterator in an undefined state. buffers_iterator() : current_buffer_(), current_buffer_position_(0), begin_(), current_(), end_(), position_(0) { } /// Construct an iterator representing the beginning of the buffers' data. static buffers_iterator begin(const BufferSequence& buffers) #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) __attribute__ ((__noinline__)) #endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) { buffers_iterator new_iter; new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers); new_iter.current_ = boost::asio::buffer_sequence_begin(buffers); new_iter.end_ = boost::asio::buffer_sequence_end(buffers); while (new_iter.current_ != new_iter.end_) { new_iter.current_buffer_ = *new_iter.current_; if (new_iter.current_buffer_.size() > 0) break; ++new_iter.current_; } return new_iter; } /// Construct an iterator representing the end of the buffers' data. static buffers_iterator end(const BufferSequence& buffers) #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) __attribute__ ((__noinline__)) #endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3) { buffers_iterator new_iter; new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers); new_iter.current_ = boost::asio::buffer_sequence_begin(buffers); new_iter.end_ = boost::asio::buffer_sequence_end(buffers); while (new_iter.current_ != new_iter.end_) { buffer_type buffer = *new_iter.current_; new_iter.position_ += buffer.size(); ++new_iter.current_; } return new_iter; } /// Dereference an iterator. reference operator*() const { return dereference(); } /// Dereference an iterator. pointer operator->() const { return &dereference(); } /// Access an individual element. reference operator[](std::ptrdiff_t difference) const { buffers_iterator tmp(*this); tmp.advance(difference); return *tmp; } /// Increment operator (prefix). buffers_iterator& operator++() { increment(); return *this; } /// Increment operator (postfix). buffers_iterator operator++(int) { buffers_iterator tmp(*this); ++*this; return tmp; } /// Decrement operator (prefix). buffers_iterator& operator--() { decrement(); return *this; } /// Decrement operator (postfix). buffers_iterator operator--(int) { buffers_iterator tmp(*this); --*this; return tmp; } /// Addition operator. buffers_iterator& operator+=(std::ptrdiff_t difference) { advance(difference); return *this; } /// Subtraction operator. buffers_iterator& operator-=(std::ptrdiff_t difference) { advance(-difference); return *this; } /// Addition operator. friend buffers_iterator operator+(const buffers_iterator& iter, std::ptrdiff_t difference) { buffers_iterator tmp(iter); tmp.advance(difference); return tmp; } /// Addition operator. friend buffers_iterator operator+(std::ptrdiff_t difference, const buffers_iterator& iter) { buffers_iterator tmp(iter); tmp.advance(difference); return tmp; } /// Subtraction operator. friend buffers_iterator operator-(const buffers_iterator& iter, std::ptrdiff_t difference) { buffers_iterator tmp(iter); tmp.advance(-difference); return tmp; } /// Subtraction operator. friend std::ptrdiff_t operator-(const buffers_iterator& a, const buffers_iterator& b) { return b.distance_to(a); } /// Test two iterators for equality. friend bool operator==(const buffers_iterator& a, const buffers_iterator& b) { return a.equal(b); } /// Test two iterators for inequality. friend bool operator!=(const buffers_iterator& a, const buffers_iterator& b) { return !a.equal(b); } /// Compare two iterators. friend bool operator<(const buffers_iterator& a, const buffers_iterator& b) { return a.distance_to(b) > 0; } /// Compare two iterators. friend bool operator<=(const buffers_iterator& a, const buffers_iterator& b) { return !(b < a); } /// Compare two iterators. friend bool operator>(const buffers_iterator& a, const buffers_iterator& b) { return b < a; } /// Compare two iterators. friend bool operator>=(const buffers_iterator& a, const buffers_iterator& b) { return !(a < b); } private: // Dereference the iterator. reference dereference() const { return static_cast<pointer>( current_buffer_.data())[current_buffer_position_]; } // Compare two iterators for equality. bool equal(const buffers_iterator& other) const { return position_ == other.position_; } // Increment the iterator. void increment() { BOOST_ASIO_ASSERT(current_ != end_ && "iterator out of bounds"); ++position_; // Check if the increment can be satisfied by the current buffer. ++current_buffer_position_; if (current_buffer_position_ != current_buffer_.size()) return; // Find the next non-empty buffer. ++current_; current_buffer_position_ = 0; while (current_ != end_) { current_buffer_ = *current_; if (current_buffer_.size() > 0) return; ++current_; } } // Decrement the iterator. void decrement() { BOOST_ASIO_ASSERT(position_ > 0 && "iterator out of bounds"); --position_; // Check if the decrement can be satisfied by the current buffer. if (current_buffer_position_ != 0) { --current_buffer_position_; return; } // Find the previous non-empty buffer. buffer_sequence_iterator_type iter = current_; while (iter != begin_) { --iter; buffer_type buffer = *iter; std::size_t buffer_size = buffer.size(); if (buffer_size > 0) { current_ = iter; current_buffer_ = buffer; current_buffer_position_ = buffer_size - 1; return; } } } // Advance the iterator by the specified distance. void advance(std::ptrdiff_t n) { if (n > 0) { BOOST_ASIO_ASSERT(current_ != end_ && "iterator out of bounds"); for (;;) { std::ptrdiff_t current_buffer_balance = current_buffer_.size() - current_buffer_position_; // Check if the advance can be satisfied by the current buffer. if (current_buffer_balance > n) { position_ += n; current_buffer_position_ += n; return; } // Update position. n -= current_buffer_balance; position_ += current_buffer_balance; // Move to next buffer. If it is empty then it will be skipped on the // next iteration of this loop. if (++current_ == end_) { BOOST_ASIO_ASSERT(n == 0 && "iterator out of bounds"); current_buffer_ = buffer_type(); current_buffer_position_ = 0; return; } current_buffer_ = *current_; current_buffer_position_ = 0; } } else if (n < 0) { std::size_t abs_n = -n; BOOST_ASIO_ASSERT(position_ >= abs_n && "iterator out of bounds"); for (;;) { // Check if the advance can be satisfied by the current buffer. if (current_buffer_position_ >= abs_n) { position_ -= abs_n; current_buffer_position_ -= abs_n; return; } // Update position. abs_n -= current_buffer_position_; position_ -= current_buffer_position_; // Check if we've reached the beginning of the buffers. if (current_ == begin_) { BOOST_ASIO_ASSERT(abs_n == 0 && "iterator out of bounds"); current_buffer_position_ = 0; return; } // Find the previous non-empty buffer. buffer_sequence_iterator_type iter = current_; while (iter != begin_) { --iter; buffer_type buffer = *iter; std::size_t buffer_size = buffer.size(); if (buffer_size > 0) { current_ = iter; current_buffer_ = buffer; current_buffer_position_ = buffer_size; break; } } } } } // Determine the distance between two iterators. std::ptrdiff_t distance_to(const buffers_iterator& other) const { return other.position_ - position_; } buffer_type current_buffer_; std::size_t current_buffer_position_; buffer_sequence_iterator_type begin_; buffer_sequence_iterator_type current_; buffer_sequence_iterator_type end_; std::size_t position_; }; /// Construct an iterator representing the beginning of the buffers' data. template <typename BufferSequence> inline buffers_iterator<BufferSequence> buffers_begin( const BufferSequence& buffers) { return buffers_iterator<BufferSequence>::begin(buffers); } /// Construct an iterator representing the end of the buffers' data. template <typename BufferSequence> inline buffers_iterator<BufferSequence> buffers_end( const BufferSequence& buffers) { return buffers_iterator<BufferSequence>::end(buffers); } } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_BUFFERS_ITERATOR_HPP PK q��[a�� � associated_allocator.hppnu �[��� // // associated_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP #define BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <memory> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace detail { template <typename T, typename E, typename = void> struct associated_allocator_impl { typedef E type; static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT { return e; } }; template <typename T, typename E> struct associated_allocator_impl<T, E, typename void_type<typename T::allocator_type>::type> { typedef typename T::allocator_type type; static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT { return t.get_allocator(); } }; } // namespace detail /// Traits type used to obtain the allocator associated with an object. /** * A program may specialise this traits type if the @c T template parameter in * the specialisation is a user-defined type. The template parameter @c * Allocator shall be a type meeting the Allocator requirements. * * Specialisations shall meet the following requirements, where @c t is a const * reference to an object of type @c T, and @c a is an object of type @c * Allocator. * * @li Provide a nested typedef @c type that identifies a type meeting the * Allocator requirements. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t) and with return type @c type. * * @li Provide a noexcept static member function named @c get, callable as @c * get(t,a) and with return type @c type. */ template <typename T, typename Allocator = std::allocator<void> > struct associated_allocator { /// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>. /// Otherwise @c Allocator. #if defined(GENERATING_DOCUMENTATION) typedef see_below type; #else // defined(GENERATING_DOCUMENTATION) typedef typename detail::associated_allocator_impl<T, Allocator>::type type; #endif // defined(GENERATING_DOCUMENTATION) /// If @c T has a nested type @c allocator_type, returns /// <tt>t.get_allocator()</tt>. Otherwise returns @c a. static type get(const T& t, const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT { return detail::associated_allocator_impl<T, Allocator>::get(t, a); } }; /// Helper function to obtain an object's associated allocator. /** * @returns <tt>associated_allocator<T>::get(t)</tt> */ template <typename T> inline typename associated_allocator<T>::type get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT { return associated_allocator<T>::get(t); } /// Helper function to obtain an object's associated allocator. /** * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt> */ template <typename T, typename Allocator> inline typename associated_allocator<T, Allocator>::type get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT { return associated_allocator<T, Allocator>::get(t, a); } #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) template <typename T, typename Allocator = std::allocator<void> > using associated_allocator_t = typename associated_allocator<T, Allocator>::type; #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP PK q��[ZQ4�� � execution/allocator.hppnu �[��� // // execution/allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_ALLOCATOR_HPP #define BOOST_ASIO_EXECUTION_ALLOCATOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/scheduler.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/is_applicable_property.hpp> #include <boost/asio/traits/query_static_constexpr_member.hpp> #include <boost/asio/traits/static_query.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(GENERATING_DOCUMENTATION) namespace execution { /// A property to describe which allocator an executor will use to allocate the /// memory required to store a submitted function object. template <typename ProtoAllocator> struct allocator_t { /// The allocator_t property applies to executors, senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The allocator_t property can be required. static constexpr bool is_requirable = true; /// The allocator_t property can be preferred. static constexpr bool is_preferable = true; /// Default constructor. constexpr allocator_t(); /// Obtain the allocator stored in the allocator_t property object. /** * Present only if @c ProtoAllocator is non-void. */ constexpr ProtoAllocator value() const; /// Create an allocator_t object with a different allocator. /** * Present only if @c ProtoAllocator is void. */ template <typename OtherAllocator> allocator_t<OtherAllocator operator()(const OtherAllocator& a); }; /// A special value used for accessing the allocator_t property. constexpr allocator_t<void> allocator; } // namespace execution #else // defined(GENERATING_DOCUMENTATION) namespace execution { template <typename ProtoAllocator> struct allocator_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, allocator_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, allocator_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, allocator_t>::value(); } template <typename E, typename T = decltype(allocator_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = allocator_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) BOOST_ASIO_CONSTEXPR ProtoAllocator value() const { return a_; } private: friend struct allocator_t<void>; explicit BOOST_ASIO_CONSTEXPR allocator_t(const ProtoAllocator& a) : a_(a) { } ProtoAllocator a_; }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename ProtoAllocator> template <typename E, typename T> const T allocator_t<ProtoAllocator>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <> struct allocator_t<void> { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); BOOST_ASIO_CONSTEXPR allocator_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, allocator_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, allocator_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, allocator_t>::value(); } template <typename E, typename T = decltype(allocator_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = allocator_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename OtherProtoAllocator> BOOST_ASIO_CONSTEXPR allocator_t<OtherProtoAllocator> operator()( const OtherProtoAllocator& a) const { return allocator_t<OtherProtoAllocator>(a); } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename E, typename T> const T allocator_t<void>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr allocator_t<void> allocator; #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) template <typename T> struct allocator_instance { static allocator_t<T> instance; }; template <typename T> allocator_t<T> allocator_instance<T>::instance; namespace { static const allocator_t<void>& allocator = allocator_instance<void>::instance; } // namespace #endif } // namespace execution #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename ProtoAllocator> struct is_applicable_property<T, execution::allocator_t<ProtoAllocator> > : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) namespace traits { #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T, typename ProtoAllocator> struct static_query<T, execution::allocator_t<ProtoAllocator>, typename enable_if< traits::query_static_constexpr_member<T, execution::allocator_t<ProtoAllocator> >::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::allocator_t<ProtoAllocator> >::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::allocator_t<ProtoAllocator> >::value(); } }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) } // namespace traits #endif // defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_ALLOCATOR_HPP PK q��[�=3J J execution/start.hppnu �[��� // // execution/start.hpp // ~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_START_HPP #define BOOST_ASIO_EXECUTION_START_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/traits/start_member.hpp> #include <boost/asio/traits/start_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that notifies an operation state object to start /// its associated operation. /** * The name <tt>execution::start</tt> denotes a customisation point object. * The expression <tt>execution::start(R)</tt> for some subexpression * <tt>R</tt> is expression-equivalent to: * * @li <tt>R.start()</tt>, if that expression is valid. * * @li Otherwise, <tt>start(R)</tt>, if that expression is valid, with * overload resolution performed in a context that includes the declaration * <tt>void start();</tt> and that does not include a declaration of * <tt>execution::start</tt>. * * @li Otherwise, <tt>execution::start(R)</tt> is ill-formed. */ inline constexpr unspecified start = unspecified; /// A type trait that determines whether a @c start expression is /// well-formed. /** * Class template @c can_start is a trait that is derived from * @c true_type if the expression <tt>execution::start(std::declval<R>(), * std::declval<E>())</tt> is well formed; otherwise @c false_type. */ template <typename R> struct can_start : integral_constant<bool, automatically_determined> { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_start_fn { using boost::asio::decay; using boost::asio::declval; using boost::asio::enable_if; using boost::asio::traits::start_free; using boost::asio::traits::start_member; void start(); enum overload_type { call_member, call_free, ill_formed }; template <typename R, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename R> struct call_traits<R, typename enable_if< ( start_member<R>::is_valid ) >::type> : start_member<R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename R> struct call_traits<R, typename enable_if< ( !start_member<R>::is_valid && start_free<R>::is_valid ) >::type> : start_free<R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; struct impl { #if defined(BOOST_ASIO_HAS_MOVE) template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R>::overload == call_member, typename call_traits<R>::result_type >::type operator()(R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(R)(r).start(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R>::overload == call_free, typename call_traits<R>::result_type >::type operator()(R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R>::is_noexcept)) { return start(BOOST_ASIO_MOVE_CAST(R)(r)); } #else // defined(BOOST_ASIO_HAS_MOVE) template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&>::overload == call_member, typename call_traits<R&>::result_type >::type operator()(R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&>::is_noexcept)) { return r.start(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&>::overload == call_member, typename call_traits<const R&>::result_type >::type operator()(const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&>::is_noexcept)) { return r.start(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&>::overload == call_free, typename call_traits<R&>::result_type >::type operator()(R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&>::is_noexcept)) { return start(r); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&>::overload == call_free, typename call_traits<const R&>::result_type >::type operator()(const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&>::is_noexcept)) { return start(r); } #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_start_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_start_fn::impl& start = asio_execution_start_fn::static_instance<>::instance; } // namespace template <typename R> struct can_start : integral_constant<bool, asio_execution_start_fn::call_traits<R>::overload != asio_execution_start_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R> constexpr bool can_start_v = can_start<R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R> struct is_nothrow_start : integral_constant<bool, asio_execution_start_fn::call_traits<R>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R> constexpr bool is_nothrow_start_v = is_nothrow_start<R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_START_HPP PK q��[=7&L`9 `9 execution/connect.hppnu �[��� // // execution/connect.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_CONNECT_HPP #define BOOST_ASIO_EXECUTION_CONNECT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/detail/as_invocable.hpp> #include <boost/asio/execution/detail/as_operation.hpp> #include <boost/asio/execution/detail/as_receiver.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/operation_state.hpp> #include <boost/asio/execution/receiver.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/traits/connect_member.hpp> #include <boost/asio/traits/connect_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that connects a sender to a receiver. /** * The name <tt>execution::connect</tt> denotes a customisation point object. * For some subexpressions <tt>s</tt> and <tt>r</tt>, let <tt>S</tt> be a type * such that <tt>decltype((s))</tt> is <tt>S</tt> and let <tt>R</tt> be a type * such that <tt>decltype((r))</tt> is <tt>R</tt>. The expression * <tt>execution::connect(s, r)</tt> is expression-equivalent to: * * @li <tt>s.connect(r)</tt>, if that expression is valid, if its type * satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies * <tt>sender</tt>. * * @li Otherwise, <tt>connect(s, r)</tt>, if that expression is valid, if its * type satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies * <tt>sender</tt>, with overload resolution performed in a context that * includes the declaration <tt>void connect();</tt> and that does not include * a declaration of <tt>execution::connect</tt>. * * @li Otherwise, <tt>as_operation{s, r}</tt>, if <tt>r</tt> is not an instance * of <tt>as_receiver<F, S></tt> for some type <tt>F</tt>, and if * <tt>receiver_of<R> && executor_of<remove_cvref_t<S>, * as_invocable<remove_cvref_t<R>, S>></tt> is <tt>true</tt>, where * <tt>as_operation</tt> is an implementation-defined class equivalent to * @code template <class S, class R> * struct as_operation * { * remove_cvref_t<S> e_; * remove_cvref_t<R> r_; * void start() noexcept try { * execution::execute(std::move(e_), * as_invocable<remove_cvref_t<R>, S>{r_}); * } catch(...) { * execution::set_error(std::move(r_), current_exception()); * } * }; @endcode * and <tt>as_invocable</tt> is a class template equivalent to the following: * @code template<class R> * struct as_invocable * { * R* r_; * explicit as_invocable(R& r) noexcept * : r_(std::addressof(r)) {} * as_invocable(as_invocable && other) noexcept * : r_(std::exchange(other.r_, nullptr)) {} * ~as_invocable() { * if(r_) * execution::set_done(std::move(*r_)); * } * void operator()() & noexcept try { * execution::set_value(std::move(*r_)); * r_ = nullptr; * } catch(...) { * execution::set_error(std::move(*r_), current_exception()); * r_ = nullptr; * } * }; * @endcode * * @li Otherwise, <tt>execution::connect(s, r)</tt> is ill-formed. */ inline constexpr unspecified connect = unspecified; /// A type trait that determines whether a @c connect expression is /// well-formed. /** * Class template @c can_connect is a trait that is derived from * @c true_type if the expression <tt>execution::connect(std::declval<S>(), * std::declval<R>())</tt> is well formed; otherwise @c false_type. */ template <typename S, typename R> struct can_connect : integral_constant<bool, automatically_determined> { }; /// A type trait to determine the result of a @c connect expression. template <typename S, typename R> struct connect_result { /// The type of the connect expression. /** * The type of the expression <tt>execution::connect(std::declval<S>(), * std::declval<R>())</tt>. */ typedef automatically_determined type; }; /// A type alis to determine the result of a @c connect expression. template <typename S, typename R> using connect_result_t = typename connect_result<S, R>::type; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_connect_fn { using boost::asio::conditional; using boost::asio::declval; using boost::asio::enable_if; using boost::asio::execution::detail::as_invocable; using boost::asio::execution::detail::as_operation; using boost::asio::execution::detail::is_as_receiver; using boost::asio::execution::is_executor_of; using boost::asio::execution::is_operation_state; using boost::asio::execution::is_receiver; using boost::asio::execution::is_sender; using boost::asio::false_type; using boost::asio::remove_cvref; using boost::asio::traits::connect_free; using boost::asio::traits::connect_member; void connect(); enum overload_type { call_member, call_free, adapter, ill_formed }; template <typename S, typename R, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename S, typename R> struct call_traits<S, void(R), typename enable_if< ( connect_member<S, R>::is_valid && is_operation_state<typename connect_member<S, R>::result_type>::value && is_sender<typename remove_cvref<S>::type>::value ) >::type> : connect_member<S, R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename S, typename R> struct call_traits<S, void(R), typename enable_if< ( !connect_member<S, R>::is_valid && connect_free<S, R>::is_valid && is_operation_state<typename connect_free<S, R>::result_type>::value && is_sender<typename remove_cvref<S>::type>::value ) >::type> : connect_free<S, R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; template <typename S, typename R> struct call_traits<S, void(R), typename enable_if< ( !connect_member<S, R>::is_valid && !connect_free<S, R>::is_valid && is_receiver<R>::value && conditional< !is_as_receiver< typename remove_cvref<R>::type >::value, is_executor_of< typename remove_cvref<S>::type, as_invocable<typename remove_cvref<R>::type, S> >, false_type >::type::value ) >::type> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef as_operation<S, R> result_type; }; struct impl { #if defined(BOOST_ASIO_HAS_MOVE) template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(R)>::overload == call_member, typename call_traits<S, void(R)>::result_type >::type operator()(S&& s, R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(R)>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(S)(s).connect(BOOST_ASIO_MOVE_CAST(R)(r)); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(R)>::overload == call_free, typename call_traits<S, void(R)>::result_type >::type operator()(S&& s, R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(R)>::is_noexcept)) { return connect(BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(R)(r)); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(R)>::overload == adapter, typename call_traits<S, void(R)>::result_type >::type operator()(S&& s, R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(R)>::is_noexcept)) { return typename call_traits<S, void(R)>::result_type( BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(R)(r)); } #else // defined(BOOST_ASIO_HAS_MOVE) template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(R&)>::overload == call_member, typename call_traits<S&, void(R&)>::result_type >::type operator()(S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(R&)>::is_noexcept)) { return s.connect(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(R&)>::overload == call_member, typename call_traits<const S&, void(R&)>::result_type >::type operator()(const S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(R&)>::is_noexcept)) { return s.connect(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(R&)>::overload == call_free, typename call_traits<S&, void(R&)>::result_type >::type operator()(S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(R&)>::is_noexcept)) { return connect(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(R&)>::overload == call_free, typename call_traits<const S&, void(R&)>::result_type >::type operator()(const S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(R&)>::is_noexcept)) { return connect(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(R&)>::overload == adapter, typename call_traits<S&, void(R&)>::result_type >::type operator()(S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(R&)>::is_noexcept)) { return typename call_traits<S&, void(R&)>::result_type(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(R&)>::overload == adapter, typename call_traits<const S&, void(R&)>::result_type >::type operator()(const S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(R&)>::is_noexcept)) { return typename call_traits<const S&, void(R&)>::result_type(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(const R&)>::overload == call_member, typename call_traits<S&, void(const R&)>::result_type >::type operator()(S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(const R&)>::is_noexcept)) { return s.connect(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(const R&)>::overload == call_member, typename call_traits<const S&, void(const R&)>::result_type >::type operator()(const S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(const R&)>::is_noexcept)) { return s.connect(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(const R&)>::overload == call_free, typename call_traits<S&, void(const R&)>::result_type >::type operator()(S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(const R&)>::is_noexcept)) { return connect(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(const R&)>::overload == call_free, typename call_traits<const S&, void(const R&)>::result_type >::type operator()(const S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(const R&)>::is_noexcept)) { return connect(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(const R&)>::overload == adapter, typename call_traits<S&, void(const R&)>::result_type >::type operator()(S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(const R&)>::is_noexcept)) { return typename call_traits<S&, void(const R&)>::result_type(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(const R&)>::overload == adapter, typename call_traits<const S&, void(const R&)>::result_type >::type operator()(const S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(const R&)>::is_noexcept)) { return typename call_traits<const S&, void(const R&)>::result_type(s, r); } #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_connect_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_connect_fn::impl& connect = asio_execution_connect_fn::static_instance<>::instance; } // namespace template <typename S, typename R> struct can_connect : integral_constant<bool, asio_execution_connect_fn::call_traits<S, void(R)>::overload != asio_execution_connect_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> constexpr bool can_connect_v = can_connect<S, R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> struct is_nothrow_connect : integral_constant<bool, asio_execution_connect_fn::call_traits<S, void(R)>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> constexpr bool is_nothrow_connect_v = is_nothrow_connect<S, R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> struct connect_result { typedef typename asio_execution_connect_fn::call_traits< S, void(R)>::result_type type; }; #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) template <typename S, typename R> using connect_result_t = typename connect_result<S, R>::type; #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_CONNECT_HPP PK q��[��I execution/impl/bad_executor.ippnu �[��� // // exection/impl/bad_executor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_IMPL_BAD_EXECUTOR_IPP #define BOOST_ASIO_EXECUTION_IMPL_BAD_EXECUTOR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/execution/bad_executor.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace execution { bad_executor::bad_executor() BOOST_ASIO_NOEXCEPT { } const char* bad_executor::what() const BOOST_ASIO_NOEXCEPT_OR_NOTHROW { return "bad executor"; } } // namespace execution } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_IMPL_BAD_EXECUTOR_IPP PK q��[��x4 4 , execution/impl/receiver_invocation_error.ippnu �[��� // // exection/impl/receiver_invocation_error.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP #define BOOST_ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/execution/receiver_invocation_error.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace execution { receiver_invocation_error::receiver_invocation_error() : std::runtime_error("receiver invocation error") { } } // namespace execution } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP PK q��[�6��} } execution/occupancy.hppnu �[��� // // execution/occupancy.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_OCCUPANCY_HPP #define BOOST_ASIO_EXECUTION_OCCUPANCY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/scheduler.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/is_applicable_property.hpp> #include <boost/asio/traits/query_static_constexpr_member.hpp> #include <boost/asio/traits/static_query.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(GENERATING_DOCUMENTATION) namespace execution { /// A property that gives an estimate of the number of execution agents that /// should occupy the associated execution context. struct occupancy_t { /// The occupancy_t property applies to executors, senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The occupancy_t property cannot be required. static constexpr bool is_requirable = false; /// The occupancy_t property cannot be preferred. static constexpr bool is_preferable = false; /// The type returned by queries against an @c any_executor. typedef std::size_t polymorphic_query_result_type; }; /// A special value used for accessing the occupancy_t property. constexpr occupancy_t occupancy; } // namespace execution #else // defined(GENERATING_DOCUMENTATION) namespace execution { namespace detail { template <int I = 0> struct occupancy_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef std::size_t polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR occupancy_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, occupancy_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, occupancy_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, occupancy_t>::value(); } template <typename E, typename T = decltype(occupancy_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = occupancy_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_CONSTEXPR) static const occupancy_t instance; #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T occupancy_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_CONSTEXPR) template <int I> const occupancy_t<I> occupancy_t<I>::instance; #endif } // namespace detail typedef detail::occupancy_t<> occupancy_t; #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr occupancy_t occupancy; #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) namespace { static const occupancy_t& occupancy = occupancy_t::instance; } #endif } // namespace execution #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> struct is_applicable_property<T, execution::occupancy_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) namespace traits { #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> struct static_query<T, execution::occupancy_t, typename enable_if< traits::query_static_constexpr_member<T, execution::occupancy_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::occupancy_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::occupancy_t>::value(); } }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) } // namespace traits #endif // defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_OCCUPANCY_HPP PK q��[�"� y y execution/schedule.hppnu �[��� // // execution/schedule.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_SCHEDULE_HPP #define BOOST_ASIO_EXECUTION_SCHEDULE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/traits/schedule_member.hpp> #include <boost/asio/traits/schedule_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that is used to obtain a sender from a scheduler. /** * The name <tt>execution::schedule</tt> denotes a customisation point object. * For some subexpression <tt>s</tt>, let <tt>S</tt> be a type such that * <tt>decltype((s))</tt> is <tt>S</tt>. The expression * <tt>execution::schedule(s)</tt> is expression-equivalent to: * * @li <tt>s.schedule()</tt>, if that expression is valid and its type models * <tt>sender</tt>. * * @li Otherwise, <tt>schedule(s)</tt>, if that expression is valid and its * type models <tt>sender</tt> with overload resolution performed in a context * that includes the declaration <tt>void schedule();</tt> and that does not * include a declaration of <tt>execution::schedule</tt>. * * @li Otherwise, <tt>S</tt> if <tt>S</tt> satisfies <tt>executor</tt>. * * @li Otherwise, <tt>execution::schedule(s)</tt> is ill-formed. */ inline constexpr unspecified schedule = unspecified; /// A type trait that determines whether a @c schedule expression is /// well-formed. /** * Class template @c can_schedule is a trait that is derived from @c true_type * if the expression <tt>execution::schedule(std::declval<S>())</tt> is well * formed; otherwise @c false_type. */ template <typename S> struct can_schedule : integral_constant<bool, automatically_determined> { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_schedule_fn { using boost::asio::decay; using boost::asio::declval; using boost::asio::enable_if; using boost::asio::execution::is_executor; using boost::asio::traits::schedule_free; using boost::asio::traits::schedule_member; void schedule(); enum overload_type { identity, call_member, call_free, ill_formed }; template <typename S, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename S> struct call_traits<S, typename enable_if< ( schedule_member<S>::is_valid ) >::type> : schedule_member<S> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename S> struct call_traits<S, typename enable_if< ( !schedule_member<S>::is_valid && schedule_free<S>::is_valid ) >::type> : schedule_free<S> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; template <typename S> struct call_traits<S, typename enable_if< ( !schedule_member<S>::is_valid && !schedule_free<S>::is_valid && is_executor<typename decay<S>::type>::value ) >::type> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = identity); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); #if defined(BOOST_ASIO_HAS_MOVE) typedef BOOST_ASIO_MOVE_ARG(S) result_type; #else // defined(BOOST_ASIO_HAS_MOVE) typedef BOOST_ASIO_MOVE_ARG(typename decay<S>::type) result_type; #endif // defined(BOOST_ASIO_HAS_MOVE) }; struct impl { template <typename S> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S>::overload == identity, typename call_traits<S>::result_type >::type operator()(BOOST_ASIO_MOVE_ARG(S) s) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(S)(s); } #if defined(BOOST_ASIO_HAS_MOVE) template <typename S> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S>::overload == call_member, typename call_traits<S>::result_type >::type operator()(S&& s) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(S)(s).schedule(); } template <typename S> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S>::overload == call_free, typename call_traits<S>::result_type >::type operator()(S&& s) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S>::is_noexcept)) { return schedule(BOOST_ASIO_MOVE_CAST(S)(s)); } #else // defined(BOOST_ASIO_HAS_MOVE) template <typename S> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&>::overload == call_member, typename call_traits<S&>::result_type >::type operator()(S& s) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&>::is_noexcept)) { return s.schedule(); } template <typename S> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&>::overload == call_member, typename call_traits<const S&>::result_type >::type operator()(const S& s) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&>::is_noexcept)) { return s.schedule(); } template <typename S> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&>::overload == call_free, typename call_traits<S&>::result_type >::type operator()(S& s) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&>::is_noexcept)) { return schedule(s); } template <typename S> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&>::overload == call_free, typename call_traits<const S&>::result_type >::type operator()(const S& s) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&>::is_noexcept)) { return schedule(s); } #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_schedule_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_schedule_fn::impl& schedule = asio_execution_schedule_fn::static_instance<>::instance; } // namespace template <typename S> struct can_schedule : integral_constant<bool, asio_execution_schedule_fn::call_traits<S>::overload != asio_execution_schedule_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S> constexpr bool can_schedule_v = can_schedule<S>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S> struct is_nothrow_schedule : integral_constant<bool, asio_execution_schedule_fn::call_traits<S>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S> constexpr bool is_nothrow_schedule_v = is_nothrow_schedule<S>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_SCHEDULE_HPP PK q��[�-��a% a% execution/prefer_only.hppnu �[��� // // execution/prefer_only.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_PREFER_ONLY_HPP #define BOOST_ASIO_EXECUTION_PREFER_ONLY_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/is_applicable_property.hpp> #include <boost/asio/prefer.hpp> #include <boost/asio/query.hpp> #include <boost/asio/traits/static_query.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(GENERATING_DOCUMENTATION) namespace execution { /// A property adapter that is used with the polymorphic executor wrapper /// to mark properties as preferable, but not requirable. template <typename Property> struct prefer_only { /// The prefer_only adapter applies to the same types as the nested property. template <typename T> static constexpr bool is_applicable_property_v = is_applicable_property<T, Property>::value; /// The context_t property cannot be required. static constexpr bool is_requirable = false; /// The context_t property can be preferred, it the underlying property can /// be preferred. /** * @c true if @c Property::is_preferable is @c true, otherwise @c false. */ static constexpr bool is_preferable = automatically_determined; /// The type returned by queries against an @c any_executor. typedef typename Property::polymorphic_query_result_type polymorphic_query_result_type; }; } // namespace execution #else // defined(GENERATING_DOCUMENTATION) namespace execution { namespace detail { template <typename InnerProperty, typename = void> struct prefer_only_is_preferable { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); }; template <typename InnerProperty> struct prefer_only_is_preferable<InnerProperty, typename enable_if< InnerProperty::is_preferable >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); }; template <typename InnerProperty, typename = void> struct prefer_only_polymorphic_query_result_type { }; template <typename InnerProperty> struct prefer_only_polymorphic_query_result_type<InnerProperty, typename void_type< typename InnerProperty::polymorphic_query_result_type >::type> { typedef typename InnerProperty::polymorphic_query_result_type polymorphic_query_result_type; }; template <typename InnerProperty, typename = void> struct prefer_only_property { InnerProperty property; prefer_only_property(const InnerProperty& p) : property(p) { } }; #if defined(BOOST_ASIO_HAS_DECLTYPE) \ && defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE) template <typename InnerProperty> struct prefer_only_property<InnerProperty, typename void_type< decltype(boost::asio::declval<const InnerProperty>().value()) >::type> { InnerProperty property; prefer_only_property(const InnerProperty& p) : property(p) { } BOOST_ASIO_CONSTEXPR auto value() const BOOST_ASIO_NOEXCEPT_IF(( noexcept(boost::asio::declval<const InnerProperty>().value()))) -> decltype(boost::asio::declval<const InnerProperty>().value()) { return property.value(); } }; #else // defined(BOOST_ASIO_HAS_DECLTYPE) // && defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE) struct prefer_only_memfns_base { void value(); }; template <typename T> struct prefer_only_memfns_derived : T, prefer_only_memfns_base { }; template <typename T, T> struct prefer_only_memfns_check { }; template <typename> char (&prefer_only_value_memfn_helper(...))[2]; template <typename T> char prefer_only_value_memfn_helper( prefer_only_memfns_check< void (prefer_only_memfns_base::*)(), &prefer_only_memfns_derived<T>::value>*); template <typename InnerProperty> struct prefer_only_property<InnerProperty, typename enable_if< sizeof(prefer_only_value_memfn_helper<InnerProperty>(0)) != 1 && !is_same<typename InnerProperty::polymorphic_query_result_type, void>::value >::type> { InnerProperty property; prefer_only_property(const InnerProperty& p) : property(p) { } BOOST_ASIO_CONSTEXPR typename InnerProperty::polymorphic_query_result_type value() const { return property.value(); } }; #endif // defined(BOOST_ASIO_HAS_DECLTYPE) // && defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE) } // namespace detail template <typename InnerProperty> struct prefer_only : detail::prefer_only_is_preferable<InnerProperty>, detail::prefer_only_polymorphic_query_result_type<InnerProperty>, detail::prefer_only_property<InnerProperty> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); BOOST_ASIO_CONSTEXPR prefer_only(const InnerProperty& p) : detail::prefer_only_property<InnerProperty>(p) { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, InnerProperty>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::static_query<T, InnerProperty>::is_noexcept)) { return traits::static_query<T, InnerProperty>::value(); } template <typename E, typename T = decltype(prefer_only::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = prefer_only::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename Executor, typename Property> friend BOOST_ASIO_CONSTEXPR typename prefer_result<const Executor&, const InnerProperty&>::type prefer(const Executor& ex, const prefer_only<Property>& p, typename enable_if< is_same<Property, InnerProperty>::value && can_prefer<const Executor&, const InnerProperty&>::value >::type* = 0) #if !defined(BOOST_ASIO_MSVC) \ && !defined(__clang__) // Clang crashes if noexcept is used here. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_prefer<const Executor&, const InnerProperty&>::value)) #endif // !defined(BOOST_ASIO_MSVC) // && !defined(__clang__) { return boost::asio::prefer(ex, p.property); } template <typename Executor, typename Property> friend BOOST_ASIO_CONSTEXPR typename query_result<const Executor&, const InnerProperty&>::type query(const Executor& ex, const prefer_only<Property>& p, typename enable_if< is_same<Property, InnerProperty>::value && can_query<const Executor&, const InnerProperty&>::value >::type* = 0) #if !defined(BOOST_ASIO_MSVC) \ && !defined(__clang__) // Clang crashes if noexcept is used here. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, const InnerProperty&>::value)) #endif // !defined(BOOST_ASIO_MSVC) // && !defined(__clang__) { return boost::asio::query(ex, p.property); } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename InnerProperty> template <typename E, typename T> const T prefer_only<InnerProperty>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) } // namespace execution template <typename T, typename InnerProperty> struct is_applicable_property<T, execution::prefer_only<InnerProperty> > : is_applicable_property<T, InnerProperty> { }; namespace traits { #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T, typename InnerProperty> struct static_query<T, execution::prefer_only<InnerProperty> > : static_query<T, const InnerProperty&> { }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT) template <typename T, typename InnerProperty> struct prefer_free_default<T, execution::prefer_only<InnerProperty>, typename enable_if< can_prefer<const T&, const InnerProperty&>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_prefer<const T&, const InnerProperty&>::value)); typedef typename prefer_result<const T&, const InnerProperty&>::type result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) template <typename T, typename InnerProperty> struct query_free<T, execution::prefer_only<InnerProperty>, typename enable_if< can_query<const T&, const InnerProperty&>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<const T&, const InnerProperty&>::value)); typedef typename query_result<const T&, const InnerProperty&>::type result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) } // namespace traits #endif // defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_PREFER_ONLY_HPP PK q��[��h�SZ SZ execution/outstanding_work.hppnu �[��� // // execution/outstanding_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_HPP #define BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/scheduler.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/is_applicable_property.hpp> #include <boost/asio/query.hpp> #include <boost/asio/traits/query_free.hpp> #include <boost/asio/traits/query_member.hpp> #include <boost/asio/traits/query_static_constexpr_member.hpp> #include <boost/asio/traits/static_query.hpp> #include <boost/asio/traits/static_require.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(GENERATING_DOCUMENTATION) namespace execution { /// A property to describe whether task submission is likely in the future. struct outstanding_work_t { /// The outstanding_work_t property applies to executors, senders, and /// schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level outstanding_work_t property cannot be required. static constexpr bool is_requirable = false; /// The top-level outstanding_work_t property cannot be preferred. static constexpr bool is_preferable = false; /// The type returned by queries against an @c any_executor. typedef outstanding_work_t polymorphic_query_result_type; /// A sub-property that indicates that the executor does not represent likely /// future submission of a function object. struct untracked_t { /// The outstanding_work_t::untracked_t property applies to executors, /// senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The outstanding_work_t::untracked_t property can be required. static constexpr bool is_requirable = true; /// The outstanding_work_t::untracked_t property can be preferred. static constexpr bool is_preferable = true; /// The type returned by queries against an @c any_executor. typedef outstanding_work_t polymorphic_query_result_type; /// Default constructor. constexpr untracked_t(); /// Get the value associated with a property object. /** * @returns untracked_t(); */ static constexpr outstanding_work_t value(); }; /// A sub-property that indicates that the executor represents likely /// future submission of a function object. struct tracked_t { /// The outstanding_work_t::untracked_t property applies to executors, /// senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The outstanding_work_t::tracked_t property can be required. static constexpr bool is_requirable = true; /// The outstanding_work_t::tracked_t property can be preferred. static constexpr bool is_preferable = true; /// The type returned by queries against an @c any_executor. typedef outstanding_work_t polymorphic_query_result_type; /// Default constructor. constexpr tracked_t(); /// Get the value associated with a property object. /** * @returns tracked_t(); */ static constexpr outstanding_work_t value(); }; /// A special value used for accessing the outstanding_work_t::untracked_t /// property. static constexpr untracked_t untracked; /// A special value used for accessing the outstanding_work_t::tracked_t /// property. static constexpr tracked_t tracked; /// Default constructor. constexpr outstanding_work_t(); /// Construct from a sub-property value. constexpr outstanding_work_t(untracked_t); /// Construct from a sub-property value. constexpr outstanding_work_t(tracked_t); /// Compare property values for equality. friend constexpr bool operator==( const outstanding_work_t& a, const outstanding_work_t& b) noexcept; /// Compare property values for inequality. friend constexpr bool operator!=( const outstanding_work_t& a, const outstanding_work_t& b) noexcept; }; /// A special value used for accessing the outstanding_work_t property. constexpr outstanding_work_t outstanding_work; } // namespace execution #else // defined(GENERATING_DOCUMENTATION) namespace execution { namespace detail { namespace outstanding_work { template <int I> struct untracked_t; template <int I> struct tracked_t; } // namespace outstanding_work template <int I = 0> struct outstanding_work_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef outstanding_work_t polymorphic_query_result_type; typedef detail::outstanding_work::untracked_t<I> untracked_t; typedef detail::outstanding_work::tracked_t<I> tracked_t; BOOST_ASIO_CONSTEXPR outstanding_work_t() : value_(-1) { } BOOST_ASIO_CONSTEXPR outstanding_work_t(untracked_t) : value_(0) { } BOOST_ASIO_CONSTEXPR outstanding_work_t(tracked_t) : value_(1) { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member< T, outstanding_work_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member< T, outstanding_work_t >::is_noexcept)) { return traits::query_static_constexpr_member< T, outstanding_work_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, untracked_t>::result_type static_query( typename enable_if< !traits::query_static_constexpr_member< T, outstanding_work_t>::is_valid && !traits::query_member<T, outstanding_work_t>::is_valid && traits::static_query<T, untracked_t>::is_valid >::type* = 0) BOOST_ASIO_NOEXCEPT { return traits::static_query<T, untracked_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, tracked_t>::result_type static_query( typename enable_if< !traits::query_static_constexpr_member< T, outstanding_work_t>::is_valid && !traits::query_member<T, outstanding_work_t>::is_valid && !traits::static_query<T, untracked_t>::is_valid && traits::static_query<T, tracked_t>::is_valid >::type* = 0) BOOST_ASIO_NOEXCEPT { return traits::static_query<T, tracked_t>::value(); } template <typename E, typename T = decltype(outstanding_work_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = outstanding_work_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) friend BOOST_ASIO_CONSTEXPR bool operator==( const outstanding_work_t& a, const outstanding_work_t& b) { return a.value_ == b.value_; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const outstanding_work_t& a, const outstanding_work_t& b) { return a.value_ != b.value_; } struct convertible_from_outstanding_work_t { BOOST_ASIO_CONSTEXPR convertible_from_outstanding_work_t(outstanding_work_t) { } }; template <typename Executor> friend BOOST_ASIO_CONSTEXPR outstanding_work_t query( const Executor& ex, convertible_from_outstanding_work_t, typename enable_if< can_query<const Executor&, untracked_t>::value >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, outstanding_work_t<>::untracked_t>::value)) #else // defined(BOOST_ASIO_MSVC) BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, untracked_t>::value)) #endif // defined(BOOST_ASIO_MSVC) #endif // !defined(__clang__) { return boost::asio::query(ex, untracked_t()); } template <typename Executor> friend BOOST_ASIO_CONSTEXPR outstanding_work_t query( const Executor& ex, convertible_from_outstanding_work_t, typename enable_if< !can_query<const Executor&, untracked_t>::value && can_query<const Executor&, tracked_t>::value >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, outstanding_work_t<>::tracked_t>::value)) #else // defined(BOOST_ASIO_MSVC) BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, tracked_t>::value)) #endif // defined(BOOST_ASIO_MSVC) #endif // !defined(__clang__) { return boost::asio::query(ex, tracked_t()); } BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(untracked_t, untracked); BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(tracked_t, tracked); #if !defined(BOOST_ASIO_HAS_CONSTEXPR) static const outstanding_work_t instance; #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) private: int value_; }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T outstanding_work_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_CONSTEXPR) template <int I> const outstanding_work_t<I> outstanding_work_t<I>::instance; #endif template <int I> const typename outstanding_work_t<I>::untracked_t outstanding_work_t<I>::untracked; template <int I> const typename outstanding_work_t<I>::tracked_t outstanding_work_t<I>::tracked; namespace outstanding_work { template <int I = 0> struct untracked_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef outstanding_work_t<I> polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR untracked_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, untracked_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, untracked_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, untracked_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR untracked_t static_query( typename enable_if< !traits::query_static_constexpr_member<T, untracked_t>::is_valid && !traits::query_member<T, untracked_t>::is_valid && !traits::query_free<T, untracked_t>::is_valid && !can_query<T, tracked_t<I> >::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return untracked_t(); } template <typename E, typename T = decltype(untracked_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = untracked_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) static BOOST_ASIO_CONSTEXPR outstanding_work_t<I> value() { return untracked_t(); } friend BOOST_ASIO_CONSTEXPR bool operator==( const untracked_t&, const untracked_t&) { return true; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const untracked_t&, const untracked_t&) { return false; } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T untracked_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I = 0> struct tracked_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef outstanding_work_t<I> polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR tracked_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, tracked_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, tracked_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, tracked_t>::value(); } template <typename E, typename T = decltype(tracked_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = tracked_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) static BOOST_ASIO_CONSTEXPR outstanding_work_t<I> value() { return tracked_t(); } friend BOOST_ASIO_CONSTEXPR bool operator==( const tracked_t&, const tracked_t&) { return true; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const tracked_t&, const tracked_t&) { return false; } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T tracked_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) } // namespace outstanding_work } // namespace detail typedef detail::outstanding_work_t<> outstanding_work_t; #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr outstanding_work_t outstanding_work; #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) namespace { static const outstanding_work_t& outstanding_work = outstanding_work_t::instance; } #endif } // namespace execution #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> struct is_applicable_property<T, execution::outstanding_work_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::untracked_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::tracked_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) namespace traits { #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) template <typename T> struct query_free_default<T, execution::outstanding_work_t, typename enable_if< can_query<T, execution::outstanding_work_t::untracked_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value)); typedef execution::outstanding_work_t result_type; }; template <typename T> struct query_free_default<T, execution::outstanding_work_t, typename enable_if< !can_query<T, execution::outstanding_work_t::untracked_t>::value && can_query<T, execution::outstanding_work_t::tracked_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value)); typedef execution::outstanding_work_t result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> struct static_query<T, execution::outstanding_work_t, typename enable_if< traits::query_static_constexpr_member<T, execution::outstanding_work_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::outstanding_work_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::outstanding_work_t>::value(); } }; template <typename T> struct static_query<T, execution::outstanding_work_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::outstanding_work_t>::is_valid && !traits::query_member<T, execution::outstanding_work_t>::is_valid && traits::static_query<T, execution::outstanding_work_t::untracked_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::outstanding_work_t::untracked_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::outstanding_work_t::untracked_t>::value(); } }; template <typename T> struct static_query<T, execution::outstanding_work_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::outstanding_work_t>::is_valid && !traits::query_member<T, execution::outstanding_work_t>::is_valid && !traits::static_query<T, execution::outstanding_work_t::untracked_t>::is_valid && traits::static_query<T, execution::outstanding_work_t::tracked_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::outstanding_work_t::tracked_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::outstanding_work_t::tracked_t>::value(); } }; template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t, typename enable_if< traits::query_static_constexpr_member<T, execution::outstanding_work_t::untracked_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::outstanding_work_t::untracked_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::outstanding_work_t::untracked_t>::value(); } }; template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::outstanding_work_t::untracked_t>::is_valid && !traits::query_member<T, execution::outstanding_work_t::untracked_t>::is_valid && !traits::query_free<T, execution::outstanding_work_t::untracked_t>::is_valid && !can_query<T, execution::outstanding_work_t::tracked_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::outstanding_work_t::untracked_t result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return result_type(); } }; template <typename T> struct static_query<T, execution::outstanding_work_t::tracked_t, typename enable_if< traits::query_static_constexpr_member<T, execution::outstanding_work_t::tracked_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::outstanding_work_t::tracked_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::outstanding_work_t::tracked_t>::value(); } }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) template <typename T> struct static_require<T, execution::outstanding_work_t::untracked_t, typename enable_if< static_query<T, execution::outstanding_work_t::untracked_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = (is_same<typename static_query<T, execution::outstanding_work_t::untracked_t>::result_type, execution::outstanding_work_t::untracked_t>::value)); }; template <typename T> struct static_require<T, execution::outstanding_work_t::tracked_t, typename enable_if< static_query<T, execution::outstanding_work_t::tracked_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = (is_same<typename static_query<T, execution::outstanding_work_t::tracked_t>::result_type, execution::outstanding_work_t::tracked_t>::value)); }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) } // namespace traits #endif // defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_OUTSTANDING_WORK_HPP PK q��[+{� � execution/set_done.hppnu �[��� // // execution/set_done.hpp // ~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_SET_DONE_HPP #define BOOST_ASIO_EXECUTION_SET_DONE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/traits/set_done_member.hpp> #include <boost/asio/traits/set_done_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that delivers a done notification to a receiver. /** * The name <tt>execution::set_done</tt> denotes a customisation point object. * The expression <tt>execution::set_done(R)</tt> for some subexpression * <tt>R</tt> is expression-equivalent to: * * @li <tt>R.set_done()</tt>, if that expression is valid. If the function * selected does not signal the receiver <tt>R</tt>'s done channel, the * program is ill-formed with no diagnostic required. * * @li Otherwise, <tt>set_done(R)</tt>, if that expression is valid, with * overload resolution performed in a context that includes the declaration * <tt>void set_done();</tt> and that does not include a declaration of * <tt>execution::set_done</tt>. If the function selected by overload * resolution does not signal the receiver <tt>R</tt>'s done channel, the * program is ill-formed with no diagnostic required. * * @li Otherwise, <tt>execution::set_done(R)</tt> is ill-formed. */ inline constexpr unspecified set_done = unspecified; /// A type trait that determines whether a @c set_done expression is /// well-formed. /** * Class template @c can_set_done is a trait that is derived from * @c true_type if the expression <tt>execution::set_done(std::declval<R>(), * std::declval<E>())</tt> is well formed; otherwise @c false_type. */ template <typename R> struct can_set_done : integral_constant<bool, automatically_determined> { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_set_done_fn { using boost::asio::decay; using boost::asio::declval; using boost::asio::enable_if; using boost::asio::traits::set_done_free; using boost::asio::traits::set_done_member; void set_done(); enum overload_type { call_member, call_free, ill_formed }; template <typename R, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename R> struct call_traits<R, typename enable_if< ( set_done_member<R>::is_valid ) >::type> : set_done_member<R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename R> struct call_traits<R, typename enable_if< ( !set_done_member<R>::is_valid && set_done_free<R>::is_valid ) >::type> : set_done_free<R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; struct impl { #if defined(BOOST_ASIO_HAS_MOVE) template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R>::overload == call_member, typename call_traits<R>::result_type >::type operator()(R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(R)(r).set_done(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R>::overload == call_free, typename call_traits<R>::result_type >::type operator()(R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R>::is_noexcept)) { return set_done(BOOST_ASIO_MOVE_CAST(R)(r)); } #else // defined(BOOST_ASIO_HAS_MOVE) template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&>::overload == call_member, typename call_traits<R&>::result_type >::type operator()(R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&>::is_noexcept)) { return r.set_done(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&>::overload == call_member, typename call_traits<const R&>::result_type >::type operator()(const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&>::is_noexcept)) { return r.set_done(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&>::overload == call_free, typename call_traits<R&>::result_type >::type operator()(R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&>::is_noexcept)) { return set_done(r); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&>::overload == call_free, typename call_traits<const R&>::result_type >::type operator()(const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&>::is_noexcept)) { return set_done(r); } #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_set_done_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_set_done_fn::impl& set_done = asio_execution_set_done_fn::static_instance<>::instance; } // namespace template <typename R> struct can_set_done : integral_constant<bool, asio_execution_set_done_fn::call_traits<R>::overload != asio_execution_set_done_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R> constexpr bool can_set_done_v = can_set_done<R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R> struct is_nothrow_set_done : integral_constant<bool, asio_execution_set_done_fn::call_traits<R>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R> constexpr bool is_nothrow_set_done_v = is_nothrow_set_done<R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_SET_DONE_HPP PK q��[�(��4 �4 execution/submit.hppnu �[��� // // execution/submit.hpp // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_SUBMIT_HPP #define BOOST_ASIO_EXECUTION_SUBMIT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/detail/submit_receiver.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/receiver.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/execution/start.hpp> #include <boost/asio/traits/submit_member.hpp> #include <boost/asio/traits/submit_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that submits a sender to a receiver. /** * The name <tt>execution::submit</tt> denotes a customisation point object. For * some subexpressions <tt>s</tt> and <tt>r</tt>, let <tt>S</tt> be a type such * that <tt>decltype((s))</tt> is <tt>S</tt> and let <tt>R</tt> be a type such * that <tt>decltype((r))</tt> is <tt>R</tt>. The expression * <tt>execution::submit(s, r)</tt> is ill-formed if <tt>sender_to<S, R></tt> is * not <tt>true</tt>. Otherwise, it is expression-equivalent to: * * @li <tt>s.submit(r)</tt>, if that expression is valid and <tt>S</tt> models * <tt>sender</tt>. If the function selected does not submit the receiver * object <tt>r</tt> via the sender <tt>s</tt>, the program is ill-formed with * no diagnostic required. * * @li Otherwise, <tt>submit(s, r)</tt>, if that expression is valid and * <tt>S</tt> models <tt>sender</tt>, with overload resolution performed in a * context that includes the declaration <tt>void submit();</tt> and that does * not include a declaration of <tt>execution::submit</tt>. If the function * selected by overload resolution does not submit the receiver object * <tt>r</tt> via the sender <tt>s</tt>, the program is ill-formed with no * diagnostic required. * * @li Otherwise, <tt>execution::start((new submit_receiver<S, * R>{s,r})->state_)</tt>, where <tt>submit_receiver</tt> is an * implementation-defined class template equivalent to: * @code template<class S, class R> * struct submit_receiver { * struct wrap { * submit_receiver * p_; * template<class...As> * requires receiver_of<R, As...> * void set_value(As&&... as) && * noexcept(is_nothrow_receiver_of_v<R, As...>) { * execution::set_value(std::move(p_->r_), (As&&) as...); * delete p_; * } * template<class E> * requires receiver<R, E> * void set_error(E&& e) && noexcept { * execution::set_error(std::move(p_->r_), (E&&) e); * delete p_; * } * void set_done() && noexcept { * execution::set_done(std::move(p_->r_)); * delete p_; * } * }; * remove_cvref_t<R> r_; * connect_result_t<S, wrap> state_; * submit_receiver(S&& s, R&& r) * : r_((R&&) r) * , state_(execution::connect((S&&) s, wrap{this})) {} * }; * @endcode */ inline constexpr unspecified submit = unspecified; /// A type trait that determines whether a @c submit expression is /// well-formed. /** * Class template @c can_submit is a trait that is derived from * @c true_type if the expression <tt>execution::submit(std::declval<R>(), * std::declval<E>())</tt> is well formed; otherwise @c false_type. */ template <typename S, typename R> struct can_submit : integral_constant<bool, automatically_determined> { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_submit_fn { using boost::asio::declval; using boost::asio::enable_if; using boost::asio::execution::is_sender_to; using boost::asio::traits::submit_free; using boost::asio::traits::submit_member; void submit(); enum overload_type { call_member, call_free, adapter, ill_formed }; template <typename S, typename R, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename S, typename R> struct call_traits<S, void(R), typename enable_if< ( submit_member<S, R>::is_valid && is_sender_to<S, R>::value ) >::type> : submit_member<S, R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename S, typename R> struct call_traits<S, void(R), typename enable_if< ( !submit_member<S, R>::is_valid && submit_free<S, R>::is_valid && is_sender_to<S, R>::value ) >::type> : submit_free<S, R> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; template <typename S, typename R> struct call_traits<S, void(R), typename enable_if< ( !submit_member<S, R>::is_valid && !submit_free<S, R>::is_valid && is_sender_to<S, R>::value ) >::type> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; struct impl { #if defined(BOOST_ASIO_HAS_MOVE) template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(R)>::overload == call_member, typename call_traits<S, void(R)>::result_type >::type operator()(S&& s, R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(R)>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(S)(s).submit(BOOST_ASIO_MOVE_CAST(R)(r)); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(R)>::overload == call_free, typename call_traits<S, void(R)>::result_type >::type operator()(S&& s, R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(R)>::is_noexcept)) { return submit(BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(R)(r)); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(R)>::overload == adapter, typename call_traits<S, void(R)>::result_type >::type operator()(S&& s, R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(R)>::is_noexcept)) { return boost::asio::execution::start( (new boost::asio::execution::detail::submit_receiver<S, R>( BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(R)(r)))->state_); } #else // defined(BOOST_ASIO_HAS_MOVE) template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(R&)>::overload == call_member, typename call_traits<S&, void(R&)>::result_type >::type operator()(S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(R&)>::is_noexcept)) { return s.submit(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(R&)>::overload == call_member, typename call_traits<const S&, void(R&)>::result_type >::type operator()(const S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(R&)>::is_noexcept)) { return s.submit(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(R&)>::overload == call_free, typename call_traits<S&, void(R&)>::result_type >::type operator()(S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(R&)>::is_noexcept)) { return submit(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(R&)>::overload == call_free, typename call_traits<const S&, void(R&)>::result_type >::type operator()(const S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(R&)>::is_noexcept)) { return submit(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(R&)>::overload == adapter, typename call_traits<S&, void(R&)>::result_type >::type operator()(S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(R&)>::is_noexcept)) { return boost::asio::execution::start( (new boost::asio::execution::detail::submit_receiver< S&, R&>(s, r))->state_); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(R&)>::overload == adapter, typename call_traits<const S&, void(R&)>::result_type >::type operator()(const S& s, R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(R&)>::is_noexcept)) { boost::asio::execution::start( (new boost::asio::execution::detail::submit_receiver< const S&, R&>(s, r))->state_); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(const R&)>::overload == call_member, typename call_traits<S&, void(const R&)>::result_type >::type operator()(S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(const R&)>::is_noexcept)) { return s.submit(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(const R&)>::overload == call_member, typename call_traits<const S&, void(const R&)>::result_type >::type operator()(const S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(const R&)>::is_noexcept)) { return s.submit(r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(const R&)>::overload == call_free, typename call_traits<S&, void(const R&)>::result_type >::type operator()(S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(const R&)>::is_noexcept)) { return submit(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(const R&)>::overload == call_free, typename call_traits<const S&, void(const R&)>::result_type >::type operator()(const S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(const R&)>::is_noexcept)) { return submit(s, r); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S&, void(const R&)>::overload == adapter, typename call_traits<S&, void(const R&)>::result_type >::type operator()(S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S&, void(const R&)>::is_noexcept)) { boost::asio::execution::start( (new boost::asio::execution::detail::submit_receiver< S&, const R&>(s, r))->state_); } template <typename S, typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const S&, void(const R&)>::overload == adapter, typename call_traits<const S&, void(const R&)>::result_type >::type operator()(const S& s, const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const S&, void(const R&)>::is_noexcept)) { boost::asio::execution::start( (new boost::asio::execution::detail::submit_receiver< const S&, const R&>(s, r))->state_); } #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_submit_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_submit_fn::impl& submit = asio_execution_submit_fn::static_instance<>::instance; } // namespace template <typename S, typename R> struct can_submit : integral_constant<bool, asio_execution_submit_fn::call_traits<S, void(R)>::overload != asio_execution_submit_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> constexpr bool can_submit_v = can_submit<S, R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> struct is_nothrow_submit : integral_constant<bool, asio_execution_submit_fn::call_traits<S, void(R)>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> constexpr bool is_nothrow_submit_v = is_nothrow_submit<S, R>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename R> struct submit_result { typedef typename asio_execution_submit_fn::call_traits< S, void(R)>::result_type type; }; namespace detail { template <typename S, typename R> void submit_helper(BOOST_ASIO_MOVE_ARG(S) s, BOOST_ASIO_MOVE_ARG(R) r) { execution::submit(BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(R)(r)); } } // namespace detail } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_SUBMIT_HPP PK q��[� '*=q =q execution/mapping.hppnu �[��� // // execution/mapping.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_MAPPING_HPP #define BOOST_ASIO_EXECUTION_MAPPING_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/scheduler.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/is_applicable_property.hpp> #include <boost/asio/query.hpp> #include <boost/asio/traits/query_free.hpp> #include <boost/asio/traits/query_member.hpp> #include <boost/asio/traits/query_static_constexpr_member.hpp> #include <boost/asio/traits/static_query.hpp> #include <boost/asio/traits/static_require.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(GENERATING_DOCUMENTATION) namespace execution { /// A property to describe what guarantees an executor makes about the mapping /// of execution agents on to threads of execution. struct mapping_t { /// The mapping_t property applies to executors, senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level mapping_t property cannot be required. static constexpr bool is_requirable = false; /// The top-level mapping_t property cannot be preferred. static constexpr bool is_preferable = false; /// The type returned by queries against an @c any_executor. typedef mapping_t polymorphic_query_result_type; /// A sub-property that indicates that execution agents are mapped on to /// threads of execution. struct thread_t { /// The mapping_t::thread_t property applies to executors, senders, and /// schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The mapping_t::thread_t property can be required. static constexpr bool is_requirable = true; /// The mapping_t::thread_t property can be preferred. static constexpr bool is_preferable = true; /// The type returned by queries against an @c any_executor. typedef mapping_t polymorphic_query_result_type; /// Default constructor. constexpr thread_t(); /// Get the value associated with a property object. /** * @returns thread_t(); */ static constexpr mapping_t value(); }; /// A sub-property that indicates that execution agents are mapped on to /// new threads of execution. struct new_thread_t { /// The mapping_t::new_thread_t property applies to executors, senders, and /// schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The mapping_t::new_thread_t property can be required. static constexpr bool is_requirable = true; /// The mapping_t::new_thread_t property can be preferred. static constexpr bool is_preferable = true; /// The type returned by queries against an @c any_executor. typedef mapping_t polymorphic_query_result_type; /// Default constructor. constexpr new_thread_t(); /// Get the value associated with a property object. /** * @returns new_thread_t(); */ static constexpr mapping_t value(); }; /// A sub-property that indicates that the mapping of execution agents is /// implementation-defined. struct other_t { /// The mapping_t::other_t property applies to executors, senders, and /// schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The mapping_t::other_t property can be required. static constexpr bool is_requirable = true; /// The mapping_t::other_t property can be preferred. static constexpr bool is_preferable = true; /// The type returned by queries against an @c any_executor. typedef mapping_t polymorphic_query_result_type; /// Default constructor. constexpr other_t(); /// Get the value associated with a property object. /** * @returns other_t(); */ static constexpr mapping_t value(); }; /// A special value used for accessing the mapping_t::thread_t property. static constexpr thread_t thread; /// A special value used for accessing the mapping_t::new_thread_t property. static constexpr new_thread_t new_thread; /// A special value used for accessing the mapping_t::other_t property. static constexpr other_t other; /// Default constructor. constexpr mapping_t(); /// Construct from a sub-property value. constexpr mapping_t(thread_t); /// Construct from a sub-property value. constexpr mapping_t(new_thread_t); /// Construct from a sub-property value. constexpr mapping_t(other_t); /// Compare property values for equality. friend constexpr bool operator==( const mapping_t& a, const mapping_t& b) noexcept; /// Compare property values for inequality. friend constexpr bool operator!=( const mapping_t& a, const mapping_t& b) noexcept; }; /// A special value used for accessing the mapping_t property. constexpr mapping_t mapping; } // namespace execution #else // defined(GENERATING_DOCUMENTATION) namespace execution { namespace detail { namespace mapping { template <int I> struct thread_t; template <int I> struct new_thread_t; template <int I> struct other_t; } // namespace mapping template <int I = 0> struct mapping_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef mapping_t polymorphic_query_result_type; typedef detail::mapping::thread_t<I> thread_t; typedef detail::mapping::new_thread_t<I> new_thread_t; typedef detail::mapping::other_t<I> other_t; BOOST_ASIO_CONSTEXPR mapping_t() : value_(-1) { } BOOST_ASIO_CONSTEXPR mapping_t(thread_t) : value_(0) { } BOOST_ASIO_CONSTEXPR mapping_t(new_thread_t) : value_(1) { } BOOST_ASIO_CONSTEXPR mapping_t(other_t) : value_(2) { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, mapping_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, mapping_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, mapping_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, thread_t>::result_type static_query( typename enable_if< !traits::query_static_constexpr_member<T, mapping_t>::is_valid && !traits::query_member<T, mapping_t>::is_valid && traits::static_query<T, thread_t>::is_valid >::type* = 0) BOOST_ASIO_NOEXCEPT { return traits::static_query<T, thread_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, new_thread_t>::result_type static_query( typename enable_if< !traits::query_static_constexpr_member<T, mapping_t>::is_valid && !traits::query_member<T, mapping_t>::is_valid && !traits::static_query<T, thread_t>::is_valid && traits::static_query<T, new_thread_t>::is_valid >::type* = 0) BOOST_ASIO_NOEXCEPT { return traits::static_query<T, new_thread_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, other_t>::result_type static_query( typename enable_if< !traits::query_static_constexpr_member<T, mapping_t>::is_valid && !traits::query_member<T, mapping_t>::is_valid && !traits::static_query<T, thread_t>::is_valid && !traits::static_query<T, new_thread_t>::is_valid && traits::static_query<T, other_t>::is_valid >::type* = 0) BOOST_ASIO_NOEXCEPT { return traits::static_query<T, other_t>::value(); } template <typename E, typename T = decltype(mapping_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = mapping_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) friend BOOST_ASIO_CONSTEXPR bool operator==( const mapping_t& a, const mapping_t& b) { return a.value_ == b.value_; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const mapping_t& a, const mapping_t& b) { return a.value_ != b.value_; } struct convertible_from_mapping_t { BOOST_ASIO_CONSTEXPR convertible_from_mapping_t(mapping_t) {} }; template <typename Executor> friend BOOST_ASIO_CONSTEXPR mapping_t query( const Executor& ex, convertible_from_mapping_t, typename enable_if< can_query<const Executor&, thread_t>::value >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, mapping_t<>::thread_t>::value)) #else // defined(BOOST_ASIO_MSVC) BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, thread_t>::value)) #endif // defined(BOOST_ASIO_MSVC) #endif // !defined(__clang__) { return boost::asio::query(ex, thread_t()); } template <typename Executor> friend BOOST_ASIO_CONSTEXPR mapping_t query( const Executor& ex, convertible_from_mapping_t, typename enable_if< !can_query<const Executor&, thread_t>::value && can_query<const Executor&, new_thread_t>::value >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, mapping_t<>::new_thread_t>::value)) #else // defined(BOOST_ASIO_MSVC) BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, new_thread_t>::value)) #endif // defined(BOOST_ASIO_MSVC) #endif // !defined(__clang__) { return boost::asio::query(ex, new_thread_t()); } template <typename Executor> friend BOOST_ASIO_CONSTEXPR mapping_t query( const Executor& ex, convertible_from_mapping_t, typename enable_if< !can_query<const Executor&, thread_t>::value && !can_query<const Executor&, new_thread_t>::value && can_query<const Executor&, other_t>::value >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, mapping_t<>::other_t>::value)) #else // defined(BOOST_ASIO_MSVC) BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, other_t>::value)) #endif // defined(BOOST_ASIO_MSVC) #endif // !defined(__clang__) { return boost::asio::query(ex, other_t()); } BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(thread_t, thread); BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(new_thread_t, new_thread); BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(other_t, other); #if !defined(BOOST_ASIO_HAS_CONSTEXPR) static const mapping_t instance; #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) private: int value_; }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T mapping_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_CONSTEXPR) template <int I> const mapping_t<I> mapping_t<I>::instance; #endif template <int I> const typename mapping_t<I>::thread_t mapping_t<I>::thread; template <int I> const typename mapping_t<I>::new_thread_t mapping_t<I>::new_thread; template <int I> const typename mapping_t<I>::other_t mapping_t<I>::other; namespace mapping { template <int I = 0> struct thread_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef mapping_t<I> polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR thread_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, thread_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, thread_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, thread_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR thread_t static_query( typename enable_if< !traits::query_static_constexpr_member<T, thread_t>::is_valid && !traits::query_member<T, thread_t>::is_valid && !traits::query_free<T, thread_t>::is_valid && !can_query<T, new_thread_t<I> >::value && !can_query<T, other_t<I> >::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return thread_t(); } template <typename E, typename T = decltype(thread_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = thread_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) static BOOST_ASIO_CONSTEXPR mapping_t<I> value() { return thread_t(); } friend BOOST_ASIO_CONSTEXPR bool operator==( const thread_t&, const thread_t&) { return true; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const thread_t&, const thread_t&) { return false; } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T thread_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I = 0> struct new_thread_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef mapping_t<I> polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR new_thread_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, new_thread_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, new_thread_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, new_thread_t>::value(); } template <typename E, typename T = decltype(new_thread_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = new_thread_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) static BOOST_ASIO_CONSTEXPR mapping_t<I> value() { return new_thread_t(); } friend BOOST_ASIO_CONSTEXPR bool operator==( const new_thread_t&, const new_thread_t&) { return true; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const new_thread_t&, const new_thread_t&) { return false; } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T new_thread_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> struct other_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef mapping_t<I> polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR other_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, other_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, other_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, other_t>::value(); } template <typename E, typename T = decltype(other_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = other_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) static BOOST_ASIO_CONSTEXPR mapping_t<I> value() { return other_t(); } friend BOOST_ASIO_CONSTEXPR bool operator==( const other_t&, const other_t&) { return true; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const other_t&, const other_t&) { return false; } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T other_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) } // namespace mapping } // namespace detail typedef detail::mapping_t<> mapping_t; #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr mapping_t mapping; #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) namespace { static const mapping_t& mapping = mapping_t::instance; } #endif } // namespace execution #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> struct is_applicable_property<T, execution::mapping_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::thread_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::new_thread_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::other_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) namespace traits { #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) template <typename T> struct query_free_default<T, execution::mapping_t, typename enable_if< can_query<T, execution::mapping_t::thread_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T, execution::mapping_t::thread_t>::value)); typedef execution::mapping_t result_type; }; template <typename T> struct query_free_default<T, execution::mapping_t, typename enable_if< !can_query<T, execution::mapping_t::thread_t>::value && can_query<T, execution::mapping_t::new_thread_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T, execution::mapping_t::new_thread_t>::value)); typedef execution::mapping_t result_type; }; template <typename T> struct query_free_default<T, execution::mapping_t, typename enable_if< !can_query<T, execution::mapping_t::thread_t>::value && !can_query<T, execution::mapping_t::new_thread_t>::value && can_query<T, execution::mapping_t::other_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T, execution::mapping_t::other_t>::value)); typedef execution::mapping_t result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> struct static_query<T, execution::mapping_t, typename enable_if< traits::query_static_constexpr_member<T, execution::mapping_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::mapping_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::mapping_t>::value(); } }; template <typename T> struct static_query<T, execution::mapping_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::mapping_t>::is_valid && !traits::query_member<T, execution::mapping_t>::is_valid && traits::static_query<T, execution::mapping_t::thread_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::mapping_t::thread_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::mapping_t::thread_t>::value(); } }; template <typename T> struct static_query<T, execution::mapping_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::mapping_t>::is_valid && !traits::query_member<T, execution::mapping_t>::is_valid && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid && traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::mapping_t::new_thread_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::mapping_t::new_thread_t>::value(); } }; template <typename T> struct static_query<T, execution::mapping_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::mapping_t>::is_valid && !traits::query_member<T, execution::mapping_t>::is_valid && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid && !traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid && traits::static_query<T, execution::mapping_t::other_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::mapping_t::other_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::mapping_t::other_t>::value(); } }; template <typename T> struct static_query<T, execution::mapping_t::thread_t, typename enable_if< traits::query_static_constexpr_member<T, execution::mapping_t::thread_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::mapping_t::thread_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::mapping_t::thread_t>::value(); } }; template <typename T> struct static_query<T, execution::mapping_t::thread_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::mapping_t::thread_t>::is_valid && !traits::query_member<T, execution::mapping_t::thread_t>::is_valid && !traits::query_free<T, execution::mapping_t::thread_t>::is_valid && !can_query<T, execution::mapping_t::new_thread_t>::value && !can_query<T, execution::mapping_t::other_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::mapping_t::thread_t result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return result_type(); } }; template <typename T> struct static_query<T, execution::mapping_t::new_thread_t, typename enable_if< traits::query_static_constexpr_member<T, execution::mapping_t::new_thread_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::mapping_t::new_thread_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::mapping_t::new_thread_t>::value(); } }; template <typename T> struct static_query<T, execution::mapping_t::other_t, typename enable_if< traits::query_static_constexpr_member<T, execution::mapping_t::other_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::mapping_t::other_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::mapping_t::other_t>::value(); } }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) template <typename T> struct static_require<T, execution::mapping_t::thread_t, typename enable_if< static_query<T, execution::mapping_t::thread_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = (is_same<typename static_query<T, execution::mapping_t::thread_t>::result_type, execution::mapping_t::thread_t>::value)); }; template <typename T> struct static_require<T, execution::mapping_t::new_thread_t, typename enable_if< static_query<T, execution::mapping_t::new_thread_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = (is_same<typename static_query<T, execution::mapping_t::new_thread_t>::result_type, execution::mapping_t::new_thread_t>::value)); }; template <typename T> struct static_require<T, execution::mapping_t::other_t, typename enable_if< static_query<T, execution::mapping_t::other_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = (is_same<typename static_query<T, execution::mapping_t::other_t>::result_type, execution::mapping_t::other_t>::value)); }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) } // namespace traits #endif // defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_MAPPING_HPP PK q��[���X execution/bad_executor.hppnu �[��� // // execution/bad_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_BAD_EXECUTOR_HPP #define BOOST_ASIO_EXECUTION_BAD_EXECUTOR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <exception> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { namespace execution { /// Exception thrown when trying to access an empty polymorphic executor. class bad_executor : public std::exception { public: /// Constructor. BOOST_ASIO_DECL bad_executor() BOOST_ASIO_NOEXCEPT; /// Obtain message associated with exception. BOOST_ASIO_DECL virtual const char* what() const BOOST_ASIO_NOEXCEPT_OR_NOTHROW; }; } // namespace execution } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #if defined(BOOST_ASIO_HEADER_ONLY) # include <boost/asio/execution/impl/bad_executor.ipp> #endif // defined(BOOST_ASIO_HEADER_ONLY) #endif // BOOST_ASIO_EXECUTION_BAD_EXECUTOR_HPP PK q��[�:��; �; execution/set_value.hppnu �[��� // // execution/set_value.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_SET_VALUE_HPP #define BOOST_ASIO_EXECUTION_SET_VALUE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/variadic_templates.hpp> #include <boost/asio/traits/set_value_member.hpp> #include <boost/asio/traits/set_value_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that delivers a value to a receiver. /** * The name <tt>execution::set_value</tt> denotes a customisation point object. * The expression <tt>execution::set_value(R, Vs...)</tt> for some * subexpressions <tt>R</tt> and <tt>Vs...</tt> is expression-equivalent to: * * @li <tt>R.set_value(Vs...)</tt>, if that expression is valid. If the * function selected does not send the value(s) <tt>Vs...</tt> to the receiver * <tt>R</tt>'s value channel, the program is ill-formed with no diagnostic * required. * * @li Otherwise, <tt>set_value(R, Vs...)</tt>, if that expression is valid, * with overload resolution performed in a context that includes the * declaration <tt>void set_value();</tt> and that does not include a * declaration of <tt>execution::set_value</tt>. If the function selected by * overload resolution does not send the value(s) <tt>Vs...</tt> to the * receiver <tt>R</tt>'s value channel, the program is ill-formed with no * diagnostic required. * * @li Otherwise, <tt>execution::set_value(R, Vs...)</tt> is ill-formed. */ inline constexpr unspecified set_value = unspecified; /// A type trait that determines whether a @c set_value expression is /// well-formed. /** * Class template @c can_set_value is a trait that is derived from * @c true_type if the expression <tt>execution::set_value(std::declval<R>(), * std::declval<Vs>()...)</tt> is well formed; otherwise @c false_type. */ template <typename R, typename... Vs> struct can_set_value : integral_constant<bool, automatically_determined> { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_set_value_fn { using boost::asio::decay; using boost::asio::declval; using boost::asio::enable_if; using boost::asio::traits::set_value_free; using boost::asio::traits::set_value_member; void set_value(); enum overload_type { call_member, call_free, ill_formed }; template <typename R, typename Vs, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename R, typename Vs> struct call_traits<R, Vs, typename enable_if< ( set_value_member<R, Vs>::is_valid ) >::type> : set_value_member<R, Vs> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename R, typename Vs> struct call_traits<R, Vs, typename enable_if< ( !set_value_member<R, Vs>::is_valid && set_value_free<R, Vs>::is_valid ) >::type> : set_value_free<R, Vs> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; struct impl { #if defined(BOOST_ASIO_HAS_MOVE) #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) template <typename R, typename... Vs> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R, void(Vs...)>::overload == call_member, typename call_traits<R, void(Vs...)>::result_type >::type operator()(R&& r, Vs&&... v) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R, void(Vs...)>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(R)(r).set_value(BOOST_ASIO_MOVE_CAST(Vs)(v)...); } template <typename R, typename... Vs> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R, void(Vs...)>::overload == call_free, typename call_traits<R, void(Vs...)>::result_type >::type operator()(R&& r, Vs&&... v) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R, void(Vs...)>::is_noexcept)) { return set_value(BOOST_ASIO_MOVE_CAST(R)(r), BOOST_ASIO_MOVE_CAST(Vs)(v)...); } #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R, void()>::overload == call_member, typename call_traits<R, void()>::result_type >::type operator()(R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R, void()>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(R)(r).set_value(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R, void()>::overload == call_free, typename call_traits<R, void()>::result_type >::type operator()(R&& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R, void()>::is_noexcept)) { return set_value(BOOST_ASIO_MOVE_CAST(R)(r)); } #define BOOST_ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ BOOST_ASIO_CONSTEXPR typename enable_if< \ call_traits<R, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::overload == call_member, \ typename call_traits<R, void(BOOST_ASIO_VARIADIC_TARGS(n))>::result_type \ >::type \ operator()(R&& r, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \ BOOST_ASIO_NOEXCEPT_IF(( \ call_traits<R, void(BOOST_ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \ { \ return BOOST_ASIO_MOVE_CAST(R)(r).set_value( \ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ BOOST_ASIO_CONSTEXPR typename enable_if< \ call_traits<R, void(BOOST_ASIO_VARIADIC_TARGS(n))>::overload == call_free, \ typename call_traits<R, void(BOOST_ASIO_VARIADIC_TARGS(n))>::result_type \ >::type \ operator()(R&& r, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \ BOOST_ASIO_NOEXCEPT_IF(( \ call_traits<R, void(BOOST_ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \ { \ return set_value(BOOST_ASIO_MOVE_CAST(R)(r), \ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_SET_VALUE_CALL_DEF) #undef BOOST_ASIO_PRIVATE_SET_VALUE_CALL_DEF #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #else // defined(BOOST_ASIO_HAS_MOVE) #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) template <typename R, typename... Vs> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&, void(const Vs&...)>::overload == call_member, typename call_traits<R&, void(const Vs&...)>::result_type >::type operator()(R& r, const Vs&... v) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&, void(const Vs&...)>::is_noexcept)) { return r.set_value(v...); } template <typename R, typename... Vs> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&, void(const Vs&...)>::overload == call_member, typename call_traits<const R&, void(const Vs&...)>::result_type >::type operator()(const R& r, const Vs&... v) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&, void(const Vs&...)>::is_noexcept)) { return r.set_value(v...); } template <typename R, typename... Vs> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&, void(const Vs&...)>::overload == call_free, typename call_traits<R&, void(const Vs&...)>::result_type >::type operator()(R& r, const Vs&... v) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&, void(const Vs&...)>::is_noexcept)) { return set_value(r, v...); } template <typename R, typename... Vs> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&, void(const Vs&...)>::overload == call_free, typename call_traits<const R&, void(const Vs&...)>::result_type >::type operator()(const R& r, const Vs&... v) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&, void(const Vs&...)>::is_noexcept)) { return set_value(r, v...); } #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&, void()>::overload == call_member, typename call_traits<R&, void()>::result_type >::type operator()(R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&, void()>::is_noexcept)) { return r.set_value(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&, void()>::overload == call_member, typename call_traits<const R&, void()>::result_type >::type operator()(const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&, void()>::is_noexcept)) { return r.set_value(); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&, void()>::overload == call_free, typename call_traits<R&, void()>::result_type >::type operator()(R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&, void()>::is_noexcept)) { return set_value(r); } template <typename R> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&, void()>::overload == call_free, typename call_traits<const R&, void()>::result_type >::type operator()(const R& r) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&, void()>::is_noexcept)) { return set_value(r); } #define BOOST_ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ BOOST_ASIO_CONSTEXPR typename enable_if< \ call_traits<R&, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::overload == call_member, \ typename call_traits<R&, void(BOOST_ASIO_VARIADIC_TARGS(n))>::result_type \ >::type \ operator()(R& r, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \ BOOST_ASIO_NOEXCEPT_IF(( \ call_traits<R&, void(BOOST_ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \ { \ return r.set_value(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ BOOST_ASIO_CONSTEXPR typename enable_if< \ call_traits<const R&, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::overload == call_member, \ typename call_traits<const R&, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::result_type \ >::type \ operator()(const R& r, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \ BOOST_ASIO_NOEXCEPT_IF(( \ call_traits<const R&, void(BOOST_ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \ { \ return r.set_value(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ BOOST_ASIO_CONSTEXPR typename enable_if< \ call_traits<R&, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::overload == call_free, \ typename call_traits<R&, void(BOOST_ASIO_VARIADIC_TARGS(n))>::result_type \ >::type \ operator()(R& r, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \ BOOST_ASIO_NOEXCEPT_IF(( \ call_traits<R&, void(BOOST_ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \ { \ return set_value(r, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ BOOST_ASIO_CONSTEXPR typename enable_if< \ call_traits<const R&, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::overload == call_free, \ typename call_traits<const R&, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::result_type \ >::type \ operator()(const R& r, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \ BOOST_ASIO_NOEXCEPT_IF(( \ call_traits<const R&, void(BOOST_ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \ { \ return set_value(r, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ } \ /**/ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_SET_VALUE_CALL_DEF) #undef BOOST_ASIO_PRIVATE_SET_VALUE_CALL_DEF #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_set_value_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_set_value_fn::impl& set_value = asio_execution_set_value_fn::static_instance<>::instance; } // namespace #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) template <typename R, typename... Vs> struct can_set_value : integral_constant<bool, asio_execution_set_value_fn::call_traits<R, void(Vs...)>::overload != asio_execution_set_value_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R, typename... Vs> constexpr bool can_set_value_v = can_set_value<R, Vs...>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R, typename... Vs> struct is_nothrow_set_value : integral_constant<bool, asio_execution_set_value_fn::call_traits<R, void(Vs...)>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R, typename... Vs> constexpr bool is_nothrow_set_value_v = is_nothrow_set_value<R, Vs...>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) template <typename R, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void> struct can_set_value; template <typename R, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void, typename = void> struct is_nothrow_set_value; template <typename R> struct can_set_value<R> : integral_constant<bool, asio_execution_set_value_fn::call_traits<R, void()>::overload != asio_execution_set_value_fn::ill_formed> { }; template <typename R> struct is_nothrow_set_value<R> : integral_constant<bool, asio_execution_set_value_fn::call_traits<R, void()>::is_noexcept> { }; #define BOOST_ASIO_PRIVATE_SET_VALUE_TRAITS_DEF(n) \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ struct can_set_value<R, BOOST_ASIO_VARIADIC_TARGS(n)> : \ integral_constant<bool, \ asio_execution_set_value_fn::call_traits<R, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::overload != \ asio_execution_set_value_fn::ill_formed> \ { \ }; \ \ template <typename R, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ struct is_nothrow_set_value<R, BOOST_ASIO_VARIADIC_TARGS(n)> : \ integral_constant<bool, \ asio_execution_set_value_fn::call_traits<R, \ void(BOOST_ASIO_VARIADIC_TARGS(n))>::is_noexcept> \ { \ }; \ /**/ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_SET_VALUE_TRAITS_DEF) #undef BOOST_ASIO_PRIVATE_SET_VALUE_TRAITS_DEF #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_SET_VALUE_HPP PK q��[���� � ! execution/blocking_adaptation.hppnu �[��� // // execution/blocking_adaptation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP #define BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/event.hpp> #include <boost/asio/detail/mutex.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/execute.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/scheduler.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/is_applicable_property.hpp> #include <boost/asio/prefer.hpp> #include <boost/asio/query.hpp> #include <boost/asio/require.hpp> #include <boost/asio/traits/prefer_member.hpp> #include <boost/asio/traits/query_free.hpp> #include <boost/asio/traits/query_member.hpp> #include <boost/asio/traits/query_static_constexpr_member.hpp> #include <boost/asio/traits/require_member.hpp> #include <boost/asio/traits/static_query.hpp> #include <boost/asio/traits/static_require.hpp> #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(GENERATING_DOCUMENTATION) namespace execution { /// A property to describe whether automatic adaptation of an executor is /// allowed in order to apply the blocking_adaptation_t::allowed_t property. struct blocking_adaptation_t { /// The blocking_adaptation_t property applies to executors, senders, and /// schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level blocking_adaptation_t property cannot be required. static constexpr bool is_requirable = false; /// The top-level blocking_adaptation_t property cannot be preferred. static constexpr bool is_preferable = false; /// The type returned by queries against an @c any_executor. typedef blocking_adaptation_t polymorphic_query_result_type; /// A sub-property that indicates that automatic adaptation is not allowed. struct disallowed_t { /// The blocking_adaptation_t::disallowed_t property applies to executors, /// senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The blocking_adaptation_t::disallowed_t property can be required. static constexpr bool is_requirable = true; /// The blocking_adaptation_t::disallowed_t property can be preferred. static constexpr bool is_preferable = true; /// The type returned by queries against an @c any_executor. typedef blocking_adaptation_t polymorphic_query_result_type; /// Default constructor. constexpr disallowed_t(); /// Get the value associated with a property object. /** * @returns disallowed_t(); */ static constexpr blocking_adaptation_t value(); }; /// A sub-property that indicates that automatic adaptation is allowed. struct allowed_t { /// The blocking_adaptation_t::allowed_t property applies to executors, /// senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The blocking_adaptation_t::allowed_t property can be required. static constexpr bool is_requirable = true; /// The blocking_adaptation_t::allowed_t property can be preferred. static constexpr bool is_preferable = false; /// The type returned by queries against an @c any_executor. typedef blocking_adaptation_t polymorphic_query_result_type; /// Default constructor. constexpr allowed_t(); /// Get the value associated with a property object. /** * @returns allowed_t(); */ static constexpr blocking_adaptation_t value(); }; /// A special value used for accessing the blocking_adaptation_t::disallowed_t /// property. static constexpr disallowed_t disallowed; /// A special value used for accessing the blocking_adaptation_t::allowed_t /// property. static constexpr allowed_t allowed; /// Default constructor. constexpr blocking_adaptation_t(); /// Construct from a sub-property value. constexpr blocking_adaptation_t(disallowed_t); /// Construct from a sub-property value. constexpr blocking_adaptation_t(allowed_t); /// Compare property values for equality. friend constexpr bool operator==( const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept; /// Compare property values for inequality. friend constexpr bool operator!=( const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept; }; /// A special value used for accessing the blocking_adaptation_t property. constexpr blocking_adaptation_t blocking_adaptation; } // namespace execution #else // defined(GENERATING_DOCUMENTATION) namespace execution { namespace detail { namespace blocking_adaptation { template <int I> struct disallowed_t; template <int I> struct allowed_t; } // namespace blocking_adaptation template <int I = 0> struct blocking_adaptation_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef blocking_adaptation_t polymorphic_query_result_type; typedef detail::blocking_adaptation::disallowed_t<I> disallowed_t; typedef detail::blocking_adaptation::allowed_t<I> allowed_t; BOOST_ASIO_CONSTEXPR blocking_adaptation_t() : value_(-1) { } BOOST_ASIO_CONSTEXPR blocking_adaptation_t(disallowed_t) : value_(0) { } BOOST_ASIO_CONSTEXPR blocking_adaptation_t(allowed_t) : value_(1) { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member< T, blocking_adaptation_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member< T, blocking_adaptation_t >::is_noexcept)) { return traits::query_static_constexpr_member< T, blocking_adaptation_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, disallowed_t>::result_type static_query( typename enable_if< !traits::query_static_constexpr_member< T, blocking_adaptation_t>::is_valid && !traits::query_member<T, blocking_adaptation_t>::is_valid && traits::static_query<T, disallowed_t>::is_valid >::type* = 0) BOOST_ASIO_NOEXCEPT { return traits::static_query<T, disallowed_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::static_query<T, allowed_t>::result_type static_query( typename enable_if< !traits::query_static_constexpr_member< T, blocking_adaptation_t>::is_valid && !traits::query_member<T, blocking_adaptation_t>::is_valid && !traits::static_query<T, disallowed_t>::is_valid && traits::static_query<T, allowed_t>::is_valid >::type* = 0) BOOST_ASIO_NOEXCEPT { return traits::static_query<T, allowed_t>::value(); } template <typename E, typename T = decltype(blocking_adaptation_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = blocking_adaptation_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) friend BOOST_ASIO_CONSTEXPR bool operator==( const blocking_adaptation_t& a, const blocking_adaptation_t& b) { return a.value_ == b.value_; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const blocking_adaptation_t& a, const blocking_adaptation_t& b) { return a.value_ != b.value_; } struct convertible_from_blocking_adaptation_t { BOOST_ASIO_CONSTEXPR convertible_from_blocking_adaptation_t( blocking_adaptation_t) { } }; template <typename Executor> friend BOOST_ASIO_CONSTEXPR blocking_adaptation_t query( const Executor& ex, convertible_from_blocking_adaptation_t, typename enable_if< can_query<const Executor&, disallowed_t>::value >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, blocking_adaptation_t<>::disallowed_t>::value)) #else // defined(BOOST_ASIO_MSVC) BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, disallowed_t>::value)) #endif // defined(BOOST_ASIO_MSVC) #endif // !defined(__clang__) { return boost::asio::query(ex, disallowed_t()); } template <typename Executor> friend BOOST_ASIO_CONSTEXPR blocking_adaptation_t query( const Executor& ex, convertible_from_blocking_adaptation_t, typename enable_if< !can_query<const Executor&, disallowed_t>::value && can_query<const Executor&, allowed_t>::value >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, blocking_adaptation_t<>::allowed_t>::value)) #else // defined(BOOST_ASIO_MSVC) BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, allowed_t>::value)) #endif // defined(BOOST_ASIO_MSVC) #endif // !defined(__clang__) { return boost::asio::query(ex, allowed_t()); } BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed); BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed); #if !defined(BOOST_ASIO_HAS_CONSTEXPR) static const blocking_adaptation_t instance; #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) private: int value_; }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T blocking_adaptation_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_CONSTEXPR) template <int I> const blocking_adaptation_t<I> blocking_adaptation_t<I>::instance; #endif template <int I> const typename blocking_adaptation_t<I>::disallowed_t blocking_adaptation_t<I>::disallowed; template <int I> const typename blocking_adaptation_t<I>::allowed_t blocking_adaptation_t<I>::allowed; namespace blocking_adaptation { template <int I = 0> struct disallowed_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef blocking_adaptation_t<I> polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR disallowed_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, disallowed_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, disallowed_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, disallowed_t>::value(); } template <typename T> static BOOST_ASIO_CONSTEXPR disallowed_t static_query( typename enable_if< !traits::query_static_constexpr_member<T, disallowed_t>::is_valid && !traits::query_member<T, disallowed_t>::is_valid && !traits::query_free<T, disallowed_t>::is_valid && !can_query<T, allowed_t<I> >::value >::type* = 0) BOOST_ASIO_NOEXCEPT { return disallowed_t(); } template <typename E, typename T = decltype(disallowed_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = disallowed_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) static BOOST_ASIO_CONSTEXPR blocking_adaptation_t<I> value() { return disallowed_t(); } friend BOOST_ASIO_CONSTEXPR bool operator==( const disallowed_t&, const disallowed_t&) { return true; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const disallowed_t&, const disallowed_t&) { return false; } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T disallowed_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename Executor> class adapter { public: adapter(int, const Executor& e) BOOST_ASIO_NOEXCEPT : executor_(e) { } adapter(const adapter& other) BOOST_ASIO_NOEXCEPT : executor_(other.executor_) { } #if defined(BOOST_ASIO_HAS_MOVE) adapter(adapter&& other) BOOST_ASIO_NOEXCEPT : executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)) { } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template <int I> static BOOST_ASIO_CONSTEXPR allowed_t<I> query( blocking_adaptation_t<I>) BOOST_ASIO_NOEXCEPT { return allowed_t<I>(); } template <int I> static BOOST_ASIO_CONSTEXPR allowed_t<I> query( allowed_t<I>) BOOST_ASIO_NOEXCEPT { return allowed_t<I>(); } template <int I> static BOOST_ASIO_CONSTEXPR allowed_t<I> query( disallowed_t<I>) BOOST_ASIO_NOEXCEPT { return allowed_t<I>(); } template <typename Property> typename enable_if< can_query<const Executor&, Property>::value, typename query_result<const Executor&, Property>::type >::type query(const Property& p) const BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_query<const Executor&, Property>::value)) { return boost::asio::query(executor_, p); } template <int I> Executor require(disallowed_t<I>) const BOOST_ASIO_NOEXCEPT { return executor_; } template <typename Property> typename enable_if< can_require<const Executor&, Property>::value, adapter<typename decay< typename require_result<const Executor&, Property>::type >::type> >::type require(const Property& p) const BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_require<const Executor&, Property>::value)) { return adapter<typename decay< typename require_result<const Executor&, Property>::type >::type>(0, boost::asio::require(executor_, p)); } template <typename Property> typename enable_if< can_prefer<const Executor&, Property>::value, adapter<typename decay< typename prefer_result<const Executor&, Property>::type >::type> >::type prefer(const Property& p) const BOOST_ASIO_NOEXCEPT_IF(( is_nothrow_prefer<const Executor&, Property>::value)) { return adapter<typename decay< typename prefer_result<const Executor&, Property>::type >::type>(0, boost::asio::prefer(executor_, p)); } template <typename Function> typename enable_if< execution::can_execute<const Executor&, Function>::value >::type execute(BOOST_ASIO_MOVE_ARG(Function) f) const { execution::execute(executor_, BOOST_ASIO_MOVE_CAST(Function)(f)); } friend bool operator==(const adapter& a, const adapter& b) BOOST_ASIO_NOEXCEPT { return a.executor_ == b.executor_; } friend bool operator!=(const adapter& a, const adapter& b) BOOST_ASIO_NOEXCEPT { return a.executor_ != b.executor_; } private: Executor executor_; }; template <int I = 0> struct allowed_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef blocking_adaptation_t<I> polymorphic_query_result_type; BOOST_ASIO_CONSTEXPR allowed_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, allowed_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, allowed_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, allowed_t>::value(); } template <typename E, typename T = decltype(allowed_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = allowed_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) static BOOST_ASIO_CONSTEXPR blocking_adaptation_t<I> value() { return allowed_t(); } friend BOOST_ASIO_CONSTEXPR bool operator==( const allowed_t&, const allowed_t&) { return true; } friend BOOST_ASIO_CONSTEXPR bool operator!=( const allowed_t&, const allowed_t&) { return false; } template <typename Executor> friend adapter<Executor> require( const Executor& e, const allowed_t&, typename enable_if< is_executor<Executor>::value >::type* = 0) { return adapter<Executor>(0, e); } }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T allowed_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename Function> class blocking_execute_state { public: template <typename F> blocking_execute_state(BOOST_ASIO_MOVE_ARG(F) f) : func_(BOOST_ASIO_MOVE_CAST(F)(f)), is_complete_(false) { } template <typename Executor> void execute_and_wait(BOOST_ASIO_MOVE_ARG(Executor) ex) { handler h = { this }; execution::execute(BOOST_ASIO_MOVE_CAST(Executor)(ex), h); boost::asio::detail::mutex::scoped_lock lock(mutex_); while (!is_complete_) event_.wait(lock); } struct cleanup { ~cleanup() { boost::asio::detail::mutex::scoped_lock lock(state_->mutex_); state_->is_complete_ = true; state_->event_.unlock_and_signal_one_for_destruction(lock); } blocking_execute_state* state_; }; struct handler { void operator()() { cleanup c = { state_ }; state_->func_(); } blocking_execute_state* state_; }; Function func_; boost::asio::detail::mutex mutex_; boost::asio::detail::event event_; bool is_complete_; }; template <typename Executor, typename Function> void blocking_execute( BOOST_ASIO_MOVE_ARG(Executor) ex, BOOST_ASIO_MOVE_ARG(Function) func) { typedef typename decay<Function>::type func_t; blocking_execute_state<func_t> state(BOOST_ASIO_MOVE_CAST(Function)(func)); state.execute_and_wait(ex); } } // namespace blocking_adaptation } // namespace detail typedef detail::blocking_adaptation_t<> blocking_adaptation_t; #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr blocking_adaptation_t blocking_adaptation; #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) namespace { static const blocking_adaptation_t& blocking_adaptation = blocking_adaptation_t::instance; } #endif } // namespace execution #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) namespace traits { #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) template <typename T> struct query_free_default<T, execution::blocking_adaptation_t, typename enable_if< can_query<T, execution::blocking_adaptation_t::disallowed_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T, execution::blocking_adaptation_t::disallowed_t>::value)); typedef execution::blocking_adaptation_t result_type; }; template <typename T> struct query_free_default<T, execution::blocking_adaptation_t, typename enable_if< !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value && can_query<T, execution::blocking_adaptation_t::allowed_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value)); typedef execution::blocking_adaptation_t result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> struct static_query<T, execution::blocking_adaptation_t, typename enable_if< traits::query_static_constexpr_member<T, execution::blocking_adaptation_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::blocking_adaptation_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::blocking_adaptation_t>::value(); } }; template <typename T> struct static_query<T, execution::blocking_adaptation_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::blocking_adaptation_t>::is_valid && !traits::query_member<T, execution::blocking_adaptation_t>::is_valid && traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::value(); } }; template <typename T> struct static_query<T, execution::blocking_adaptation_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::blocking_adaptation_t>::is_valid && !traits::query_member<T, execution::blocking_adaptation_t>::is_valid && !traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid && traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::value(); } }; template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t, typename enable_if< traits::query_static_constexpr_member<T, execution::blocking_adaptation_t::disallowed_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::blocking_adaptation_t::disallowed_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::blocking_adaptation_t::disallowed_t>::value(); } }; template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t, typename enable_if< !traits::query_static_constexpr_member<T, execution::blocking_adaptation_t::disallowed_t>::is_valid && !traits::query_member<T, execution::blocking_adaptation_t::disallowed_t>::is_valid && !traits::query_free<T, execution::blocking_adaptation_t::disallowed_t>::is_valid && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::disallowed_t result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return result_type(); } }; template <typename T> struct static_query<T, execution::blocking_adaptation_t::allowed_t, typename enable_if< traits::query_static_constexpr_member<T, execution::blocking_adaptation_t::allowed_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::blocking_adaptation_t::allowed_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::blocking_adaptation_t::allowed_t>::value(); } }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) template <typename T> struct static_require<T, execution::blocking_adaptation_t::disallowed_t, typename enable_if< static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = (is_same<typename static_query<T, execution::blocking_adaptation_t::disallowed_t>::result_type, execution::blocking_adaptation_t::disallowed_t>::value)); }; template <typename T> struct static_require<T, execution::blocking_adaptation_t::allowed_t, typename enable_if< static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = (is_same<typename static_query<T, execution::blocking_adaptation_t::allowed_t>::result_type, execution::blocking_adaptation_t::allowed_t>::value)); }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT) template <typename T> struct require_free_default<T, execution::blocking_adaptation_t::allowed_t, typename enable_if< is_same<T, typename decay<T>::type>::value && execution::is_executor<T>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef execution::detail::blocking_adaptation::adapter<T> result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) template <typename Executor> struct equality_comparable< execution::detail::blocking_adaptation::adapter<Executor> > { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) template <typename Executor, typename Function> struct execute_member< execution::detail::blocking_adaptation::adapter<Executor>, Function> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking_adaptation::adapter<Executor>, execution::detail::blocking_adaptation_t<I> > { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::allowed_t result_type; static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT { return result_type(); } }; template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking_adaptation::adapter<Executor>, execution::detail::blocking_adaptation::allowed_t<I> > { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::allowed_t result_type; static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT { return result_type(); } }; template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking_adaptation::adapter<Executor>, execution::detail::blocking_adaptation::disallowed_t<I> > { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::allowed_t result_type; static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT { return result_type(); } }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) template <typename Executor, typename Property> struct query_member< execution::detail::blocking_adaptation::adapter<Executor>, Property, typename enable_if< can_query<const Executor&, Property>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<Executor, Property>::value)); typedef typename query_result<Executor, Property>::type result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) template <typename Executor, int I> struct require_member< execution::detail::blocking_adaptation::adapter<Executor>, execution::detail::blocking_adaptation::disallowed_t<I> > { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Executor result_type; }; template <typename Executor, typename Property> struct require_member< execution::detail::blocking_adaptation::adapter<Executor>, Property, typename enable_if< can_require<const Executor&, Property>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_require<Executor, Property>::value)); typedef execution::detail::blocking_adaptation::adapter<typename decay< typename require_result<Executor, Property>::type >::type> result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) #if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) template <typename Executor, typename Property> struct prefer_member< execution::detail::blocking_adaptation::adapter<Executor>, Property, typename enable_if< can_prefer<const Executor&, Property>::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_prefer<Executor, Property>::value)); typedef execution::detail::blocking_adaptation::adapter<typename decay< typename prefer_result<Executor, Property>::type >::type> result_type; }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) } // namespace traits #endif // defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP PK q��[��Z� � execution/set_error.hppnu �[��� // // execution/set_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_SET_ERROR_HPP #define BOOST_ASIO_EXECUTION_SET_ERROR_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/traits/set_error_member.hpp> #include <boost/asio/traits/set_error_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that delivers an error notification to a receiver. /** * The name <tt>execution::set_error</tt> denotes a customisation point object. * The expression <tt>execution::set_error(R, E)</tt> for some subexpressions * <tt>R</tt> and <tt>E</tt> are expression-equivalent to: * * @li <tt>R.set_error(E)</tt>, if that expression is valid. If the function * selected does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s * error channel, the program is ill-formed with no diagnostic required. * * @li Otherwise, <tt>set_error(R, E)</tt>, if that expression is valid, with * overload resolution performed in a context that includes the declaration * <tt>void set_error();</tt> and that does not include a declaration of * <tt>execution::set_error</tt>. If the function selected by overload * resolution does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s * error channel, the program is ill-formed with no diagnostic required. * * @li Otherwise, <tt>execution::set_error(R, E)</tt> is ill-formed. */ inline constexpr unspecified set_error = unspecified; /// A type trait that determines whether a @c set_error expression is /// well-formed. /** * Class template @c can_set_error is a trait that is derived from * @c true_type if the expression <tt>execution::set_error(std::declval<R>(), * std::declval<E>())</tt> is well formed; otherwise @c false_type. */ template <typename R, typename E> struct can_set_error : integral_constant<bool, automatically_determined> { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_set_error_fn { using boost::asio::decay; using boost::asio::declval; using boost::asio::enable_if; using boost::asio::traits::set_error_free; using boost::asio::traits::set_error_member; void set_error(); enum overload_type { call_member, call_free, ill_formed }; template <typename R, typename E, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename R, typename E> struct call_traits<R, void(E), typename enable_if< ( set_error_member<R, E>::is_valid ) >::type> : set_error_member<R, E> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename R, typename E> struct call_traits<R, void(E), typename enable_if< ( !set_error_member<R, E>::is_valid && set_error_free<R, E>::is_valid ) >::type> : set_error_free<R, E> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; struct impl { #if defined(BOOST_ASIO_HAS_MOVE) template <typename R, typename E> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R, void(E)>::overload == call_member, typename call_traits<R, void(E)>::result_type >::type operator()(R&& r, E&& e) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R, void(E)>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(R)(r).set_error(BOOST_ASIO_MOVE_CAST(E)(e)); } template <typename R, typename E> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R, void(E)>::overload == call_free, typename call_traits<R, void(E)>::result_type >::type operator()(R&& r, E&& e) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R, void(E)>::is_noexcept)) { return set_error(BOOST_ASIO_MOVE_CAST(R)(r), BOOST_ASIO_MOVE_CAST(E)(e)); } #else // defined(BOOST_ASIO_HAS_MOVE) template <typename R, typename E> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&, void(const E&)>::overload == call_member, typename call_traits<R&, void(const E&)>::result_type >::type operator()(R& r, const E& e) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&, void(const E&)>::is_noexcept)) { return r.set_error(e); } template <typename R, typename E> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&, void(const E&)>::overload == call_member, typename call_traits<const R&, void(const E&)>::result_type >::type operator()(const R& r, const E& e) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&, void(const E&)>::is_noexcept)) { return r.set_error(e); } template <typename R, typename E> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<R&, void(const E&)>::overload == call_free, typename call_traits<R&, void(const E&)>::result_type >::type operator()(R& r, const E& e) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<R&, void(const E&)>::is_noexcept)) { return set_error(r, e); } template <typename R, typename E> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<const R&, void(const E&)>::overload == call_free, typename call_traits<const R&, void(const E&)>::result_type >::type operator()(const R& r, const E& e) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<const R&, void(const E&)>::is_noexcept)) { return set_error(r, e); } #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_set_error_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_set_error_fn::impl& set_error = asio_execution_set_error_fn::static_instance<>::instance; } // namespace template <typename R, typename E> struct can_set_error : integral_constant<bool, asio_execution_set_error_fn::call_traits<R, void(E)>::overload != asio_execution_set_error_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R, typename E> constexpr bool can_set_error_v = can_set_error<R, E>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R, typename E> struct is_nothrow_set_error : integral_constant<bool, asio_execution_set_error_fn::call_traits<R, void(E)>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename R, typename E> constexpr bool is_nothrow_set_error_v = is_nothrow_set_error<R, E>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_SET_ERROR_HPP PK q��[�Wp*� � execution/context.hppnu �[��� // // execution/context.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_CONTEXT2_HPP #define BOOST_ASIO_EXECUTION_CONTEXT2_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/scheduler.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/is_applicable_property.hpp> #include <boost/asio/traits/query_static_constexpr_member.hpp> #include <boost/asio/traits/static_query.hpp> #if defined(BOOST_ASIO_HAS_STD_ANY) # include <any> #endif // defined(BOOST_ASIO_HAS_STD_ANY) #include <boost/asio/detail/push_options.hpp> namespace boost { namespace asio { #if defined(GENERATING_DOCUMENTATION) namespace execution { /// A property that is used to obtain the execution context that is associated /// with an executor. struct context_t { /// The context_t property applies to executors, senders, and schedulers. template <typename T> static constexpr bool is_applicable_property_v = is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The context_t property cannot be required. static constexpr bool is_requirable = false; /// The context_t property cannot be preferred. static constexpr bool is_preferable = false; /// The type returned by queries against an @c any_executor. typedef std::any polymorphic_query_result_type; }; /// A special value used for accessing the context_t property. constexpr context_t context; } // namespace execution #else // defined(GENERATING_DOCUMENTATION) namespace execution { namespace detail { template <int I = 0> struct context_t { #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> BOOST_ASIO_STATIC_CONSTEXPR(bool, is_applicable_property_v = is_executor<T>::value || is_sender<T>::value || is_scheduler<T>::value); #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); #if defined(BOOST_ASIO_HAS_STD_ANY) typedef std::any polymorphic_query_result_type; #endif // defined(BOOST_ASIO_HAS_STD_ANY) BOOST_ASIO_CONSTEXPR context_t() { } #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> static BOOST_ASIO_CONSTEXPR typename traits::query_static_constexpr_member<T, context_t>::result_type static_query() BOOST_ASIO_NOEXCEPT_IF(( traits::query_static_constexpr_member<T, context_t>::is_noexcept)) { return traits::query_static_constexpr_member<T, context_t>::value(); } template <typename E, typename T = decltype(context_t::static_query<E>())> static BOOST_ASIO_CONSTEXPR const T static_query_v = context_t::static_query<E>(); #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_CONSTEXPR) static const context_t instance; #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) }; #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <int I> template <typename E, typename T> const T context_t<I>::static_query_v; #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) #if !defined(BOOST_ASIO_HAS_CONSTEXPR) template <int I> const context_t<I> context_t<I>::instance; #endif } // namespace detail typedef detail::context_t<> context_t; #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) constexpr context_t context; #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) namespace { static const context_t& context = context_t::instance; } #endif } // namespace execution #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename T> struct is_applicable_property<T, execution::context_t> : integral_constant<bool, execution::is_executor<T>::value || execution::is_sender<T>::value || execution::is_scheduler<T>::value> { }; #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) namespace traits { #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T> struct static_query<T, execution::context_t, typename enable_if< traits::query_static_constexpr_member<T, execution::context_t>::is_valid >::type> { BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::query_static_constexpr_member<T, execution::context_t>::result_type result_type; static BOOST_ASIO_CONSTEXPR result_type value() { return traits::query_static_constexpr_member<T, execution::context_t>::value(); } }; #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) } // namespace traits #endif // defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_CONTEXT2_HPP PK q��[옝��2 �2 execution/bulk_execute.hppnu �[��� // // execution/bulk_execute.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff 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) // #ifndef BOOST_ASIO_EXECUTION_BULK_EXECUTE_HPP #define BOOST_ASIO_EXECUTION_BULK_EXECUTE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> #include <boost/asio/detail/type_traits.hpp> #include <boost/asio/execution/bulk_guarantee.hpp> #include <boost/asio/execution/detail/bulk_sender.hpp> #include <boost/asio/execution/executor.hpp> #include <boost/asio/execution/sender.hpp> #include <boost/asio/traits/bulk_execute_member.hpp> #include <boost/asio/traits/bulk_execute_free.hpp> #include <boost/asio/detail/push_options.hpp> #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that creates a bulk sender. /** * The name <tt>execution::bulk_execute</tt> denotes a customisation point * object. If <tt>is_convertible_v<N, size_t></tt> is true, then the expression * <tt>execution::bulk_execute(S, F, N)</tt> for some subexpressions * <tt>S</tt>, <tt>F</tt>, and <tt>N</tt> is expression-equivalent to: * * @li <tt>S.bulk_execute(F, N)</tt>, if that expression is valid. If the * function selected does not execute <tt>N</tt> invocations of the function * object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward progress * guarantee <tt>boost::asio::query(S, execution::bulk_guarantee)</tt>, and * the result of that function does not model <tt>sender<void></tt>, the * program is ill-formed with no diagnostic required. * * @li Otherwise, <tt>bulk_execute(S, F, N)</tt>, if that expression is valid, * with overload resolution performed in a context that includes the * declaration <tt>void bulk_execute();</tt> and that does not include a * declaration of <tt>execution::bulk_execute</tt>. If the function selected * by overload resolution does not execute <tt>N</tt> invocations of the * function object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward * progress guarantee <tt>boost::asio::query(E, * execution::bulk_guarantee)</tt>, and the result of that function does not * model <tt>sender<void></tt>, the program is ill-formed with no diagnostic * required. * * @li Otherwise, if the types <tt>F</tt> and * <tt>executor_index_t<remove_cvref_t<S>></tt> model <tt>invocable</tt> and * if <tt>boost::asio::query(S, execution::bulk_guarantee)</tt> equals * <tt>execution::bulk_guarantee.unsequenced</tt>, then * * - Evaluates <tt>DECAY_COPY(std::forward<decltype(F)>(F))</tt> on the * calling thread to create a function object <tt>cf</tt>. [Note: * Additional copies of <tt>cf</tt> may subsequently be created. --end * note.] * * - For each value of <tt>i</tt> in <tt>N</tt>, <tt>cf(i)</tt> (or copy of * <tt>cf</tt>)) will be invoked at most once by an execution agent that is * unique for each value of <tt>i</tt>. * * - May block pending completion of one or more invocations of <tt>cf</tt>. * * - Synchronizes with (C++Std [intro.multithread]) the invocations of * <tt>cf</tt>. * * @li Otherwise, <tt>execution::bulk_execute(S, F, N)</tt> is ill-formed. */ inline constexpr unspecified bulk_execute = unspecified; /// A type trait that determines whether a @c bulk_execute expression is /// well-formed. /** * Class template @c can_bulk_execute is a trait that is derived from @c * true_type if the expression <tt>execution::bulk_execute(std::declval<S>(), * std::declval<F>(), std::declval<N>)</tt> is well formed; otherwise @c * false_type. */ template <typename S, typename F, typename N> struct can_bulk_execute : integral_constant<bool, automatically_determined> { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace asio_execution_bulk_execute_fn { using boost::asio::declval; using boost::asio::enable_if; using boost::asio::execution::bulk_guarantee_t; using boost::asio::execution::detail::bulk_sender; using boost::asio::execution::executor_index; using boost::asio::execution::is_sender; using boost::asio::is_convertible; using boost::asio::is_same; using boost::asio::remove_cvref; using boost::asio::result_of; using boost::asio::traits::bulk_execute_free; using boost::asio::traits::bulk_execute_member; using boost::asio::traits::static_require; void bulk_execute(); enum overload_type { call_member, call_free, adapter, ill_formed }; template <typename S, typename Args, typename = void> struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename S, typename F, typename N> struct call_traits<S, void(F, N), typename enable_if< ( is_convertible<N, std::size_t>::value && bulk_execute_member<S, F, N>::is_valid && is_sender< typename bulk_execute_member<S, F, N>::result_type >::value ) >::type> : bulk_execute_member<S, F, N> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename S, typename F, typename N> struct call_traits<S, void(F, N), typename enable_if< ( is_convertible<N, std::size_t>::value && !bulk_execute_member<S, F, N>::is_valid && bulk_execute_free<S, F, N>::is_valid && is_sender< typename bulk_execute_free<S, F, N>::result_type >::value ) >::type> : bulk_execute_free<S, F, N> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; template <typename S, typename F, typename N> struct call_traits<S, void(F, N), typename enable_if< ( is_convertible<N, std::size_t>::value && !bulk_execute_member<S, F, N>::is_valid && !bulk_execute_free<S, F, N>::is_valid && is_sender<S>::value && is_same< typename result_of< F(typename executor_index<typename remove_cvref<S>::type>::type) >::type, typename result_of< F(typename executor_index<typename remove_cvref<S>::type>::type) >::type >::value && static_require<S, bulk_guarantee_t::unsequenced_t>::is_valid ) >::type> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef bulk_sender<S, F, N> result_type; }; struct impl { #if defined(BOOST_ASIO_HAS_MOVE) template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(F, N)>::overload == call_member, typename call_traits<S, void(F, N)>::result_type >::type operator()(S&& s, F&& f, N&& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(F, N)>::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(S)(s).bulk_execute( BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(F, N)>::overload == call_free, typename call_traits<S, void(F, N)>::result_type >::type operator()(S&& s, F&& f, N&& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(F, N)>::is_noexcept)) { return bulk_execute(BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(F, N)>::overload == adapter, typename call_traits<S, void(F, N)>::result_type >::type operator()(S&& s, F&& f, N&& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(F, N)>::is_noexcept)) { return typename call_traits<S, void(F, N)>::result_type( BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } #else // defined(BOOST_ASIO_HAS_MOVE) template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(const F&, const N&)>::overload == call_member, typename call_traits<S, void(const F&, const N&)>::result_type >::type operator()(S& s, const F& f, const N& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(const F&, const N&)>::is_noexcept)) { return s.bulk_execute(BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(const F&, const N&)>::overload == call_member, typename call_traits<S, void(const F&, const N&)>::result_type >::type operator()(const S& s, const F& f, const N& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(const F&, const N&)>::is_noexcept)) { return s.bulk_execute(BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(const F&, const N&)>::overload == call_free, typename call_traits<S, void(const F&, const N&)>::result_type >::type operator()(S& s, const F& f, const N& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(const F&, const N&)>::is_noexcept)) { return bulk_execute(s, BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(const F&, const N&)>::overload == call_free, typename call_traits<S, void(const F&, const N&)>::result_type >::type operator()(const S& s, const F& f, const N& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(const F&, const N&)>::is_noexcept)) { return bulk_execute(s, BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(const F&, const N&)>::overload == adapter, typename call_traits<S, void(const F&, const N&)>::result_type >::type operator()(S& s, const F& f, const N& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(const F&, const N&)>::is_noexcept)) { return typename call_traits<S, void(const F&, const N&)>::result_type( s, BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } template <typename S, typename F, typename N> BOOST_ASIO_CONSTEXPR typename enable_if< call_traits<S, void(const F&, const N&)>::overload == adapter, typename call_traits<S, void(const F&, const N&)>::result_type >::type operator()(const S& s, const F& f, const N& n) const BOOST_ASIO_NOEXCEPT_IF(( call_traits<S, void(const F&, const N&)>::is_noexcept)) { return typename call_traits<S, void(const F&, const N&)>::result_type( s, BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n)); } #endif // defined(BOOST_ASIO_HAS_MOVE) }; template <typename T = impl> struct static_instance { static const T instance; }; template <typename T> const T static_instance<T>::instance = {}; } // namespace asio_execution_bulk_execute_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_bulk_execute_fn::impl& bulk_execute = asio_execution_bulk_execute_fn::static_instance<>::instance; } // namespace template <typename S, typename F, typename N> struct can_bulk_execute : integral_constant<bool, asio_execution_bulk_execute_fn::call_traits<S, void(F, N)>::overload != asio_execution_bulk_execute_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename F, typename N> constexpr bool can_bulk_execute_v = can_bulk_execute<S, F, N>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename F, typename N> struct is_nothrow_bulk_execute : integral_constant<bool, asio_execution_bulk_execute_fn::call_traits<S, void(F, N)>::is_noexcept> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename F, typename N> constexpr bool is_nothrow_bulk_execute_v = is_nothrow_bulk_execute<S, F, N>::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template <typename S, typename F, typename N> struct bulk_execute_result { typedef typename asio_execution_bulk_execute_fn::call_traits< S, void(F, N)>::result_type type; }; } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_EXECUTION_BULK_EXECUTE_HPP PK q��[n/�S S "