externals: Update boost to 1.72 and add Boost Context

This commit is contained in:
Fernando Sahmkow 2020-02-10 12:31:57 -04:00
parent 5e8300b76a
commit 77abe07b3b
618 changed files with 96299 additions and 14263 deletions

329
Jamroot Normal file
View file

@ -0,0 +1,329 @@
# Copyright Vladimir Prus 2002-2006.
# Copyright Dave Abrahams 2005-2006.
# Copyright Rene Rivera 2005-2007.
# Copyright Douglas Gregor 2005.
#
# 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)
# Usage:
#
# b2 [options] [properties] [install|stage]
#
# Builds and installs Boost.
#
# Targets and Related Options:
#
# install Install headers and compiled library files to the
# ======= configured locations (below).
#
# --prefix=<PREFIX> Install architecture independent files here.
# Default: C:\Boost on Windows
# Default: /usr/local on Unix, Linux, etc.
#
# --exec-prefix=<EPREFIX> Install architecture dependent files here.
# Default: <PREFIX>
#
# --libdir=<LIBDIR> Install library files here.
# Default: <EPREFIX>/lib
#
# --includedir=<HDRDIR> Install header files here.
# Default: <PREFIX>/include
#
# --cmakedir=<CMAKEDIR> Install CMake configuration files here.
# Default: <LIBDIR>/cmake
#
# --no-cmake-config Do not install CMake configuration files.
#
# stage Build and install only compiled library files to the
# ===== stage directory.
#
# --stagedir=<STAGEDIR> Install library files here
# Default: ./stage
#
# Other Options:
#
# --build-type=<type> Build the specified pre-defined set of variations of
# the libraries. Note, that which variants get built
# depends on what each library supports.
#
# -- minimal -- (default) Builds a minimal set of
# variants. On Windows, these are static
# multithreaded libraries in debug and release
# modes, using shared runtime. On Linux, these are
# static and shared multithreaded libraries in
# release mode.
#
# -- complete -- Build all possible variations.
#
# --build-dir=DIR Build in this location instead of building within
# the distribution tree. Recommended!
#
# --show-libraries Display the list of Boost libraries that require
# build and installation steps, and then exit.
#
# --layout=<layout> Determine whether to choose library names and header
# locations such that multiple versions of Boost or
# multiple compilers can be used on the same system.
#
# -- versioned -- Names of boost binaries include
# the Boost version number, name and version of
# the compiler and encoded build properties. Boost
# headers are installed in a subdirectory of
# <HDRDIR> whose name contains the Boost version
# number.
#
# -- tagged -- Names of boost binaries include the
# encoded build properties such as variant and
# threading, but do not including compiler name
# and version, or Boost version. This option is
# useful if you build several variants of Boost,
# using the same compiler.
#
# -- system -- Binaries names do not include the
# Boost version number or the name and version
# number of the compiler. Boost headers are
# installed directly into <HDRDIR>. This option is
# intended for system integrators building
# distribution packages.
#
# The default value is 'versioned' on Windows, and
# 'system' on Unix.
#
# --buildid=ID Add the specified ID to the name of built libraries.
# The default is to not add anything.
#
# --python-buildid=ID Add the specified ID to the name of built libraries
# that depend on Python. The default is to not add
# anything. This ID is added in addition to --buildid.
#
# --help This message.
#
# --with-<library> Build and install the specified <library>. If this
# option is used, only libraries specified using this
# option will be built.
#
# --without-<library> Do not build, stage, or install the specified
# <library>. By default, all libraries are built.
#
# Properties:
#
# toolset=toolset Indicate the toolset to build with.
#
# variant=debug|release Select the build variant
#
# link=static|shared Whether to build static or shared libraries
#
# threading=single|multi Whether to build single or multithreaded binaries
#
# runtime-link=static|shared
# Whether to link to static or shared C and C++
# runtime.
#
# TODO:
# - handle boost version
# - handle python options such as pydebug
import boostcpp ;
import package ;
import sequence ;
import xsltproc ;
import set ;
import path ;
import link ;
import notfile ;
import virtual-target ;
import "class" : new ;
import property-set ;
import threadapi-feature ;
import option ;
# Backslash because of `bcp --namespace`
import tools/boost\_install/boost-install ;
path-constant BOOST_ROOT : . ;
constant BOOST_VERSION : 1.72.0 ;
constant BOOST_JAMROOT_MODULE : $(__name__) ;
boostcpp.set-version $(BOOST_VERSION) ;
use-project /boost/architecture : libs/config/checks/architecture ;
local all-headers =
[ MATCH .*libs/(.*)/include/boost : [ glob libs/*/include/boost libs/*/*/include/boost ] ] ;
for dir in $(all-headers)
{
link-directory $(dir)-headers : libs/$(dir)/include/boost : <location>. ;
explicit $(dir)-headers ;
}
if $(all-headers)
{
constant BOOST_MODULARLAYOUT : $(all-headers) ;
}
project boost
: requirements <include>.
[ boostcpp.architecture ]
[ boostcpp.address-model ]
# Disable auto-linking for all targets here, primarily because it caused
# troubles with V2.
<define>BOOST_ALL_NO_LIB=1
# Used to encode variant in target name. See the 'tag' rule below.
<tag>@$(__name__).tag
<conditional>@handle-static-runtime
# Comeau does not support shared lib
<toolset>como:<link>static
<toolset>como-linux:<define>_GNU_SOURCE=1
# When building docs within Boost, we want the standard Boost style
<xsl:param>boost.defaults=Boost
<conditional>@threadapi-feature.detect
: usage-requirements <include>.
: default-build
<visibility>hidden
<threading>multi
: build-dir bin.v2
;
# This rule is called by Boost.Build to determine the name of target. We use it
# to encode the build variant, compiler name and boost version in the target
# name.
#
rule tag ( name : type ? : property-set )
{
return [ boostcpp.tag $(name) : $(type) : $(property-set) ] ;
}
rule python-tag ( name : type ? : property-set )
{
return [ boostcpp.python-tag $(name) : $(type) : $(property-set) ] ;
}
rule handle-static-runtime ( properties * )
{
# Using static runtime with shared libraries is impossible on Linux, and
# dangerous on Windows. Therefore, we disallow it. This might be drastic,
# but it was disabled for a while without anybody complaining.
# For CW, static runtime is needed so that std::locale works.
if <link>shared in $(properties) && <runtime-link>static in $(properties) &&
! ( <toolset>cw in $(properties) )
{
if ! $(.shared-static-warning-emitted)
{
ECHO "warning: skipping configuration link=shared, runtime-link=static" ;
ECHO "warning: this combination is either impossible or too dangerous" ;
ECHO "warning: to be of any use" ;
.shared-static-warning-emitted = 1 ;
}
return <build>no ;
}
}
all-libraries = [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ]
[ glob libs/*/build/Jamfile ] ] ;
all-libraries = [ sequence.unique $(all-libraries) ] ;
# The function_types library has a Jamfile, but it's used for maintenance
# purposes, there's no library to build and install.
all-libraries = [ set.difference $(all-libraries) : function_types ] ;
# Setup convenient aliases for all libraries.
local rule explicit-alias ( id : targets + )
{
alias $(id) : $(targets) ;
explicit $(id) ;
}
# First, the complicated libraries: where the target name in Jamfile is
# different from its directory name.
explicit-alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ;
explicit-alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ;
explicit-alias unit_test_framework : libs/test/build//boost_unit_test_framework ;
explicit-alias bgl-vis : libs/graps/build//bgl-vis ;
explicit-alias serialization : libs/serialization/build//boost_serialization ;
explicit-alias wserialization : libs/serialization/build//boost_wserialization ;
for local l in $(all-libraries)
{
if ! $(l) in test graph serialization headers
{
explicit-alias $(l) : libs/$(l)/build//boost_$(l) ;
}
}
# Log has an additional target
explicit-alias log_setup : libs/log/build//boost_log_setup ;
rule do-nothing { }
rule generate-alias ( project name : property-set : sources * )
{
local action-name = [ $(property-set).get <action> ] ;
local m = [ MATCH ^@(.*) : $(action-name) ] ;
property-set = [ property-set.empty ] ;
local action = [ new action $(sources) : $(m[1]) : $(property-set) ] ;
local t = [ new notfile-target $(name) : $(project) : $(action) ] ;
return [ virtual-target.register $(t) ] ;
}
generate headers : $(all-headers)-headers : <generating-rule>@generate-alias <action>@do-nothing : : <include>. ;
#alias headers : $(all-headers)-headers : : : <include>. ;
explicit headers ;
# Make project ids of all libraries known.
for local l in $(all-libraries)
{
use-project /boost/$(l) : libs/$(l)/build ;
}
if [ path.exists $(BOOST_ROOT)/tools/inspect/build ]
{
use-project /boost/tools/inspect : tools/inspect/build ;
}
if [ path.exists $(BOOST_ROOT)/libs/wave/tool/build ]
{
use-project /boost/libs/wave/tool : libs/wave/tool/build ;
}
# Make the boost-install rule visible in subprojects
# This rule should be called from libraries' Jamfiles and will create two
# targets, "install" and "stage", that will install or stage that library. The
# --prefix option is respected, but --with and --without options, naturally, are
# ignored.
#
# - libraries -- list of library targets to install.
rule boost-install ( libraries * )
{
boost-install.boost-install $(libraries) ;
}
# Creates a library target, adding autolink support and also creates
# stage and install targets via boost-install, above.
rule boost-lib ( name : sources * : requirements * : default-build * : usage-requirements * )
{
autolink = <link>shared:<define>BOOST_$(name:U)_DYN_LINK=1 ;
name = boost_$(name) ;
lib $(name)
: $(sources)
: $(requirements) $(autolink)
: $(default-build)
: $(usage-requirements) $(autolink)
;
boost-install $(name) ;
}
# Declare special top-level targets that build and install the desired variants
# of the libraries.
boostcpp.declare-targets $(all-libraries) ;

View file

@ -1,553 +0,0 @@
// (C) Copyright Herve Bronnimann 2004.
//
// 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)
/*
Revision history:
1 July 2004
Split the code into two headers to lessen dependence on
Boost.tuple. (Herve)
26 June 2004
Added the code for the boost minmax library. (Herve)
*/
#ifndef BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
#define BOOST_ALGORITHM_MINMAX_ELEMENT_HPP
/* PROPOSED STANDARD EXTENSIONS:
*
* minmax_element(first, last)
* Effect: std::make_pair( std::min_element(first, last),
* std::max_element(first, last) );
*
* minmax_element(first, last, comp)
* Effect: std::make_pair( std::min_element(first, last, comp),
* std::max_element(first, last, comp) );
*/
#include <utility> // for std::pair and std::make_pair
namespace boost {
namespace detail { // for obtaining a uniform version of minmax_element
// that compiles with VC++ 6.0 -- avoid the iterator_traits by
// having comparison object over iterator, not over dereferenced value
template <typename Iterator>
struct less_over_iter {
bool operator()(Iterator const& it1,
Iterator const& it2) const { return *it1 < *it2; }
};
template <typename Iterator, class BinaryPredicate>
struct binary_pred_over_iter {
explicit binary_pred_over_iter(BinaryPredicate const& p ) : m_p( p ) {}
bool operator()(Iterator const& it1,
Iterator const& it2) const { return m_p(*it1, *it2); }
private:
BinaryPredicate m_p;
};
// common base for the two minmax_element overloads
template <typename ForwardIter, class Compare >
std::pair<ForwardIter,ForwardIter>
basic_minmax_element(ForwardIter first, ForwardIter last, Compare comp)
{
if (first == last)
return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
// if only one element
ForwardIter second = first; ++second;
if (second == last)
return std::make_pair(min_result, max_result);
// treat first pair separately (only one comparison for first two elements)
ForwardIter potential_min_result = last;
if (comp(first, second))
max_result = second;
else {
min_result = second;
potential_min_result = first;
}
// then each element by pairs, with at most 3 comparisons per pair
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (comp(first, min_result)) {
min_result = first;
potential_min_result = last;
}
if (comp(max_result, second))
max_result = second;
} else {
if (comp(second, min_result)) {
min_result = second;
potential_min_result = first;
}
if (comp(max_result, first))
max_result = first;
}
first = ++second;
if (first != last) ++second;
}
// if odd number of elements, treat last element
if (first != last) { // odd number of elements
if (comp(first, min_result)) {
min_result = first;
potential_min_result = last;
}
else if (comp(max_result, first))
max_result = first;
}
// resolve min_result being incorrect with one extra comparison
// (in which case potential_min_result is necessarily the correct result)
if (potential_min_result != last
&& !comp(min_result, potential_min_result))
min_result = potential_min_result;
return std::make_pair(min_result,max_result);
}
} // namespace detail
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
minmax_element(ForwardIter first, ForwardIter last)
{
return detail::basic_minmax_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
minmax_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_minmax_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
}
/* PROPOSED BOOST EXTENSIONS
* In the description below, [rfirst,rlast) denotes the reversed range
* of [first,last). Even though the iterator type of first and last may
* be only a Forward Iterator, it is possible to explain the semantics
* by assuming that it is a Bidirectional Iterator. In the sequel,
* reverse(ForwardIterator&) returns the reverse_iterator adaptor.
* This is not how the functions would be implemented!
*
* first_min_element(first, last)
* Effect: std::min_element(first, last);
*
* first_min_element(first, last, comp)
* Effect: std::min_element(first, last, comp);
*
* last_min_element(first, last)
* Effect: reverse( std::min_element(reverse(last), reverse(first)) );
*
* last_min_element(first, last, comp)
* Effect: reverse( std::min_element(reverse(last), reverse(first), comp) );
*
* first_max_element(first, last)
* Effect: std::max_element(first, last);
*
* first_max_element(first, last, comp)
* Effect: max_element(first, last);
*
* last_max_element(first, last)
* Effect: reverse( std::max_element(reverse(last), reverse(first)) );
*
* last_max_element(first, last, comp)
* Effect: reverse( std::max_element(reverse(last), reverse(first), comp) );
*
* first_min_first_max_element(first, last)
* Effect: std::make_pair( first_min_element(first, last),
* first_max_element(first, last) );
*
* first_min_first_max_element(first, last, comp)
* Effect: std::make_pair( first_min_element(first, last, comp),
* first_max_element(first, last, comp) );
*
* first_min_last_max_element(first, last)
* Effect: std::make_pair( first_min_element(first, last),
* last_max_element(first, last) );
*
* first_min_last_max_element(first, last, comp)
* Effect: std::make_pair( first_min_element(first, last, comp),
* last_max_element(first, last, comp) );
*
* last_min_first_max_element(first, last)
* Effect: std::make_pair( last_min_element(first, last),
* first_max_element(first, last) );
*
* last_min_first_max_element(first, last, comp)
* Effect: std::make_pair( last_min_element(first, last, comp),
* first_max_element(first, last, comp) );
*
* last_min_last_max_element(first, last)
* Effect: std::make_pair( last_min_element(first, last),
* last_max_element(first, last) );
*
* last_min_last_max_element(first, last, comp)
* Effect: std::make_pair( last_min_element(first, last, comp),
* last_max_element(first, last, comp) );
*/
namespace boost {
// Min_element and max_element variants
namespace detail { // common base for the overloads
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_first_min_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter min_result = first;
while (++first != last)
if (comp(first, min_result))
min_result = first;
return min_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_last_min_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter min_result = first;
while (++first != last)
if (!comp(min_result, first))
min_result = first;
return min_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter max_result = first;
while (++first != last)
if (comp(max_result, first))
max_result = first;
return max_result;
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
basic_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return last;
ForwardIter max_result = first;
while (++first != last)
if (!comp(first, max_result))
max_result = first;
return max_result;
}
} // namespace detail
template <typename ForwardIter>
ForwardIter
first_min_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_min_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
first_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_first_min_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
last_min_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
last_min_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_last_min_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
first_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
first_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_first_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
ForwardIter
last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
ForwardIter
last_max_element(ForwardIter first, ForwardIter last, BinaryPredicate comp)
{
return detail::basic_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
// Minmax_element variants -- comments removed
namespace detail {
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_first_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last)
return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = ++first;
if (second == last)
return std::make_pair(min_result, max_result);
if (comp(second, min_result))
min_result = second;
else
max_result = second;
first = ++second; if (first != last) ++second;
while (second != last) {
if (!comp(second, first)) {
if (comp(first, min_result))
min_result = first;
if (!comp(second, max_result))
max_result = second;
} else {
if (comp(second, min_result))
min_result = second;
if (!comp(first, max_result))
max_result = first;
}
first = ++second; if (first != last) ++second;
}
if (first != last) {
if (comp(first, min_result))
min_result = first;
else if (!comp(first, max_result))
max_result = first;
}
return std::make_pair(min_result, max_result);
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_last_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = ++first;
if (second == last)
return std::make_pair(min_result, max_result);
if (comp(max_result, second))
max_result = second;
else
min_result = second;
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (!comp(min_result, first))
min_result = first;
if (comp(max_result, second))
max_result = second;
} else {
if (!comp(min_result, second))
min_result = second;
if (comp(max_result, first))
max_result = first;
}
first = ++second; if (first != last) ++second;
}
if (first != last) {
if (!comp(min_result, first))
min_result = first;
else if (comp(max_result, first))
max_result = first;
}
return std::make_pair(min_result, max_result);
}
template <typename ForwardIter, class BinaryPredicate>
std::pair<ForwardIter,ForwardIter>
basic_last_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
if (first == last) return std::make_pair(last,last);
ForwardIter min_result = first;
ForwardIter max_result = first;
ForwardIter second = first; ++second;
if (second == last)
return std::make_pair(min_result,max_result);
ForwardIter potential_max_result = last;
if (comp(first, second))
max_result = second;
else {
min_result = second;
potential_max_result = second;
}
first = ++second; if (first != last) ++second;
while (second != last) {
if (comp(first, second)) {
if (!comp(min_result, first))
min_result = first;
if (!comp(second, max_result)) {
max_result = second;
potential_max_result = last;
}
} else {
if (!comp(min_result, second))
min_result = second;
if (!comp(first, max_result)) {
max_result = first;
potential_max_result = second;
}
}
first = ++second;
if (first != last) ++second;
}
if (first != last) {
if (!comp(min_result, first))
min_result = first;
if (!comp(first, max_result)) {
max_result = first;
potential_max_result = last;
}
}
if (potential_max_result != last
&& !comp(potential_max_result, max_result))
max_result = potential_max_result;
return std::make_pair(min_result,max_result);
}
} // namespace detail
template <typename ForwardIter>
inline std::pair<ForwardIter,ForwardIter>
first_min_first_max_element(ForwardIter first, ForwardIter last)
{
return minmax_element(first, last);
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
first_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return minmax_element(first, last, comp);
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
first_min_last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_first_min_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
first_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_first_min_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
last_min_first_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_first_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
last_min_first_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_last_min_first_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
template <typename ForwardIter>
std::pair<ForwardIter,ForwardIter>
last_min_last_max_element(ForwardIter first, ForwardIter last)
{
return detail::basic_last_min_last_max_element(first, last,
detail::less_over_iter<ForwardIter>() );
}
template <typename ForwardIter, class BinaryPredicate>
inline std::pair<ForwardIter,ForwardIter>
last_min_last_max_element(ForwardIter first, ForwardIter last,
BinaryPredicate comp)
{
return detail::basic_last_min_last_max_element(first, last,
detail::binary_pred_over_iter<ForwardIter,BinaryPredicate>(comp) );
}
} // namespace boost
#endif // BOOST_ALGORITHM_MINMAX_ELEMENT_HPP

View file

@ -0,0 +1,312 @@
// Boost string_algo library classification.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CLASSIFICATION_HPP
#define BOOST_STRING_CLASSIFICATION_HPP
#include <algorithm>
#include <locale>
#include <boost/range/value_type.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/detail/classification.hpp>
#include <boost/algorithm/string/predicate_facade.hpp>
/*! \file
Classification predicates are included in the library to give
some more convenience when using algorithms like \c trim() and \c all().
They wrap functionality of STL classification functions ( e.g. \c std::isspace() )
into generic functors.
*/
namespace boost {
namespace algorithm {
// classification functor generator -------------------------------------//
//! is_classified predicate
/*!
Construct the \c is_classified predicate. This predicate holds if the input is
of specified \c std::ctype category.
\param Type A \c std::ctype category
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(Type, Loc);
}
//! is_space predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::space category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_space(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::space, Loc);
}
//! is_alnum predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::alnum category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_alnum(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::alnum, Loc);
}
//! is_alpha predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::alpha category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_alpha(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::alpha, Loc);
}
//! is_cntrl predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::cntrl category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_cntrl(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::cntrl, Loc);
}
//! is_digit predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::digit category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_digit(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::digit, Loc);
}
//! is_graph predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::graph category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_graph(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::graph, Loc);
}
//! is_lower predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::lower category.
\param Loc A locale used for classification
\return An instance of \c is_classified predicate
*/
inline detail::is_classifiedF
is_lower(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::lower, Loc);
}
//! is_print predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::print category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_print(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::print, Loc);
}
//! is_punct predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::punct category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_punct(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::punct, Loc);
}
//! is_upper predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::upper category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_upper(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::upper, Loc);
}
//! is_xdigit predicate
/*!
Construct the \c is_classified predicate for the \c ctype_base::xdigit category.
\param Loc A locale used for classification
\return An instance of the \c is_classified predicate
*/
inline detail::is_classifiedF
is_xdigit(const std::locale& Loc=std::locale())
{
return detail::is_classifiedF(std::ctype_base::xdigit, Loc);
}
//! is_any_of predicate
/*!
Construct the \c is_any_of predicate. The predicate holds if the input
is included in the specified set of characters.
\param Set A set of characters to be recognized
\return An instance of the \c is_any_of predicate
*/
template<typename RangeT>
inline detail::is_any_ofF<
BOOST_STRING_TYPENAME range_value<RangeT>::type>
is_any_of( const RangeT& Set )
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_set(boost::as_literal(Set));
return detail::is_any_ofF<BOOST_STRING_TYPENAME range_value<RangeT>::type>(lit_set);
}
//! is_from_range predicate
/*!
Construct the \c is_from_range predicate. The predicate holds if the input
is included in the specified range. (i.e. From <= Ch <= To )
\param From The start of the range
\param To The end of the range
\return An instance of the \c is_from_range predicate
*/
template<typename CharT>
inline detail::is_from_rangeF<CharT> is_from_range(CharT From, CharT To)
{
return detail::is_from_rangeF<CharT>(From,To);
}
// predicate combinators ---------------------------------------------------//
//! predicate 'and' composition predicate
/*!
Construct the \c class_and predicate. This predicate can be used
to logically combine two classification predicates. \c class_and holds,
if both predicates return true.
\param Pred1 The first predicate
\param Pred2 The second predicate
\return An instance of the \c class_and predicate
*/
template<typename Pred1T, typename Pred2T>
inline detail::pred_andF<Pred1T, Pred2T>
operator&&(
const predicate_facade<Pred1T>& Pred1,
const predicate_facade<Pred2T>& Pred2 )
{
// Doing the static_cast with the pointer instead of the reference
// is a workaround for some compilers which have problems with
// static_cast's of template references, i.e. CW8. /grafik/
return detail::pred_andF<Pred1T,Pred2T>(
*static_cast<const Pred1T*>(&Pred1),
*static_cast<const Pred2T*>(&Pred2) );
}
//! predicate 'or' composition predicate
/*!
Construct the \c class_or predicate. This predicate can be used
to logically combine two classification predicates. \c class_or holds,
if one of the predicates return true.
\param Pred1 The first predicate
\param Pred2 The second predicate
\return An instance of the \c class_or predicate
*/
template<typename Pred1T, typename Pred2T>
inline detail::pred_orF<Pred1T, Pred2T>
operator||(
const predicate_facade<Pred1T>& Pred1,
const predicate_facade<Pred2T>& Pred2 )
{
// Doing the static_cast with the pointer instead of the reference
// is a workaround for some compilers which have problems with
// static_cast's of template references, i.e. CW8. /grafik/
return detail::pred_orF<Pred1T,Pred2T>(
*static_cast<const Pred1T*>(&Pred1),
*static_cast<const Pred2T*>(&Pred2));
}
//! predicate negation operator
/*!
Construct the \c class_not predicate. This predicate represents a negation.
\c class_or holds if of the predicates return false.
\param Pred The predicate to be negated
\return An instance of the \c class_not predicate
*/
template<typename PredT>
inline detail::pred_notF<PredT>
operator!( const predicate_facade<PredT>& Pred )
{
// Doing the static_cast with the pointer instead of the reference
// is a workaround for some compilers which have problems with
// static_cast's of template references, i.e. CW8. /grafik/
return detail::pred_notF<PredT>(*static_cast<const PredT*>(&Pred));
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::is_classified;
using algorithm::is_space;
using algorithm::is_alnum;
using algorithm::is_alpha;
using algorithm::is_cntrl;
using algorithm::is_digit;
using algorithm::is_graph;
using algorithm::is_lower;
using algorithm::is_upper;
using algorithm::is_print;
using algorithm::is_punct;
using algorithm::is_xdigit;
using algorithm::is_any_of;
using algorithm::is_from_range;
} // namespace boost
#endif // BOOST_STRING_PREDICATE_HPP

View file

@ -0,0 +1,353 @@
// Boost string_algo library classification.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <algorithm>
#include <functional>
#include <locale>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/algorithm/string/predicate_facade.hpp>
#include <boost/type_traits/remove_const.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// classification functors -----------------------------------------------//
// is_classified functor
struct is_classifiedF :
public predicate_facade<is_classifiedF>
{
// Boost.ResultOf support
typedef bool result_type;
// Constructor from a locale
is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
m_Type(Type), m_Locale(Loc) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
}
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL)
template<>
bool operator()( char const Ch ) const
{
return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
}
#endif
private:
std::ctype_base::mask m_Type;
std::locale m_Locale;
};
// is_any_of functor
/*
returns true if the value is from the specified set
*/
template<typename CharT>
struct is_any_ofF :
public predicate_facade<is_any_ofF<CharT> >
{
private:
// set cannot operate on const value-type
typedef typename ::boost::remove_const<CharT>::type set_value_type;
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
template<typename RangeT>
is_any_ofF( const RangeT& Range ) : m_Size(0)
{
// Prepare storage
m_Storage.m_dynSet=0;
std::size_t Size=::boost::distance(Range);
m_Size=Size;
set_value_type* Storage=0;
if(use_fixed_storage(m_Size))
{
// Use fixed storage
Storage=&m_Storage.m_fixSet[0];
}
else
{
// Use dynamic storage
m_Storage.m_dynSet=new set_value_type[m_Size];
Storage=m_Storage.m_dynSet;
}
// Use fixed storage
::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
::std::sort(Storage, Storage+m_Size);
}
// Copy constructor
is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
{
// Prepare storage
m_Storage.m_dynSet=0;
const set_value_type* SrcStorage=0;
set_value_type* DestStorage=0;
if(use_fixed_storage(m_Size))
{
// Use fixed storage
DestStorage=&m_Storage.m_fixSet[0];
SrcStorage=&Other.m_Storage.m_fixSet[0];
}
else
{
// Use dynamic storage
m_Storage.m_dynSet=new set_value_type[m_Size];
DestStorage=m_Storage.m_dynSet;
SrcStorage=Other.m_Storage.m_dynSet;
}
// Use fixed storage
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
}
// Destructor
~is_any_ofF()
{
if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
{
delete [] m_Storage.m_dynSet;
}
}
// Assignment
is_any_ofF& operator=(const is_any_ofF& Other)
{
// Handle self assignment
if(this==&Other) return *this;
// Prepare storage
const set_value_type* SrcStorage;
set_value_type* DestStorage;
if(use_fixed_storage(Other.m_Size))
{
// Use fixed storage
DestStorage=&m_Storage.m_fixSet[0];
SrcStorage=&Other.m_Storage.m_fixSet[0];
// Delete old storage if was present
if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
{
delete [] m_Storage.m_dynSet;
}
// Set new size
m_Size=Other.m_Size;
}
else
{
// Other uses dynamic storage
SrcStorage=Other.m_Storage.m_dynSet;
// Check what kind of storage are we using right now
if(use_fixed_storage(m_Size))
{
// Using fixed storage, allocate new
set_value_type* pTemp=new set_value_type[Other.m_Size];
DestStorage=pTemp;
m_Storage.m_dynSet=pTemp;
m_Size=Other.m_Size;
}
else
{
// Using dynamic storage, check if can reuse
if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2)
{
// Reuse the current storage
DestStorage=m_Storage.m_dynSet;
m_Size=Other.m_Size;
}
else
{
// Allocate the new one
set_value_type* pTemp=new set_value_type[Other.m_Size];
DestStorage=pTemp;
// Delete old storage if necessary
if(m_Storage.m_dynSet!=0)
{
delete [] m_Storage.m_dynSet;
}
// Store the new storage
m_Storage.m_dynSet=pTemp;
// Set new size
m_Size=Other.m_Size;
}
}
}
// Copy the data
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
return *this;
}
// Operation
template<typename Char2T>
bool operator()( Char2T Ch ) const
{
const set_value_type* Storage=
(use_fixed_storage(m_Size))
? &m_Storage.m_fixSet[0]
: m_Storage.m_dynSet;
return ::std::binary_search(Storage, Storage+m_Size, Ch);
}
private:
// check if the size is eligible for fixed storage
static bool use_fixed_storage(std::size_t size)
{
return size<=sizeof(set_value_type*)*2;
}
private:
// storage
// The actual used storage is selected on the type
union
{
set_value_type* m_dynSet;
set_value_type m_fixSet[sizeof(set_value_type*)*2];
}
m_Storage;
// storage size
::std::size_t m_Size;
};
// is_from_range functor
/*
returns true if the value is from the specified range.
(i.e. x>=From && x>=To)
*/
template<typename CharT>
struct is_from_rangeF :
public predicate_facade< is_from_rangeF<CharT> >
{
// Boost.ResultOf support
typedef bool result_type;
// Constructor
is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
// Operation
template<typename Char2T>
bool operator()( Char2T Ch ) const
{
return ( m_From <= Ch ) && ( Ch <= m_To );
}
private:
CharT m_From;
CharT m_To;
};
// class_and composition predicate
template<typename Pred1T, typename Pred2T>
struct pred_andF :
public predicate_facade< pred_andF<Pred1T,Pred2T> >
{
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
m_Pred1(Pred1), m_Pred2(Pred2) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return m_Pred1(Ch) && m_Pred2(Ch);
}
private:
Pred1T m_Pred1;
Pred2T m_Pred2;
};
// class_or composition predicate
template<typename Pred1T, typename Pred2T>
struct pred_orF :
public predicate_facade< pred_orF<Pred1T,Pred2T> >
{
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
m_Pred1(Pred1), m_Pred2(Pred2) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return m_Pred1(Ch) || m_Pred2(Ch);
}
private:
Pred1T m_Pred1;
Pred2T m_Pred2;
};
// class_not composition predicate
template< typename PredT >
struct pred_notF :
public predicate_facade< pred_notF<PredT> >
{
public:
// Boost.ResultOf support
typedef bool result_type;
// Constructor
pred_notF( PredT Pred ) : m_Pred(Pred) {}
// Operation
template<typename CharT>
bool operator()( CharT Ch ) const
{
return !m_Pred(Ch);
}
private:
PredT m_Pred;
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP

View file

@ -0,0 +1,87 @@
// Boost string_algo library find_iterator.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/function.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// find_iterator base -----------------------------------------------//
// Find iterator base
template<typename IteratorT>
class find_iterator_base
{
protected:
// typedefs
typedef IteratorT input_iterator_type;
typedef iterator_range<IteratorT> match_type;
typedef function2<
match_type,
input_iterator_type,
input_iterator_type> finder_type;
protected:
// Protected construction/destruction
// Default constructor
find_iterator_base() {}
// Copy construction
find_iterator_base( const find_iterator_base& Other ) :
m_Finder(Other.m_Finder) {}
// Constructor
template<typename FinderT>
find_iterator_base( FinderT Finder, int ) :
m_Finder(Finder) {}
// Destructor
~find_iterator_base() {}
// Find operation
match_type do_find(
input_iterator_type Begin,
input_iterator_type End ) const
{
if (!m_Finder.empty())
{
return m_Finder(Begin,End);
}
else
{
return match_type(End,End);
}
}
// Check
bool is_null() const
{
return m_Finder.empty();
}
private:
// Finder
finder_type m_Finder;
};
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_FIND_ITERATOR_DETAIL_HPP

View file

@ -0,0 +1,95 @@
// Boost string_algo library trim.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_TRIM_DETAIL_HPP
#define BOOST_STRING_TRIM_DETAIL_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/detail/iterator.hpp>
namespace boost {
namespace algorithm {
namespace detail {
// trim iterator helper -----------------------------------------------//
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_end_iter_select(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace,
std::forward_iterator_tag )
{
ForwardIteratorT TrimIt=InBegin;
for( ForwardIteratorT It=InBegin; It!=InEnd; ++It )
{
if ( !IsSpace(*It) )
{
TrimIt=It;
++TrimIt;
}
}
return TrimIt;
}
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_end_iter_select(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace,
std::bidirectional_iterator_tag )
{
for( ForwardIteratorT It=InEnd; It!=InBegin; )
{
if ( !IsSpace(*(--It)) )
return ++It;
}
return InBegin;
}
// Search for first non matching character from the beginning of the sequence
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_begin(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace )
{
ForwardIteratorT It=InBegin;
for(; It!=InEnd; ++It )
{
if (!IsSpace(*It))
return It;
}
return It;
}
// Search for first non matching character from the end of the sequence
template< typename ForwardIteratorT, typename PredicateT >
inline ForwardIteratorT trim_end(
ForwardIteratorT InBegin,
ForwardIteratorT InEnd,
PredicateT IsSpace )
{
typedef BOOST_STRING_TYPENAME boost::detail::
iterator_traits<ForwardIteratorT>::iterator_category category;
return ::boost::algorithm::detail::trim_end_iter_select( InBegin, InEnd, IsSpace, category() );
}
} // namespace detail
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_TRIM_DETAIL_HPP

View file

@ -0,0 +1,388 @@
// Boost string_algo library find_iterator.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2004.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_FIND_ITERATOR_HPP
#define BOOST_STRING_FIND_ITERATOR_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/detail/find_iterator.hpp>
/*! \file
Defines find iterator classes. Find iterator repeatedly applies a Finder
to the specified input string to search for matches. Dereferencing
the iterator yields the current match or a range between the last and the current
match depending on the iterator used.
*/
namespace boost {
namespace algorithm {
// find_iterator -----------------------------------------------//
//! find_iterator
/*!
Find iterator encapsulates a Finder and allows
for incremental searching in a string.
Each increment moves the iterator to the next match.
Find iterator is a readable forward traversal iterator.
Dereferencing the iterator yields an iterator_range delimiting
the current match.
*/
template<typename IteratorT>
class find_iterator :
public iterator_facade<
find_iterator<IteratorT>,
const iterator_range<IteratorT>,
forward_traversal_tag >,
private detail::find_iterator_base<IteratorT>
{
private:
// facade support
friend class ::boost::iterator_core_access;
private:
// typedefs
typedef detail::find_iterator_base<IteratorT> base_type;
typedef BOOST_STRING_TYPENAME
base_type::input_iterator_type input_iterator_type;
typedef BOOST_STRING_TYPENAME
base_type::match_type match_type;
public:
//! Default constructor
/*!
Construct null iterator. All null iterators are equal.
\post eof()==true
*/
find_iterator() {}
//! Copy constructor
/*!
Construct a copy of the find_iterator
*/
find_iterator( const find_iterator& Other ) :
base_type(Other),
m_Match(Other.m_Match),
m_End(Other.m_End) {}
//! Constructor
/*!
Construct new find_iterator for a given finder
and a range.
*/
template<typename FinderT>
find_iterator(
IteratorT Begin,
IteratorT End,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0),
m_Match(Begin,Begin),
m_End(End)
{
increment();
}
//! Constructor
/*!
Construct new find_iterator for a given finder
and a range.
*/
template<typename FinderT, typename RangeT>
find_iterator(
RangeT& Col,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0)
{
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
m_End=::boost::end(lit_col);
increment();
}
private:
// iterator operations
// dereference
const match_type& dereference() const
{
return m_Match;
}
// increment
void increment()
{
m_Match=this->do_find(m_Match.end(),m_End);
}
// comparison
bool equal( const find_iterator& Other ) const
{
bool bEof=eof();
bool bOtherEof=Other.eof();
return bEof || bOtherEof ? bEof==bOtherEof :
(
m_Match==Other.m_Match &&
m_End==Other.m_End
);
}
public:
// operations
//! Eof check
/*!
Check the eof condition. Eof condition means that
there is nothing more to be searched i.e. find_iterator
is after the last match.
*/
bool eof() const
{
return
this->is_null() ||
(
m_Match.begin() == m_End &&
m_Match.end() == m_End
);
}
private:
// Attributes
match_type m_Match;
input_iterator_type m_End;
};
//! find iterator construction helper
/*!
* Construct a find iterator to iterate through the specified string
*/
template<typename RangeT, typename FinderT>
inline find_iterator<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
make_find_iterator(
RangeT& Collection,
FinderT Finder)
{
return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
Collection, Finder);
}
// split iterator -----------------------------------------------//
//! split_iterator
/*!
Split iterator encapsulates a Finder and allows
for incremental searching in a string.
Unlike the find iterator, split iterator iterates
through gaps between matches.
Find iterator is a readable forward traversal iterator.
Dereferencing the iterator yields an iterator_range delimiting
the current match.
*/
template<typename IteratorT>
class split_iterator :
public iterator_facade<
split_iterator<IteratorT>,
const iterator_range<IteratorT>,
forward_traversal_tag >,
private detail::find_iterator_base<IteratorT>
{
private:
// facade support
friend class ::boost::iterator_core_access;
private:
// typedefs
typedef detail::find_iterator_base<IteratorT> base_type;
typedef BOOST_STRING_TYPENAME
base_type::input_iterator_type input_iterator_type;
typedef BOOST_STRING_TYPENAME
base_type::match_type match_type;
public:
//! Default constructor
/*!
Construct null iterator. All null iterators are equal.
\post eof()==true
*/
split_iterator() :
m_Next(),
m_End(),
m_bEof(true)
{}
//! Copy constructor
/*!
Construct a copy of the split_iterator
*/
split_iterator( const split_iterator& Other ) :
base_type(Other),
m_Match(Other.m_Match),
m_Next(Other.m_Next),
m_End(Other.m_End),
m_bEof(Other.m_bEof)
{}
//! Constructor
/*!
Construct new split_iterator for a given finder
and a range.
*/
template<typename FinderT>
split_iterator(
IteratorT Begin,
IteratorT End,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0),
m_Match(Begin,Begin),
m_Next(Begin),
m_End(End),
m_bEof(false)
{
// force the correct behavior for empty sequences and yield at least one token
if(Begin!=End)
{
increment();
}
}
//! Constructor
/*!
Construct new split_iterator for a given finder
and a collection.
*/
template<typename FinderT, typename RangeT>
split_iterator(
RangeT& Col,
FinderT Finder ) :
detail::find_iterator_base<IteratorT>(Finder,0),
m_bEof(false)
{
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
m_Next=::boost::begin(lit_col);
m_End=::boost::end(lit_col);
// force the correct behavior for empty sequences and yield at least one token
if(m_Next!=m_End)
{
increment();
}
}
private:
// iterator operations
// dereference
const match_type& dereference() const
{
return m_Match;
}
// increment
void increment()
{
match_type FindMatch=this->do_find( m_Next, m_End );
if(FindMatch.begin()==m_End && FindMatch.end()==m_End)
{
if(m_Match.end()==m_End)
{
// Mark iterator as eof
m_bEof=true;
}
}
m_Match=match_type( m_Next, FindMatch.begin() );
m_Next=FindMatch.end();
}
// comparison
bool equal( const split_iterator& Other ) const
{
bool bEof=eof();
bool bOtherEof=Other.eof();
return bEof || bOtherEof ? bEof==bOtherEof :
(
m_Match==Other.m_Match &&
m_Next==Other.m_Next &&
m_End==Other.m_End
);
}
public:
// operations
//! Eof check
/*!
Check the eof condition. Eof condition means that
there is nothing more to be searched i.e. find_iterator
is after the last match.
*/
bool eof() const
{
return this->is_null() || m_bEof;
}
private:
// Attributes
match_type m_Match;
input_iterator_type m_Next;
input_iterator_type m_End;
bool m_bEof;
};
//! split iterator construction helper
/*!
* Construct a split iterator to iterate through the specified collection
*/
template<typename RangeT, typename FinderT>
inline split_iterator<
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
make_split_iterator(
RangeT& Collection,
FinderT Finder)
{
return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
Collection, Finder);
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::find_iterator;
using algorithm::make_find_iterator;
using algorithm::split_iterator;
using algorithm::make_split_iterator;
} // namespace boost
#endif // BOOST_STRING_FIND_ITERATOR_HPP

View file

@ -0,0 +1,201 @@
// Boost string_algo library iter_find.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_ITER_FIND_HPP
#define BOOST_STRING_ITER_FIND_HPP
#include <boost/algorithm/string/config.hpp>
#include <algorithm>
#include <iterator>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/concept.hpp>
#include <boost/algorithm/string/find_iterator.hpp>
#include <boost/algorithm/string/detail/util.hpp>
/*! \file
Defines generic split algorithms. Split algorithms can be
used to divide a sequence into several part according
to a given criteria. Result is given as a 'container
of containers' where elements are copies or references
to extracted parts.
There are two algorithms provided. One iterates over matching
substrings, the other one over the gaps between these matches.
*/
namespace boost {
namespace algorithm {
// iterate find ---------------------------------------------------//
//! Iter find algorithm
/*!
This algorithm executes a given finder in iteration on the input,
until the end of input is reached, or no match is found.
Iteration is done using built-in find_iterator, so the real
searching is performed only when needed.
In each iteration new match is found and added to the result.
\param Result A 'container container' to contain the result of search.
Both outer and inner container must have constructor taking a pair
of iterators as an argument.
Typical type of the result is
\c std::vector<boost::iterator_range<iterator>>
(each element of such a vector will container a range delimiting
a match).
\param Input A container which will be searched.
\param Finder A Finder object used for searching
\return A reference to the result
\note Prior content of the result will be overwritten.
*/
template<
typename SequenceSequenceT,
typename RangeT,
typename FinderT >
inline SequenceSequenceT&
iter_find(
SequenceSequenceT& Result,
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
RangeT&& Input,
#else
RangeT& Input,
#endif
FinderT Finder )
{
BOOST_CONCEPT_ASSERT((
FinderConcept<
FinderT,
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
));
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
typedef BOOST_STRING_TYPENAME
range_iterator<RangeT>::type input_iterator_type;
typedef find_iterator<input_iterator_type> find_iterator_type;
typedef detail::copy_iterator_rangeF<
BOOST_STRING_TYPENAME
range_value<SequenceSequenceT>::type,
input_iterator_type> copy_range_type;
input_iterator_type InputEnd=::boost::end(lit_input);
typedef transform_iterator<copy_range_type, find_iterator_type>
transform_iter_type;
transform_iter_type itBegin=
::boost::make_transform_iterator(
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
copy_range_type());
transform_iter_type itEnd=
::boost::make_transform_iterator(
find_iterator_type(),
copy_range_type());
SequenceSequenceT Tmp(itBegin, itEnd);
Result.swap(Tmp);
return Result;
}
// iterate split ---------------------------------------------------//
//! Split find algorithm
/*!
This algorithm executes a given finder in iteration on the input,
until the end of input is reached, or no match is found.
Iteration is done using built-in find_iterator, so the real
searching is performed only when needed.
Each match is used as a separator of segments. These segments are then
returned in the result.
\param Result A 'container container' to contain the result of search.
Both outer and inner container must have constructor taking a pair
of iterators as an argument.
Typical type of the result is
\c std::vector<boost::iterator_range<iterator>>
(each element of such a vector will container a range delimiting
a match).
\param Input A container which will be searched.
\param Finder A finder object used for searching
\return A reference to the result
\note Prior content of the result will be overwritten.
*/
template<
typename SequenceSequenceT,
typename RangeT,
typename FinderT >
inline SequenceSequenceT&
iter_split(
SequenceSequenceT& Result,
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
RangeT&& Input,
#else
RangeT& Input,
#endif
FinderT Finder )
{
BOOST_CONCEPT_ASSERT((
FinderConcept<FinderT,
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
));
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
typedef BOOST_STRING_TYPENAME
range_iterator<RangeT>::type input_iterator_type;
typedef split_iterator<input_iterator_type> find_iterator_type;
typedef detail::copy_iterator_rangeF<
BOOST_STRING_TYPENAME
range_value<SequenceSequenceT>::type,
input_iterator_type> copy_range_type;
input_iterator_type InputEnd=::boost::end(lit_input);
typedef transform_iterator<copy_range_type, find_iterator_type>
transform_iter_type;
transform_iter_type itBegin=
::boost::make_transform_iterator(
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
copy_range_type() );
transform_iter_type itEnd=
::boost::make_transform_iterator(
find_iterator_type(),
copy_range_type() );
SequenceSequenceT Tmp(itBegin, itEnd);
Result.swap(Tmp);
return Result;
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::iter_find;
using algorithm::iter_split;
} // namespace boost
#endif // BOOST_STRING_ITER_FIND_HPP

View file

@ -0,0 +1,42 @@
// Boost string_algo library predicate_facade.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_PREDICATE_FACADE_HPP
#define BOOST_STRING_PREDICATE_FACADE_HPP
#include <boost/algorithm/string/config.hpp>
/*
\file boost/algorith/string/predicate_facade.hpp
This file contains predicate_facade definition. This template class is used
to identify classification predicates, so they can be combined using
composition operators.
*/
namespace boost {
namespace algorithm {
// predicate facade ------------------------------------------------------//
//! Predicate facade
/*!
This class allows to recognize classification
predicates, so that they can be combined using
composition operators.
Every classification predicate must be derived from this class.
*/
template<typename Derived>
struct predicate_facade {};
} // namespace algorithm
} // namespace boost
#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP

View file

@ -0,0 +1,175 @@
// Boost string_algo library split.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2006.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_SPLIT_HPP
#define BOOST_STRING_SPLIT_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/algorithm/string/iter_find.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <boost/algorithm/string/compare.hpp>
/*! \file
Defines basic split algorithms.
Split algorithms can be used to divide a string
into several parts according to given criteria.
Each part is copied and added as a new element to the
output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
*/
namespace boost {
namespace algorithm {
// find_all ------------------------------------------------------------//
//! Find all algorithm
/*!
This algorithm finds all occurrences of the search string
in the input.
Each part is copied and added as a new element to the
output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
\param Result A container that can hold copies of references to the substrings
\param Input A container which will be searched.
\param Search A substring to be searched for.
\return A reference the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename Range1T, typename Range2T >
inline SequenceSequenceT& find_all(
SequenceSequenceT& Result,
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
Range1T&& Input,
#else
Range1T& Input,
#endif
const Range2T& Search)
{
return ::boost::algorithm::iter_find(
Result,
Input,
::boost::algorithm::first_finder(Search) );
}
//! Find all algorithm ( case insensitive )
/*!
This algorithm finds all occurrences of the search string
in the input.
Each part is copied and added as a new element to the
output container. Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
Searching is case insensitive.
\param Result A container that can hold copies of references to the substrings
\param Input A container which will be searched.
\param Search A substring to be searched for.
\param Loc A locale used for case insensitive comparison
\return A reference the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename Range1T, typename Range2T >
inline SequenceSequenceT& ifind_all(
SequenceSequenceT& Result,
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
Range1T&& Input,
#else
Range1T& Input,
#endif
const Range2T& Search,
const std::locale& Loc=std::locale() )
{
return ::boost::algorithm::iter_find(
Result,
Input,
::boost::algorithm::first_finder(Search, is_iequal(Loc) ) );
}
// tokenize -------------------------------------------------------------//
//! Split algorithm
/*!
Tokenize expression. This function is equivalent to C strtok. Input
sequence is split into tokens, separated by separators. Separators
are given by means of the predicate.
Each part is copied and added as a new element to the
output container.
Thus the result container must be able to hold copies
of the matches (in a compatible structure like std::string) or
a reference to it (e.g. using the iterator range class).
Examples of such a container are \c std::vector<std::string>
or \c std::list<boost::iterator_range<std::string::iterator>>
\param Result A container that can hold copies of references to the substrings
\param Input A container which will be searched.
\param Pred A predicate to identify separators. This predicate is
supposed to return true if a given element is a separator.
\param eCompress If eCompress argument is set to token_compress_on, adjacent
separators are merged together. Otherwise, every two separators
delimit a token.
\return A reference the result
\note Prior content of the result will be overwritten.
\note This function provides the strong exception-safety guarantee
*/
template< typename SequenceSequenceT, typename RangeT, typename PredicateT >
inline SequenceSequenceT& split(
SequenceSequenceT& Result,
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
RangeT&& Input,
#else
RangeT& Input,
#endif
PredicateT Pred,
token_compress_mode_type eCompress=token_compress_off )
{
return ::boost::algorithm::iter_split(
Result,
Input,
::boost::algorithm::token_finder( Pred, eCompress ) );
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::find_all;
using algorithm::ifind_all;
using algorithm::split;
} // namespace boost
#endif // BOOST_STRING_SPLIT_HPP

View file

@ -0,0 +1,398 @@
// Boost string_algo library trim.hpp header file ---------------------------//
// Copyright Pavol Droba 2002-2003.
//
// 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)
// See http://www.boost.org/ for updates, documentation, and revision history.
#ifndef BOOST_STRING_TRIM_HPP
#define BOOST_STRING_TRIM_HPP
#include <boost/algorithm/string/config.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/algorithm/string/detail/trim.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <locale>
/*! \file
Defines trim algorithms.
Trim algorithms are used to remove trailing and leading spaces from a
sequence (string). Space is recognized using given locales.
Parametric (\c _if) variants use a predicate (functor) to select which characters
are to be trimmed..
Functions take a selection predicate as a parameter, which is used to determine
whether a character is a space. Common predicates are provided in classification.hpp header.
*/
namespace boost {
namespace algorithm {
// left trim -----------------------------------------------//
//! Left trim - parametric
/*!
Remove all leading spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The result is a trimmed copy of the input. It is returned as a sequence
or copied to the output iterator
\param Output An output iterator to which the result will be copied
\param Input An input range
\param IsSpace A unary predicate identifying spaces
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT, typename PredicateT>
inline OutputIteratorT trim_left_copy_if(
OutputIteratorT Output,
const RangeT& Input,
PredicateT IsSpace)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
std::copy(
::boost::algorithm::detail::trim_begin(
::boost::begin(lit_range),
::boost::end(lit_range),
IsSpace ),
::boost::end(lit_range),
Output);
return Output;
}
//! Left trim - parametric
/*!
\overload
*/
template<typename SequenceT, typename PredicateT>
inline SequenceT trim_left_copy_if(const SequenceT& Input, PredicateT IsSpace)
{
return SequenceT(
::boost::algorithm::detail::trim_begin(
::boost::begin(Input),
::boost::end(Input),
IsSpace ),
::boost::end(Input));
}
//! Left trim - parametric
/*!
Remove all leading spaces from the input.
The result is a trimmed copy of the input.
\param Input An input sequence
\param Loc a locale used for 'space' classification
\return A trimmed copy of the input
\note This function provides the strong exception-safety guarantee
*/
template<typename SequenceT>
inline SequenceT trim_left_copy(const SequenceT& Input, const std::locale& Loc=std::locale())
{
return
::boost::algorithm::trim_left_copy_if(
Input,
is_space(Loc));
}
//! Left trim
/*!
Remove all leading spaces from the input. The supplied predicate is
used to determine which characters are considered spaces.
The input sequence is modified in-place.
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename PredicateT>
inline void trim_left_if(SequenceT& Input, PredicateT IsSpace)
{
Input.erase(
::boost::begin(Input),
::boost::algorithm::detail::trim_begin(
::boost::begin(Input),
::boost::end(Input),
IsSpace));
}
//! Left trim
/*!
Remove all leading spaces from the input.
The Input sequence is modified in-place.
\param Input An input sequence
\param Loc A locale used for 'space' classification
*/
template<typename SequenceT>
inline void trim_left(SequenceT& Input, const std::locale& Loc=std::locale())
{
::boost::algorithm::trim_left_if(
Input,
is_space(Loc));
}
// right trim -----------------------------------------------//
//! Right trim - parametric
/*!
Remove all trailing spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The result is a trimmed copy of the input. It is returned as a sequence
or copied to the output iterator
\param Output An output iterator to which the result will be copied
\param Input An input range
\param IsSpace A unary predicate identifying spaces
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT, typename PredicateT>
inline OutputIteratorT trim_right_copy_if(
OutputIteratorT Output,
const RangeT& Input,
PredicateT IsSpace )
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
std::copy(
::boost::begin(lit_range),
::boost::algorithm::detail::trim_end(
::boost::begin(lit_range),
::boost::end(lit_range),
IsSpace ),
Output );
return Output;
}
//! Right trim - parametric
/*!
\overload
*/
template<typename SequenceT, typename PredicateT>
inline SequenceT trim_right_copy_if(const SequenceT& Input, PredicateT IsSpace)
{
return SequenceT(
::boost::begin(Input),
::boost::algorithm::detail::trim_end(
::boost::begin(Input),
::boost::end(Input),
IsSpace)
);
}
//! Right trim
/*!
Remove all trailing spaces from the input.
The result is a trimmed copy of the input
\param Input An input sequence
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
\note This function provides the strong exception-safety guarantee
*/
template<typename SequenceT>
inline SequenceT trim_right_copy(const SequenceT& Input, const std::locale& Loc=std::locale())
{
return
::boost::algorithm::trim_right_copy_if(
Input,
is_space(Loc));
}
//! Right trim - parametric
/*!
Remove all trailing spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The input sequence is modified in-place.
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename PredicateT>
inline void trim_right_if(SequenceT& Input, PredicateT IsSpace)
{
Input.erase(
::boost::algorithm::detail::trim_end(
::boost::begin(Input),
::boost::end(Input),
IsSpace ),
::boost::end(Input)
);
}
//! Right trim
/*!
Remove all trailing spaces from the input.
The input sequence is modified in-place.
\param Input An input sequence
\param Loc A locale used for 'space' classification
*/
template<typename SequenceT>
inline void trim_right(SequenceT& Input, const std::locale& Loc=std::locale())
{
::boost::algorithm::trim_right_if(
Input,
is_space(Loc) );
}
// both side trim -----------------------------------------------//
//! Trim - parametric
/*!
Remove all trailing and leading spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The result is a trimmed copy of the input. It is returned as a sequence
or copied to the output iterator
\param Output An output iterator to which the result will be copied
\param Input An input range
\param IsSpace A unary predicate identifying spaces
\return
An output iterator pointing just after the last inserted character or
a copy of the input
\note The second variant of this function provides the strong exception-safety guarantee
*/
template<typename OutputIteratorT, typename RangeT, typename PredicateT>
inline OutputIteratorT trim_copy_if(
OutputIteratorT Output,
const RangeT& Input,
PredicateT IsSpace)
{
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
BOOST_STRING_TYPENAME
range_const_iterator<RangeT>::type TrimEnd=
::boost::algorithm::detail::trim_end(
::boost::begin(lit_range),
::boost::end(lit_range),
IsSpace);
std::copy(
detail::trim_begin(
::boost::begin(lit_range), TrimEnd, IsSpace),
TrimEnd,
Output
);
return Output;
}
//! Trim - parametric
/*!
\overload
*/
template<typename SequenceT, typename PredicateT>
inline SequenceT trim_copy_if(const SequenceT& Input, PredicateT IsSpace)
{
BOOST_STRING_TYPENAME
range_const_iterator<SequenceT>::type TrimEnd=
::boost::algorithm::detail::trim_end(
::boost::begin(Input),
::boost::end(Input),
IsSpace);
return SequenceT(
detail::trim_begin(
::boost::begin(Input),
TrimEnd,
IsSpace),
TrimEnd
);
}
//! Trim
/*!
Remove all leading and trailing spaces from the input.
The result is a trimmed copy of the input
\param Input An input sequence
\param Loc A locale used for 'space' classification
\return A trimmed copy of the input
\note This function provides the strong exception-safety guarantee
*/
template<typename SequenceT>
inline SequenceT trim_copy( const SequenceT& Input, const std::locale& Loc=std::locale() )
{
return
::boost::algorithm::trim_copy_if(
Input,
is_space(Loc) );
}
//! Trim
/*!
Remove all leading and trailing spaces from the input.
The supplied predicate is used to determine which characters are considered spaces.
The input sequence is modified in-place.
\param Input An input sequence
\param IsSpace A unary predicate identifying spaces
*/
template<typename SequenceT, typename PredicateT>
inline void trim_if(SequenceT& Input, PredicateT IsSpace)
{
::boost::algorithm::trim_right_if( Input, IsSpace );
::boost::algorithm::trim_left_if( Input, IsSpace );
}
//! Trim
/*!
Remove all leading and trailing spaces from the input.
The input sequence is modified in-place.
\param Input An input sequence
\param Loc A locale used for 'space' classification
*/
template<typename SequenceT>
inline void trim(SequenceT& Input, const std::locale& Loc=std::locale())
{
::boost::algorithm::trim_if(
Input,
is_space( Loc ) );
}
} // namespace algorithm
// pull names to the boost namespace
using algorithm::trim_left;
using algorithm::trim_left_if;
using algorithm::trim_left_copy;
using algorithm::trim_left_copy_if;
using algorithm::trim_right;
using algorithm::trim_right_if;
using algorithm::trim_right_copy;
using algorithm::trim_right_copy_if;
using algorithm::trim;
using algorithm::trim_if;
using algorithm::trim_copy;
using algorithm::trim_copy_if;
} // namespace boost
#endif // BOOST_STRING_TRIM_HPP

View file

@ -24,6 +24,66 @@
namespace boost { namespace boost {
namespace asio { namespace asio {
#if defined(BOOST_ASIO_HAS_CONCEPTS) \
&& defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
&& defined(BOOST_ASIO_HAS_DECLTYPE)
namespace detail {
template <typename T>
struct is_completion_signature : false_type
{
};
template <typename R, typename... Args>
struct is_completion_signature<R(Args...)> : true_type
{
};
template <typename T, typename... Args>
BOOST_ASIO_CONCEPT callable_with = requires(T t, Args&&... args)
{
t(static_cast<Args&&>(args)...);
};
template <typename T, typename Signature>
struct is_completion_handler_for : false_type
{
};
template <typename T, typename R, typename... Args>
struct is_completion_handler_for<T, R(Args...)>
: integral_constant<bool, (callable_with<T, Args...>)>
{
};
} // namespace detail
template <typename T>
BOOST_ASIO_CONCEPT completion_signature =
detail::is_completion_signature<T>::value;
#define BOOST_ASIO_COMPLETION_SIGNATURE \
::boost::asio::completion_signature
template <typename T, completion_signature Signature>
BOOST_ASIO_CONCEPT completion_handler_for =
detail::is_completion_handler_for<T, Signature>::value;
#define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) \
::boost::asio::completion_handler_for<s>
#else // defined(BOOST_ASIO_HAS_CONCEPTS)
// && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// && defined(BOOST_ASIO_HAS_DECLTYPE)
#define BOOST_ASIO_COMPLETION_SIGNATURE typename
#define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) typename
#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
// && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// && defined(BOOST_ASIO_HAS_DECLTYPE)
/// An interface for customising the behaviour of an initiating function. /// An interface for customising the behaviour of an initiating function.
/** /**
* The async_result traits class is used for determining: * The async_result traits class is used for determining:
@ -42,7 +102,7 @@ namespace asio {
* The primary template assumes that the CompletionToken is the completion * The primary template assumes that the CompletionToken is the completion
* handler. * handler.
*/ */
template <typename CompletionToken, typename Signature> template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature>
class async_result class async_result
{ {
public: public:
@ -68,12 +128,21 @@ public:
{ {
} }
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \ #if defined(GENERATING_DOCUMENTATION)
|| defined(GENERATING_DOCUMENTATION)
/// Initiate the asynchronous operation that will produce the result, and /// Initiate the asynchronous operation that will produce the result, and
/// obtain the value to be returned from the initiating function. /// obtain the value to be returned from the initiating function.
template <typename Initiation, typename RawCompletionToken, typename... Args> template <typename Initiation, typename RawCompletionToken, typename... Args>
static return_type initiate(
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
BOOST_ASIO_MOVE_ARG(Args)... args);
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Initiation,
BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken,
typename... Args>
static return_type initiate( static return_type initiate(
BOOST_ASIO_MOVE_ARG(Initiation) initiation, BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
@ -85,9 +154,9 @@ public:
} }
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
template <typename Initiation, typename RawCompletionToken> template <typename Initiation,
BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken>
static return_type initiate( static return_type initiate(
BOOST_ASIO_MOVE_ARG(Initiation) initiation, BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token) BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
@ -97,7 +166,8 @@ public:
} }
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \ #define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, typename RawCompletionToken, \ template <typename Initiation, \
BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken, \
BOOST_ASIO_VARIADIC_TPARAMS(n)> \ BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate( \ static return_type initiate( \
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
@ -113,17 +183,26 @@ public:
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF #undef BOOST_ASIO_PRIVATE_INITIATE_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
private: private:
async_result(const async_result&) BOOST_ASIO_DELETED; async_result(const async_result&) BOOST_ASIO_DELETED;
async_result& operator=(const async_result&) BOOST_ASIO_DELETED; async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
}; };
#if !defined(GENERATING_DOCUMENTATION)
template <BOOST_ASIO_COMPLETION_SIGNATURE Signature>
class async_result<void, Signature>
{
// Empty.
};
#endif // !defined(GENERATING_DOCUMENTATION)
/// Helper template to deduce the handler type from a CompletionToken, capture /// Helper template to deduce the handler type from a CompletionToken, capture
/// a local copy of the handler, and then create an async_result for the /// a local copy of the handler, and then create an async_result for the
/// handler. /// handler.
template <typename CompletionToken, typename Signature> template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature>
struct async_completion struct async_completion
{ {
/// The real handler type to be used for the asynchronous operation. /// The real handler type to be used for the asynchronous operation.
@ -233,22 +312,50 @@ struct async_result_has_initiate_memfn
typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
#endif #endif
#if defined(GENERATION_DOCUMENTATION)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
auto
#elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
auto
#else
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
#endif
#if defined(GENERATION_DOCUMENTATION)
# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
void_or_deduced
#elif defined(BOOST_ASIO_HAS_DECLTYPE)
# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
decltype expr
#else
# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
#endif
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature, template <typename CompletionToken,
completion_signature Signature,
typename Initiation, typename... Args> typename Initiation, typename... Args>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) void_or_deduced async_initiate(
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken), BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
BOOST_ASIO_MOVE_ARG(Args)... args); BOOST_ASIO_MOVE_ARG(Args)... args);
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature, template <typename CompletionToken,
BOOST_ASIO_COMPLETION_SIGNATURE Signature,
typename Initiation, typename... Args> typename Initiation, typename... Args>
inline typename enable_if< inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
(async_result<typename decay<CompletionToken>::type,
Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(),
declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(),
declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
BOOST_ASIO_MOVE_ARG(Args)... args) BOOST_ASIO_MOVE_ARG(Args)... args)
@ -259,7 +366,8 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_CAST(Args)(args)...); BOOST_ASIO_MOVE_CAST(Args)(args)...);
} }
template <typename CompletionToken, typename Signature, template <typename CompletionToken,
BOOST_ASIO_COMPLETION_SIGNATURE Signature,
typename Initiation, typename... Args> typename Initiation, typename... Args>
inline typename enable_if< inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
@ -280,10 +388,15 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature, typename Initiation> template <typename CompletionToken,
BOOST_ASIO_COMPLETION_SIGNATURE Signature,
typename Initiation>
inline typename enable_if< inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
(async_result<typename decay<CompletionToken>::type,
Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(),
declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>())))>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{ {
@ -292,7 +405,9 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_CAST(CompletionToken)(token)); BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
} }
template <typename CompletionToken, typename Signature, typename Initiation> template <typename CompletionToken,
BOOST_ASIO_COMPLETION_SIGNATURE Signature,
typename Initiation>
inline typename enable_if< inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
@ -309,12 +424,17 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
} }
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \ #define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename CompletionToken, typename Signature, \ template <typename CompletionToken, \
BOOST_ASIO_COMPLETION_SIGNATURE Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \ inline typename enable_if< \
detail::async_result_has_initiate_memfn< \ detail::async_result_has_initiate_memfn< \
CompletionToken, Signature>::value, \ CompletionToken, Signature>::value, \
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \ BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, \
(async_result<typename decay<CompletionToken>::type, \
Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(), \
declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(), \
BOOST_ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
@ -325,7 +445,8 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \ } \
\ \
template <typename CompletionToken, typename Signature, \ template <typename CompletionToken, \
BOOST_ASIO_COMPLETION_SIGNATURE Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \ inline typename enable_if< \
!detail::async_result_has_initiate_memfn< \ !detail::async_result_has_initiate_memfn< \
@ -350,6 +471,114 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#if defined(BOOST_ASIO_HAS_CONCEPTS) \
&& defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
&& defined(BOOST_ASIO_HAS_DECLTYPE)
namespace detail {
template <typename Signature>
struct initiation_archetype
{
template <completion_handler_for<Signature> CompletionHandler>
void operator()(CompletionHandler&&) const
{
}
};
} // namespace detail
template <typename T, completion_signature Signature>
BOOST_ASIO_CONCEPT completion_token_for = requires(T&& t)
{
async_initiate<T, Signature>(detail::initiation_archetype<Signature>{}, t);
};
#define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) \
::boost::asio::completion_token_for<s>
#else // defined(BOOST_ASIO_HAS_CONCEPTS)
// && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// && defined(BOOST_ASIO_HAS_DECLTYPE)
#define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) typename
#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
// && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// && defined(BOOST_ASIO_HAS_DECLTYPE)
namespace detail {
template <typename>
struct default_completion_token_check
{
typedef void type;
};
template <typename T, typename = void>
struct default_completion_token_impl
{
typedef void type;
};
template <typename T>
struct default_completion_token_impl<T,
typename default_completion_token_check<
typename T::default_completion_token_type>::type>
{
typedef typename T::default_completion_token_type type;
};
} // namespace detail
#if defined(GENERATING_DOCUMENTATION)
/// Traits type used to determine the default completion token type associated
/// with a type (such as an executor).
/**
* A program may specialise this traits type if the @c T template parameter in
* the specialisation is a user-defined type.
*
* Specialisations of this trait may provide a nested typedef @c type, which is
* a default-constructible completion token type.
*/
template <typename T>
struct default_completion_token
{
/// If @c T has a nested type @c default_completion_token_type,
/// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type
/// is not defined.
typedef see_below type;
};
#else
template <typename T>
struct default_completion_token
: detail::default_completion_token_impl<T>
{
};
#endif
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
template <typename T>
using default_completion_token_t = typename default_completion_token<T>::type;
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
#if defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \
= typename ::boost::asio::default_completion_token<e>::type
#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e) \
= typename ::boost::asio::default_completion_token<e>::type()
#else // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e)
#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e)
#endif // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
} // namespace asio } // namespace asio
} // namespace boost } // namespace boost

View file

@ -249,7 +249,7 @@ public:
* constructed using the @c basic_datagram_socket(const executor_type&) * constructed using the @c basic_datagram_socket(const executor_type&)
* constructor. * constructor.
*/ */
basic_datagram_socket(basic_datagram_socket&& other) basic_datagram_socket(basic_datagram_socket&& other) BOOST_ASIO_NOEXCEPT
: basic_socket<Protocol, Executor>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -448,15 +448,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, initiate_async_send(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
@ -488,16 +492,20 @@ public:
* Use the async_send_to function to send data on an unconnected datagram * Use the async_send_to function to send data on an unconnected datagram
* socket. * socket.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags); initiate_async_send(this), handler, buffers, flags);
} }
/// Send a datagram to the specified endpoint. /// Send a datagram to the specified endpoint.
@ -625,16 +633,20 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send_to(const ConstBufferSequence& buffers, async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, initiate_async_send_to(this), handler, buffers,
destination, socket_base::message_flags(0)); destination, socket_base::message_flags(0));
} }
@ -665,16 +677,20 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send_to(const ConstBufferSequence& buffers, async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags); initiate_async_send_to(this), handler, buffers, destination, flags);
} }
/// Receive some data on a connected socket. /// Receive some data on a connected socket.
@ -802,15 +818,19 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, initiate_async_receive(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
@ -842,16 +862,20 @@ public:
* Use the async_receive_from function to receive data on an unconnected * Use the async_receive_from function to receive data on an unconnected
* datagram socket. * datagram socket.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags); initiate_async_receive(this), handler, buffers, flags);
} }
/// Receive a datagram with the endpoint of the sender. /// Receive a datagram with the endpoint of the sender.
@ -979,16 +1003,20 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive_from(const MutableBufferSequence& buffers, async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers, initiate_async_receive_from(this), handler, buffers,
&sender_endpoint, socket_base::message_flags(0)); &sender_endpoint, socket_base::message_flags(0));
} }
@ -1021,25 +1049,42 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive_from(const MutableBufferSequence& buffers, async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler, initiate_async_receive_from(this), handler,
this, buffers, &sender_endpoint, flags); buffers, &sender_endpoint, flags);
} }
private: private:
struct initiate_async_send class initiate_async_send
{ {
public:
typedef Executor executor_type;
explicit initiate_async_send(basic_datagram_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_datagram_socket* self, const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1047,18 +1092,33 @@ private:
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send( self_->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags, self_->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_datagram_socket* self_;
}; };
struct initiate_async_send_to class initiate_async_send_to
{ {
public:
typedef Executor executor_type;
explicit initiate_async_send_to(basic_datagram_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_datagram_socket* self, const ConstBufferSequence& buffers, const ConstBufferSequence& buffers, const endpoint_type& destination,
const endpoint_type& destination,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1066,17 +1126,33 @@ private:
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to( self_->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags, self_->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_datagram_socket* self_;
}; };
struct initiate_async_receive class initiate_async_receive
{ {
public:
typedef Executor executor_type;
explicit initiate_async_receive(basic_datagram_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_datagram_socket* self, const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1084,28 +1160,47 @@ private:
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive( self_->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags, self_->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_datagram_socket* self_;
}; };
struct initiate_async_receive_from class initiate_async_receive_from
{ {
public:
typedef Executor executor_type;
explicit initiate_async_receive_from(basic_datagram_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_datagram_socket* self, const MutableBufferSequence& buffers, const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,
endpoint_type* sender_endpoint, socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler. // does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from( self_->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags, self_->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_datagram_socket* self_;
}; };
}; };

View file

@ -133,6 +133,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the timer type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The timer type when rebound to the specified executor.
typedef basic_deadline_timer<Time, TimeTraits, Executor1> other;
};
/// The time traits type. /// The time traits type.
typedef TimeTraits traits_type; typedef TimeTraits traits_type;
@ -621,13 +629,17 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename WaitHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(
BOOST_ASIO_MOVE_ARG(WaitHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WaitHandler, void (boost::system::error_code)>( return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(), handler, this); initiate_async_wait(this), handler);
} }
private: private:
@ -636,21 +648,36 @@ private:
basic_deadline_timer& operator=( basic_deadline_timer& operator=(
const basic_deadline_timer&) BOOST_ASIO_DELETED; const basic_deadline_timer&) BOOST_ASIO_DELETED;
struct initiate_async_wait class initiate_async_wait
{ {
public:
typedef Executor executor_type;
explicit initiate_async_wait(basic_deadline_timer* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WaitHandler> template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) const
basic_deadline_timer* self) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler. // does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler); detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait( self_->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value, self_->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_deadline_timer* self_;
}; };
detail::io_object_impl< detail::io_object_impl<

View file

@ -247,7 +247,7 @@ public:
* constructed using the @c basic_raw_socket(const executor_type&) * constructed using the @c basic_raw_socket(const executor_type&)
* constructor. * constructor.
*/ */
basic_raw_socket(basic_raw_socket&& other) basic_raw_socket(basic_raw_socket&& other) BOOST_ASIO_NOEXCEPT
: basic_socket<Protocol, Executor>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -440,15 +440,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, initiate_async_send(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
@ -480,16 +484,20 @@ public:
* Use the async_send_to function to send data on an unconnected raw * Use the async_send_to function to send data on an unconnected raw
* socket. * socket.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags); initiate_async_send(this), handler, buffers, flags);
} }
/// Send raw data to the specified endpoint. /// Send raw data to the specified endpoint.
@ -617,16 +625,20 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send_to(const ConstBufferSequence& buffers, async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, initiate_async_send_to(this), handler, buffers,
destination, socket_base::message_flags(0)); destination, socket_base::message_flags(0));
} }
@ -657,16 +669,20 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send_to(const ConstBufferSequence& buffers, async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags); initiate_async_send_to(this), handler, buffers, destination, flags);
} }
/// Receive some data on a connected socket. /// Receive some data on a connected socket.
@ -794,15 +810,19 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, initiate_async_receive(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
@ -834,16 +854,20 @@ public:
* Use the async_receive_from function to receive data on an unconnected * Use the async_receive_from function to receive data on an unconnected
* raw socket. * raw socket.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags); initiate_async_receive(this), handler, buffers, flags);
} }
/// Receive raw data with the endpoint of the sender. /// Receive raw data with the endpoint of the sender.
@ -971,16 +995,20 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive_from(const MutableBufferSequence& buffers, async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers, initiate_async_receive_from(this), handler, buffers,
&sender_endpoint, socket_base::message_flags(0)); &sender_endpoint, socket_base::message_flags(0));
} }
@ -1013,25 +1041,42 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive_from(const MutableBufferSequence& buffers, async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler, initiate_async_receive_from(this), handler,
this, buffers, &sender_endpoint, flags); buffers, &sender_endpoint, flags);
} }
private: private:
struct initiate_async_send class initiate_async_send
{ {
public:
typedef Executor executor_type;
explicit initiate_async_send(basic_raw_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_raw_socket* self, const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1039,18 +1084,33 @@ private:
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send( self_->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags, self_->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_raw_socket* self_;
}; };
struct initiate_async_send_to class initiate_async_send_to
{ {
public:
typedef Executor executor_type;
explicit initiate_async_send_to(basic_raw_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_raw_socket* self, const ConstBufferSequence& buffers, const ConstBufferSequence& buffers, const endpoint_type& destination,
const endpoint_type& destination,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1058,17 +1118,33 @@ private:
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to( self_->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags, self_->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_raw_socket* self_;
}; };
struct initiate_async_receive class initiate_async_receive
{ {
public:
typedef Executor executor_type;
explicit initiate_async_receive(basic_raw_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_raw_socket* self, const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1076,28 +1152,47 @@ private:
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive( self_->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags, self_->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_raw_socket* self_;
}; };
struct initiate_async_receive_from class initiate_async_receive_from
{ {
public:
typedef Executor executor_type;
explicit initiate_async_receive_from(basic_raw_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_raw_socket* self, const MutableBufferSequence& buffers, const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,
endpoint_type* sender_endpoint, socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler. // does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from( self_->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags, self_->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_raw_socket* self_;
}; };
}; };

View file

@ -256,7 +256,7 @@ public:
* constructed using the @c basic_seq_packet_socket(const executor_type&) * constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor. * constructor.
*/ */
basic_seq_packet_socket(basic_seq_packet_socket&& other) basic_seq_packet_socket(basic_seq_packet_socket&& other) BOOST_ASIO_NOEXCEPT
: basic_socket<Protocol, Executor>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -429,16 +429,20 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags); initiate_async_send(this), handler, buffers, flags);
} }
/// Receive some data on the socket. /// Receive some data on the socket.
@ -598,16 +602,20 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags& out_flags, socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler, this, initiate_async_receive_with_flags(this), handler,
buffers, socket_base::message_flags(0), &out_flags); buffers, socket_base::message_flags(0), &out_flags);
} }
@ -653,26 +661,43 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags in_flags, socket_base::message_flags in_flags,
socket_base::message_flags& out_flags, socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler, initiate_async_receive_with_flags(this),
this, buffers, in_flags, &out_flags); handler, buffers, in_flags, &out_flags);
} }
private: private:
struct initiate_async_send class initiate_async_send
{ {
public:
typedef Executor executor_type;
explicit initiate_async_send(basic_seq_packet_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_seq_packet_socket* self, const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -680,17 +705,33 @@ private:
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send( self_->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags, self_->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_seq_packet_socket* self_;
}; };
struct initiate_async_receive_with_flags class initiate_async_receive_with_flags
{ {
public:
typedef Executor executor_type;
explicit initiate_async_receive_with_flags(basic_seq_packet_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_seq_packet_socket* self, const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
socket_base::message_flags in_flags, socket_base::message_flags in_flags,
socket_base::message_flags* out_flags) const socket_base::message_flags* out_flags) const
{ {
@ -699,10 +740,13 @@ private:
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_with_flags( self_->impl_.get_service().async_receive_with_flags(
self->impl_.get_implementation(), buffers, in_flags, *out_flags, self_->impl_.get_implementation(), buffers, in_flags, *out_flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_seq_packet_socket* self_;
}; };
}; };

View file

@ -64,6 +64,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the serial port type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The serial port type when rebound to the specified executor.
typedef basic_serial_port<Executor1> other;
};
/// The native representation of a serial port. /// The native representation of a serial port.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
@ -682,15 +690,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_write_some(), handler, this, buffers); initiate_async_write_some(this), handler, buffers);
} }
/// Read some data from the serial port. /// Read some data from the serial port.
@ -793,15 +805,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_read_some(), handler, this, buffers); initiate_async_read_some(this), handler, buffers);
} }
private: private:
@ -809,38 +825,70 @@ private:
basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED; basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED;
basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED; basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED;
struct initiate_async_write_some class initiate_async_write_some
{ {
public:
typedef Executor executor_type;
explicit initiate_async_write_some(basic_serial_port* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_serial_port* self, const ConstBufferSequence& buffers) const const ConstBufferSequence& buffers) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler. // does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_write_some( self_->impl_.get_service().async_write_some(
self->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_serial_port* self_;
}; };
struct initiate_async_read_some class initiate_async_read_some
{ {
public:
typedef Executor executor_type;
explicit initiate_async_read_some(basic_serial_port* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_serial_port* self, const MutableBufferSequence& buffers) const const MutableBufferSequence& buffers) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler. // does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_read_some( self_->impl_.get_service().async_read_some(
self->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_serial_port* self_;
}; };
#if defined(BOOST_ASIO_HAS_IOCP) #if defined(BOOST_ASIO_HAS_IOCP)

View file

@ -98,6 +98,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the signal set type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The signal set type when rebound to the specified executor.
typedef basic_signal_set<Executor1> other;
};
/// Construct a signal set without adding any signals. /// Construct a signal set without adding any signals.
/** /**
* This constructor creates a signal set without registering for any signals. * This constructor creates a signal set without registering for any signals.
@ -503,13 +511,17 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename SignalHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, int))
SignalHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(SignalHandler,
void (boost::system::error_code, int)) void (boost::system::error_code, int))
async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler) async_wait(
BOOST_ASIO_MOVE_ARG(SignalHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<SignalHandler, void (boost::system::error_code, int)>( return async_initiate<SignalHandler, void (boost::system::error_code, int)>(
initiate_async_wait(), handler, this); initiate_async_wait(this), handler);
} }
private: private:
@ -517,21 +529,36 @@ private:
basic_signal_set(const basic_signal_set&) BOOST_ASIO_DELETED; basic_signal_set(const basic_signal_set&) BOOST_ASIO_DELETED;
basic_signal_set& operator=(const basic_signal_set&) BOOST_ASIO_DELETED; basic_signal_set& operator=(const basic_signal_set&) BOOST_ASIO_DELETED;
struct initiate_async_wait class initiate_async_wait
{ {
public:
typedef Executor executor_type;
explicit initiate_async_wait(basic_signal_set* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename SignalHandler> template <typename SignalHandler>
void operator()(BOOST_ASIO_MOVE_ARG(SignalHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(SignalHandler) handler) const
basic_signal_set* self) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a SignalHandler. // does not meet the documented type requirements for a SignalHandler.
BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
detail::non_const_lvalue<SignalHandler> handler2(handler); detail::non_const_lvalue<SignalHandler> handler2(handler);
self->impl_.get_service().async_wait( self_->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value, self_->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_signal_set* self_;
}; };
detail::io_object_impl<detail::signal_set_service, Executor> impl_; detail::io_object_impl<detail::signal_set_service, Executor> impl_;

View file

@ -295,7 +295,7 @@ public:
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_socket(const executor_type&) constructor. * constructed using the @c basic_socket(const executor_type&) constructor.
*/ */
basic_socket(basic_socket&& other) basic_socket(basic_socket&& other) BOOST_ASIO_NOEXCEPT
: impl_(std::move(other.impl_)) : impl_(std::move(other.impl_))
{ {
} }
@ -940,11 +940,14 @@ public:
* socket.async_connect(endpoint, connect_handler); * socket.async_connect(endpoint, connect_handler);
* @endcode * @endcode
*/ */
template <typename ConnectHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
ConnectHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_connect(const endpoint_type& peer_endpoint, async_connect(const endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) BOOST_ASIO_MOVE_ARG(ConnectHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
boost::system::error_code open_ec; boost::system::error_code open_ec;
if (!is_open()) if (!is_open())
@ -954,7 +957,7 @@ public:
} }
return async_initiate<ConnectHandler, void (boost::system::error_code)>( return async_initiate<ConnectHandler, void (boost::system::error_code)>(
initiate_async_connect(), handler, this, peer_endpoint, open_ec); initiate_async_connect(this), handler, peer_endpoint, open_ec);
} }
/// Set an option on the socket. /// Set an option on the socket.
@ -1770,13 +1773,17 @@ public:
* socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
* @endcode * @endcode
*/ */
template <typename WaitHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(wait_type w,
BOOST_ASIO_MOVE_ARG(WaitHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WaitHandler, void (boost::system::error_code)>( return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(), handler, this, w); initiate_async_wait(this), handler, w);
} }
protected: protected:
@ -1805,11 +1812,24 @@ private:
basic_socket(const basic_socket&) BOOST_ASIO_DELETED; basic_socket(const basic_socket&) BOOST_ASIO_DELETED;
basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED; basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;
struct initiate_async_connect class initiate_async_connect
{ {
public:
typedef Executor executor_type;
explicit initiate_async_connect(basic_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ConnectHandler> template <typename ConnectHandler>
void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,
basic_socket* self, const endpoint_type& peer_endpoint, const endpoint_type& peer_endpoint,
const boost::system::error_code& open_ec) const const boost::system::error_code& open_ec) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1818,35 +1838,53 @@ private:
if (open_ec) if (open_ec)
{ {
boost::asio::post(self->impl_.get_executor(), boost::asio::post(self_->impl_.get_executor(),
boost::asio::detail::bind_handler( boost::asio::detail::bind_handler(
BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
} }
else else
{ {
detail::non_const_lvalue<ConnectHandler> handler2(handler); detail::non_const_lvalue<ConnectHandler> handler2(handler);
self->impl_.get_service().async_connect( self_->impl_.get_service().async_connect(
self->impl_.get_implementation(), peer_endpoint, self_->impl_.get_implementation(), peer_endpoint,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
} }
private:
basic_socket* self_;
}; };
struct initiate_async_wait class initiate_async_wait
{ {
public:
typedef Executor executor_type;
explicit initiate_async_wait(basic_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WaitHandler> template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
basic_socket* self, wait_type w) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler. // does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler); detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait( self_->impl_.get_service().async_wait(
self->impl_.get_implementation(), w, handler2.value, self_->impl_.get_implementation(), w, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_socket* self_;
}; };
}; };

View file

@ -81,6 +81,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the acceptor type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_socket_acceptor<Protocol, Executor1> other;
};
/// The native representation of an acceptor. /// The native representation of an acceptor.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
@ -1211,13 +1219,17 @@ public:
* wait_handler); * wait_handler);
* @endcode * @endcode
*/ */
template <typename WaitHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(wait_type w,
BOOST_ASIO_MOVE_ARG(WaitHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WaitHandler, void (boost::system::error_code)>( return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(), handler, this, w); initiate_async_wait(this), handler, w);
} }
#if !defined(BOOST_ASIO_NO_EXTENSIONS) #if !defined(BOOST_ASIO_NO_EXTENSIONS)
@ -1324,17 +1336,20 @@ public:
* acceptor.async_accept(socket, accept_handler); * acceptor.async_accept(socket, accept_handler);
* @endcode * @endcode
*/ */
template <typename Protocol1, typename Executor1, typename AcceptHandler> template <typename Protocol1, typename Executor1,
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
AcceptHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_accept(basic_socket<Protocol1, Executor1>& peer, async_accept(basic_socket<Protocol1, Executor1>& peer,
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
typename enable_if< typename enable_if<
is_convertible<Protocol, Protocol1>::value is_convertible<Protocol, Protocol1>::value
>::type* = 0) >::type* = 0)
{ {
return async_initiate<AcceptHandler, void (boost::system::error_code)>( return async_initiate<AcceptHandler, void (boost::system::error_code)>(
initiate_async_accept(), handler, this, initiate_async_accept(this), handler,
&peer, static_cast<endpoint_type*>(0)); &peer, static_cast<endpoint_type*>(0));
} }
@ -1434,14 +1449,18 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename Executor1, typename AcceptHandler> template <typename Executor1,
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
AcceptHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(AcceptHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_accept(basic_socket<protocol_type, Executor1>& peer, async_accept(basic_socket<protocol_type, Executor1>& peer,
endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<AcceptHandler, void (boost::system::error_code)>( return async_initiate<AcceptHandler, void (boost::system::error_code)>(
initiate_async_accept(), handler, this, &peer, &peer_endpoint); initiate_async_accept(this), handler, &peer, &peer_endpoint);
} }
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
@ -1466,10 +1485,12 @@ public:
* boost::asio::ip::tcp::socket socket(acceptor.accept()); * boost::asio::ip::tcp::socket socket(acceptor.accept());
* @endcode * @endcode
*/ */
typename Protocol::socket accept() typename Protocol::socket::template rebind_executor<executor_type>::other
accept()
{ {
boost::system::error_code ec; boost::system::error_code ec;
typename Protocol::socket peer(impl_.get_executor()); typename Protocol::socket::template rebind_executor<
executor_type>::other peer(impl_.get_executor());
impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
boost::asio::detail::throw_error(ec, "accept"); boost::asio::detail::throw_error(ec, "accept");
return peer; return peer;
@ -1500,9 +1521,11 @@ public:
* } * }
* @endcode * @endcode
*/ */
typename Protocol::socket accept(boost::system::error_code& ec) typename Protocol::socket::template rebind_executor<executor_type>::other
accept(boost::system::error_code& ec)
{ {
typename Protocol::socket peer(impl_.get_executor()); typename Protocol::socket::template rebind_executor<
executor_type>::other peer(impl_.get_executor());
impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
return peer; return peer;
} }
@ -1519,8 +1542,11 @@ public:
* completes. Copies will be made of the handler as required. The function * completes. Copies will be made of the handler as required. The function
* signature of the handler must be: * signature of the handler must be:
* @code void handler( * @code void handler(
* const boost::system::error_code& error, // Result of operation. * // Result of operation.
* typename Protocol::socket peer // On success, the newly accepted socket. * const boost::system::error_code& error,
* // On success, the newly accepted socket.
* typename Protocol::socket::template
* rebind_executor<executor_type>::other peer
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On * not, the handler will not be invoked from within this function. On
@ -1545,16 +1571,26 @@ public:
* acceptor.async_accept(accept_handler); * acceptor.async_accept(accept_handler);
* @endcode * @endcode
*/ */
template <typename MoveAcceptHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
void (boost::system::error_code, typename Protocol::socket)) typename Protocol::socket::template rebind_executor<
async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) executor_type>::other)) MoveAcceptHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
void (boost::system::error_code,
typename Protocol::socket::template
rebind_executor<executor_type>::other))
async_accept(
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<MoveAcceptHandler, return async_initiate<MoveAcceptHandler,
void (boost::system::error_code, typename Protocol::socket)>( void (boost::system::error_code, typename Protocol::socket::template
initiate_async_move_accept(), handler, this, rebind_executor<executor_type>::other)>(
initiate_async_move_accept(this), handler,
impl_.get_executor(), static_cast<endpoint_type*>(0), impl_.get_executor(), static_cast<endpoint_type*>(0),
static_cast<typename Protocol::socket*>(0)); static_cast<typename Protocol::socket::template
rebind_executor<executor_type>::other*>(0));
} }
/// Accept a new connection. /// Accept a new connection.
@ -1759,13 +1795,18 @@ public:
* acceptor.async_accept(my_context2, accept_handler); * acceptor.async_accept(my_context2, accept_handler);
* @endcode * @endcode
*/ */
template <typename Executor1, typename MoveAcceptHandler> template <typename Executor1,
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
typename Protocol::socket::template rebind_executor<
Executor1>::other)) MoveAcceptHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
void (boost::system::error_code, void (boost::system::error_code,
typename Protocol::socket::template rebind_executor< typename Protocol::socket::template rebind_executor<
Executor1>::other)) Executor1>::other))
async_accept(const Executor1& ex, async_accept(const Executor1& ex,
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
typename enable_if< typename enable_if<
is_executor<Executor1>::value is_executor<Executor1>::value
>::type* = 0) >::type* = 0)
@ -1775,7 +1816,7 @@ public:
return async_initiate<MoveAcceptHandler, return async_initiate<MoveAcceptHandler,
void (boost::system::error_code, other_socket_type)>( void (boost::system::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this, initiate_async_move_accept(this), handler,
ex, static_cast<endpoint_type*>(0), ex, static_cast<endpoint_type*>(0),
static_cast<other_socket_type*>(0)); static_cast<other_socket_type*>(0));
} }
@ -1823,13 +1864,18 @@ public:
* acceptor.async_accept(my_context2, accept_handler); * acceptor.async_accept(my_context2, accept_handler);
* @endcode * @endcode
*/ */
template <typename ExecutionContext, typename MoveAcceptHandler> template <typename ExecutionContext,
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
void (boost::system::error_code, void (boost::system::error_code,
typename Protocol::socket::template rebind_executor< typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other)) typename ExecutionContext::executor_type>::other))
async_accept(ExecutionContext& context, async_accept(ExecutionContext& context,
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
typename enable_if< typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0) >::type* = 0)
@ -1839,7 +1885,7 @@ public:
return async_initiate<MoveAcceptHandler, return async_initiate<MoveAcceptHandler,
void (boost::system::error_code, other_socket_type)>( void (boost::system::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this, initiate_async_move_accept(this), handler,
context.get_executor(), static_cast<endpoint_type*>(0), context.get_executor(), static_cast<endpoint_type*>(0),
static_cast<other_socket_type*>(0)); static_cast<other_socket_type*>(0));
} }
@ -1868,10 +1914,12 @@ public:
* boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
* @endcode * @endcode
*/ */
typename Protocol::socket accept(endpoint_type& peer_endpoint) typename Protocol::socket::template rebind_executor<executor_type>::other
accept(endpoint_type& peer_endpoint)
{ {
boost::system::error_code ec; boost::system::error_code ec;
typename Protocol::socket peer(impl_.get_executor()); typename Protocol::socket::template rebind_executor<
executor_type>::other peer(impl_.get_executor());
impl_.get_service().accept(impl_.get_implementation(), impl_.get_service().accept(impl_.get_implementation(),
peer, &peer_endpoint, ec); peer, &peer_endpoint, ec);
boost::asio::detail::throw_error(ec, "accept"); boost::asio::detail::throw_error(ec, "accept");
@ -1907,10 +1955,11 @@ public:
* } * }
* @endcode * @endcode
*/ */
typename Protocol::socket accept( typename Protocol::socket::template rebind_executor<executor_type>::other
endpoint_type& peer_endpoint, boost::system::error_code& ec) accept(endpoint_type& peer_endpoint, boost::system::error_code& ec)
{ {
typename Protocol::socket peer(impl_.get_executor()); typename Protocol::socket::template rebind_executor<
executor_type>::other peer(impl_.get_executor());
impl_.get_service().accept(impl_.get_implementation(), impl_.get_service().accept(impl_.get_implementation(),
peer, &peer_endpoint, ec); peer, &peer_endpoint, ec);
return peer; return peer;
@ -1933,8 +1982,11 @@ public:
* completes. Copies will be made of the handler as required. The function * completes. Copies will be made of the handler as required. The function
* signature of the handler must be: * signature of the handler must be:
* @code void handler( * @code void handler(
* const boost::system::error_code& error, // Result of operation. * // Result of operation.
* typename Protocol::socket peer // On success, the newly accepted socket. * const boost::system::error_code& error,
* // On success, the newly accepted socket.
* typename Protocol::socket::template
* rebind_executor<executor_type>::other peer
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On * not, the handler will not be invoked from within this function. On
@ -1960,17 +2012,26 @@ public:
* acceptor.async_accept(endpoint, accept_handler); * acceptor.async_accept(endpoint, accept_handler);
* @endcode * @endcode
*/ */
template <typename MoveAcceptHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
void (boost::system::error_code, typename Protocol::socket)) typename Protocol::socket::template rebind_executor<
executor_type>::other)) MoveAcceptHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
void (boost::system::error_code,
typename Protocol::socket::template
rebind_executor<executor_type>::other))
async_accept(endpoint_type& peer_endpoint, async_accept(endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<MoveAcceptHandler, return async_initiate<MoveAcceptHandler,
void (boost::system::error_code, typename Protocol::socket)>( void (boost::system::error_code, typename Protocol::socket::template
initiate_async_move_accept(), handler, this, rebind_executor<executor_type>::other)>(
initiate_async_move_accept(this), handler,
impl_.get_executor(), &peer_endpoint, impl_.get_executor(), &peer_endpoint,
static_cast<typename Protocol::socket*>(0)); static_cast<typename Protocol::socket::template
rebind_executor<executor_type>::other*>(0));
} }
/// Accept a new connection. /// Accept a new connection.
@ -2207,13 +2268,18 @@ public:
* acceptor.async_accept(my_context2, endpoint, accept_handler); * acceptor.async_accept(my_context2, endpoint, accept_handler);
* @endcode * @endcode
*/ */
template <typename Executor1, typename MoveAcceptHandler> template <typename Executor1,
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
typename Protocol::socket::template rebind_executor<
Executor1>::other)) MoveAcceptHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
void (boost::system::error_code, void (boost::system::error_code,
typename Protocol::socket::template rebind_executor< typename Protocol::socket::template rebind_executor<
Executor1>::other)) Executor1>::other))
async_accept(const Executor1& ex, endpoint_type& peer_endpoint, async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
typename enable_if< typename enable_if<
is_executor<Executor1>::value is_executor<Executor1>::value
>::type* = 0) >::type* = 0)
@ -2223,7 +2289,7 @@ public:
return async_initiate<MoveAcceptHandler, return async_initiate<MoveAcceptHandler,
void (boost::system::error_code, other_socket_type)>( void (boost::system::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this, initiate_async_move_accept(this), handler,
ex, &peer_endpoint, ex, &peer_endpoint,
static_cast<other_socket_type*>(0)); static_cast<other_socket_type*>(0));
} }
@ -2277,14 +2343,19 @@ public:
* acceptor.async_accept(my_context2, endpoint, accept_handler); * acceptor.async_accept(my_context2, endpoint, accept_handler);
* @endcode * @endcode
*/ */
template <typename ExecutionContext, typename MoveAcceptHandler> template <typename ExecutionContext,
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other)) MoveAcceptHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(MoveAcceptHandler,
void (boost::system::error_code, void (boost::system::error_code,
typename Protocol::socket::template rebind_executor< typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other)) typename ExecutionContext::executor_type>::other))
async_accept(ExecutionContext& context, async_accept(ExecutionContext& context,
endpoint_type& peer_endpoint, endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
typename enable_if< typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0) >::type* = 0)
@ -2294,7 +2365,7 @@ public:
return async_initiate<MoveAcceptHandler, return async_initiate<MoveAcceptHandler,
void (boost::system::error_code, other_socket_type)>( void (boost::system::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this, initiate_async_move_accept(this), handler,
context.get_executor(), &peer_endpoint, context.get_executor(), &peer_endpoint,
static_cast<other_socket_type*>(0)); static_cast<other_socket_type*>(0));
} }
@ -2306,28 +2377,56 @@ private:
basic_socket_acceptor& operator=( basic_socket_acceptor& operator=(
const basic_socket_acceptor&) BOOST_ASIO_DELETED; const basic_socket_acceptor&) BOOST_ASIO_DELETED;
struct initiate_async_wait class initiate_async_wait
{ {
public:
typedef Executor executor_type;
explicit initiate_async_wait(basic_socket_acceptor* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WaitHandler> template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
basic_socket_acceptor* self, wait_type w) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler. // does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler); detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait( self_->impl_.get_service().async_wait(
self->impl_.get_implementation(), w, handler2.value, self_->impl_.get_implementation(), w, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_socket_acceptor* self_;
}; };
struct initiate_async_accept class initiate_async_accept
{ {
public:
typedef Executor executor_type;
explicit initiate_async_accept(basic_socket_acceptor* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename AcceptHandler, typename Protocol1, typename Executor1> template <typename AcceptHandler, typename Protocol1, typename Executor1>
void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
basic_socket_acceptor* self, basic_socket<Protocol1, Executor1>* peer, basic_socket<Protocol1, Executor1>* peer,
endpoint_type* peer_endpoint) const endpoint_type* peer_endpoint) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -2335,18 +2434,33 @@ private:
BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
detail::non_const_lvalue<AcceptHandler> handler2(handler); detail::non_const_lvalue<AcceptHandler> handler2(handler);
self->impl_.get_service().async_accept( self_->impl_.get_service().async_accept(
self->impl_.get_implementation(), *peer, peer_endpoint, self_->impl_.get_implementation(), *peer, peer_endpoint,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_socket_acceptor* self_;
}; };
struct initiate_async_move_accept class initiate_async_move_accept
{ {
public:
typedef Executor executor_type;
explicit initiate_async_move_accept(basic_socket_acceptor* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename MoveAcceptHandler, typename Executor1, typename Socket> template <typename MoveAcceptHandler, typename Executor1, typename Socket>
void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
basic_socket_acceptor* self, const Executor1& peer_ex, const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const
endpoint_type* peer_endpoint, Socket*) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a MoveAcceptHandler. // does not meet the documented type requirements for a MoveAcceptHandler.
@ -2354,10 +2468,13 @@ private:
MoveAcceptHandler, handler, Socket) type_check; MoveAcceptHandler, handler, Socket) type_check;
detail::non_const_lvalue<MoveAcceptHandler> handler2(handler); detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
self->impl_.get_service().async_move_accept( self_->impl_.get_service().async_move_accept(
self->impl_.get_implementation(), peer_ex, peer_endpoint, self_->impl_.get_implementation(), peer_ex, peer_endpoint,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_socket_acceptor* self_;
}; };
#if defined(BOOST_ASIO_WINDOWS_RUNTIME) #if defined(BOOST_ASIO_WINDOWS_RUNTIME)

View file

@ -254,7 +254,7 @@ public:
* constructed using the @c basic_stream_socket(const executor_type&) * constructed using the @c basic_stream_socket(const executor_type&)
* constructor. * constructor.
*/ */
basic_stream_socket(basic_stream_socket&& other) basic_stream_socket(basic_stream_socket&& other) BOOST_ASIO_NOEXCEPT
: basic_socket<Protocol, Executor>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -464,15 +464,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, initiate_async_send(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
@ -513,16 +517,20 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags); initiate_async_send(this), handler, buffers, flags);
} }
/// Receive some data on the socket. /// Receive some data on the socket.
@ -667,15 +675,19 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, initiate_async_receive(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
@ -718,16 +730,20 @@ public:
* multiple buffers in one go, and how to use it with arrays, boost::array or * multiple buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags); initiate_async_receive(this), handler, buffers, flags);
} }
/// Write some data to the socket. /// Write some data to the socket.
@ -826,15 +842,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, initiate_async_send(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
@ -937,24 +957,41 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, initiate_async_receive(this), handler,
buffers, socket_base::message_flags(0)); buffers, socket_base::message_flags(0));
} }
private: private:
struct initiate_async_send class initiate_async_send
{ {
public:
typedef Executor executor_type;
explicit initiate_async_send(basic_stream_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_stream_socket* self, const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -962,17 +999,33 @@ private:
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send( self_->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags, self_->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_stream_socket* self_;
}; };
struct initiate_async_receive class initiate_async_receive
{ {
public:
typedef Executor executor_type;
explicit initiate_async_receive(basic_stream_socket* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_stream_socket* self, const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const socket_base::message_flags flags) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -980,10 +1033,13 @@ private:
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive( self_->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags, self_->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor()); handler2.value, self_->impl_.get_implementation_executor());
} }
private:
basic_stream_socket* self_;
}; };
}; };

View file

@ -146,6 +146,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the timer type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The timer type when rebound to the specified executor.
typedef basic_waitable_timer<Clock, WaitTraits, Executor1> other;
};
/// The clock type. /// The clock type.
typedef Clock clock_type; typedef Clock clock_type;
@ -692,13 +700,17 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename WaitHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(
BOOST_ASIO_MOVE_ARG(WaitHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WaitHandler, void (boost::system::error_code)>( return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(), handler, this); initiate_async_wait(this), handler);
} }
private: private:
@ -707,21 +719,36 @@ private:
basic_waitable_timer& operator=( basic_waitable_timer& operator=(
const basic_waitable_timer&) BOOST_ASIO_DELETED; const basic_waitable_timer&) BOOST_ASIO_DELETED;
struct initiate_async_wait class initiate_async_wait
{ {
public:
typedef Executor executor_type;
explicit initiate_async_wait(basic_waitable_timer* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WaitHandler> template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) const
basic_waitable_timer* self) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler. // does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler); detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait( self_->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value, self_->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_waitable_timer* self_;
}; };
detail::io_object_impl< detail::io_object_impl<

View file

@ -137,11 +137,15 @@ public:
/// Start an asynchronous write. The data being written must be valid for the /// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation. /// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return next_layer_.async_write_some(buffers, return next_layer_.async_write_some(buffers,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
@ -156,10 +160,15 @@ public:
std::size_t fill(boost::system::error_code& ec); std::size_t fill(boost::system::error_code& ec);
/// Start an asynchronous fill. /// Start an asynchronous fill.
template <typename ReadHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_fill(BOOST_ASIO_MOVE_ARG(ReadHandler) handler); async_fill(
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type));
/// Read some data from the stream. Returns the number of bytes read. Throws /// Read some data from the stream. Returns the number of bytes read. Throws
/// an exception on failure. /// an exception on failure.
@ -174,11 +183,15 @@ public:
/// Start an asynchronous read. The buffer into which the data will be read /// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation. /// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type));
/// Peek at the incoming data on the stream. Returns the number of bytes read. /// Peek at the incoming data on the stream. Returns the number of bytes read.
/// Throws an exception on failure. /// Throws an exception on failure.

View file

@ -126,10 +126,15 @@ public:
} }
/// Start an asynchronous flush. /// Start an asynchronous flush.
template <typename WriteHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_flush(BOOST_ASIO_MOVE_ARG(WriteHandler) handler) async_flush(
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return stream_impl_.next_layer().async_flush( return stream_impl_.next_layer().async_flush(
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
@ -154,11 +159,15 @@ public:
/// Start an asynchronous write. The data being written must be valid for the /// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation. /// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return stream_impl_.async_write_some(buffers, return stream_impl_.async_write_some(buffers,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
@ -179,10 +188,15 @@ public:
} }
/// Start an asynchronous fill. /// Start an asynchronous fill.
template <typename ReadHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_fill(BOOST_ASIO_MOVE_ARG(ReadHandler) handler) async_fill(
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return stream_impl_.async_fill(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); return stream_impl_.async_fill(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
@ -206,11 +220,15 @@ public:
/// Start an asynchronous read. The buffer into which the data will be read /// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation. /// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return stream_impl_.async_read_some(buffers, return stream_impl_.async_read_some(buffers,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));

View file

@ -129,10 +129,15 @@ public:
std::size_t flush(boost::system::error_code& ec); std::size_t flush(boost::system::error_code& ec);
/// Start an asynchronous flush. /// Start an asynchronous flush.
template <typename WriteHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_flush(BOOST_ASIO_MOVE_ARG(WriteHandler) handler); async_flush(
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type));
/// Write the given data to the stream. Returns the number of bytes written. /// Write the given data to the stream. Returns the number of bytes written.
/// Throws an exception on failure. /// Throws an exception on failure.
@ -147,11 +152,15 @@ public:
/// Start an asynchronous write. The data being written must be valid for the /// Start an asynchronous write. The data being written must be valid for the
/// lifetime of the asynchronous operation. /// lifetime of the asynchronous operation.
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler); BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type));
/// Read some data from the stream. Returns the number of bytes read. Throws /// Read some data from the stream. Returns the number of bytes read. Throws
/// an exception on failure. /// an exception on failure.
@ -172,11 +181,15 @@ public:
/// Start an asynchronous read. The buffer into which the data will be read /// Start an asynchronous read. The buffer into which the data will be read
/// must be valid for the lifetime of the asynchronous operation. /// must be valid for the lifetime of the asynchronous operation.
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return next_layer_.async_read_some(buffers, return next_layer_.async_read_some(buffers,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));

View file

@ -54,10 +54,15 @@ struct awaitable_signature<awaitable<void, Executor>>
* *
* where @c E is convertible from @c Executor. * where @c E is convertible from @c Executor.
*/ */
template <typename Executor, typename F, typename CompletionToken> template <typename Executor, typename F,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
typename result_of<F()>::type>::type) CompletionToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type) typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(const Executor& ex, F&& f, CompletionToken&& token, co_spawn(const Executor& ex, F&& f,
CompletionToken&& token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if< typename enable_if<
is_executor<Executor>::value is_executor<Executor>::value
>::type* = 0); >::type* = 0);
@ -70,10 +75,17 @@ co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
* *
* where @c E is convertible from @c ExecutionContext::executor_type. * where @c E is convertible from @c ExecutionContext::executor_type.
*/ */
template <typename ExecutionContext, typename F, typename CompletionToken> template <typename ExecutionContext, typename F,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
typename result_of<F()>::type>::type) CompletionToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename ExecutionContext::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type) typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token, co_spawn(ExecutionContext& ctx, F&& f,
CompletionToken&& token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename ExecutionContext::executor_type),
typename enable_if< typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0); >::type* = 0);

View file

@ -101,7 +101,7 @@ namespace asio {
*/ */
template <typename CompletionToken, typename Signature, template <typename CompletionToken, typename Signature,
typename Implementation, typename... IoObjectsOrExecutors> typename Implementation, typename... IoObjectsOrExecutors>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors); BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors);
@ -110,14 +110,14 @@ async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
// || defined(GENERATING_DOCUMENTATION) // || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature, typename Implementation> template <typename CompletionToken, typename Signature, typename Implementation>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token); BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token);
#define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \ #define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
template <typename CompletionToken, typename Signature, \ template <typename CompletionToken, typename Signature, \
typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) \ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) \
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \ async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)); BOOST_ASIO_VARIADIC_MOVE_PARAMS(n));

View file

@ -666,13 +666,16 @@ Iterator connect(basic_socket<Protocol, Executor>& s,
* // ... * // ...
* } @endcode * } @endcode
*/ */
template <typename Protocol, typename Executor, template <typename Protocol, typename Executor, typename EndpointSequence,
typename EndpointSequence, typename RangeConnectHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, typename Protocol::endpoint)) RangeConnectHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)) void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol, Executor>& s, async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, const EndpointSequence& endpoints,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler, BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
@ -712,12 +715,15 @@ async_connect(basic_socket<Protocol, Executor>& s,
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol, typename Executor, template <typename Protocol, typename Executor, typename Iterator,
typename Iterator, typename IteratorConnectHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, Iterator)) IteratorConnectHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -770,12 +776,15 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
* // ... * // ...
* } @endcode * } @endcode
*/ */
template <typename Protocol, typename Executor, template <typename Protocol, typename Executor, typename Iterator,
typename Iterator, typename IteratorConnectHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, Iterator)) IteratorConnectHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler); BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor));
/// Asynchronously establishes a socket connection by trying each endpoint in a /// Asynchronously establishes a socket connection by trying each endpoint in a
/// sequence. /// sequence.
@ -872,13 +881,17 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
* } * }
* } @endcode * } @endcode
*/ */
template <typename Protocol, typename Executor, typename EndpointSequence, template <typename Protocol, typename Executor,
typename ConnectCondition, typename RangeConnectHandler> typename EndpointSequence, typename ConnectCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
typename Protocol::endpoint)) RangeConnectHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)) void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol, Executor>& s, async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition, const EndpointSequence& endpoints, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler, BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
@ -929,13 +942,17 @@ async_connect(basic_socket<Protocol, Executor>& s,
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol, typename Executor, typename Iterator, template <typename Protocol, typename Executor,
typename ConnectCondition, typename IteratorConnectHandler> typename Iterator, typename ConnectCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
Iterator)) IteratorConnectHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -1037,13 +1054,17 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
* } * }
* } @endcode * } @endcode
*/ */
template <typename Protocol, typename Executor, typename Iterator, template <typename Protocol, typename Executor,
typename ConnectCondition, typename IteratorConnectHandler> typename Iterator, typename ConnectCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
Iterator)) IteratorConnectHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition, Iterator end, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler); BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor));
/*@}*/ /*@}*/

View file

@ -55,8 +55,8 @@ namespace asio {
* *
* @li Returns <tt>result.get()</tt>. * @li Returns <tt>result.get()</tt>.
*/ */
template <typename CompletionToken> template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
BOOST_ASIO_MOVE_ARG(CompletionToken) token); BOOST_ASIO_MOVE_ARG(CompletionToken) token);
/// Submits a completion token or function object for execution. /// Submits a completion token or function object for execution.
@ -94,18 +94,28 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
* *
* @li Returns <tt>result.get()</tt>. * @li Returns <tt>result.get()</tt>.
*/ */
template <typename Executor, typename CompletionToken> template <typename Executor,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token, BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
const Executor& ex,
BOOST_ASIO_MOVE_ARG(CompletionToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if<is_executor<Executor>::value>::type* = 0); typename enable_if<is_executor<Executor>::value>::type* = 0);
/// Submits a completion token or function object for execution. /// Submits a completion token or function object for execution.
/** /**
* @returns <tt>defer(ctx.get_executor(), forward<CompletionToken>(token))</tt>. * @returns <tt>defer(ctx.get_executor(), forward<CompletionToken>(token))</tt>.
*/ */
template <typename ExecutionContext, typename CompletionToken> template <typename ExecutionContext,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token, BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename ExecutionContext::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
ExecutionContext& ctx,
BOOST_ASIO_MOVE_ARG(CompletionToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename ExecutionContext::executor_type),
typename enable_if<is_convertible< typename enable_if<is_convertible<
ExecutionContext&, execution_context&>::value>::type* = 0); ExecutionContext&, execution_context&>::value>::type* = 0);

View file

@ -314,6 +314,42 @@
# endif // !defined(BOOST_ASIO_DISABLE_ALIAS_TEMPLATES) # endif // !defined(BOOST_ASIO_DISABLE_ALIAS_TEMPLATES)
#endif // !defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) #endif // !defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
// Support return type deduction on compilers known to allow it.
#if !defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
# if !defined(BOOST_ASIO_DISABLE_RETURN_TYPE_DEDUCTION)
# if defined(__clang__)
# if __has_feature(__cxx_return_type_deduction__)
# define BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION 1
# endif // __has_feature(__cxx_alias_templates__)
# elif (__cplusplus >= 201402)
# define BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION 1
# elif defined(__cpp_return_type_deduction)
# if (__cpp_return_type_deduction >= 201304)
# define BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION 1
# endif // (__cpp_return_type_deduction >= 201304)
# endif // defined(__cpp_return_type_deduction)
# endif // !defined(BOOST_ASIO_DISABLE_RETURN_TYPE_DEDUCTION)
#endif // !defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
// Support default function template arguments on compilers known to allow it.
#if !defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
# if !defined(BOOST_ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
# if (__cplusplus >= 201103)
# define BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1
# endif // (__cplusplus >= 201103)
# endif // !defined(BOOST_ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
#endif // !defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
// Support concepts on compilers known to allow them.
#if !defined(BOOST_ASIO_HAS_CONCEPTS)
# if !defined(BOOST_ASIO_DISABLE_CONCEPTS)
# if __cpp_concepts
# define BOOST_ASIO_HAS_CONCEPTS 1
# define BOOST_ASIO_CONCEPT concept bool
# endif // __cpp_concepts
# endif // !defined(BOOST_ASIO_DISABLE_CONCEPTS)
#endif // !defined(BOOST_ASIO_HAS_CONCEPTS)
// Standard library support for system errors. // Standard library support for system errors.
# if !defined(BOOST_ASIO_DISABLE_STD_SYSTEM_ERROR) # if !defined(BOOST_ASIO_DISABLE_STD_SYSTEM_ERROR)
# if defined(__clang__) # if defined(__clang__)

View file

@ -49,6 +49,7 @@ void reactive_socket_service_base::construct(
void reactive_socket_service_base::base_move_construct( void reactive_socket_service_base::base_move_construct(
reactive_socket_service_base::base_implementation_type& impl, reactive_socket_service_base::base_implementation_type& impl,
reactive_socket_service_base::base_implementation_type& other_impl) reactive_socket_service_base::base_implementation_type& other_impl)
BOOST_ASIO_NOEXCEPT
{ {
impl.socket_ = other_impl.socket_; impl.socket_ = other_impl.socket_;
other_impl.socket_ = invalid_socket; other_impl.socket_ = invalid_socket;

View file

@ -84,7 +84,7 @@ boost::system::error_code win_iocp_serial_port_service::open(
dcb.fBinary = TRUE; // Win32 only supports binary mode. dcb.fBinary = TRUE; // Win32 only supports binary mode.
dcb.fNull = FALSE; // Do not ignore NULL characters. dcb.fNull = FALSE; // Do not ignore NULL characters.
dcb.fAbortOnError = FALSE; // Ignore serial framing errors. dcb.fAbortOnError = FALSE; // Ignore serial framing errors.
dcb.BaudRate = 0; // 0 baud by default dcb.BaudRate = CBR_9600; // 9600 baud by default
dcb.ByteSize = 8; // 8 bit bytes dcb.ByteSize = 8; // 8 bit bytes
dcb.fOutxCtsFlow = FALSE; // No flow control dcb.fOutxCtsFlow = FALSE; // No flow control
dcb.fOutxDsrFlow = FALSE; dcb.fOutxDsrFlow = FALSE;
@ -92,7 +92,7 @@ boost::system::error_code win_iocp_serial_port_service::open(
dcb.fDsrSensitivity = FALSE; dcb.fDsrSensitivity = FALSE;
dcb.fOutX = FALSE; dcb.fOutX = FALSE;
dcb.fInX = FALSE; dcb.fInX = FALSE;
dcb.fRtsControl = DTR_CONTROL_DISABLE; dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fParity = FALSE; // No parity dcb.fParity = FALSE; // No parity
dcb.Parity = NOPARITY; dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT; // One stop bit dcb.StopBits = ONESTOPBIT; // One stop bit

View file

@ -73,6 +73,7 @@ void win_iocp_socket_service_base::construct(
void win_iocp_socket_service_base::base_move_construct( void win_iocp_socket_service_base::base_move_construct(
win_iocp_socket_service_base::base_implementation_type& impl, win_iocp_socket_service_base::base_implementation_type& impl,
win_iocp_socket_service_base::base_implementation_type& other_impl) win_iocp_socket_service_base::base_implementation_type& other_impl)
BOOST_ASIO_NOEXCEPT
{ {
impl.socket_ = other_impl.socket_; impl.socket_ = other_impl.socket_;
other_impl.socket_ = invalid_socket; other_impl.socket_ = invalid_socket;

View file

@ -89,7 +89,7 @@ public:
// Move-construct a new socket implementation. // Move-construct a new socket implementation.
void move_construct(implementation_type& impl, void move_construct(implementation_type& impl,
implementation_type& other_impl) implementation_type& other_impl) BOOST_ASIO_NOEXCEPT
{ {
this->base_move_construct(impl, other_impl); this->base_move_construct(impl, other_impl);

View file

@ -73,7 +73,7 @@ public:
// Move-construct a new socket implementation. // Move-construct a new socket implementation.
BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl,
base_implementation_type& other_impl); base_implementation_type& other_impl) BOOST_ASIO_NOEXCEPT;
// Move-assign from another socket implementation. // Move-assign from another socket implementation.
BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl,

View file

@ -32,6 +32,7 @@
# include <boost/type_traits/is_same.hpp> # include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/remove_pointer.hpp> # include <boost/type_traits/remove_pointer.hpp>
# include <boost/type_traits/remove_reference.hpp> # include <boost/type_traits/remove_reference.hpp>
# include <boost/utility/declval.hpp>
# include <boost/utility/enable_if.hpp> # include <boost/utility/enable_if.hpp>
# include <boost/utility/result_of.hpp> # include <boost/utility/result_of.hpp>
#endif // defined(BOOST_ASIO_HAS_TYPE_TRAITS) #endif // defined(BOOST_ASIO_HAS_TYPE_TRAITS)
@ -43,6 +44,7 @@ namespace asio {
using std::add_const; using std::add_const;
using std::conditional; using std::conditional;
using std::decay; using std::decay;
using std::declval;
using std::enable_if; using std::enable_if;
using std::false_type; using std::false_type;
using std::integral_constant; using std::integral_constant;
@ -68,6 +70,7 @@ template <bool Condition, typename Type = void>
struct enable_if : boost::enable_if_c<Condition, Type> {}; struct enable_if : boost::enable_if_c<Condition, Type> {};
using boost::conditional; using boost::conditional;
using boost::decay; using boost::decay;
using boost::declval;
using boost::false_type; using boost::false_type;
using boost::integral_constant; using boost::integral_constant;
using boost::is_base_of; using boost::is_base_of;

View file

@ -108,6 +108,24 @@
BOOST_ASIO_MOVE_CAST(T3)(x3), BOOST_ASIO_MOVE_CAST(T4)(x4), \ BOOST_ASIO_MOVE_CAST(T3)(x3), BOOST_ASIO_MOVE_CAST(T4)(x4), \
BOOST_ASIO_MOVE_CAST(T5)(x5) BOOST_ASIO_MOVE_CAST(T5)(x5)
# define BOOST_ASIO_VARIADIC_MOVE_DECLVAL(n) \
BOOST_ASIO_VARIADIC_MOVE_DECLVAL_##n
# define BOOST_ASIO_VARIADIC_MOVE_DECLVAL_1 \
declval<BOOST_ASIO_MOVE_ARG(T1)>()
# define BOOST_ASIO_VARIADIC_MOVE_DECLVAL_2 \
declval<BOOST_ASIO_MOVE_ARG(T1)>(), declval<BOOST_ASIO_MOVE_ARG(T2)>()
# define BOOST_ASIO_VARIADIC_MOVE_DECLVAL_3 \
declval<BOOST_ASIO_MOVE_ARG(T1)>(), declval<BOOST_ASIO_MOVE_ARG(T2)>(), \
declval<BOOST_ASIO_MOVE_ARG(T3)>()
# define BOOST_ASIO_VARIADIC_MOVE_DECLVAL_4 \
declval<BOOST_ASIO_MOVE_ARG(T1)>(), declval<BOOST_ASIO_MOVE_ARG(T2)>(), \
declval<BOOST_ASIO_MOVE_ARG(T3)>(), declval<BOOST_ASIO_MOVE_ARG(T4)>()
# define BOOST_ASIO_VARIADIC_MOVE_DECLVAL_5 \
declval<BOOST_ASIO_MOVE_ARG(T1)>(), declval<BOOST_ASIO_MOVE_ARG(T2)>(), \
declval<BOOST_ASIO_MOVE_ARG(T3)>(), declval<BOOST_ASIO_MOVE_ARG(T4)>(), \
declval<BOOST_ASIO_MOVE_ARG(T5)>()
# define BOOST_ASIO_VARIADIC_DECAY(n) \ # define BOOST_ASIO_VARIADIC_DECAY(n) \
BOOST_ASIO_VARIADIC_DECAY_##n BOOST_ASIO_VARIADIC_DECAY_##n

View file

@ -100,6 +100,7 @@ public:
if (ec == boost::asio::error::connection_aborted if (ec == boost::asio::error::connection_aborted
&& !o->enable_connection_aborted_) && !o->enable_connection_aborted_)
{ {
handler_work<Handler, IoExecutor>::start(o->handler_, o->io_executor_);
o->reset(); o->reset();
o->socket_service_.restart_accept_op(o->socket_, o->socket_service_.restart_accept_op(o->socket_,
o->new_socket_, o->protocol_.family(), o->new_socket_, o->protocol_.family(),
@ -229,6 +230,7 @@ public:
if (ec == boost::asio::error::connection_aborted if (ec == boost::asio::error::connection_aborted
&& !o->enable_connection_aborted_) && !o->enable_connection_aborted_)
{ {
handler_work<Handler, IoExecutor>::start(o->handler_, o->io_executor_);
o->reset(); o->reset();
o->socket_service_.restart_accept_op(o->socket_, o->socket_service_.restart_accept_op(o->socket_,
o->new_socket_, o->protocol_.family(), o->new_socket_, o->protocol_.family(),

View file

@ -145,7 +145,7 @@ public:
// Move-construct a new socket implementation. // Move-construct a new socket implementation.
void move_construct(implementation_type& impl, void move_construct(implementation_type& impl,
implementation_type& other_impl) implementation_type& other_impl) BOOST_ASIO_NOEXCEPT
{ {
this->base_move_construct(impl, other_impl); this->base_move_construct(impl, other_impl);

View file

@ -96,7 +96,7 @@ public:
// Move-construct a new socket implementation. // Move-construct a new socket implementation.
BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl,
base_implementation_type& other_impl); base_implementation_type& other_impl) BOOST_ASIO_NOEXCEPT;
// Move-assign from another socket implementation. // Move-assign from another socket implementation.
BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl,

View file

@ -50,8 +50,8 @@ namespace asio {
* *
* @li Returns <tt>result.get()</tt>. * @li Returns <tt>result.get()</tt>.
*/ */
template <typename CompletionToken> template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
BOOST_ASIO_MOVE_ARG(CompletionToken) token); BOOST_ASIO_MOVE_ARG(CompletionToken) token);
/// Submits a completion token or function object for execution. /// Submits a completion token or function object for execution.
@ -84,9 +84,13 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
* *
* @li Returns <tt>result.get()</tt>. * @li Returns <tt>result.get()</tt>.
*/ */
template <typename Executor, typename CompletionToken> template <typename Executor,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token, BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
const Executor& ex,
BOOST_ASIO_MOVE_ARG(CompletionToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if<is_executor<Executor>::value>::type* = 0); typename enable_if<is_executor<Executor>::value>::type* = 0);
/// Submits a completion token or function object for execution. /// Submits a completion token or function object for execution.
@ -94,9 +98,15 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
* @returns <tt>dispatch(ctx.get_executor(), * @returns <tt>dispatch(ctx.get_executor(),
* forward<CompletionToken>(token))</tt>. * forward<CompletionToken>(token))</tt>.
*/ */
template <typename ExecutionContext, typename CompletionToken> template <typename ExecutionContext,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token, BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename ExecutionContext::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
ExecutionContext& ctx,
BOOST_ASIO_MOVE_ARG(CompletionToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename ExecutionContext::executor_type),
typename enable_if<is_convertible< typename enable_if<is_convertible<
ExecutionContext&, execution_context&>::value>::type* = 0); ExecutionContext&, execution_context&>::value>::type* = 0);

View file

@ -55,7 +55,7 @@ public:
#endif #endif
/// Default constructor. /// Default constructor.
basic_endpoint() basic_endpoint() BOOST_ASIO_NOEXCEPT
{ {
} }

View file

@ -74,19 +74,19 @@ public:
} }
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(SOCK_DGRAM); return BOOST_ASIO_OS_DEF(SOCK_DGRAM);
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return protocol_; return protocol_;
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return family_; return family_;
} }

View file

@ -74,19 +74,19 @@ public:
} }
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(SOCK_RAW); return BOOST_ASIO_OS_DEF(SOCK_RAW);
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return protocol_; return protocol_;
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return family_; return family_;
} }

View file

@ -73,19 +73,19 @@ public:
} }
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(SOCK_SEQPACKET); return BOOST_ASIO_OS_DEF(SOCK_SEQPACKET);
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return protocol_; return protocol_;
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return family_; return family_;
} }

View file

@ -75,19 +75,19 @@ public:
} }
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(SOCK_STREAM); return BOOST_ASIO_OS_DEF(SOCK_STREAM);
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return protocol_; return protocol_;
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return family_; return family_;
} }

View file

@ -22,6 +22,7 @@
#include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp> #include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@ -140,11 +141,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_buffered_fill template <typename Stream>
class initiate_async_buffered_fill
{ {
template <typename ReadHandler, typename Stream> public:
typedef typename remove_reference<
Stream>::type::lowest_layer_type::executor_type executor_type;
explicit initiate_async_buffered_fill(Stream& next_layer)
: next_layer_(next_layer)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return next_layer_.lowest_layer().get_executor();
}
template <typename ReadHandler>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
buffered_stream_storage* storage, Stream* next_layer) const buffered_stream_storage* storage) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler. // does not meet the documented type requirements for a ReadHandler.
@ -153,13 +169,16 @@ namespace detail
non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<ReadHandler> handler2(handler);
std::size_t previous_size = storage->size(); std::size_t previous_size = storage->size();
storage->resize(storage->capacity()); storage->resize(storage->capacity());
next_layer->async_read_some( next_layer_.async_read_some(
buffer( buffer(
storage->data() + previous_size, storage->data() + previous_size,
storage->size() - previous_size), storage->size() - previous_size),
buffered_fill_handler<typename decay<ReadHandler>::type>( buffered_fill_handler<typename decay<ReadHandler>::type>(
*storage, previous_size, handler2.value)); *storage, previous_size, handler2.value));
} }
private:
Stream& next_layer_;
}; };
} // namespace detail } // namespace detail
@ -194,15 +213,18 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename Stream> template <typename Stream>
template <typename ReadHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
buffered_read_stream<Stream>::async_fill( buffered_read_stream<Stream>::async_fill(
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_buffered_fill(), handler, &storage_, &next_layer_); detail::initiate_async_buffered_fill<Stream>(next_layer_),
handler, &storage_);
} }
template <typename Stream> template <typename Stream>
@ -336,12 +358,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_buffered_read_some template <typename Stream>
class initiate_async_buffered_read_some
{ {
template <typename ReadHandler, typename Stream, public:
typename MutableBufferSequence> typedef typename remove_reference<
Stream>::type::lowest_layer_type::executor_type executor_type;
explicit initiate_async_buffered_read_some(Stream& next_layer)
: next_layer_(next_layer)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return next_layer_.lowest_layer().get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
buffered_stream_storage* storage, Stream* next_layer, buffered_stream_storage* storage,
const MutableBufferSequence& buffers) const const MutableBufferSequence& buffers) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -352,20 +388,23 @@ namespace detail
non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<ReadHandler> handler2(handler);
if (buffer_size(buffers) == 0 || !storage->empty()) if (buffer_size(buffers) == 0 || !storage->empty())
{ {
next_layer->async_read_some(BOOST_ASIO_MUTABLE_BUFFER(0, 0), next_layer_.async_read_some(BOOST_ASIO_MUTABLE_BUFFER(0, 0),
buffered_read_some_handler<MutableBufferSequence, buffered_read_some_handler<MutableBufferSequence,
typename decay<ReadHandler>::type>( typename decay<ReadHandler>::type>(
*storage, buffers, handler2.value)); *storage, buffers, handler2.value));
} }
else else
{ {
initiate_async_buffered_fill()( initiate_async_buffered_fill<Stream>(this->next_layer_)(
buffered_read_some_handler<MutableBufferSequence, buffered_read_some_handler<MutableBufferSequence,
typename decay<ReadHandler>::type>( typename decay<ReadHandler>::type>(
*storage, buffers, handler2.value), *storage, buffers, handler2.value),
storage, next_layer); storage);
} }
} }
private:
Stream& next_layer_;
}; };
} // namespace detail } // namespace detail
@ -408,8 +447,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename Stream> template <typename Stream>
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
buffered_read_stream<Stream>::async_read_some( buffered_read_stream<Stream>::async_read_some(
const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
@ -417,8 +458,8 @@ buffered_read_stream<Stream>::async_read_some(
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_buffered_read_some(), detail::initiate_async_buffered_read_some<Stream>(next_layer_),
handler, &storage_, &next_layer_, buffers); handler, &storage_, buffers);
} }
template <typename Stream> template <typename Stream>

View file

@ -126,21 +126,39 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_buffered_flush template <typename Stream>
class initiate_async_buffered_flush
{ {
template <typename WriteHandler, typename Stream> public:
typedef typename remove_reference<
Stream>::type::lowest_layer_type::executor_type executor_type;
explicit initiate_async_buffered_flush(Stream& next_layer)
: next_layer_(next_layer)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return next_layer_.lowest_layer().get_executor();
}
template <typename WriteHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
buffered_stream_storage* storage, Stream* next_layer) const buffered_stream_storage* storage) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler. // does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<WriteHandler> handler2(handler);
async_write(*next_layer, buffer(storage->data(), storage->size()), async_write(next_layer_, buffer(storage->data(), storage->size()),
buffered_flush_handler<typename decay<WriteHandler>::type>( buffered_flush_handler<typename decay<WriteHandler>::type>(
*storage, handler2.value)); *storage, handler2.value));
} }
private:
Stream& next_layer_;
}; };
} // namespace detail } // namespace detail
@ -175,16 +193,18 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename Stream> template <typename Stream>
template <typename WriteHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
buffered_write_stream<Stream>::async_flush( buffered_write_stream<Stream>::async_flush(
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_buffered_flush(), detail::initiate_async_buffered_flush<Stream>(next_layer_),
handler, &storage_, &next_layer_); handler, &storage_);
} }
template <typename Stream> template <typename Stream>
@ -324,12 +344,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_buffered_write_some template <typename Stream>
class initiate_async_buffered_write_some
{ {
template <typename WriteHandler, typename Stream, public:
typename ConstBufferSequence> typedef typename remove_reference<
Stream>::type::lowest_layer_type::executor_type executor_type;
explicit initiate_async_buffered_write_some(Stream& next_layer)
: next_layer_(next_layer)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return next_layer_.lowest_layer().get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
buffered_stream_storage* storage, Stream* next_layer, buffered_stream_storage* storage,
const ConstBufferSequence& buffers) const const ConstBufferSequence& buffers) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -340,20 +374,23 @@ namespace detail
non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<WriteHandler> handler2(handler);
if (buffer_size(buffers) == 0 || storage->size() < storage->capacity()) if (buffer_size(buffers) == 0 || storage->size() < storage->capacity())
{ {
next_layer->async_write_some(BOOST_ASIO_CONST_BUFFER(0, 0), next_layer_.async_write_some(BOOST_ASIO_CONST_BUFFER(0, 0),
buffered_write_some_handler<ConstBufferSequence, buffered_write_some_handler<ConstBufferSequence,
typename decay<WriteHandler>::type>( typename decay<WriteHandler>::type>(
*storage, buffers, handler2.value)); *storage, buffers, handler2.value));
} }
else else
{ {
initiate_async_buffered_flush()( initiate_async_buffered_flush<Stream>(this->next_layer_)(
buffered_write_some_handler<ConstBufferSequence, buffered_write_some_handler<ConstBufferSequence,
typename decay<WriteHandler>::type>( typename decay<WriteHandler>::type>(
*storage, buffers, handler2.value), *storage, buffers, handler2.value),
storage, next_layer); storage);
} }
} }
private:
Stream& next_layer_;
}; };
} // namespace detail } // namespace detail
@ -396,8 +433,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename Stream> template <typename Stream>
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
buffered_write_stream<Stream>::async_write_some( buffered_write_stream<Stream>::async_write_some(
const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
@ -405,8 +444,8 @@ buffered_write_stream<Stream>::async_write_some(
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_buffered_write_some(), detail::initiate_async_buffered_write_some<Stream>(next_layer_),
handler, &storage_, &next_layer_, buffers); handler, &storage_, buffers);
} }
template <typename Stream> template <typename Stream>

View file

@ -90,25 +90,43 @@ awaitable<void, Executor> co_spawn_entry_point(
}); });
} }
struct initiate_co_spawn template <typename Executor>
class initiate_co_spawn
{ {
template <typename Handler, typename Executor, typename F> public:
void operator()(Handler&& handler, const Executor& ex, F&& f) const typedef Executor executor_type;
template <typename OtherExecutor>
explicit initiate_co_spawn(const OtherExecutor& ex)
: ex_(ex)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return ex_;
}
template <typename Handler, typename F>
void operator()(Handler&& handler, F&& f) const
{ {
typedef typename result_of<F()>::type awaitable_type; typedef typename result_of<F()>::type awaitable_type;
typedef typename awaitable_type::executor_type executor_type;
executor_type ex2(ex);
auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr), auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr),
ex2, std::forward<F>(f), std::forward<Handler>(handler)); ex_, std::forward<F>(f), std::forward<Handler>(handler));
awaitable_handler<executor_type, void>(std::move(a), ex2).launch(); awaitable_handler<executor_type, void>(std::move(a), ex_).launch();
} }
private:
Executor ex_;
}; };
} // namespace detail } // namespace detail
template <typename Executor, typename F, typename CompletionToken> template <typename Executor, typename F,
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
typename result_of<F()>::type>::type) CompletionToken>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type) typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(const Executor& ex, F&& f, CompletionToken&& token, co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
typename enable_if< typename enable_if<
@ -117,11 +135,15 @@ co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
{ {
return async_initiate<CompletionToken, return async_initiate<CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>>( typename detail::awaitable_signature<typename result_of<F()>::type>>(
detail::initiate_co_spawn(), token, ex, std::forward<F>(f)); detail::initiate_co_spawn<
typename result_of<F()>::type::executor_type>(ex),
token, std::forward<F>(f));
} }
template <typename ExecutionContext, typename F, typename CompletionToken> template <typename ExecutionContext, typename F,
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
typename result_of<F()>::type>::type) CompletionToken>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type) typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token, co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
typename enable_if< typename enable_if<

View file

@ -32,13 +32,123 @@ namespace asio {
namespace detail namespace detail
{ {
template <typename>
struct composed_io_executors;
template <>
struct composed_io_executors<void()>
{
composed_io_executors() BOOST_ASIO_NOEXCEPT
: head_(system_executor())
{
}
typedef system_executor head_type;
system_executor head_;
};
inline composed_io_executors<void()> make_composed_io_executors()
{
return composed_io_executors<void()>();
}
template <typename Head>
struct composed_io_executors<void(Head)>
{
explicit composed_io_executors(const Head& ex) BOOST_ASIO_NOEXCEPT
: head_(ex)
{
}
typedef Head head_type;
Head head_;
};
template <typename Head>
inline composed_io_executors<void(Head)>
make_composed_io_executors(const Head& head)
{
return composed_io_executors<void(Head)>(head);
}
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Head, typename... Tail>
struct composed_io_executors<void(Head, Tail...)>
{
explicit composed_io_executors(const Head& head,
const Tail&... tail) BOOST_ASIO_NOEXCEPT
: head_(head),
tail_(tail...)
{
}
void reset()
{
head_.reset();
tail_.reset();
}
typedef Head head_type;
Head head_;
composed_io_executors<void(Tail...)> tail_;
};
template <typename Head, typename... Tail>
inline composed_io_executors<void(Head, Tail...)>
make_composed_io_executors(const Head& head, const Tail&... tail)
{
return composed_io_executors<void(Head, Tail...)>(head, tail...);
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#define BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF(n) \
template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
struct composed_io_executors<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
{ \
explicit composed_io_executors(const Head& head, \
BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) BOOST_ASIO_NOEXCEPT \
: head_(head), \
tail_(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) \
{ \
} \
\
void reset() \
{ \
head_.reset(); \
tail_.reset(); \
} \
\
typedef Head head_type; \
Head head_; \
composed_io_executors<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
}; \
\
template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline composed_io_executors<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
make_composed_io_executors(const Head& head, \
BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
{ \
return composed_io_executors< \
void(Head, BOOST_ASIO_VARIADIC_TARGS(n))>( \
head, BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)); \
} \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF)
#undef BOOST_ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename> template <typename>
struct composed_work; struct composed_work;
template <> template <>
struct composed_work<void()> struct composed_work<void()>
{ {
composed_work() BOOST_ASIO_NOEXCEPT typedef composed_io_executors<void()> executors_type;
composed_work(const executors_type&) BOOST_ASIO_NOEXCEPT
: head_(system_executor()) : head_(system_executor())
{ {
} }
@ -52,16 +162,13 @@ namespace detail
executor_work_guard<system_executor> head_; executor_work_guard<system_executor> head_;
}; };
inline composed_work<void()> make_composed_work()
{
return composed_work<void()>();
}
template <typename Head> template <typename Head>
struct composed_work<void(Head)> struct composed_work<void(Head)>
{ {
explicit composed_work(const Head& ex) BOOST_ASIO_NOEXCEPT typedef composed_io_executors<void(Head)> executors_type;
: head_(ex)
explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT
: head_(ex.head_)
{ {
} }
@ -74,21 +181,16 @@ namespace detail
executor_work_guard<Head> head_; executor_work_guard<Head> head_;
}; };
template <typename Head>
inline composed_work<void(Head)> make_composed_work(const Head& head)
{
return composed_work<void(Head)>(head);
}
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Head, typename... Tail> template <typename Head, typename... Tail>
struct composed_work<void(Head, Tail...)> struct composed_work<void(Head, Tail...)>
{ {
explicit composed_work(const Head& head, typedef composed_io_executors<void(Head, Tail...)> executors_type;
const Tail&... tail) BOOST_ASIO_NOEXCEPT
: head_(head), explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT
tail_(tail...) : head_(ex.head_),
tail_(ex.tail_)
{ {
} }
@ -103,23 +205,18 @@ namespace detail
composed_work<void(Tail...)> tail_; composed_work<void(Tail...)> tail_;
}; };
template <typename Head, typename... Tail>
inline composed_work<void(Head, Tail...)>
make_composed_work(const Head& head, const Tail&... tail)
{
return composed_work<void(Head, Tail...)>(head, tail...);
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#define BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \ #define BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \
template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
struct composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \ struct composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
{ \ { \
explicit composed_work(const Head& head, \ typedef composed_io_executors<void(Head, \
BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) BOOST_ASIO_NOEXCEPT \ BOOST_ASIO_VARIADIC_TARGS(n))> executors_type; \
: head_(head), \ \
tail_(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) \ explicit composed_work(const executors_type& ex) BOOST_ASIO_NOEXCEPT \
: head_(ex.head_), \
tail_(ex.tail_) \
{ \ { \
} \ } \
\ \
@ -133,15 +230,6 @@ namespace detail
executor_work_guard<Head> head_; \ executor_work_guard<Head> head_; \
composed_work<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \ composed_work<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
}; \ }; \
\
template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
make_composed_work(const Head& head, BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
{ \
return composed_work< \
void(Head, BOOST_ASIO_VARIADIC_TARGS(n))>( \
head, BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)); \
} \
/**/ /**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF) BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF)
#undef BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF #undef BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF
@ -299,21 +387,46 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
template <typename Signature> template <typename Signature, typename Executors>
struct initiate_composed_op class initiate_composed_op
{ {
template <typename Handler, typename Impl, typename Work> public:
typedef typename composed_io_executors<Executors>::head_type executor_type;
template <typename T>
explicit initiate_composed_op(BOOST_ASIO_MOVE_ARG(T) executors)
: executors_(BOOST_ASIO_MOVE_CAST(T)(executors))
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return executors_.head_;
}
template <typename Handler, typename Impl>
void operator()(BOOST_ASIO_MOVE_ARG(Handler) handler, void operator()(BOOST_ASIO_MOVE_ARG(Handler) handler,
BOOST_ASIO_MOVE_ARG(Impl) impl, BOOST_ASIO_MOVE_ARG(Impl) impl) const
BOOST_ASIO_MOVE_ARG(Work) work) const
{ {
composed_op<typename decay<Impl>::type, typename decay<Work>::type, composed_op<typename decay<Impl>::type, composed_work<Executors>,
typename decay<Handler>::type, Signature>( typename decay<Handler>::type, Signature>(
BOOST_ASIO_MOVE_CAST(Impl)(impl), BOOST_ASIO_MOVE_CAST(Work)(work), BOOST_ASIO_MOVE_CAST(Impl)(impl),
composed_work<Executors>(executors_),
BOOST_ASIO_MOVE_CAST(Handler)(handler))(); BOOST_ASIO_MOVE_CAST(Handler)(handler))();
} }
private:
composed_io_executors<Executors> executors_;
}; };
template <typename Signature, typename Executors>
inline initiate_composed_op<Signature, Executors> make_initiate_composed_op(
BOOST_ASIO_MOVE_ARG(composed_io_executors<Executors>) executors)
{
return initiate_composed_op<Signature, Executors>(
BOOST_ASIO_MOVE_CAST(composed_io_executors<Executors>)(executors));
}
template <typename IoObject> template <typename IoObject>
inline typename IoObject::executor_type inline typename IoObject::executor_type
get_composed_io_executor(IoObject& io_object) get_composed_io_executor(IoObject& io_object)
@ -334,31 +447,31 @@ namespace detail
template <typename CompletionToken, typename Signature, template <typename CompletionToken, typename Signature,
typename Implementation, typename... IoObjectsOrExecutors> typename Implementation, typename... IoObjectsOrExecutors>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors) BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors)
{ {
return async_initiate<CompletionToken, Signature>( return async_initiate<CompletionToken, Signature>(
detail::initiate_composed_op<Signature>(), token, detail::make_initiate_composed_op<Signature>(
BOOST_ASIO_MOVE_CAST(Implementation)(implementation), detail::make_composed_io_executors(
detail::make_composed_work(
detail::get_composed_io_executor( detail::get_composed_io_executor(
BOOST_ASIO_MOVE_CAST(IoObjectsOrExecutors)( BOOST_ASIO_MOVE_CAST(IoObjectsOrExecutors)(
io_objects_or_executors))...)); io_objects_or_executors))...)),
token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation));
} }
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature, typename Implementation> template <typename CompletionToken, typename Signature, typename Implementation>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature)
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{ {
return async_initiate<CompletionToken, Signature>( return async_initiate<CompletionToken, Signature>(
detail::initiate_composed_op<Signature>(), token, detail::make_initiate_composed_op<Signature>(
BOOST_ASIO_MOVE_CAST(Implementation)(implementation), detail::make_composed_io_executors()),
detail::make_composed_work()); token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation));
} }
# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \ # define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \
@ -388,16 +501,16 @@ async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
#define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \ #define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
template <typename CompletionToken, typename Signature, \ template <typename CompletionToken, typename Signature, \
typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \ typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) \ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, Signature) \
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \ async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \ { \
return async_initiate<CompletionToken, Signature>( \ return async_initiate<CompletionToken, Signature>( \
detail::initiate_composed_op<Signature>(), token, \ detail::make_initiate_composed_op<Signature>( \
BOOST_ASIO_MOVE_CAST(Implementation)(implementation), \ detail::make_composed_io_executors( \
detail::make_composed_work( \ BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \
BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))); \ token, BOOST_ASIO_MOVE_CAST(Implementation)(implementation)); \
} \ } \
/**/ /**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF) BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)

View file

@ -455,12 +455,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_range_connect template <typename Protocol, typename Executor>
class initiate_async_range_connect
{ {
template <typename RangeConnectHandler, typename Protocol, public:
typename Executor, typename EndpointSequence, typename ConnectCondition> typedef Executor executor_type;
explicit initiate_async_range_connect(basic_socket<Protocol, Executor>& s)
: socket_(s)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return socket_.get_executor();
}
template <typename RangeConnectHandler,
typename EndpointSequence, typename ConnectCondition>
void operator()(BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
basic_socket<Protocol, Executor>* s, const EndpointSequence& endpoints, const EndpointSequence& endpoints,
const ConnectCondition& connect_condition) const const ConnectCondition& connect_condition) const
{ {
// If you get an error on the following line it means that your // If you get an error on the following line it means that your
@ -471,9 +485,12 @@ namespace detail
non_const_lvalue<RangeConnectHandler> handler2(handler); non_const_lvalue<RangeConnectHandler> handler2(handler);
range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition, range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,
typename decay<RangeConnectHandler>::type>(*s, endpoints, typename decay<RangeConnectHandler>::type>(socket_, endpoints,
connect_condition, handler2.value)(boost::system::error_code(), 1); connect_condition, handler2.value)(boost::system::error_code(), 1);
} }
private:
basic_socket<Protocol, Executor>& socket_;
}; };
template <typename Protocol, typename Executor, typename Iterator, template <typename Protocol, typename Executor, typename Iterator,
@ -624,13 +641,28 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_iterator_connect template <typename Protocol, typename Executor>
class initiate_async_iterator_connect
{ {
template <typename IteratorConnectHandler, typename Protocol, public:
typename Executor, typename Iterator, typename ConnectCondition> typedef Executor executor_type;
explicit initiate_async_iterator_connect(
basic_socket<Protocol, Executor>& s)
: socket_(s)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return socket_.get_executor();
}
template <typename IteratorConnectHandler,
typename Iterator, typename ConnectCondition>
void operator()(BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
basic_socket<Protocol, Executor>* s, Iterator begin, Iterator begin, Iterator end,
Iterator end, const ConnectCondition& connect_condition) const const ConnectCondition& connect_condition) const
{ {
// If you get an error on the following line it means that your // If you get an error on the following line it means that your
// handler does not meet the documented type requirements for an // handler does not meet the documented type requirements for an
@ -640,9 +672,12 @@ namespace detail
non_const_lvalue<IteratorConnectHandler> handler2(handler); non_const_lvalue<IteratorConnectHandler> handler2(handler);
iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition, iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,
typename decay<IteratorConnectHandler>::type>(*s, begin, end, typename decay<IteratorConnectHandler>::type>(socket_, begin, end,
connect_condition, handler2.value)(boost::system::error_code(), 1); connect_condition, handler2.value)(boost::system::error_code(), 1);
} }
private:
basic_socket<Protocol, Executor>& socket_;
}; };
} // namespace detail } // namespace detail
@ -730,9 +765,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename Protocol, typename Executor, template <typename Protocol, typename Executor, typename EndpointSequence,
typename EndpointSequence, typename RangeConnectHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, typename Protocol::endpoint)) RangeConnectHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)) void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol, Executor>& s, async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, const EndpointSequence& endpoints,
@ -742,14 +778,15 @@ async_connect(basic_socket<Protocol, Executor>& s,
{ {
return async_initiate<RangeConnectHandler, return async_initiate<RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)>( void (boost::system::error_code, typename Protocol::endpoint)>(
detail::initiate_async_range_connect(), handler, detail::initiate_async_range_connect<Protocol, Executor>(s),
&s, endpoints, detail::default_connect_condition()); handler, endpoints, detail::default_connect_condition());
} }
#if !defined(BOOST_ASIO_NO_DEPRECATED) #if !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename Protocol, typename Executor, template <typename Protocol, typename Executor, typename Iterator,
typename Iterator, typename IteratorConnectHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, Iterator)) IteratorConnectHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
@ -757,27 +794,30 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
{ {
return async_initiate<IteratorConnectHandler, return async_initiate<IteratorConnectHandler,
void (boost::system::error_code, Iterator)>( void (boost::system::error_code, Iterator)>(
detail::initiate_async_iterator_connect(), handler, detail::initiate_async_iterator_connect<Protocol, Executor>(s),
&s, begin, Iterator(), detail::default_connect_condition()); handler, begin, Iterator(), detail::default_connect_condition());
} }
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename Protocol, typename Executor, template <typename Protocol, typename Executor, typename Iterator,
typename Iterator, typename IteratorConnectHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, Iterator)) IteratorConnectHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler) BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
{ {
return async_initiate<IteratorConnectHandler, return async_initiate<IteratorConnectHandler,
void (boost::system::error_code, Iterator)>( void (boost::system::error_code, Iterator)>(
detail::initiate_async_iterator_connect(), handler, detail::initiate_async_iterator_connect<Protocol, Executor>(s),
&s, begin, end, detail::default_connect_condition()); handler, begin, end, detail::default_connect_condition());
} }
template <typename Protocol, typename Executor, typename EndpointSequence, template <typename Protocol, typename Executor,
typename ConnectCondition, typename RangeConnectHandler> typename EndpointSequence, typename ConnectCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
typename Protocol::endpoint)) RangeConnectHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)) void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol, Executor>& s, async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition, const EndpointSequence& endpoints, ConnectCondition connect_condition,
@ -787,14 +827,16 @@ async_connect(basic_socket<Protocol, Executor>& s,
{ {
return async_initiate<RangeConnectHandler, return async_initiate<RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)>( void (boost::system::error_code, typename Protocol::endpoint)>(
detail::initiate_async_range_connect(), detail::initiate_async_range_connect<Protocol, Executor>(s),
handler, &s, endpoints, connect_condition); handler, endpoints, connect_condition);
} }
#if !defined(BOOST_ASIO_NO_DEPRECATED) #if !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename Protocol, typename Executor, typename Iterator, template <typename Protocol, typename Executor,
typename ConnectCondition, typename IteratorConnectHandler> typename Iterator, typename ConnectCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
Iterator)) IteratorConnectHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition, ConnectCondition connect_condition,
@ -803,14 +845,16 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
{ {
return async_initiate<IteratorConnectHandler, return async_initiate<IteratorConnectHandler,
void (boost::system::error_code, Iterator)>( void (boost::system::error_code, Iterator)>(
detail::initiate_async_iterator_connect(), detail::initiate_async_iterator_connect<Protocol, Executor>(s),
handler, &s, begin, Iterator(), connect_condition); handler, begin, Iterator(), connect_condition);
} }
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename Protocol, typename Executor, typename Iterator, template <typename Protocol, typename Executor,
typename ConnectCondition, typename IteratorConnectHandler> typename Iterator, typename ConnectCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
Iterator)) IteratorConnectHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition, Iterator end, ConnectCondition connect_condition,
@ -818,8 +862,8 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
{ {
return async_initiate<IteratorConnectHandler, return async_initiate<IteratorConnectHandler,
void (boost::system::error_code, Iterator)>( void (boost::system::error_code, Iterator)>(
detail::initiate_async_iterator_connect(), detail::initiate_async_iterator_connect<Protocol, Executor>(s),
handler, &s, begin, end, connect_condition); handler, begin, end, connect_condition);
} }
} // namespace asio } // namespace asio

View file

@ -26,8 +26,9 @@ namespace boost {
namespace asio { namespace asio {
namespace detail { namespace detail {
struct initiate_defer class initiate_defer
{ {
public:
template <typename CompletionHandler> template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
{ {
@ -41,42 +42,63 @@ struct initiate_defer
ex.defer(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); ex.defer(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
} }
};
template <typename CompletionHandler, typename Executor> template <typename Executor>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, class initiate_defer_with_executor
BOOST_ASIO_MOVE_ARG(Executor) ex) const {
public:
typedef Executor executor_type;
explicit initiate_defer_with_executor(const Executor& ex)
: ex_(ex)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return ex_;
}
template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
{ {
typedef typename decay<CompletionHandler>::type DecayedHandler; typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_allocator<DecayedHandler>::type alloc( typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler)); (get_associated_allocator)(handler));
ex.defer(detail::work_dispatcher<DecayedHandler>( ex_.defer(detail::work_dispatcher<DecayedHandler>(
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
} }
private:
Executor ex_;
}; };
} // namespace detail } // namespace detail
template <typename CompletionToken> template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
BOOST_ASIO_MOVE_ARG(CompletionToken) token) BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{ {
return async_initiate<CompletionToken, void()>( return async_initiate<CompletionToken, void()>(
detail::initiate_defer(), token); detail::initiate_defer(), token);
} }
template <typename Executor, typename CompletionToken> template <typename Executor,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token, const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*) typename enable_if<is_executor<Executor>::value>::type*)
{ {
return async_initiate<CompletionToken, void()>( return async_initiate<CompletionToken, void()>(
detail::initiate_defer(), token, ex); detail::initiate_defer_with_executor<Executor>(ex), token);
} }
template <typename ExecutionContext, typename CompletionToken> template <typename ExecutionContext,
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token, ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_convertible< typename enable_if<is_convertible<
ExecutionContext&, execution_context&>::value>::type*) ExecutionContext&, execution_context&>::value>::type*)

View file

@ -26,8 +26,9 @@ namespace boost {
namespace asio { namespace asio {
namespace detail { namespace detail {
struct initiate_dispatch class initiate_dispatch
{ {
public:
template <typename CompletionHandler> template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
{ {
@ -41,42 +42,63 @@ struct initiate_dispatch
ex.dispatch(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); ex.dispatch(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
} }
};
template <typename CompletionHandler, typename Executor> template <typename Executor>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, class initiate_dispatch_with_executor
BOOST_ASIO_MOVE_ARG(Executor) ex) const {
public:
typedef Executor executor_type;
explicit initiate_dispatch_with_executor(const Executor& ex)
: ex_(ex)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return ex_;
}
template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
{ {
typedef typename decay<CompletionHandler>::type DecayedHandler; typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_allocator<DecayedHandler>::type alloc( typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler)); (get_associated_allocator)(handler));
ex.dispatch(detail::work_dispatcher<DecayedHandler>( ex_.dispatch(detail::work_dispatcher<DecayedHandler>(
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
} }
private:
Executor ex_;
}; };
} // namespace detail } // namespace detail
template <typename CompletionToken> template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
BOOST_ASIO_MOVE_ARG(CompletionToken) token) BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{ {
return async_initiate<CompletionToken, void()>( return async_initiate<CompletionToken, void()>(
detail::initiate_dispatch(), token); detail::initiate_dispatch(), token);
} }
template <typename Executor, typename CompletionToken> template <typename Executor,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token, const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*) typename enable_if<is_executor<Executor>::value>::type*)
{ {
return async_initiate<CompletionToken, void()>( return async_initiate<CompletionToken, void()>(
detail::initiate_dispatch(), token, ex); detail::initiate_dispatch_with_executor<Executor>(ex), token);
} }
template <typename ExecutionContext, typename CompletionToken> template <typename ExecutionContext,
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token, ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_convertible< typename enable_if<is_convertible<
ExecutionContext&, execution_context&>::value>::type*) ExecutionContext&, execution_context&>::value>::type*)

View file

@ -172,7 +172,7 @@ struct io_context::initiate_dispatch
}; };
template <typename LegacyCompletionHandler> template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ())
io_context::dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler) io_context::dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{ {
return async_initiate<LegacyCompletionHandler, void ()>( return async_initiate<LegacyCompletionHandler, void ()>(
@ -211,7 +211,7 @@ struct io_context::initiate_post
}; };
template <typename LegacyCompletionHandler> template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ())
io_context::post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler) io_context::post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{ {
return async_initiate<LegacyCompletionHandler, void ()>( return async_initiate<LegacyCompletionHandler, void ()>(

View file

@ -26,8 +26,9 @@ namespace boost {
namespace asio { namespace asio {
namespace detail { namespace detail {
struct initiate_post class initiate_post
{ {
public:
template <typename CompletionHandler> template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
{ {
@ -41,42 +42,63 @@ struct initiate_post
ex.post(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc); ex.post(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
} }
};
template <typename CompletionHandler, typename Executor> template <typename Executor>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler, class initiate_post_with_executor
BOOST_ASIO_MOVE_ARG(Executor) ex) const {
public:
typedef Executor executor_type;
explicit initiate_post_with_executor(const Executor& ex)
: ex_(ex)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return ex_;
}
template <typename CompletionHandler>
void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
{ {
typedef typename decay<CompletionHandler>::type DecayedHandler; typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_allocator<DecayedHandler>::type alloc( typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler)); (get_associated_allocator)(handler));
ex.post(detail::work_dispatcher<DecayedHandler>( ex_.post(detail::work_dispatcher<DecayedHandler>(
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
} }
private:
Executor ex_;
}; };
} // namespace detail } // namespace detail
template <typename CompletionToken> template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
BOOST_ASIO_MOVE_ARG(CompletionToken) token) BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{ {
return async_initiate<CompletionToken, void()>( return async_initiate<CompletionToken, void()>(
detail::initiate_post(), token); detail::initiate_post(), token);
} }
template <typename Executor, typename CompletionToken> template <typename Executor,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token, const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*) typename enable_if<is_executor<Executor>::value>::type*)
{ {
return async_initiate<CompletionToken, void()>( return async_initiate<CompletionToken, void()>(
detail::initiate_post(), token, ex); detail::initiate_post_with_executor<Executor>(ex), token);
} }
template <typename ExecutionContext, typename CompletionToken> template <typename ExecutionContext,
inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token, ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_convertible< typename enable_if<is_convertible<
ExecutionContext&, execution_context&>::value>::type*) ExecutionContext&, execution_context&>::value>::type*)

View file

@ -453,12 +453,26 @@ namespace detail
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
struct initiate_async_read_buffer_sequence template <typename AsyncReadStream>
class initiate_async_read_buffer_sequence
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename MutableBufferSequence, typename CompletionCondition> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_buffer_sequence(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -467,10 +481,13 @@ namespace detail
non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<ReadHandler> handler2(handler);
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
start_read_buffer_sequence_op(*s, buffers, start_read_buffer_sequence_op(stream_, buffers,
boost::asio::buffer_sequence_begin(buffers), boost::asio::buffer_sequence_begin(buffers),
completion_cond2.value, handler2.value); completion_cond2.value, handler2.value);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -516,9 +533,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, typename MutableBufferSequence, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename MutableBufferSequence, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
@ -529,13 +548,14 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_buffer_sequence(), handler, &s, buffers, detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s), handler,
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
template <typename AsyncReadStream, typename MutableBufferSequence, template <typename AsyncReadStream, typename MutableBufferSequence,
typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@ -545,8 +565,8 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_buffer_sequence(), detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s),
handler, &s, buffers, transfer_all()); handler, buffers, transfer_all());
} }
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
@ -692,12 +712,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_dynbuf_v1 template <typename AsyncReadStream>
class initiate_async_read_dynbuf_v1
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v1, typename CompletionCondition> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_dynbuf_v1(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v1,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -708,10 +742,13 @@ namespace detail
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type, read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,
CompletionCondition, typename decay<ReadHandler>::type>( CompletionCondition, typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
completion_cond2.value, handler2.value)( completion_cond2.value, handler2.value)(
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -755,9 +792,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, async_read(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -772,9 +810,11 @@ async_read(AsyncReadStream& s,
transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
template <typename AsyncReadStream, typename DynamicBuffer_v1, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename DynamicBuffer_v1, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, async_read(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -791,16 +831,18 @@ async_read(AsyncReadStream& s,
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_dynbuf_v1(), handler, &s, detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),
BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
#if !defined(BOOST_ASIO_NO_EXTENSIONS) #if !defined(BOOST_ASIO_NO_EXTENSIONS)
#if !defined(BOOST_ASIO_NO_IOSTREAM) #if !defined(BOOST_ASIO_NO_IOSTREAM)
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
@ -809,9 +851,11 @@ async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
template <typename AsyncReadStream, typename Allocator, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename Allocator, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, CompletionCondition completion_condition,
@ -973,12 +1017,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_dynbuf_v2 template <typename AsyncReadStream>
class initiate_async_read_dynbuf_v2
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v2, typename CompletionCondition> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_dynbuf_v2(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v2,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -989,10 +1047,13 @@ namespace detail
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type, read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,
CompletionCondition, typename decay<ReadHandler>::type>( CompletionCondition, typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
completion_cond2.value, handler2.value)( completion_cond2.value, handler2.value)(
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -1036,9 +1097,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@ -1051,9 +1113,11 @@ async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
template <typename AsyncReadStream, typename DynamicBuffer_v2, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename DynamicBuffer_v2, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
@ -1068,8 +1132,8 @@ async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_dynbuf_v2(), handler, &s, detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),
BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }

View file

@ -321,13 +321,27 @@ namespace detail
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
struct initiate_async_read_at_buffer_sequence template <typename AsyncRandomAccessReadDevice>
class initiate_async_read_at_buffer_sequence
{ {
template <typename ReadHandler, typename AsyncRandomAccessReadDevice, public:
typename MutableBufferSequence, typename CompletionCondition> typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
explicit initiate_async_read_at_buffer_sequence(
AsyncRandomAccessReadDevice& device)
: device_(device)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return device_.get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncRandomAccessReadDevice* d, uint64_t offset, uint64_t offset, const MutableBufferSequence& buffers,
const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -336,10 +350,13 @@ namespace detail
non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<ReadHandler> handler2(handler);
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
start_read_at_buffer_sequence_op(*d, offset, buffers, start_read_at_buffer_sequence_op(device_, offset, buffers,
boost::asio::buffer_sequence_begin(buffers), boost::asio::buffer_sequence_begin(buffers),
completion_cond2.value, handler2.value); completion_cond2.value, handler2.value);
} }
private:
AsyncRandomAccessReadDevice& device_;
}; };
} // namespace detail } // namespace detail
@ -387,9 +404,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, template <typename AsyncRandomAccessReadDevice,
typename CompletionCondition, typename ReadHandler> typename MutableBufferSequence, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, const MutableBufferSequence& buffers, uint64_t offset, const MutableBufferSequence& buffers,
@ -398,13 +417,16 @@ async_read_at(AsyncRandomAccessReadDevice& d,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_at_buffer_sequence(), handler, &d, offset, detail::initiate_async_read_at_buffer_sequence<
buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); AsyncRandomAccessReadDevice>(d),
handler, offset, buffers,
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, const MutableBufferSequence& buffers, uint64_t offset, const MutableBufferSequence& buffers,
@ -412,8 +434,9 @@ async_read_at(AsyncRandomAccessReadDevice& d,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_at_buffer_sequence(), detail::initiate_async_read_at_buffer_sequence<
handler, &d, offset, buffers, transfer_all()); AsyncRandomAccessReadDevice>(d),
handler, offset, buffers, transfer_all());
} }
#if !defined(BOOST_ASIO_NO_EXTENSIONS) #if !defined(BOOST_ASIO_NO_EXTENSIONS)
@ -554,13 +577,27 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_at_streambuf template <typename AsyncRandomAccessReadDevice>
class initiate_async_read_at_streambuf
{ {
template <typename ReadHandler, typename AsyncRandomAccessReadDevice, public:
typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
explicit initiate_async_read_at_streambuf(
AsyncRandomAccessReadDevice& device)
: device_(device)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return device_.get_executor();
}
template <typename ReadHandler,
typename Allocator, typename CompletionCondition> typename Allocator, typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncRandomAccessReadDevice* d, uint64_t offset, uint64_t offset, basic_streambuf<Allocator>* b,
basic_streambuf<Allocator>* b,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -571,9 +608,12 @@ namespace detail
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator, read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
CompletionCondition, typename decay<ReadHandler>::type>( CompletionCondition, typename decay<ReadHandler>::type>(
*d, offset, *b, completion_cond2.value, handler2.value)( device_, offset, *b, completion_cond2.value, handler2.value)(
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
private:
AsyncRandomAccessReadDevice& device_;
}; };
} // namespace detail } // namespace detail
@ -617,9 +657,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncRandomAccessReadDevice, typename Allocator, template <typename AsyncRandomAccessReadDevice,
typename CompletionCondition, typename ReadHandler> typename Allocator, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
@ -628,13 +670,15 @@ async_read_at(AsyncRandomAccessReadDevice& d,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_at_streambuf(), handler, &d, offset, detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
&b, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); handler, offset, &b,
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
template <typename AsyncRandomAccessReadDevice, typename Allocator, template <typename AsyncRandomAccessReadDevice, typename Allocator,
typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
@ -642,8 +686,8 @@ async_read_at(AsyncRandomAccessReadDevice& d,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_at_streambuf(), detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
handler, &d, offset, &b, transfer_all()); handler, offset, &b, transfer_all());
} }
#endif // !defined(BOOST_ASIO_NO_IOSTREAM) #endif // !defined(BOOST_ASIO_NO_IOSTREAM)

View file

@ -952,12 +952,25 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_delim_v1 template <typename AsyncReadStream>
class initiate_async_read_until_delim_v1
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v1> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_delim_v1(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v1>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
char delim) const char delim) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -968,9 +981,12 @@ namespace detail
read_until_delim_op_v1<AsyncReadStream, read_until_delim_op_v1<AsyncReadStream,
typename decay<DynamicBuffer_v1>::type, typename decay<DynamicBuffer_v1>::type,
typename decay<ReadHandler>::type>( typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
delim, handler2.value)(boost::system::error_code(), 0, 1); delim, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -1014,9 +1030,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -1028,8 +1045,8 @@ async_read_until(AsyncReadStream& s,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_delim_v1(), handler, detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),
&s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim); handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim);
} }
namespace detail namespace detail
@ -1219,12 +1236,25 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_delim_string_v1 template <typename AsyncReadStream>
class initiate_async_read_until_delim_string_v1
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v1> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_delim_string_v1(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v1>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
const std::string& delim) const const std::string& delim) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1235,9 +1265,12 @@ namespace detail
read_until_delim_string_op_v1<AsyncReadStream, read_until_delim_string_op_v1<AsyncReadStream,
typename decay<DynamicBuffer_v1>::type, typename decay<DynamicBuffer_v1>::type,
typename decay<ReadHandler>::type>( typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
delim, handler2.value)(boost::system::error_code(), 0, 1); delim, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -1281,9 +1314,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -1296,8 +1330,8 @@ async_read_until(AsyncReadStream& s,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_delim_string_v1(), detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),
handler, &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
static_cast<std::string>(delim)); static_cast<std::string>(delim));
} }
@ -1494,13 +1528,25 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_expr_v1 template <typename AsyncReadStream>
class initiate_async_read_until_expr_v1
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v1, typename RegEx> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_expr_v1(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v1, typename RegEx>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const RegEx& expr) const
const RegEx& expr) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler. // does not meet the documented type requirements for a ReadHandler.
@ -1510,9 +1556,12 @@ namespace detail
read_until_expr_op_v1<AsyncReadStream, read_until_expr_op_v1<AsyncReadStream,
typename decay<DynamicBuffer_v1>::type, typename decay<DynamicBuffer_v1>::type,
RegEx, typename decay<ReadHandler>::type>( RegEx, typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
expr, handler2.value)(boost::system::error_code(), 0, 1); expr, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -1556,9 +1605,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -1571,8 +1621,8 @@ async_read_until(AsyncReadStream& s,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_expr_v1(), handler, detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),
&s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr); handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr);
} }
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX) #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
@ -1765,12 +1815,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_match_v1 template <typename AsyncReadStream>
class initiate_async_read_until_match_v1
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_match_v1(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler,
typename DynamicBuffer_v1, typename MatchCondition> typename DynamicBuffer_v1, typename MatchCondition>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition) const MatchCondition match_condition) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -1781,9 +1845,12 @@ namespace detail
read_until_match_op_v1<AsyncReadStream, read_until_match_op_v1<AsyncReadStream,
typename decay<DynamicBuffer_v1>::type, typename decay<DynamicBuffer_v1>::type,
MatchCondition, typename decay<ReadHandler>::type>( MatchCondition, typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
match_condition, handler2.value)(boost::system::error_code(), 0, 1); match_condition, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -1827,9 +1894,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, typename DynamicBuffer_v1, template <typename AsyncReadStream,
typename MatchCondition, typename ReadHandler> typename DynamicBuffer_v1, typename MatchCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -1842,14 +1911,16 @@ async_read_until(AsyncReadStream& s,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_match_v1(), handler, detail::initiate_async_read_until_match_v1<AsyncReadStream>(s), handler,
&s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition); BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition);
} }
#if !defined(BOOST_ASIO_NO_IOSTREAM) #if !defined(BOOST_ASIO_NO_IOSTREAM)
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b,
@ -1859,8 +1930,10 @@ async_read_until(AsyncReadStream& s,
delim, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); delim, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b,
@ -1873,8 +1946,10 @@ async_read_until(AsyncReadStream& s,
#if defined(BOOST_ASIO_HAS_BOOST_REGEX) #if defined(BOOST_ASIO_HAS_BOOST_REGEX)
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr, boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
@ -1886,9 +1961,10 @@ async_read_until(AsyncReadStream& s,
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX) #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
template <typename AsyncReadStream, typename Allocator, template <typename AsyncReadStream, typename Allocator, typename MatchCondition,
typename MatchCondition, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b,
@ -2087,13 +2163,25 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_delim_v2 template <typename AsyncReadStream>
class initiate_async_read_until_delim_v2
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v2> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_delim_v2(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v2>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, char delim) const
char delim) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler. // does not meet the documented type requirements for a ReadHandler.
@ -2103,9 +2191,12 @@ namespace detail
read_until_delim_op_v2<AsyncReadStream, read_until_delim_op_v2<AsyncReadStream,
typename decay<DynamicBuffer_v2>::type, typename decay<DynamicBuffer_v2>::type,
typename decay<ReadHandler>::type>( typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
delim, handler2.value)(boost::system::error_code(), 0, 1); delim, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -2149,9 +2240,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@ -2161,8 +2253,8 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_delim_v2(), handler, detail::initiate_async_read_until_delim_v2<AsyncReadStream>(s),
&s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim); handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim);
} }
namespace detail namespace detail
@ -2360,12 +2452,25 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_delim_string_v2 template <typename AsyncReadStream>
class initiate_async_read_until_delim_string_v2
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v2> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_delim_string_v2(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v2>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
const std::string& delim) const const std::string& delim) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -2376,9 +2481,12 @@ namespace detail
read_until_delim_string_op_v2<AsyncReadStream, read_until_delim_string_op_v2<AsyncReadStream,
typename decay<DynamicBuffer_v2>::type, typename decay<DynamicBuffer_v2>::type,
typename decay<ReadHandler>::type>( typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
delim, handler2.value)(boost::system::error_code(), 0, 1); delim, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -2423,8 +2531,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream,
typename DynamicBuffer_v2, typename ReadHandler> typename DynamicBuffer_v2,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
DynamicBuffer_v2 buffers, BOOST_ASIO_STRING_VIEW_PARAM delim, DynamicBuffer_v2 buffers, BOOST_ASIO_STRING_VIEW_PARAM delim,
@ -2435,8 +2545,8 @@ async_read_until(AsyncReadStream& s,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_delim_string_v2(), detail::initiate_async_read_until_delim_string_v2<AsyncReadStream>(s),
handler, &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
static_cast<std::string>(delim)); static_cast<std::string>(delim));
} }
@ -2641,12 +2751,25 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_expr_v2 template <typename AsyncReadStream>
class initiate_async_read_until_expr_v2
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typename DynamicBuffer_v2, typename RegEx> typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_expr_v2(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler, typename DynamicBuffer_v2, typename RegEx>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
const RegEx& expr) const const RegEx& expr) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -2657,9 +2780,12 @@ namespace detail
read_until_expr_op_v2<AsyncReadStream, read_until_expr_op_v2<AsyncReadStream,
typename decay<DynamicBuffer_v2>::type, typename decay<DynamicBuffer_v2>::type,
RegEx, typename decay<ReadHandler>::type>( RegEx, typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
expr, handler2.value)(boost::system::error_code(), 0, 1); expr, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -2703,9 +2829,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
const boost::regex& expr, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, const boost::regex& expr, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@ -2715,8 +2842,8 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_expr_v2(), handler, detail::initiate_async_read_until_expr_v2<AsyncReadStream>(s),
&s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr); handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr);
} }
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX) #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
@ -2917,12 +3044,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_read_until_match_v2 template <typename AsyncReadStream>
class initiate_async_read_until_match_v2
{ {
template <typename ReadHandler, typename AsyncReadStream, public:
typedef typename AsyncReadStream::executor_type executor_type;
explicit initiate_async_read_until_match_v2(AsyncReadStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename ReadHandler,
typename DynamicBuffer_v2, typename MatchCondition> typename DynamicBuffer_v2, typename MatchCondition>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
MatchCondition match_condition) const MatchCondition match_condition) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -2933,9 +3074,12 @@ namespace detail
read_until_match_op_v2<AsyncReadStream, read_until_match_op_v2<AsyncReadStream,
typename decay<DynamicBuffer_v2>::type, typename decay<DynamicBuffer_v2>::type,
MatchCondition, typename decay<ReadHandler>::type>( MatchCondition, typename decay<ReadHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
match_condition, handler2.value)(boost::system::error_code(), 0, 1); match_condition, handler2.value)(boost::system::error_code(), 0, 1);
} }
private:
AsyncReadStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -2979,9 +3123,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream, typename DynamicBuffer_v2, template <typename AsyncReadStream,
typename MatchCondition, typename ReadHandler> typename DynamicBuffer_v2, typename MatchCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@ -2992,8 +3138,8 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_read_until_match_v2(), handler, detail::initiate_async_read_until_match_v2<AsyncReadStream>(s), handler,
&s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition); BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition);
} }
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)

View file

@ -418,12 +418,26 @@ namespace detail
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
struct initiate_async_write_buffer_sequence template <typename AsyncWriteStream>
class initiate_async_write_buffer_sequence
{ {
template <typename WriteHandler, typename AsyncWriteStream, public:
typename ConstBufferSequence, typename CompletionCondition> typedef typename AsyncWriteStream::executor_type executor_type;
explicit initiate_async_write_buffer_sequence(AsyncWriteStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
AsyncWriteStream* s, const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -432,10 +446,13 @@ namespace detail
non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<WriteHandler> handler2(handler);
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
start_write_buffer_sequence_op(*s, buffers, start_write_buffer_sequence_op(stream_, buffers,
boost::asio::buffer_sequence_begin(buffers), boost::asio::buffer_sequence_begin(buffers),
completion_cond2.value, handler2.value); completion_cond2.value, handler2.value);
} }
private:
AsyncWriteStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -481,9 +498,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncWriteStream, typename ConstBufferSequence, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename ConstBufferSequence, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
@ -494,13 +513,15 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_buffer_sequence(), handler, &s, buffers, detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
handler, buffers,
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
template <typename AsyncWriteStream, typename ConstBufferSequence, template <typename AsyncWriteStream, typename ConstBufferSequence,
typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler, BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
@ -510,8 +531,8 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_buffer_sequence(), detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
handler, &s, buffers, transfer_all()); handler, buffers, transfer_all());
} }
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
@ -629,12 +650,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_write_dynbuf_v1 template <typename AsyncWriteStream>
class initiate_async_write_dynbuf_v1
{ {
template <typename WriteHandler, typename AsyncWriteStream, public:
typename DynamicBuffer_v1, typename CompletionCondition> typedef typename AsyncWriteStream::executor_type executor_type;
explicit initiate_async_write_dynbuf_v1(AsyncWriteStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename WriteHandler, typename DynamicBuffer_v1,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
AsyncWriteStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -646,10 +681,13 @@ namespace detail
write_dynbuf_v1_op<AsyncWriteStream, write_dynbuf_v1_op<AsyncWriteStream,
typename decay<DynamicBuffer_v1>::type, typename decay<DynamicBuffer_v1>::type,
CompletionCondition, typename decay<WriteHandler>::type>( CompletionCondition, typename decay<WriteHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
completion_cond2.value, handler2.value)( completion_cond2.value, handler2.value)(
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
private:
AsyncWriteStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -693,9 +731,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncWriteStream, template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, async_write(AsyncWriteStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -710,9 +749,11 @@ async_write(AsyncWriteStream& s,
transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
template <typename AsyncWriteStream, typename DynamicBuffer_v1, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename DynamicBuffer_v1, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, async_write(AsyncWriteStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -725,16 +766,18 @@ async_write(AsyncWriteStream& s,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_dynbuf_v1(), handler, &s, detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
#if !defined(BOOST_ASIO_NO_EXTENSIONS) #if !defined(BOOST_ASIO_NO_EXTENSIONS)
#if !defined(BOOST_ASIO_NO_IOSTREAM) #if !defined(BOOST_ASIO_NO_IOSTREAM)
template <typename AsyncWriteStream, typename Allocator, typename WriteHandler> template <typename AsyncWriteStream, typename Allocator,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, async_write(AsyncWriteStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b,
@ -744,9 +787,11 @@ async_write(AsyncWriteStream& s,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
template <typename AsyncWriteStream, typename Allocator, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename Allocator, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, async_write(AsyncWriteStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b,
@ -875,12 +920,26 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_write_dynbuf_v2 template <typename AsyncWriteStream>
class initiate_async_write_dynbuf_v2
{ {
template <typename WriteHandler, typename AsyncWriteStream, public:
typename DynamicBuffer_v2, typename CompletionCondition> typedef typename AsyncWriteStream::executor_type executor_type;
explicit initiate_async_write_dynbuf_v2(AsyncWriteStream& stream)
: stream_(stream)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return stream_.get_executor();
}
template <typename WriteHandler, typename DynamicBuffer_v2,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
AsyncWriteStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -892,10 +951,13 @@ namespace detail
write_dynbuf_v2_op<AsyncWriteStream, write_dynbuf_v2_op<AsyncWriteStream,
typename decay<DynamicBuffer_v2>::type, typename decay<DynamicBuffer_v2>::type,
CompletionCondition, typename decay<WriteHandler>::type>( CompletionCondition, typename decay<WriteHandler>::type>(
*s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
completion_cond2.value, handler2.value)( completion_cond2.value, handler2.value)(
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
private:
AsyncWriteStream& stream_;
}; };
} // namespace detail } // namespace detail
@ -939,9 +1001,10 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncWriteStream, template <typename AsyncWriteStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler, BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
@ -954,9 +1017,11 @@ async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
template <typename AsyncWriteStream, typename DynamicBuffer_v2, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename DynamicBuffer_v2, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
@ -967,8 +1032,8 @@ async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_dynbuf_v2(), handler, &s, detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),
BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }

View file

@ -306,13 +306,27 @@ namespace detail
boost::system::error_code(), 0, 1); boost::system::error_code(), 0, 1);
} }
struct initiate_async_write_at_buffer_sequence template <typename AsyncRandomAccessWriteDevice>
class initiate_async_write_at_buffer_sequence
{ {
template <typename WriteHandler, typename AsyncRandomAccessWriteDevice, public:
typename ConstBufferSequence, typename CompletionCondition> typedef typename AsyncRandomAccessWriteDevice::executor_type executor_type;
explicit initiate_async_write_at_buffer_sequence(
AsyncRandomAccessWriteDevice& device)
: device_(device)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return device_.get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence,
typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
AsyncRandomAccessWriteDevice* d, uint64_t offset, uint64_t offset, const ConstBufferSequence& buffers,
const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -321,10 +335,13 @@ namespace detail
non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<WriteHandler> handler2(handler);
non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
start_write_at_buffer_sequence_op(*d, offset, buffers, start_write_at_buffer_sequence_op(device_, offset, buffers,
boost::asio::buffer_sequence_begin(buffers), boost::asio::buffer_sequence_begin(buffers),
completion_cond2.value, handler2.value); completion_cond2.value, handler2.value);
} }
private:
AsyncRandomAccessWriteDevice& device_;
}; };
} // namespace detail } // namespace detail
@ -372,9 +389,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, template <typename AsyncRandomAccessWriteDevice,
typename CompletionCondition, typename WriteHandler> typename ConstBufferSequence, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, const ConstBufferSequence& buffers, uint64_t offset, const ConstBufferSequence& buffers,
@ -383,13 +402,16 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_at_buffer_sequence(), handler, &d, offset, detail::initiate_async_write_at_buffer_sequence<
buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); AsyncRandomAccessWriteDevice>(d),
handler, offset, buffers,
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, const ConstBufferSequence& buffers, uint64_t offset, const ConstBufferSequence& buffers,
@ -397,8 +419,9 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_at_buffer_sequence(), detail::initiate_async_write_at_buffer_sequence<
handler, &d, offset, buffers, transfer_all()); AsyncRandomAccessWriteDevice>(d),
handler, offset, buffers, transfer_all());
} }
#if !defined(BOOST_ASIO_NO_EXTENSIONS) #if !defined(BOOST_ASIO_NO_EXTENSIONS)
@ -484,13 +507,27 @@ namespace detail
function, this_handler->handler_); function, this_handler->handler_);
} }
struct initiate_async_write_at_streambuf template <typename AsyncRandomAccessWriteDevice>
class initiate_async_write_at_streambuf
{ {
template <typename WriteHandler, typename AsyncRandomAccessWriteDevice, public:
typedef typename AsyncRandomAccessWriteDevice::executor_type executor_type;
explicit initiate_async_write_at_streambuf(
AsyncRandomAccessWriteDevice& device)
: device_(device)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return device_.get_executor();
}
template <typename WriteHandler,
typename Allocator, typename CompletionCondition> typename Allocator, typename CompletionCondition>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
AsyncRandomAccessWriteDevice* d, uint64_t offset, uint64_t offset, basic_streambuf<Allocator>* b,
basic_streambuf<Allocator>* b,
BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_condition) const BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_condition) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -498,11 +535,14 @@ namespace detail
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<WriteHandler> handler2(handler);
async_write_at(*d, offset, b->data(), async_write_at(device_, offset, b->data(),
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>( write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>(
*b, handler2.value)); *b, handler2.value));
} }
private:
AsyncRandomAccessWriteDevice& device_;
}; };
} // namespace detail } // namespace detail
@ -540,9 +580,11 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION) #endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncRandomAccessWriteDevice, typename Allocator, template <typename AsyncRandomAccessWriteDevice,
typename CompletionCondition, typename WriteHandler> typename Allocator, typename CompletionCondition,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
@ -551,13 +593,16 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_at_streambuf(), handler, &d, offset, detail::initiate_async_write_at_streambuf<
&b, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); AsyncRandomAccessWriteDevice>(d),
handler, offset, &b,
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
} }
template <typename AsyncRandomAccessWriteDevice, typename Allocator, template <typename AsyncRandomAccessWriteDevice, typename Allocator,
typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler>
inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
@ -565,8 +610,9 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
detail::initiate_async_write_at_streambuf(), detail::initiate_async_write_at_streambuf<
handler, &d, offset, &b, transfer_all()); AsyncRandomAccessWriteDevice>(d),
handler, offset, &b, transfer_all());
} }
#endif // !defined(BOOST_ASIO_NO_IOSTREAM) #endif // !defined(BOOST_ASIO_NO_IOSTREAM)

View file

@ -533,7 +533,7 @@ public:
* throws an exception. * throws an exception.
*/ */
template <typename LegacyCompletionHandler> template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ())
dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler); dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler);
/// (Deprecated: Use boost::asio::post().) Request the io_context to invoke /// (Deprecated: Use boost::asio::post().) Request the io_context to invoke
@ -560,7 +560,7 @@ public:
* throws an exception. * throws an exception.
*/ */
template <typename LegacyCompletionHandler> template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ())
post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler); post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler);
/// (Deprecated: Use boost::asio::bind_executor().) Create a new handler that /// (Deprecated: Use boost::asio::bind_executor().) Create a new handler that

View file

@ -183,7 +183,7 @@ public:
* @code void handler(); @endcode * @code void handler(); @endcode
*/ */
template <typename LegacyCompletionHandler> template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ())
dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler) dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{ {
return async_initiate<LegacyCompletionHandler, void ()>( return async_initiate<LegacyCompletionHandler, void ()>(
@ -230,7 +230,7 @@ public:
* @code void handler(); @endcode * @code void handler(); @endcode
*/ */
template <typename LegacyCompletionHandler> template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ()) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(LegacyCompletionHandler, void ())
post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler) post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{ {
return async_initiate<LegacyCompletionHandler, void ()>( return async_initiate<LegacyCompletionHandler, void ()>(

View file

@ -72,6 +72,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the resolver type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The resolver type when rebound to the specified executor.
typedef basic_resolver<InternetProtocol, Executor1> other;
};
/// The protocol type. /// The protocol type.
typedef InternetProtocol protocol_type; typedef InternetProtocol protocol_type;
@ -613,15 +621,19 @@ public:
* A successful resolve operation is guaranteed to pass a non-empty range to * A successful resolve operation is guaranteed to pass a non-empty range to
* the handler. * the handler.
*/ */
template <typename ResolveHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
results_type)) ResolveHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
void (boost::system::error_code, results_type)) void (boost::system::error_code, results_type))
async_resolve(const query& q, async_resolve(const query& q,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler) BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return boost::asio::async_initiate<ResolveHandler, return boost::asio::async_initiate<ResolveHandler,
void (boost::system::error_code, results_type)>( void (boost::system::error_code, results_type)>(
initiate_async_resolve(), handler, this, q); initiate_async_resolve(this), handler, q);
} }
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -667,12 +679,16 @@ public:
* <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
* may use additional locations when resolving service names. * may use additional locations when resolving service names.
*/ */
template <typename ResolveHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
results_type)) ResolveHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
void (boost::system::error_code, results_type)) void (boost::system::error_code, results_type))
async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host, async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
BOOST_ASIO_STRING_VIEW_PARAM service, BOOST_ASIO_STRING_VIEW_PARAM service,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler) BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_resolve(host, service, resolver_base::flags(), return async_resolve(host, service, resolver_base::flags(),
BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler)); BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
@ -725,20 +741,24 @@ public:
* <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
* may use additional locations when resolving service names. * may use additional locations when resolving service names.
*/ */
template <typename ResolveHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
results_type)) ResolveHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
void (boost::system::error_code, results_type)) void (boost::system::error_code, results_type))
async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host, async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
BOOST_ASIO_STRING_VIEW_PARAM service, BOOST_ASIO_STRING_VIEW_PARAM service,
resolver_base::flags resolve_flags, resolver_base::flags resolve_flags,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler) BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
basic_resolver_query<protocol_type> q(static_cast<std::string>(host), basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags); static_cast<std::string>(service), resolve_flags);
return boost::asio::async_initiate<ResolveHandler, return boost::asio::async_initiate<ResolveHandler,
void (boost::system::error_code, results_type)>( void (boost::system::error_code, results_type)>(
initiate_async_resolve(), handler, this, q); initiate_async_resolve(this), handler, q);
} }
/// Asynchronously perform forward resolution of a query to a list of entries. /// Asynchronously perform forward resolution of a query to a list of entries.
@ -786,12 +806,16 @@ public:
* <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
* may use additional locations when resolving service names. * may use additional locations when resolving service names.
*/ */
template <typename ResolveHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
results_type)) ResolveHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
void (boost::system::error_code, results_type)) void (boost::system::error_code, results_type))
async_resolve(const protocol_type& protocol, async_resolve(const protocol_type& protocol,
BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service, BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler) BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_resolve(protocol, host, service, resolver_base::flags(), return async_resolve(protocol, host, service, resolver_base::flags(),
BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler)); BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
@ -847,13 +871,17 @@ public:
* <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
* may use additional locations when resolving service names. * may use additional locations when resolving service names.
*/ */
template <typename ResolveHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
results_type)) ResolveHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
void (boost::system::error_code, results_type)) void (boost::system::error_code, results_type))
async_resolve(const protocol_type& protocol, async_resolve(const protocol_type& protocol,
BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service, BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
resolver_base::flags resolve_flags, resolver_base::flags resolve_flags,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler) BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
basic_resolver_query<protocol_type> q( basic_resolver_query<protocol_type> q(
protocol, static_cast<std::string>(host), protocol, static_cast<std::string>(host),
@ -861,7 +889,7 @@ public:
return boost::asio::async_initiate<ResolveHandler, return boost::asio::async_initiate<ResolveHandler,
void (boost::system::error_code, results_type)>( void (boost::system::error_code, results_type)>(
initiate_async_resolve(), handler, this, q); initiate_async_resolve(this), handler, q);
} }
/// Perform reverse resolution of an endpoint to a list of entries. /// Perform reverse resolution of an endpoint to a list of entries.
@ -930,15 +958,19 @@ public:
* A successful resolve operation is guaranteed to pass a non-empty range to * A successful resolve operation is guaranteed to pass a non-empty range to
* the handler. * the handler.
*/ */
template <typename ResolveHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
results_type)) ResolveHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
void (boost::system::error_code, results_type)) void (boost::system::error_code, results_type))
async_resolve(const endpoint_type& e, async_resolve(const endpoint_type& e,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler) BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return boost::asio::async_initiate<ResolveHandler, return boost::asio::async_initiate<ResolveHandler,
void (boost::system::error_code, results_type)>( void (boost::system::error_code, results_type)>(
initiate_async_resolve(), handler, this, e); initiate_async_resolve(this), handler, e);
} }
private: private:
@ -946,11 +978,24 @@ private:
basic_resolver(const basic_resolver&) BOOST_ASIO_DELETED; basic_resolver(const basic_resolver&) BOOST_ASIO_DELETED;
basic_resolver& operator=(const basic_resolver&) BOOST_ASIO_DELETED; basic_resolver& operator=(const basic_resolver&) BOOST_ASIO_DELETED;
struct initiate_async_resolve class initiate_async_resolve
{ {
public:
typedef Executor executor_type;
explicit initiate_async_resolve(basic_resolver* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ResolveHandler, typename Query> template <typename ResolveHandler, typename Query>
void operator()(BOOST_ASIO_MOVE_ARG(ResolveHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ResolveHandler) handler,
basic_resolver* self, const Query& q) const const Query& q) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ResolveHandler. // does not meet the documented type requirements for a ResolveHandler.
@ -958,10 +1003,13 @@ private:
ResolveHandler, handler, results_type) type_check; ResolveHandler, handler, results_type) type_check;
boost::asio::detail::non_const_lvalue<ResolveHandler> handler2(handler); boost::asio::detail::non_const_lvalue<ResolveHandler> handler2(handler);
self->impl_.get_service().async_resolve( self_->impl_.get_service().async_resolve(
self->impl_.get_implementation(), q, handler2.value, self_->impl_.get_implementation(), q, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_resolver* self_;
}; };
# if defined(BOOST_ASIO_WINDOWS_RUNTIME) # if defined(BOOST_ASIO_WINDOWS_RUNTIME)

View file

@ -47,33 +47,33 @@ public:
typedef basic_endpoint<icmp> endpoint; typedef basic_endpoint<icmp> endpoint;
/// Construct to represent the IPv4 ICMP protocol. /// Construct to represent the IPv4 ICMP protocol.
static icmp v4() static icmp v4() BOOST_ASIO_NOEXCEPT
{ {
return icmp(BOOST_ASIO_OS_DEF(IPPROTO_ICMP), return icmp(BOOST_ASIO_OS_DEF(IPPROTO_ICMP),
BOOST_ASIO_OS_DEF(AF_INET)); BOOST_ASIO_OS_DEF(AF_INET));
} }
/// Construct to represent the IPv6 ICMP protocol. /// Construct to represent the IPv6 ICMP protocol.
static icmp v6() static icmp v6() BOOST_ASIO_NOEXCEPT
{ {
return icmp(BOOST_ASIO_OS_DEF(IPPROTO_ICMPV6), return icmp(BOOST_ASIO_OS_DEF(IPPROTO_ICMPV6),
BOOST_ASIO_OS_DEF(AF_INET6)); BOOST_ASIO_OS_DEF(AF_INET6));
} }
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(SOCK_RAW); return BOOST_ASIO_OS_DEF(SOCK_RAW);
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return protocol_; return protocol_;
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return family_; return family_;
} }
@ -98,7 +98,7 @@ public:
private: private:
// Construct with a specific family. // Construct with a specific family.
explicit icmp(int protocol_id, int protocol_family) explicit icmp(int protocol_id, int protocol_family) BOOST_ASIO_NOEXCEPT
: protocol_(protocol_id), : protocol_(protocol_id),
family_(protocol_family) family_(protocol_family)
{ {

View file

@ -50,31 +50,31 @@ public:
typedef basic_endpoint<tcp> endpoint; typedef basic_endpoint<tcp> endpoint;
/// Construct to represent the IPv4 TCP protocol. /// Construct to represent the IPv4 TCP protocol.
static tcp v4() static tcp v4() BOOST_ASIO_NOEXCEPT
{ {
return tcp(BOOST_ASIO_OS_DEF(AF_INET)); return tcp(BOOST_ASIO_OS_DEF(AF_INET));
} }
/// Construct to represent the IPv6 TCP protocol. /// Construct to represent the IPv6 TCP protocol.
static tcp v6() static tcp v6() BOOST_ASIO_NOEXCEPT
{ {
return tcp(BOOST_ASIO_OS_DEF(AF_INET6)); return tcp(BOOST_ASIO_OS_DEF(AF_INET6));
} }
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(SOCK_STREAM); return BOOST_ASIO_OS_DEF(SOCK_STREAM);
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(IPPROTO_TCP); return BOOST_ASIO_OS_DEF(IPPROTO_TCP);
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return family_; return family_;
} }
@ -140,7 +140,7 @@ public:
private: private:
// Construct with a specific family. // Construct with a specific family.
explicit tcp(int protocol_family) explicit tcp(int protocol_family) BOOST_ASIO_NOEXCEPT
: family_(protocol_family) : family_(protocol_family)
{ {
} }

View file

@ -47,31 +47,31 @@ public:
typedef basic_endpoint<udp> endpoint; typedef basic_endpoint<udp> endpoint;
/// Construct to represent the IPv4 UDP protocol. /// Construct to represent the IPv4 UDP protocol.
static udp v4() static udp v4() BOOST_ASIO_NOEXCEPT
{ {
return udp(BOOST_ASIO_OS_DEF(AF_INET)); return udp(BOOST_ASIO_OS_DEF(AF_INET));
} }
/// Construct to represent the IPv6 UDP protocol. /// Construct to represent the IPv6 UDP protocol.
static udp v6() static udp v6() BOOST_ASIO_NOEXCEPT
{ {
return udp(BOOST_ASIO_OS_DEF(AF_INET6)); return udp(BOOST_ASIO_OS_DEF(AF_INET6));
} }
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(SOCK_DGRAM); return BOOST_ASIO_OS_DEF(SOCK_DGRAM);
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return BOOST_ASIO_OS_DEF(IPPROTO_UDP); return BOOST_ASIO_OS_DEF(IPPROTO_UDP);
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return family_; return family_;
} }
@ -96,7 +96,7 @@ public:
private: private:
// Construct with a specific family. // Construct with a specific family.
explicit udp(int protocol_family) explicit udp(int protocol_family) BOOST_ASIO_NOEXCEPT
: family_(protocol_family) : family_(protocol_family)
{ {
} }

View file

@ -61,7 +61,7 @@ public:
#endif #endif
/// Default constructor. /// Default constructor.
basic_endpoint() basic_endpoint() BOOST_ASIO_NOEXCEPT
{ {
} }

View file

@ -46,19 +46,19 @@ class datagram_protocol
{ {
public: public:
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return SOCK_DGRAM; return SOCK_DGRAM;
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return 0; return 0;
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return AF_UNIX; return AF_UNIX;
} }

View file

@ -48,19 +48,19 @@ class stream_protocol
{ {
public: public:
/// Obtain an identifier for the type of the protocol. /// Obtain an identifier for the type of the protocol.
int type() const int type() const BOOST_ASIO_NOEXCEPT
{ {
return SOCK_STREAM; return SOCK_STREAM;
} }
/// Obtain an identifier for the protocol. /// Obtain an identifier for the protocol.
int protocol() const int protocol() const BOOST_ASIO_NOEXCEPT
{ {
return 0; return 0;
} }
/// Obtain an identifier for the protocol family. /// Obtain an identifier for the protocol family.
int family() const int family() const BOOST_ASIO_NOEXCEPT
{ {
return AF_UNIX; return AF_UNIX;
} }

View file

@ -58,6 +58,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the descriptor type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The descriptor type when rebound to the specified executor.
typedef basic_descriptor<Executor1> other;
};
/// The native representation of a descriptor. /// The native representation of a descriptor.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
@ -615,13 +623,17 @@ public:
* wait_handler); * wait_handler);
* @endcode * @endcode
*/ */
template <typename WaitHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(wait_type w,
BOOST_ASIO_MOVE_ARG(WaitHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WaitHandler, void (boost::system::error_code)>( return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(), handler, this, w); initiate_async_wait(this), handler, w);
} }
protected: protected:
@ -642,21 +654,36 @@ private:
basic_descriptor(const basic_descriptor&) BOOST_ASIO_DELETED; basic_descriptor(const basic_descriptor&) BOOST_ASIO_DELETED;
basic_descriptor& operator=(const basic_descriptor&) BOOST_ASIO_DELETED; basic_descriptor& operator=(const basic_descriptor&) BOOST_ASIO_DELETED;
struct initiate_async_wait class initiate_async_wait
{ {
public:
typedef Executor executor_type;
explicit initiate_async_wait(basic_descriptor* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WaitHandler> template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
basic_descriptor* self, wait_type w) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler. // does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler); detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait( self_->impl_.get_service().async_wait(
self->impl_.get_implementation(), w, handler2.value, self_->impl_.get_implementation(), w, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_descriptor* self_;
}; };
}; };

View file

@ -45,6 +45,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the descriptor type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The descriptor type when rebound to the specified executor.
typedef basic_stream_descriptor<Executor1> other;
};
/// The native representation of a descriptor. /// The native representation of a descriptor.
typedef typename basic_descriptor<Executor>::native_handle_type typedef typename basic_descriptor<Executor>::native_handle_type
native_handle_type; native_handle_type;
@ -257,15 +265,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<WriteHandler, return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_write_some(), handler, this, buffers); initiate_async_write_some(this), handler, buffers);
} }
/// Read some data from the descriptor. /// Read some data from the descriptor.
@ -367,23 +379,39 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return async_initiate<ReadHandler, return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>( void (boost::system::error_code, std::size_t)>(
initiate_async_read_some(), handler, this, buffers); initiate_async_read_some(this), handler, buffers);
} }
private: private:
struct initiate_async_write_some class initiate_async_write_some
{ {
public:
typedef Executor executor_type;
explicit initiate_async_write_some(basic_stream_descriptor* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence> template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_stream_descriptor* self,
const ConstBufferSequence& buffers) const const ConstBufferSequence& buffers) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -391,17 +419,32 @@ private:
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler); detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_write_some( self_->impl_.get_service().async_write_some(
self->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_stream_descriptor* self_;
}; };
struct initiate_async_read_some class initiate_async_read_some
{ {
public:
typedef Executor executor_type;
explicit initiate_async_read_some(basic_stream_descriptor* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence> template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_stream_descriptor* self,
const MutableBufferSequence& buffers) const const MutableBufferSequence& buffers) const
{ {
// If you get an error on the following line it means that your handler // If you get an error on the following line it means that your handler
@ -409,10 +452,13 @@ private:
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler); detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_read_some( self_->impl_.get_service().async_read_some(
self->impl_.get_implementation(), buffers, handler2.value, self_->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor()); self_->impl_.get_implementation_executor());
} }
private:
basic_stream_descriptor* self_;
}; };
}; };

View file

@ -53,8 +53,8 @@ namespace asio {
* *
* @li Returns <tt>result.get()</tt>. * @li Returns <tt>result.get()</tt>.
*/ */
template <typename CompletionToken> template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
BOOST_ASIO_MOVE_ARG(CompletionToken) token); BOOST_ASIO_MOVE_ARG(CompletionToken) token);
/// Submits a completion token or function object for execution. /// Submits a completion token or function object for execution.
@ -90,18 +90,28 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
* *
* @li Returns <tt>result.get()</tt>. * @li Returns <tt>result.get()</tt>.
*/ */
template <typename Executor, typename CompletionToken> template <typename Executor,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token, BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
const Executor& ex,
BOOST_ASIO_MOVE_ARG(CompletionToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
typename enable_if<is_executor<Executor>::value>::type* = 0); typename enable_if<is_executor<Executor>::value>::type* = 0);
/// Submits a completion token or function object for execution. /// Submits a completion token or function object for execution.
/** /**
* @returns <tt>post(ctx.get_executor(), forward<CompletionToken>(token))</tt>. * @returns <tt>post(ctx.get_executor(), forward<CompletionToken>(token))</tt>.
*/ */
template <typename ExecutionContext, typename CompletionToken> template <typename ExecutionContext,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post( BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token, BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename ExecutionContext::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
ExecutionContext& ctx,
BOOST_ASIO_MOVE_ARG(CompletionToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename ExecutionContext::executor_type),
typename enable_if<is_convertible< typename enable_if<is_convertible<
ExecutionContext&, execution_context&>::value>::type* = 0); ExecutionContext&, execution_context&>::value>::type* = 0);

View file

@ -761,11 +761,16 @@ std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
* handler); @endcode * handler); @endcode
*/ */
template <typename AsyncReadStream, typename MutableBufferSequence, template <typename AsyncReadStream, typename MutableBufferSequence,
typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_mutable_buffer_sequence<MutableBufferSequence>::value is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type* = 0); >::type* = 0);
@ -833,13 +838,19 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename AsyncReadStream, typename MutableBufferSequence, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename MutableBufferSequence, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_mutable_buffer_sequence<MutableBufferSequence>::value is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type* = 0); >::type* = 0);
@ -896,13 +907,18 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
* boost::asio::transfer_all(), * boost::asio::transfer_all(),
* handler); @endcode * handler); @endcode
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, async_read(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
&& !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
@ -966,14 +982,20 @@ async_read(AsyncReadStream& s,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncReadStream, typename DynamicBuffer_v1, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename DynamicBuffer_v1, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, async_read(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
&& !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
@ -1030,11 +1052,17 @@ async_read(AsyncReadStream& s,
* boost::asio::transfer_all(), * boost::asio::transfer_all(),
* handler); @endcode * handler); @endcode
*/ */
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type));
/// Start an asynchronous operation to read a certain amount of data from a /// Start an asynchronous operation to read a certain amount of data from a
/// stream. /// stream.
@ -1092,13 +1120,19 @@ async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncReadStream, typename Allocator, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename Allocator, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type));
#endif // !defined(BOOST_ASIO_NO_IOSTREAM) #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
@ -1154,12 +1188,17 @@ async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
* boost::asio::transfer_all(), * boost::asio::transfer_all(),
* handler); @endcode * handler); @endcode
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v2<DynamicBuffer_v2>::value is_dynamic_buffer_v2<DynamicBuffer_v2>::value
>::type* = 0); >::type* = 0);
@ -1222,13 +1261,19 @@ async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncReadStream, typename DynamicBuffer_v2, template <typename AsyncReadStream,
typename CompletionCondition, typename ReadHandler> typename DynamicBuffer_v2, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v2<DynamicBuffer_v2>::value is_dynamic_buffer_v2<DynamicBuffer_v2>::value
>::type* = 0); >::type* = 0);

View file

@ -460,12 +460,17 @@ std::size_t read_at(SyncRandomAccessReadDevice& d,
* handler); @endcode * handler); @endcode
*/ */
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessReadDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,
const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessReadDevice::executor_type));
/// Start an asynchronous operation to read a certain amount of data at the /// Start an asynchronous operation to read a certain amount of data at the
/// specified offset. /// specified offset.
@ -532,14 +537,20 @@ async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, template <typename AsyncRandomAccessReadDevice,
typename CompletionCondition, typename ReadHandler> typename MutableBufferSequence, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessReadDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, const MutableBufferSequence& buffers, uint64_t offset, const MutableBufferSequence& buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessReadDevice::executor_type));
#if !defined(BOOST_ASIO_NO_EXTENSIONS) #if !defined(BOOST_ASIO_NO_EXTENSIONS)
#if !defined(BOOST_ASIO_NO_IOSTREAM) #if !defined(BOOST_ASIO_NO_IOSTREAM)
@ -590,11 +601,17 @@ async_read_at(AsyncRandomAccessReadDevice& d,
* handler); @endcode * handler); @endcode
*/ */
template <typename AsyncRandomAccessReadDevice, typename Allocator, template <typename AsyncRandomAccessReadDevice, typename Allocator,
typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessReadDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, async_read_at(AsyncRandomAccessReadDevice& d,
basic_streambuf<Allocator>& b, BOOST_ASIO_MOVE_ARG(ReadHandler) handler); uint64_t offset, basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessReadDevice::executor_type));
/// Start an asynchronous operation to read a certain amount of data at the /// Start an asynchronous operation to read a certain amount of data at the
/// specified offset. /// specified offset.
@ -649,14 +666,20 @@ async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncRandomAccessReadDevice, typename Allocator, template <typename AsyncRandomAccessReadDevice,
typename CompletionCondition, typename ReadHandler> typename Allocator, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessReadDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_at(AsyncRandomAccessReadDevice& d, async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, basic_streambuf<Allocator>& b, uint64_t offset, basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessReadDevice::executor_type));
#endif // !defined(BOOST_ASIO_NO_IOSTREAM) #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)

View file

@ -1599,13 +1599,18 @@ std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,
char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
&& !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
@ -1693,14 +1698,19 @@ async_read_until(AsyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_STRING_VIEW_PARAM delim, BOOST_ASIO_STRING_VIEW_PARAM delim,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
&& !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
@ -1795,14 +1805,19 @@ async_read_until(AsyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
const boost::regex& expr, const boost::regex& expr,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
&& !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
@ -1939,13 +1954,20 @@ async_read_until(AsyncReadStream& s,
* boost::asio::async_read_until(s, data, match_char('a'), handler); * boost::asio::async_read_until(s, data, match_char('a'), handler);
* @endcode * @endcode
*/ */
template <typename AsyncReadStream, typename DynamicBuffer_v1, template <typename AsyncReadStream,
typename MatchCondition, typename ReadHandler> typename DynamicBuffer_v1, typename MatchCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, MatchCondition match_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_match_condition<MatchCondition>::value is_match_condition<MatchCondition>::value
&& is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value && is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
@ -2032,12 +2054,18 @@ async_read_until(AsyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b, char delim,
char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type));
/// Start an asynchronous operation to read data into a streambuf until it /// Start an asynchronous operation to read data into a streambuf until it
/// contains a specified delimiter. /// contains a specified delimiter.
@ -2117,13 +2145,19 @@ async_read_until(AsyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b,
BOOST_ASIO_STRING_VIEW_PARAM delim, BOOST_ASIO_STRING_VIEW_PARAM delim,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type));
#if defined(BOOST_ASIO_HAS_BOOST_REGEX) \ #if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
|| defined(GENERATING_DOCUMENTATION) || defined(GENERATING_DOCUMENTATION)
@ -2210,12 +2244,18 @@ async_read_until(AsyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, typename Allocator, typename ReadHandler> template <typename AsyncReadStream, typename Allocator,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr, boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler); BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type));
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX) #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
// || defined(GENERATING_DOCUMENTATION) // || defined(GENERATING_DOCUMENTATION)
@ -2343,13 +2383,19 @@ async_read_until(AsyncReadStream& s,
* boost::asio::async_read_until(s, b, match_char('a'), handler); * boost::asio::async_read_until(s, b, match_char('a'), handler);
* @endcode * @endcode
*/ */
template <typename AsyncReadStream, typename Allocator, template <typename AsyncReadStream, typename Allocator, typename MatchCondition,
typename MatchCondition, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, async_read_until(AsyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b, boost::asio::basic_streambuf<Allocator>& b,
MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, MatchCondition match_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if<is_match_condition<MatchCondition>::value>::type* = 0); typename enable_if<is_match_condition<MatchCondition>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_IOSTREAM) #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
@ -2438,12 +2484,17 @@ async_read_until(AsyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, char delim,
char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v2<DynamicBuffer_v2>::value is_dynamic_buffer_v2<DynamicBuffer_v2>::value
>::type* = 0); >::type* = 0);
@ -2530,13 +2581,18 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
BOOST_ASIO_STRING_VIEW_PARAM delim, BOOST_ASIO_STRING_VIEW_PARAM delim,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v2<DynamicBuffer_v2>::value is_dynamic_buffer_v2<DynamicBuffer_v2>::value
>::type* = 0); >::type* = 0);
@ -2630,13 +2686,18 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
* This data may be the start of a new line, to be extracted by a subsequent * This data may be the start of a new line, to be extracted by a subsequent
* @c async_read_until operation. * @c async_read_until operation.
*/ */
template <typename AsyncReadStream, template <typename AsyncReadStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename ReadHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
const boost::regex& expr, const boost::regex& expr,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler, BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v2<DynamicBuffer_v2>::value is_dynamic_buffer_v2<DynamicBuffer_v2>::value
>::type* = 0); >::type* = 0);
@ -2772,12 +2833,19 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
* boost::asio::async_read_until(s, data, match_char('a'), handler); * boost::asio::async_read_until(s, data, match_char('a'), handler);
* @endcode * @endcode
*/ */
template <typename AsyncReadStream, typename DynamicBuffer_v2, template <typename AsyncReadStream,
typename MatchCondition, typename ReadHandler> typename DynamicBuffer_v2, typename MatchCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncReadStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, MatchCondition match_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncReadStream::executor_type),
typename enable_if< typename enable_if<
is_match_condition<MatchCondition>::value is_match_condition<MatchCondition>::value
&& is_dynamic_buffer_v2<DynamicBuffer_v2>::value && is_dynamic_buffer_v2<DynamicBuffer_v2>::value

View file

@ -46,9 +46,47 @@ namespace asio {
template <typename Executor = executor> template <typename Executor = executor>
struct use_awaitable_t struct use_awaitable_t
{ {
/// Default constructor.
BOOST_ASIO_CONSTEXPR use_awaitable_t() BOOST_ASIO_CONSTEXPR use_awaitable_t()
{ {
} }
/// Adapts an executor to add the @c use_awaitable_t completion token as the
/// default.
template <typename InnerExecutor>
struct executor_with_default : InnerExecutor
{
/// Specify @c use_awaitable_t as the default completion token type.
typedef use_awaitable_t default_completion_token_type;
/// Construct the adapted executor from the inner executor type.
executor_with_default(const InnerExecutor& ex) BOOST_ASIO_NOEXCEPT
: InnerExecutor(ex)
{
}
};
/// Type alias to adapt an I/O object to use @c use_awaitable_t as its
/// default completion token type.
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) \
|| defined(GENERATING_DOCUMENTATION)
template <typename T>
using as_default_on_t = typename T::template rebind_executor<
executor_with_default<typename T::executor_type> >::other;
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
/// Function helper to adapt an I/O object to use @c use_awaitable_t as its
/// default completion token type.
template <typename T>
static typename T::template rebind_executor<
executor_with_default<typename T::executor_type>
>::other
as_default_on(BOOST_ASIO_MOVE_ARG(T) object)
{
return typename as_default_on_t<typename decay<T>::type>::type(
BOOST_ASIO_MOVE_CAST(T)(object));
}
}; };
/// A completion token object that represents the currently executing coroutine. /// A completion token object that represents the currently executing coroutine.

View file

@ -18,6 +18,6 @@
// BOOST_ASIO_VERSION % 100 is the sub-minor version // BOOST_ASIO_VERSION % 100 is the sub-minor version
// BOOST_ASIO_VERSION / 100 % 1000 is the minor version // BOOST_ASIO_VERSION / 100 % 1000 is the minor version
// BOOST_ASIO_VERSION / 100000 is the major version // BOOST_ASIO_VERSION / 100000 is the major version
#define BOOST_ASIO_VERSION 101401 // 1.14.1 #define BOOST_ASIO_VERSION 101600 // 1.16.0
#endif // BOOST_ASIO_VERSION_HPP #endif // BOOST_ASIO_VERSION_HPP

View file

@ -55,6 +55,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the handle type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The handle type when rebound to the specified executor.
typedef basic_object_handle<Executor1> other;
};
/// The native representation of a handle. /// The native representation of a handle.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
@ -363,18 +371,17 @@ public:
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename WaitHandler> template <
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(
BOOST_ASIO_MOVE_ARG(WaitHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
boost::asio::async_completion<WaitHandler, return async_initiate<WaitHandler, void (boost::system::error_code)>(
void (boost::system::error_code)> init(handler); initiate_async_wait(this), handler);
impl_.get_service().async_wait(impl_.get_implementation(),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
} }
private: private:
@ -382,6 +389,38 @@ private:
basic_object_handle(const basic_object_handle&) BOOST_ASIO_DELETED; basic_object_handle(const basic_object_handle&) BOOST_ASIO_DELETED;
basic_object_handle& operator=(const basic_object_handle&) BOOST_ASIO_DELETED; basic_object_handle& operator=(const basic_object_handle&) BOOST_ASIO_DELETED;
class initiate_async_wait
{
public:
typedef Executor executor_type;
explicit initiate_async_wait(basic_object_handle* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self_->impl_.get_service().async_wait(
self_->impl_.get_implementation(), handler2.value,
self_->impl_.get_implementation_executor());
}
private:
basic_object_handle* self_;
};
boost::asio::detail::io_object_impl< boost::asio::detail::io_object_impl<
boost::asio::detail::win_object_handle_service, Executor> impl_; boost::asio::detail::win_object_handle_service, Executor> impl_;
}; };

View file

@ -58,6 +58,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the handle type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The handle type when rebound to the specified executor.
typedef basic_overlapped_handle<Executor1> other;
};
/// The native representation of a handle. /// The native representation of a handle.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;

View file

@ -44,6 +44,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the handle type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The handle type when rebound to the specified executor.
typedef basic_random_access_handle<Executor1> other;
};
/// The native representation of a handle. /// The native representation of a handle.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
@ -266,26 +274,20 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some_at(uint64_t offset, async_write_some_at(uint64_t offset,
const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_write_some_at(this), handler, offset, buffers);
boost::asio::async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_write_some_at(
this->impl_.get_implementation(), offset,
buffers, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
} }
/// Read some data from the handle at the specified offset. /// Read some data from the handle at the specified offset.
@ -394,27 +396,88 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some_at(uint64_t offset, async_read_some_at(uint64_t offset,
const MutableBufferSequence& buffers, const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
initiate_async_read_some_at(this), handler, offset, buffers);
}
private:
class initiate_async_write_some_at
{
public:
typedef Executor executor_type;
explicit initiate_async_write_some_at(basic_random_access_handle* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
uint64_t offset, const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self_->impl_.get_service().async_write_some_at(
self_->impl_.get_implementation(), offset, buffers, handler2.value,
self_->impl_.get_implementation_executor());
}
private:
basic_random_access_handle* self_;
};
class initiate_async_read_some_at
{
public:
typedef Executor executor_type;
explicit initiate_async_read_some_at(basic_random_access_handle* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
uint64_t offset, const MutableBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
boost::asio::async_completion<ReadHandler, detail::non_const_lvalue<ReadHandler> handler2(handler);
void (boost::system::error_code, std::size_t)> init(handler); self_->impl_.get_service().async_read_some_at(
self_->impl_.get_implementation(), offset, buffers, handler2.value,
this->impl_.get_service().async_read_some_at( self_->impl_.get_implementation_executor());
this->impl_.get_implementation(), offset,
buffers, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
} }
private:
basic_random_access_handle* self_;
};
}; };
} // namespace windows } // namespace windows

View file

@ -47,6 +47,14 @@ public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef Executor executor_type; typedef Executor executor_type;
/// Rebinds the handle type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The handle type when rebound to the specified executor.
typedef basic_stream_handle<Executor1> other;
};
/// The native representation of a handle. /// The native representation of a handle.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
@ -259,25 +267,19 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_write_some(this), handler, buffers);
boost::asio::async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_write_some(
this->impl_.get_implementation(),
buffers, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
} }
/// Read some data from the handle. /// Read some data from the handle.
@ -379,26 +381,87 @@ public:
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence,
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
initiate_async_read_some(this), handler, buffers);
}
private:
class initiate_async_write_some
{
public:
typedef Executor executor_type;
explicit initiate_async_write_some(basic_stream_handle* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self_->impl_.get_service().async_write_some(
self_->impl_.get_implementation(), buffers, handler2.value,
self_->impl_.get_implementation_executor());
}
private:
basic_stream_handle* self_;
};
class initiate_async_read_some
{
public:
typedef Executor executor_type;
explicit initiate_async_read_some(basic_stream_handle* self)
: self_(self)
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
const MutableBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
boost::asio::async_completion<ReadHandler, detail::non_const_lvalue<ReadHandler> handler2(handler);
void (boost::system::error_code, std::size_t)> init(handler); self_->impl_.get_service().async_read_some(
self_->impl_.get_implementation(), buffers, handler2.value,
this->impl_.get_service().async_read_some( self_->impl_.get_implementation_executor());
this->impl_.get_implementation(),
buffers, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
} }
private:
basic_stream_handle* self_;
};
}; };
} // namespace windows } // namespace windows

View file

@ -755,11 +755,16 @@ std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
* std::vector. * std::vector.
*/ */
template <typename AsyncWriteStream, typename ConstBufferSequence, template <typename AsyncWriteStream, typename ConstBufferSequence,
typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncWriteStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler, BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncWriteStream::executor_type),
typename enable_if< typename enable_if<
is_const_buffer_sequence<ConstBufferSequence>::value is_const_buffer_sequence<ConstBufferSequence>::value
>::type* = 0); >::type* = 0);
@ -831,9 +836,11 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename AsyncWriteStream, typename ConstBufferSequence, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename ConstBufferSequence, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
@ -887,13 +894,18 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncWriteStream, template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename DynamicBuffer_v1, typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncWriteStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, async_write(AsyncWriteStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler, BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncWriteStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
&& !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
@ -956,9 +968,11 @@ async_write(AsyncWriteStream& s,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncWriteStream, typename DynamicBuffer_v1, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename DynamicBuffer_v1, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, async_write(AsyncWriteStream& s,
BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@ -1013,11 +1027,17 @@ async_write(AsyncWriteStream& s,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncWriteStream, typename Allocator, typename WriteHandler> template <typename AsyncWriteStream, typename Allocator,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncWriteStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b, async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler); BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncWriteStream::executor_type));
/// Start an asynchronous operation to write a certain amount of data to a /// Start an asynchronous operation to write a certain amount of data to a
/// stream. /// stream.
@ -1074,9 +1094,11 @@ async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncWriteStream, typename Allocator, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename Allocator, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b, async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, CompletionCondition completion_condition,
@ -1129,12 +1151,17 @@ async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncWriteStream, template <typename AsyncWriteStream, typename DynamicBuffer_v2,
typename DynamicBuffer_v2, typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncWriteStream::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler, BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncWriteStream::executor_type),
typename enable_if< typename enable_if<
is_dynamic_buffer_v2<DynamicBuffer_v2>::value is_dynamic_buffer_v2<DynamicBuffer_v2>::value
>::type* = 0); >::type* = 0);
@ -1196,9 +1223,11 @@ async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncWriteStream, typename DynamicBuffer_v2, template <typename AsyncWriteStream,
typename CompletionCondition, typename WriteHandler> typename DynamicBuffer_v2, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,

View file

@ -457,12 +457,17 @@ std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset,
* std::vector. * std::vector.
*/ */
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessWriteDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,
const ConstBufferSequence& buffers, const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler); BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessWriteDevice::executor_type));
/// Start an asynchronous operation to write a certain amount of data at the /// Start an asynchronous operation to write a certain amount of data at the
/// specified offset. /// specified offset.
@ -535,14 +540,20 @@ async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
* std::vector. * std::vector.
*/ */
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, template <typename AsyncRandomAccessWriteDevice,
typename CompletionCondition, typename WriteHandler> typename ConstBufferSequence, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessWriteDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, const ConstBufferSequence& buffers, uint64_t offset, const ConstBufferSequence& buffers,
CompletionCondition completion_condition, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler); BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessWriteDevice::executor_type));
#if !defined(BOOST_ASIO_NO_EXTENSIONS) #if !defined(BOOST_ASIO_NO_EXTENSIONS)
#if !defined(BOOST_ASIO_NO_IOSTREAM) #if !defined(BOOST_ASIO_NO_IOSTREAM)
@ -593,11 +604,17 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncRandomAccessWriteDevice, typename Allocator, template <typename AsyncRandomAccessWriteDevice, typename Allocator,
typename WriteHandler> BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessWriteDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, async_write_at(AsyncRandomAccessWriteDevice& d,
basic_streambuf<Allocator>& b, BOOST_ASIO_MOVE_ARG(WriteHandler) handler); uint64_t offset, basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessWriteDevice::executor_type));
/// Start an asynchronous operation to write a certain amount of data at the /// Start an asynchronous operation to write a certain amount of data at the
/// specified offset. /// specified offset.
@ -658,13 +675,19 @@ async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,
* immediate completion, invocation of the handler will be performed in a * immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename AsyncRandomAccessWriteDevice, typename Allocator, template <typename AsyncRandomAccessWriteDevice,
typename CompletionCondition, typename WriteHandler> typename Allocator, typename CompletionCondition,
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
typename AsyncRandomAccessWriteDevice::executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t)) void (boost::system::error_code, std::size_t))
async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,
basic_streambuf<Allocator>& b, CompletionCondition completion_condition, basic_streambuf<Allocator>& b, CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler); BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
typename AsyncRandomAccessWriteDevice::executor_type));
#endif // !defined(BOOST_ASIO_NO_IOSTREAM) #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)

18
boost/atomic.hpp Normal file
View file

@ -0,0 +1,18 @@
#ifndef BOOST_ATOMIC_HPP
#define BOOST_ATOMIC_HPP
// Copyright (c) 2011 Helge Bahmann
//
// 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)
// This header includes all Boost.Atomic public headers
#include <boost/atomic/atomic.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#endif

104
boost/atomic/atomic.hpp Normal file
View file

@ -0,0 +1,104 @@
/*
* 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)
*
* Copyright (c) 2011 Helge Bahmann
* Copyright (c) 2013 Tim Blechmann
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/atomic.hpp
*
* This header contains definition of \c atomic template and \c atomic_flag.
*/
#ifndef BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_
#define BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_
#include <boost/atomic/capabilities.hpp>
#include <boost/atomic/fences.hpp>
#include <boost/atomic/atomic_flag.hpp>
#include <boost/atomic/detail/atomic_template.hpp>
#include <boost/atomic/detail/operations.hpp>
#include <boost/atomic/detail/extra_operations.hpp>
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#include <boost/atomic/detail/fp_operations.hpp>
#include <boost/atomic/detail/extra_fp_operations.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
using atomics::atomic;
using atomics::atomic_char;
using atomics::atomic_uchar;
using atomics::atomic_schar;
using atomics::atomic_uint8_t;
using atomics::atomic_int8_t;
using atomics::atomic_ushort;
using atomics::atomic_short;
using atomics::atomic_uint16_t;
using atomics::atomic_int16_t;
using atomics::atomic_uint;
using atomics::atomic_int;
using atomics::atomic_uint32_t;
using atomics::atomic_int32_t;
using atomics::atomic_ulong;
using atomics::atomic_long;
using atomics::atomic_uint64_t;
using atomics::atomic_int64_t;
#ifdef BOOST_HAS_LONG_LONG
using atomics::atomic_ullong;
using atomics::atomic_llong;
#endif
using atomics::atomic_address;
using atomics::atomic_bool;
using atomics::atomic_wchar_t;
#if !defined(BOOST_NO_CXX11_CHAR16_T)
using atomics::atomic_char16_t;
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
using atomics::atomic_char32_t;
#endif
using atomics::atomic_int_least8_t;
using atomics::atomic_uint_least8_t;
using atomics::atomic_int_least16_t;
using atomics::atomic_uint_least16_t;
using atomics::atomic_int_least32_t;
using atomics::atomic_uint_least32_t;
using atomics::atomic_int_least64_t;
using atomics::atomic_uint_least64_t;
using atomics::atomic_int_fast8_t;
using atomics::atomic_uint_fast8_t;
using atomics::atomic_int_fast16_t;
using atomics::atomic_uint_fast16_t;
using atomics::atomic_int_fast32_t;
using atomics::atomic_uint_fast32_t;
using atomics::atomic_int_fast64_t;
using atomics::atomic_uint_fast64_t;
using atomics::atomic_intmax_t;
using atomics::atomic_uintmax_t;
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
using atomics::atomic_float_t;
using atomics::atomic_double_t;
using atomics::atomic_long_double_t;
#endif
using atomics::atomic_size_t;
using atomics::atomic_ptrdiff_t;
#if defined(BOOST_HAS_INTPTR_T)
using atomics::atomic_intptr_t;
using atomics::atomic_uintptr_t;
#endif
} // namespace boost
#endif // BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_

View file

@ -0,0 +1,33 @@
/*
* 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)
*
* Copyright (c) 2011 Helge Bahmann
* Copyright (c) 2013 Tim Blechmann
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/atomic_flag.hpp
*
* This header contains definition of \c atomic_flag.
*/
#ifndef BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_
#define BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_
#include <boost/atomic/capabilities.hpp>
#include <boost/atomic/detail/operations.hpp>
#include <boost/atomic/detail/atomic_flag.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
using atomics::atomic_flag;
} // namespace boost
#endif // BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_

View file

@ -0,0 +1,210 @@
/*
* 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)
*
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/capabilities.hpp
*
* This header defines feature capabilities macros.
*/
#ifndef BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_
#define BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/platform.hpp>
#include <boost/atomic/detail/int_sizes.hpp>
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#include <boost/atomic/detail/float_sizes.hpp>
#endif
#if !defined(BOOST_ATOMIC_EMULATED)
#include BOOST_ATOMIC_DETAIL_BACKEND_HEADER(boost/atomic/detail/caps_)
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#ifndef BOOST_ATOMIC_INT8_LOCK_FREE
#define BOOST_ATOMIC_INT8_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_INT16_LOCK_FREE
#define BOOST_ATOMIC_INT16_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_INT32_LOCK_FREE
#define BOOST_ATOMIC_INT32_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_INT64_LOCK_FREE
#define BOOST_ATOMIC_INT64_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_INT128_LOCK_FREE
#define BOOST_ATOMIC_INT128_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_CHAR_LOCK_FREE
#define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#endif
#ifndef BOOST_ATOMIC_CHAR16_T_LOCK_FREE
#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#endif
#ifndef BOOST_ATOMIC_CHAR32_T_LOCK_FREE
#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#endif
#ifndef BOOST_ATOMIC_WCHAR_T_LOCK_FREE
#if BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#else
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0
#endif
#endif
#ifndef BOOST_ATOMIC_SHORT_LOCK_FREE
#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1
#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2
#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4
#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8
#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#else
#define BOOST_ATOMIC_SHORT_LOCK_FREE 0
#endif
#endif
#ifndef BOOST_ATOMIC_INT_LOCK_FREE
#if BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1
#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2
#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4
#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8
#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#else
#define BOOST_ATOMIC_INT_LOCK_FREE 0
#endif
#endif
#ifndef BOOST_ATOMIC_LONG_LOCK_FREE
#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1
#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2
#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4
#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8
#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#else
#define BOOST_ATOMIC_LONG_LOCK_FREE 0
#endif
#endif
#ifndef BOOST_ATOMIC_LLONG_LOCK_FREE
#if BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1
#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2
#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4
#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8
#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#else
#define BOOST_ATOMIC_LLONG_LOCK_FREE 0
#endif
#endif
#ifndef BOOST_ATOMIC_POINTER_LOCK_FREE
#if (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 8
#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 4
#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#else
#define BOOST_ATOMIC_POINTER_LOCK_FREE 0
#endif
#endif
#define BOOST_ATOMIC_ADDRESS_LOCK_FREE BOOST_ATOMIC_POINTER_LOCK_FREE
#ifndef BOOST_ATOMIC_BOOL_LOCK_FREE
// We store bools in 1-byte storage in all backends
#define BOOST_ATOMIC_BOOL_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#endif
#ifndef BOOST_ATOMIC_FLAG_LOCK_FREE
#define BOOST_ATOMIC_FLAG_LOCK_FREE BOOST_ATOMIC_BOOL_LOCK_FREE
#endif
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#if !defined(BOOST_ATOMIC_FLOAT_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT)
#if BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 2
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 4
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 8
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 16
#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#else
#define BOOST_ATOMIC_FLOAT_LOCK_FREE 0
#endif
#endif
#if !defined(BOOST_ATOMIC_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE)
#if BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 2
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 4
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 8
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 16
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#else
#define BOOST_ATOMIC_DOUBLE_LOCK_FREE 0
#endif
#endif
#if !defined(BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 2
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 4
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 8
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 16
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#else
#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE 0
#endif
#endif
#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
#ifndef BOOST_ATOMIC_THREAD_FENCE
#define BOOST_ATOMIC_THREAD_FENCE 0
#endif
#ifndef BOOST_ATOMIC_SIGNAL_FENCE
#define BOOST_ATOMIC_SIGNAL_FENCE 0
#endif
#endif // BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_

View file

@ -0,0 +1,58 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/addressof.hpp
*
* This header defines \c addressof helper function. It is similar to \c boost::addressof but it is more
* lightweight and also contains a workaround for some compiler warnings.
*/
#ifndef BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
// Detection logic is based on boost/core/addressof.hpp
#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
#elif defined(BOOST_GCC) && BOOST_GCC >= 70000
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
#elif defined(__has_builtin)
#if __has_builtin(__builtin_addressof)
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
#endif
#endif
namespace boost {
namespace atomics {
namespace detail {
template< typename T >
BOOST_FORCEINLINE T* addressof(T& value) BOOST_NOEXCEPT
{
#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF)
return __builtin_addressof(value);
#else
// Note: The point of using a local struct as the intermediate type instead of char is to avoid gcc warnings
// if T is a const volatile char*:
// warning: casting 'const volatile char* const' to 'const volatile char&' does not dereference pointer
// The local struct makes sure T is not related to the cast target type.
struct opaque_type;
return reinterpret_cast< T* >(&const_cast< opaque_type& >(reinterpret_cast< const volatile opaque_type& >(value)));
#endif
}
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_

View file

@ -0,0 +1,71 @@
/*
* 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)
*
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/atomic_flag.hpp
*
* This header contains interface definition of \c atomic_flag.
*/
#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_
#include <boost/assert.hpp>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/operations_lockfree.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
/*
* IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
* see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
*/
namespace boost {
namespace atomics {
#if defined(BOOST_NO_CXX11_CONSTEXPR) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
#define BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT
#else
#define BOOST_ATOMIC_FLAG_INIT {}
#endif
struct atomic_flag
{
typedef atomics::detail::operations< 1u, false > operations;
typedef operations::storage_type storage_type;
operations::aligned_storage_type m_storage;
BOOST_FORCEINLINE BOOST_CONSTEXPR atomic_flag() BOOST_NOEXCEPT : m_storage(0)
{
}
BOOST_FORCEINLINE bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return operations::test_and_set(m_storage.value, order);
}
BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
BOOST_ASSERT(order != memory_order_consume);
BOOST_ASSERT(order != memory_order_acquire);
BOOST_ASSERT(order != memory_order_acq_rel);
operations::clear(m_storage.value, order);
}
BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&))
};
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,68 @@
/*
* 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)
*
* Copyright (c) 2009 Helge Bahmann
* Copyright (c) 2012 Tim Blechmann
* Copyright (c) 2013 - 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/bitwise_cast.hpp
*
* This header defines \c bitwise_cast used to convert between storage and value types
*/
#ifndef BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
#include <cstddef>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/addressof.hpp>
#include <boost/atomic/detail/string_ops.hpp>
#include <boost/atomic/detail/type_traits/integral_constant.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
template< std::size_t FromSize, typename To >
BOOST_FORCEINLINE void clear_padding(To& to, atomics::detail::true_type) BOOST_NOEXCEPT
{
BOOST_ATOMIC_DETAIL_MEMSET(reinterpret_cast< unsigned char* >(atomics::detail::addressof(to)) + FromSize, 0, sizeof(To) - FromSize);
}
template< std::size_t FromSize, typename To >
BOOST_FORCEINLINE void clear_padding(To&, atomics::detail::false_type) BOOST_NOEXCEPT
{
}
template< typename To, std::size_t FromSize, typename From >
BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
{
To to;
BOOST_ATOMIC_DETAIL_MEMCPY
(
atomics::detail::addressof(to),
atomics::detail::addressof(from),
(FromSize < sizeof(To) ? FromSize : sizeof(To))
);
atomics::detail::clear_padding< FromSize >(to, atomics::detail::integral_constant< bool, FromSize < sizeof(To) >());
return to;
}
template< typename To, typename From >
BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
{
return atomics::detail::bitwise_cast< To, sizeof(From) >(from);
}
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_

View file

@ -0,0 +1,86 @@
/*
* 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)
*
* Copyright (c) 2018 Andrey Semashev
*/
/*!
* \file atomic/detail/bitwise_fp_cast.hpp
*
* This header defines \c bitwise_fp_cast used to convert between storage and floating point value types
*/
#ifndef BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
#include <cstddef>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/float_sizes.hpp>
#include <boost/atomic/detail/bitwise_cast.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
/*!
* \brief The type trait returns the size of the value of the specified floating point type
*
* This size may be less than <tt>sizeof(T)</tt> if the implementation uses padding bytes for a particular FP type. This is
* often the case with 80-bit extended double, which is stored in 12 or 16 bytes with padding filled with garbage.
*/
template< typename T >
struct value_sizeof
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = sizeof(T);
};
#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE)
template< >
struct value_sizeof< float >
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE;
};
#endif
#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE)
template< >
struct value_sizeof< double >
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE;
};
#endif
#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE)
template< >
struct value_sizeof< long double >
{
static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE;
};
#endif
template< typename T >
struct value_sizeof< const T > : value_sizeof< T > {};
template< typename T >
struct value_sizeof< volatile T > : value_sizeof< T > {};
template< typename T >
struct value_sizeof< const volatile T > : value_sizeof< T > {};
template< typename To, typename From >
BOOST_FORCEINLINE To bitwise_fp_cast(From const& from) BOOST_NOEXCEPT
{
return atomics::detail::bitwise_cast< To, atomics::detail::value_sizeof< From >::value >(from);
}
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_

View file

@ -0,0 +1,34 @@
/*
* 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)
*
* Copyright (c) 2009 Helge Bahmann
* Copyright (c) 2013 Tim Blechmann
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_gcc_alpha.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_

View file

@ -0,0 +1,39 @@
/*
* 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)
*
* Copyright (c) 2009 Helge Bahmann
* Copyright (c) 2009 Phil Endecott
* Copyright (c) 2013 Tim Blechmann
* ARM Code by Phil Endecott, based on other architectures.
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_gcc_arm.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD)
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#endif
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_

View file

@ -0,0 +1,133 @@
/*
* 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)
*
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_gcc_atomic.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/int_sizes.hpp>
#if defined(__i386__) || defined(__x86_64__)
#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
#elif defined(__arm__)
#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
#elif defined(__POWERPC__) || defined(__PPC__)
#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT))
#define BOOST_ATOMIC_INT128_LOCK_FREE 2
#else
#define BOOST_ATOMIC_INT128_LOCK_FREE 0
#endif
#if (__GCC_ATOMIC_LLONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8)
#define BOOST_ATOMIC_LLONG_LOCK_FREE 2
#else
#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
#endif
#if (__GCC_ATOMIC_LONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8)
#define BOOST_ATOMIC_LONG_LOCK_FREE 2
#else
#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
#endif
#if __GCC_ATOMIC_INT_LOCK_FREE == 2
#define BOOST_ATOMIC_INT_LOCK_FREE 2
#else
#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
#endif
#if __GCC_ATOMIC_SHORT_LOCK_FREE == 2
#define BOOST_ATOMIC_SHORT_LOCK_FREE 2
#else
#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
#endif
#if __GCC_ATOMIC_CHAR_LOCK_FREE == 2
#define BOOST_ATOMIC_CHAR_LOCK_FREE 2
#else
#define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
#endif
#if __GCC_ATOMIC_POINTER_LOCK_FREE == 2
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#else
#define BOOST_ATOMIC_POINTER_LOCK_FREE 0
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE BOOST_ATOMIC_CHAR_LOCK_FREE
#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2
#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2
#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2
#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2
#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
#else
#define BOOST_ATOMIC_INT16_LOCK_FREE 0
#endif
#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4
#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4
#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4
#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4
#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
#else
#define BOOST_ATOMIC_INT32_LOCK_FREE 0
#endif
#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8
#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8
#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8
#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8
#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
#else
#define BOOST_ATOMIC_INT64_LOCK_FREE 0
#endif
#if __GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
#else
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0
#endif
#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_

View file

@ -0,0 +1,37 @@
/*
* 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)
*
* Copyright (c) 2009 Helge Bahmann
* Copyright (c) 2013 Tim Blechmann
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_gcc_ppc.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#endif
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_

View file

@ -0,0 +1,34 @@
/*
* 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)
*
* Copyright (c) 2010 Helge Bahmann
* Copyright (c) 2013 Tim Blechmann
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_gcc_sparc.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_

View file

@ -0,0 +1,61 @@
/*
* 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)
*
* Copyright (c) 2011 Helge Bahmann
* Copyright (c) 2013 Tim Blechmann
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_gcc_sync.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#if defined(__i386__) || defined(__x86_64__)
#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
#elif defined(__arm__)
#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
#elif defined(__POWERPC__) || defined(__PPC__)
#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT128_LOCK_FREE 2
#endif
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_

View file

@ -0,0 +1,40 @@
/*
* 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)
*
* Copyright (c) 2009 Helge Bahmann
* Copyright (c) 2012 Tim Blechmann
* Copyright (c) 2013 - 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_gcc_x86.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#if defined(__x86_64__) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#endif
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT))
#define BOOST_ATOMIC_INT128_LOCK_FREE 2
#endif
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_

View file

@ -0,0 +1,35 @@
/*
* 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)
*
* Copyright (c) 2009, 2011 Helge Bahmann
* Copyright (c) 2009 Phil Endecott
* Copyright (c) 2013 Tim Blechmann
* Linux-specific code by Phil Endecott
* Copyright (c) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/caps_linux_arm.hpp
*
* This header defines feature capabilities macros
*/
#ifndef BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2
#endif // BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_

Some files were not shown because too many files have changed in this diff Show more