Update to v1.82.0.

This commit is contained in:
Zangetsu38 2023-02-23 01:17:39 +01:00
parent 508872dea2
commit 42df183321
3346 changed files with 218342 additions and 74792 deletions

View File

@ -144,7 +144,7 @@ import option ;
import tools/boost\_install/boost-install ;
path-constant BOOST_ROOT : . ;
constant BOOST_VERSION : 1.78.0 ;
constant BOOST_VERSION : 1.82.0 ;
constant BOOST_JAMROOT_MODULE : $(__name__) ;
# Allow subprojects to simply `import config : requires ;` to get access to the requires rule

View File

@ -1,6 +1,6 @@
# Boost libraries - trimmed down for Vita3K
This is a subset of Boost v1.78.0 generated using the bcp tool. To get a list of boost modules guaranteed to exist, check the build script.
This is a subset of Boost v1.82.0 generated using the bcp tool. To get a list of boost modules guaranteed to exist, check the build script.
Adapted from [citra-emu/ext-boost](https://github.com/citra-emu/ext-boost).
## Updating this repo
@ -10,8 +10,7 @@ To update the Boost version (or to add a new library) follow these steps:
- Download [`boost`](https://boost.org) and extract the package.
- Copy `update.sh` or `update.cmd` in this repo to extracted directory of `boost`.
- `cd` to extracted `boost` directory and run `update` script. The trimed down version of `boost` will be in the `subsets-boost` directory.
- Copy `update.sh`, `update.bat`, `.gitignore`, and `README.md` in this repo to another directory.
- Copy `update.sh`, `update.bat`, `.gitignore`, and `README.md` in this repo to subsets-boost directory.
- Remove all the files in this directory (except the `.git` directory).
- Copy all files in `subsets-boost` to this repo directory.
- Copy `update.sh`, `update.bat`, `.gitignore`, and `README.md` back to this repo directory.
- Commit all changes.

View File

@ -40,10 +40,18 @@ namespace boost {
// Protected construction/destruction
// Default constructor
find_iterator_base() {}
BOOST_DEFAULTED_FUNCTION(find_iterator_base(), {})
// Copy construction
find_iterator_base( const find_iterator_base& Other ) :
BOOST_DEFAULTED_FUNCTION(find_iterator_base( const find_iterator_base& Other ), :
m_Finder(Other.m_Finder) {}
)
// Assignment
BOOST_DEFAULTED_FUNCTION(find_iterator_base& operator=( const find_iterator_base& Other ), {
m_Finder = Other.m_Finder;
return *this;
})
// Constructor
template<typename FinderT>
@ -51,7 +59,7 @@ namespace boost {
m_Finder(Finder) {}
// Destructor
~find_iterator_base() {}
BOOST_DEFAULTED_FUNCTION(~find_iterator_base(), {})
// Find operation
match_type do_find(

View File

@ -74,7 +74,7 @@ namespace boost {
\post eof()==true
*/
find_iterator() {}
BOOST_DEFAULTED_FUNCTION(find_iterator(), {})
//! Copy constructor
/*!
@ -85,6 +85,18 @@ namespace boost {
m_Match(Other.m_Match),
m_End(Other.m_End) {}
//! Copy assignment
/*!
Assigns a copy of the find_iterator
*/
BOOST_DEFAULTED_FUNCTION(find_iterator& operator=( const find_iterator& Other ), {
if (this == &Other) return *this;
this->base_type::operator=(Other);
m_Match = Other.m_Match;
m_End = Other.m_End;
return *this;
})
//! Constructor
/*!
Construct new find_iterator for a given finder
@ -248,6 +260,20 @@ namespace boost {
m_bEof(Other.m_bEof)
{}
//! Assignment operator
/*!
Assigns a copy of the split_iterator
*/
BOOST_DEFAULTED_FUNCTION(split_iterator& operator=( const split_iterator& Other ), {
if (this == &Other) return *this;
this->base_type::operator=(Other);
m_Match = Other.m_Match;
m_Next = Other.m_Next;
m_End = Other.m_End;
m_bEof = Other.m_bEof;
return *this;
})
//! Constructor
/*!
Construct new split_iterator for a given finder

View File

@ -38,7 +38,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/align/detail/aligned_alloc_posix.hpp>
#elif defined(sun) || defined(__sun)
#include <boost/align/detail/aligned_alloc_sunos.hpp>
#elif (_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600)
#elif defined(_POSIX_VERSION)
#include <boost/align/detail/aligned_alloc_posix.hpp>
#else
#include <boost/align/detail/aligned_alloc.hpp>

View File

@ -26,7 +26,7 @@
#include <boost/type_traits/is_const.hpp>
#include <boost/throw_exception.hpp>
#include <boost/static_assert.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/core/addressof.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/conditional.hpp>
@ -335,7 +335,7 @@ namespace boost
}
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
// Copyright Antony Polukhin, 2013-2021.
// Copyright Antony Polukhin, 2013-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2020-2021.
// Copyright Antony Polukhin, 2020-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2021.
// Copyright Antony Polukhin, 2021-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@ -1,100 +0,0 @@
#ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// archive/archive_exception.hpp:
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to 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.
#include <exception>
#include <boost/assert.hpp>
#include <string>
#include <boost/config.hpp>
#include <boost/archive/detail/decl.hpp>
// note: the only reason this is in here is that windows header
// includes #define exception_code _exception_code (arrrgghhhh!).
// the most expedient way to address this is be sure that this
// header is always included whenever this header file is included.
#if defined(BOOST_WINDOWS)
#include <excpt.h>
#endif
#include <boost/archive/detail/abi_prefix.hpp> // must be the last header
namespace boost {
namespace archive {
//////////////////////////////////////////////////////////////////////
// exceptions thrown by archives
//
class BOOST_SYMBOL_VISIBLE archive_exception :
public virtual std::exception
{
private:
char m_buffer[128];
protected:
BOOST_ARCHIVE_DECL unsigned int
append(unsigned int l, const char * a);
BOOST_ARCHIVE_DECL
archive_exception() BOOST_NOEXCEPT;
public:
typedef enum {
no_exception, // initialized without code
other_exception, // any exception not listed below
unregistered_class, // attempt to serialize a pointer of
// an unregistered class
invalid_signature, // first line of archive does not contain
// expected string
unsupported_version,// archive created with library version
// subsequent to this one
pointer_conflict, // an attempt has been made to directly
// serialize an object which has
// already been serialized through a pointer.
// Were this permitted, the archive load would result
// in the creation of an extra copy of the object.
incompatible_native_format, // attempt to read native binary format
// on incompatible platform
array_size_too_short,// array being loaded doesn't fit in array allocated
input_stream_error, // error on input stream
invalid_class_name, // class name greater than the maximum permitted.
// most likely a corrupted archive or an attempt
// to insert virus via buffer overrun method.
unregistered_cast, // base - derived relationship not registered with
// void_cast_register
unsupported_class_version, // type saved with a version # greater than the
// one used by the program. This indicates that the program
// needs to be rebuilt.
multiple_code_instantiation, // code for implementing serialization for some
// type has been instantiated in more than one module.
output_stream_error // error on input stream
} exception_code;
exception_code code;
BOOST_ARCHIVE_DECL archive_exception(
exception_code c,
const char * e1 = NULL,
const char * e2 = NULL
) BOOST_NOEXCEPT;
BOOST_ARCHIVE_DECL archive_exception(archive_exception const &) BOOST_NOEXCEPT;
BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE;
BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE;
};
}// namespace archive
}// namespace boost
#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP

View File

@ -1,16 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// abi_prefix.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to 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.
#include <boost/config/abi_prefix.hpp> // must be the last header
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4251 4231 4660 4275)
#endif

View File

@ -1,15 +0,0 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// abi_suffix.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to 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.
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas

View File

@ -1,57 +0,0 @@
#ifndef BOOST_ARCHIVE_DETAIL_DECL_HPP
#define BOOST_ARCHIVE_DETAIL_DECL_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8
// decl.hpp
//
// (c) Copyright Robert Ramey 2004
// Use, modification, and distribution is subject to 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 library home page at http://www.boost.org/libs/serialization
//----------------------------------------------------------------------------//
// This header implements separate compilation features as described in
// http://www.boost.org/more/separate_compilation.html
#include <boost/config.hpp>
#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK))
#if defined(BOOST_ARCHIVE_SOURCE)
#define BOOST_ARCHIVE_DECL BOOST_SYMBOL_EXPORT
#else
#define BOOST_ARCHIVE_DECL BOOST_SYMBOL_IMPORT
#endif
#if defined(BOOST_WARCHIVE_SOURCE)
#define BOOST_WARCHIVE_DECL BOOST_SYMBOL_EXPORT
#else
#define BOOST_WARCHIVE_DECL BOOST_SYMBOL_IMPORT
#endif
#if defined(BOOST_WARCHIVE_SOURCE) || defined(BOOST_ARCHIVE_SOURCE)
#define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_EXPORT
#else
#define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_IMPORT
#endif
#endif
#if ! defined(BOOST_ARCHIVE_DECL)
#define BOOST_ARCHIVE_DECL
#endif
#if ! defined(BOOST_WARCHIVE_DECL)
#define BOOST_WARCHIVE_DECL
#endif
#if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL)
#define BOOST_ARCHIVE_OR_WARCHIVE_DECL
#endif
#endif // BOOST_ARCHIVE_DETAIL_DECL_HPP

View File

@ -44,8 +44,8 @@
#include <iterator>
#include <stdexcept>
#include <boost/assert.hpp>
#include <boost/core/swap.hpp>
#include <boost/static_assert.hpp>
#include <boost/swap.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>

View File

@ -2,7 +2,7 @@
// any_io_executor.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -124,6 +124,40 @@ public:
}
#endif // defined(GENERATING_DOCUMENTATION)
/// Construct to point to the same target as another any_executor.
#if defined(GENERATING_DOCUMENTATION)
template <class... OtherSupportableProperties>
any_io_executor(std::nothrow_t,
execution::any_executor<OtherSupportableProperties...> e);
#else // defined(GENERATING_DOCUMENTATION)
template <typename OtherAnyExecutor>
any_io_executor(std::nothrow_t, OtherAnyExecutor e,
typename constraint<
conditional<
!is_same<OtherAnyExecutor, any_io_executor>::value
&& is_base_of<execution::detail::any_executor_base,
OtherAnyExecutor>::value,
typename execution::detail::supportable_properties<
0, supportable_properties_type>::template
is_valid_target<OtherAnyExecutor>,
false_type
>::type::value
>::type = 0) BOOST_ASIO_NOEXCEPT
: base_type(std::nothrow, BOOST_ASIO_MOVE_CAST(OtherAnyExecutor)(e))
{
}
#endif // defined(GENERATING_DOCUMENTATION)
/// Construct to point to the same target as another any_executor.
BOOST_ASIO_DECL any_io_executor(std::nothrow_t,
const any_io_executor& e) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Construct to point to the same target as another any_executor.
BOOST_ASIO_DECL any_io_executor(std::nothrow_t,
any_io_executor&& e) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Construct a polymorphic wrapper for the specified executor.
#if defined(GENERATING_DOCUMENTATION)
template <BOOST_ASIO_EXECUTION_EXECUTOR Executor>
@ -146,6 +180,28 @@ public:
}
#endif // defined(GENERATING_DOCUMENTATION)
/// Construct a polymorphic wrapper for the specified executor.
#if defined(GENERATING_DOCUMENTATION)
template <BOOST_ASIO_EXECUTION_EXECUTOR Executor>
any_io_executor(std::nothrow_t, Executor e);
#else // defined(GENERATING_DOCUMENTATION)
template <BOOST_ASIO_EXECUTION_EXECUTOR Executor>
any_io_executor(std::nothrow_t, Executor e,
typename constraint<
conditional<
!is_same<Executor, any_io_executor>::value
&& !is_base_of<execution::detail::any_executor_base,
Executor>::value,
execution::detail::is_valid_target_executor<
Executor, supportable_properties_type>,
false_type
>::type::value
>::type = 0) BOOST_ASIO_NOEXCEPT
: base_type(std::nothrow, BOOST_ASIO_MOVE_CAST(Executor)(e))
{
}
#endif // defined(GENERATING_DOCUMENTATION)
/// Assignment operator.
BOOST_ASIO_DECL any_io_executor& operator=(
const any_io_executor& e) BOOST_ASIO_NOEXCEPT;

View File

@ -2,7 +2,7 @@
// associated_allocator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -38,42 +38,58 @@ struct has_allocator_type : false_type
template <typename T>
struct has_allocator_type<T,
typename void_type<typename T::executor_type>::type>
typename void_type<typename T::allocator_type>::type>
: true_type
{
};
template <typename T, typename E, typename = void, typename = void>
template <typename T, typename A, typename = void, typename = void>
struct associated_allocator_impl
{
typedef E type;
typedef void asio_associated_allocator_is_unspecialised;
static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
typedef A type;
static type get(const T&) BOOST_ASIO_NOEXCEPT
{
return e;
return type();
}
static const type& get(const T&, const A& a) BOOST_ASIO_NOEXCEPT
{
return a;
}
};
template <typename T, typename E>
struct associated_allocator_impl<T, E,
template <typename T, typename A>
struct associated_allocator_impl<T, A,
typename void_type<typename T::allocator_type>::type>
{
typedef typename T::allocator_type type;
static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T& t) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator()))
{
return t.get_allocator();
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T& t, const A&) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator()))
{
return t.get_allocator();
}
};
template <typename T, typename E>
struct associated_allocator_impl<T, E,
template <typename T, typename A>
struct associated_allocator_impl<T, A,
typename enable_if<
!has_allocator_type<T>::value
>::type,
typename void_type<
typename associator<associated_allocator, T, E>::type
>::type> : associator<associated_allocator, T, E>
typename associator<associated_allocator, T, A>::type
>::type> : associator<associated_allocator, T, A>
{
};
@ -93,29 +109,32 @@ struct associated_allocator_impl<T, E,
* Allocator requirements.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t) and with return type @c type.
* get(t) and with return type @c type or a (possibly const) reference to @c
* type.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t,a) and with return type @c type.
* get(t,a) and with return type @c type or a (possibly const) reference to @c
* type.
*/
template <typename T, typename Allocator = std::allocator<void> >
struct associated_allocator
#if !defined(GENERATING_DOCUMENTATION)
: detail::associated_allocator_impl<T, Allocator>
#endif // !defined(GENERATING_DOCUMENTATION)
{
#if defined(GENERATING_DOCUMENTATION)
/// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
/// Otherwise @c Allocator.
#if defined(GENERATING_DOCUMENTATION)
typedef see_below type;
#else // defined(GENERATING_DOCUMENTATION)
typedef typename detail::associated_allocator_impl<T, Allocator>::type type;
#endif // defined(GENERATING_DOCUMENTATION)
/// If @c T has a nested type @c allocator_type, returns
/// <tt>t.get_allocator()</tt>. Otherwise returns @c type().
static decltype(auto) get(const T& t) BOOST_ASIO_NOEXCEPT;
/// If @c T has a nested type @c allocator_type, returns
/// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
static type get(const T& t,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return detail::associated_allocator_impl<T, Allocator>::get(t, a);
}
static decltype(auto) get(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT;
#endif // defined(GENERATING_DOCUMENTATION)
};
/// Helper function to obtain an object's associated allocator.
@ -123,7 +142,7 @@ struct associated_allocator
* @returns <tt>associated_allocator<T>::get(t)</tt>
*/
template <typename T>
inline typename associated_allocator<T>::type
BOOST_ASIO_NODISCARD inline typename associated_allocator<T>::type
get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<T>::get(t);
@ -134,8 +153,11 @@ get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
* @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
*/
template <typename T, typename Allocator>
inline typename associated_allocator<T, Allocator>::type
BOOST_ASIO_NODISCARD inline BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename associated_allocator<T, Allocator>::type)
get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_allocator<T, Allocator>::get(t, a)))
{
return associated_allocator<T, Allocator>::get(t, a);
}
@ -148,12 +170,37 @@ using associated_allocator_t
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
namespace detail {
template <typename T, typename A, typename = void>
struct associated_allocator_forwarding_base
{
};
template <typename T, typename A>
struct associated_allocator_forwarding_base<T, A,
typename enable_if<
is_same<
typename associated_allocator<T,
A>::asio_associated_allocator_is_unspecialised,
void
>::value
>::type>
{
typedef void asio_associated_allocator_is_unspecialised;
};
} // namespace detail
#if defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER) \
|| defined(GENERATING_DOCUMENTATION)
/// Specialisation of associated_allocator for @c std::reference_wrapper.
template <typename T, typename Allocator>
struct associated_allocator<reference_wrapper<T>, Allocator>
#if !defined(GENERATING_DOCUMENTATION)
: detail::associated_allocator_forwarding_base<T, Allocator>
#endif // !defined(GENERATING_DOCUMENTATION)
{
/// Forwards @c type to the associator specialisation for the unwrapped type
/// @c T.
@ -161,8 +208,17 @@ struct associated_allocator<reference_wrapper<T>, Allocator>
/// Forwards the request to get the allocator to the associator specialisation
/// for the unwrapped type @c T.
static type get(reference_wrapper<T> t,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
static type get(reference_wrapper<T> t) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<T, Allocator>::get(t.get());
}
/// Forwards the request to get the allocator to the associator specialisation
/// for the unwrapped type @c T.
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
reference_wrapper<T> t, const Allocator& a) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_allocator<T, Allocator>::get(t.get(), a)))
{
return associated_allocator<T, Allocator>::get(t.get(), a);
}

View File

@ -2,7 +2,7 @@
// associated_cancellation_slot.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -18,6 +18,7 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/associator.hpp>
#include <boost/asio/cancellation_signal.hpp>
#include <boost/asio/detail/functional.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/push_options.hpp>
@ -49,7 +50,12 @@ struct associated_cancellation_slot_impl
typedef S type;
static type get(const T&, const S& s = S()) BOOST_ASIO_NOEXCEPT
static type get(const T&) BOOST_ASIO_NOEXCEPT
{
return type();
}
static const type& get(const T&, const S& s) BOOST_ASIO_NOEXCEPT
{
return s;
}
@ -61,7 +67,16 @@ struct associated_cancellation_slot_impl<T, S,
{
typedef typename T::cancellation_slot_type type;
static type get(const T& t, const S& = S()) BOOST_ASIO_NOEXCEPT
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T& t) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot()))
{
return t.get_cancellation_slot();
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T& t, const S&) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot()))
{
return t.get_cancellation_slot();
}
@ -94,10 +109,12 @@ struct associated_cancellation_slot_impl<T, S,
* CancellationSlot requirements.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t) and with return type @c type.
* get(t) and with return type @c type or a (possibly const) reference to @c
* type.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t,s) and with return type @c type.
* get(t,s) and with return type @c type or a (possibly const) reference to @c
* type.
*/
template <typename T, typename CancellationSlot = cancellation_slot>
struct associated_cancellation_slot
@ -111,10 +128,14 @@ struct associated_cancellation_slot
/// @c CancellationSlot.
typedef see_below type;
/// If @c T has a nested type @c cancellation_slot_type, returns
/// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c type().
static decltype(auto) get(const T& t) BOOST_ASIO_NOEXCEPT;
/// If @c T has a nested type @c cancellation_slot_type, returns
/// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c s.
static type get(const T& t,
const CancellationSlot& s = CancellationSlot()) BOOST_ASIO_NOEXCEPT;
static decltype(auto) get(const T& t,
const CancellationSlot& s) BOOST_ASIO_NOEXCEPT;
#endif // defined(GENERATING_DOCUMENTATION)
};
@ -123,7 +144,7 @@ struct associated_cancellation_slot
* @returns <tt>associated_cancellation_slot<T>::get(t)</tt>
*/
template <typename T>
inline typename associated_cancellation_slot<T>::type
BOOST_ASIO_NODISCARD inline typename associated_cancellation_slot<T>::type
get_associated_cancellation_slot(const T& t) BOOST_ASIO_NOEXCEPT
{
return associated_cancellation_slot<T>::get(t);
@ -135,9 +156,12 @@ get_associated_cancellation_slot(const T& t) BOOST_ASIO_NOEXCEPT
* CancellationSlot>::get(t, st)</tt>
*/
template <typename T, typename CancellationSlot>
inline typename associated_cancellation_slot<T, CancellationSlot>::type
BOOST_ASIO_NODISCARD inline BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename associated_cancellation_slot<T, CancellationSlot>::type)
get_associated_cancellation_slot(const T& t,
const CancellationSlot& st) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_cancellation_slot<T, CancellationSlot>::get(t, st)))
{
return associated_cancellation_slot<T, CancellationSlot>::get(t, st);
}
@ -171,6 +195,43 @@ struct associated_cancellation_slot_forwarding_base<T, S,
};
} // namespace detail
#if defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER) \
|| defined(GENERATING_DOCUMENTATION)
/// Specialisation of associated_cancellation_slot for @c
/// std::reference_wrapper.
template <typename T, typename CancellationSlot>
struct associated_cancellation_slot<reference_wrapper<T>, CancellationSlot>
#if !defined(GENERATING_DOCUMENTATION)
: detail::associated_cancellation_slot_forwarding_base<T, CancellationSlot>
#endif // !defined(GENERATING_DOCUMENTATION)
{
/// Forwards @c type to the associator specialisation for the unwrapped type
/// @c T.
typedef typename associated_cancellation_slot<T, CancellationSlot>::type type;
/// Forwards the request to get the cancellation slot to the associator
/// specialisation for the unwrapped type @c T.
static type get(reference_wrapper<T> t) BOOST_ASIO_NOEXCEPT
{
return associated_cancellation_slot<T, CancellationSlot>::get(t.get());
}
/// Forwards the request to get the cancellation slot to the associator
/// specialisation for the unwrapped type @c T.
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(reference_wrapper<T> t,
const CancellationSlot& s) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s)))
{
return associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s);
}
};
#endif // defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER)
// || defined(GENERATING_DOCUMENTATION)
} // namespace asio
} // namespace boost

View File

@ -2,7 +2,7 @@
// associated_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -52,7 +52,12 @@ struct associated_executor_impl
typedef E type;
static type get(const T&, const E& e = E()) BOOST_ASIO_NOEXCEPT
static type get(const T&) BOOST_ASIO_NOEXCEPT
{
return type();
}
static const type& get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
{
return e;
}
@ -64,7 +69,16 @@ struct associated_executor_impl<T, E,
{
typedef typename T::executor_type type;
static type get(const T& t, const E& = E()) BOOST_ASIO_NOEXCEPT
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T& t) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor()))
{
return t.get_executor();
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T& t, const E&) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor()))
{
return t.get_executor();
}
@ -97,10 +111,12 @@ struct associated_executor_impl<T, E,
* Executor requirements.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t) and with return type @c type.
* get(t) and with return type @c type or a (possibly const) reference to @c
* type.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t,e) and with return type @c type.
* get(t,e) and with return type @c type or a (possibly const) reference to @c
* type.
*/
template <typename T, typename Executor = system_executor>
struct associated_executor
@ -113,10 +129,13 @@ struct associated_executor
/// Otherwise @c Executor.
typedef see_below type;
/// If @c T has a nested type @c executor_type, returns
/// <tt>t.get_executor()</tt>. Otherwise returns @c type().
static decltype(auto) get(const T& t) BOOST_ASIO_NOEXCEPT;
/// If @c T has a nested type @c executor_type, returns
/// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
static type get(const T& t,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT;
static decltype(auto) get(const T& t, const Executor& ex) BOOST_ASIO_NOEXCEPT;
#endif // defined(GENERATING_DOCUMENTATION)
};
@ -125,7 +144,7 @@ struct associated_executor
* @returns <tt>associated_executor<T>::get(t)</tt>
*/
template <typename T>
inline typename associated_executor<T>::type
BOOST_ASIO_NODISCARD inline typename associated_executor<T>::type
get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
{
return associated_executor<T>::get(t);
@ -136,11 +155,14 @@ get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
* @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
*/
template <typename T, typename Executor>
inline typename associated_executor<T, Executor>::type
BOOST_ASIO_NODISCARD inline BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename associated_executor<T, Executor>::type)
get_associated_executor(const T& t, const Executor& ex,
typename constraint<
is_executor<Executor>::value || execution::is_executor<Executor>::value
>::type = 0) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_executor<T, Executor>::get(t, ex)))
{
return associated_executor<T, Executor>::get(t, ex);
}
@ -151,8 +173,8 @@ get_associated_executor(const T& t, const Executor& ex,
* ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
*/
template <typename T, typename ExecutionContext>
inline typename associated_executor<T,
typename ExecutionContext::executor_type>::type
BOOST_ASIO_NODISCARD inline typename associated_executor<T,
typename ExecutionContext::executor_type>::type
get_associated_executor(const T& t, ExecutionContext& ctx,
typename constraint<is_convertible<ExecutionContext&,
execution_context&>::value>::type = 0) BOOST_ASIO_NOEXCEPT
@ -206,8 +228,17 @@ struct associated_executor<reference_wrapper<T>, Executor>
/// Forwards the request to get the executor to the associator specialisation
/// for the unwrapped type @c T.
static type get(reference_wrapper<T> t,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
static type get(reference_wrapper<T> t) BOOST_ASIO_NOEXCEPT
{
return associated_executor<T, Executor>::get(t.get());
}
/// Forwards the request to get the executor to the associator specialisation
/// for the unwrapped type @c T.
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
reference_wrapper<T> t, const Executor& ex) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_executor<T, Executor>::get(t.get(), ex)))
{
return associated_executor<T, Executor>::get(t.get(), ex);
}

View File

@ -0,0 +1,299 @@
//
// associated_immediate_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_ASSOCIATED_IMMEDIATE_EXECUTOR_HPP
#define BOOST_ASIO_ASSOCIATED_IMMEDIATE_EXECUTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/associator.hpp>
#include <boost/asio/detail/functional.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/execution/blocking.hpp>
#include <boost/asio/execution/executor.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/is_executor.hpp>
#include <boost/asio/require.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
template <typename T, typename Executor>
struct associated_immediate_executor;
namespace detail {
template <typename T, typename = void>
struct has_immediate_executor_type : false_type
{
};
template <typename T>
struct has_immediate_executor_type<T,
typename void_type<typename T::immediate_executor_type>::type>
: true_type
{
};
template <typename E, typename = void, typename = void>
struct default_immediate_executor
{
typedef typename require_result<E, execution::blocking_t::never_t>::type type;
static type get(const E& e) BOOST_ASIO_NOEXCEPT
{
return boost::asio::require(e, execution::blocking.never);
}
};
template <typename E>
struct default_immediate_executor<E,
typename enable_if<
!execution::is_executor<E>::value
>::type,
typename enable_if<
is_executor<E>::value
>::type>
{
class type : public E
{
public:
template <typename Executor1>
explicit type(const Executor1& e,
typename constraint<
conditional<
!is_same<Executor1, type>::value,
is_convertible<Executor1, E>,
false_type
>::type::value
>::type = 0) BOOST_ASIO_NOEXCEPT
: E(e)
{
}
type(const type& other) BOOST_ASIO_NOEXCEPT
: E(static_cast<const E&>(other))
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
type(type&& other) BOOST_ASIO_NOEXCEPT
: E(BOOST_ASIO_MOVE_CAST(E)(other))
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename Function, typename Allocator>
void dispatch(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const
{
this->post(BOOST_ASIO_MOVE_CAST(Function)(f), a);
}
friend bool operator==(const type& a, const type& b) BOOST_ASIO_NOEXCEPT
{
return static_cast<const E&>(a) == static_cast<const E&>(b);
}
friend bool operator!=(const type& a, const type& b) BOOST_ASIO_NOEXCEPT
{
return static_cast<const E&>(a) != static_cast<const E&>(b);
}
};
static type get(const E& e) BOOST_ASIO_NOEXCEPT
{
return type(e);
}
};
template <typename T, typename E, typename = void, typename = void>
struct associated_immediate_executor_impl
{
typedef void asio_associated_immediate_executor_is_unspecialised;
typedef typename default_immediate_executor<E>::type type;
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T&, const E& e) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((default_immediate_executor<E>::get(e)))
{
return default_immediate_executor<E>::get(e);
}
};
template <typename T, typename E>
struct associated_immediate_executor_impl<T, E,
typename void_type<typename T::immediate_executor_type>::type>
{
typedef typename T::immediate_executor_type type;
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
const T& t, const E&) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_immediate_executor()))
{
return t.get_immediate_executor();
}
};
template <typename T, typename E>
struct associated_immediate_executor_impl<T, E,
typename enable_if<
!has_immediate_executor_type<T>::value
>::type,
typename void_type<
typename associator<associated_immediate_executor, T, E>::type
>::type> : associator<associated_immediate_executor, T, E>
{
};
} // namespace detail
/// Traits type used to obtain the immediate executor associated with an object.
/**
* A program may specialise this traits type if the @c T template parameter in
* the specialisation is a user-defined type. The template parameter @c
* Executor shall be a type meeting the Executor requirements.
*
* Specialisations shall meet the following requirements, where @c t is a const
* reference to an object of type @c T, and @c e is an object of type @c
* Executor.
*
* @li Provide a nested typedef @c type that identifies a type meeting the
* Executor requirements.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t) and with return type @c type or a (possibly const) reference to @c
* type.
*
* @li Provide a noexcept static member function named @c get, callable as @c
* get(t,e) and with return type @c type or a (possibly const) reference to @c
* type.
*/
template <typename T, typename Executor>
struct associated_immediate_executor
#if !defined(GENERATING_DOCUMENTATION)
: detail::associated_immediate_executor_impl<T, Executor>
#endif // !defined(GENERATING_DOCUMENTATION)
{
#if defined(GENERATING_DOCUMENTATION)
/// If @c T has a nested type @c immediate_executor_type,
// <tt>T::immediate_executor_type</tt>. Otherwise @c Executor.
typedef see_below type;
/// If @c T has a nested type @c immediate_executor_type, returns
/// <tt>t.get_immediate_executor()</tt>. Otherwise returns
/// <tt>boost::asio::require(ex, boost::asio::execution::blocking.never)</tt>.
static decltype(auto) get(const T& t, const Executor& ex) BOOST_ASIO_NOEXCEPT;
#endif // defined(GENERATING_DOCUMENTATION)
};
/// Helper function to obtain an object's associated executor.
/**
* @returns <tt>associated_immediate_executor<T, Executor>::get(t, ex)</tt>
*/
template <typename T, typename Executor>
BOOST_ASIO_NODISCARD inline BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename associated_immediate_executor<T, Executor>::type)
get_associated_immediate_executor(const T& t, const Executor& ex,
typename constraint<
is_executor<Executor>::value || execution::is_executor<Executor>::value
>::type = 0) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_immediate_executor<T, Executor>::get(t, ex)))
{
return associated_immediate_executor<T, Executor>::get(t, ex);
}
/// Helper function to obtain an object's associated executor.
/**
* @returns <tt>associated_immediate_executor<T, typename
* ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
*/
template <typename T, typename ExecutionContext>
BOOST_ASIO_NODISCARD inline typename associated_immediate_executor<T,
typename ExecutionContext::executor_type>::type
get_associated_immediate_executor(const T& t, ExecutionContext& ctx,
typename constraint<is_convertible<ExecutionContext&,
execution_context&>::value>::type = 0) BOOST_ASIO_NOEXCEPT
{
return associated_immediate_executor<T,
typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
}
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
template <typename T, typename Executor>
using associated_immediate_executor_t =
typename associated_immediate_executor<T, Executor>::type;
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
namespace detail {
template <typename T, typename E, typename = void>
struct associated_immediate_executor_forwarding_base
{
};
template <typename T, typename E>
struct associated_immediate_executor_forwarding_base<T, E,
typename enable_if<
is_same<
typename associated_immediate_executor<T,
E>::asio_associated_immediate_executor_is_unspecialised,
void
>::value
>::type>
{
typedef void asio_associated_immediate_executor_is_unspecialised;
};
} // namespace detail
#if defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER) \
|| defined(GENERATING_DOCUMENTATION)
/// Specialisation of associated_immediate_executor for
/// @c std::reference_wrapper.
template <typename T, typename Executor>
struct associated_immediate_executor<reference_wrapper<T>, Executor>
#if !defined(GENERATING_DOCUMENTATION)
: detail::associated_immediate_executor_forwarding_base<T, Executor>
#endif // !defined(GENERATING_DOCUMENTATION)
{
/// Forwards @c type to the associator specialisation for the unwrapped type
/// @c T.
typedef typename associated_immediate_executor<T, Executor>::type type;
/// Forwards the request to get the executor to the associator specialisation
/// for the unwrapped type @c T.
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(
reference_wrapper<T> t, const Executor& ex) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
associated_immediate_executor<T, Executor>::get(t.get(), ex)))
{
return associated_immediate_executor<T, Executor>::get(t.get(), ex);
}
};
#endif // defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER)
// || defined(GENERATING_DOCUMENTATION)
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_ASSOCIATED_IMMEDIATE_EXECUTOR_HPP

View File

@ -2,7 +2,7 @@
// associator.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// async_result.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -808,6 +808,40 @@ struct async_result_has_initiate_memfn
BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)
#endif
#if defined(GENERATING_DOCUMENTATION)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)
#elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)
#elif defined(BOOST_ASIO_HAS_DECLTYPE)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
auto
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr) -> decltype expr
#else
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \
BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \
BOOST_ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \
BOOST_ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)
# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)
#endif
#if defined(GENERATING_DOCUMENTATION)
# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
void_or_deduced
@ -1202,6 +1236,372 @@ BOOST_ASIO_CONCEPT completion_token_for =
namespace detail {
struct async_operation_probe {};
struct async_operation_probe_result {};
template <typename Call, typename = void>
struct is_async_operation_call : false_type
{
};
template <typename Call>
struct is_async_operation_call<Call,
typename void_type<
typename enable_if<
is_same<
typename result_of<Call>::type,
async_operation_probe_result
>::value
>::type
>::type> : true_type
{
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename... Signatures>
class async_result<detail::async_operation_probe, Signatures...>
{
public:
typedef detail::async_operation_probe_result return_type;
template <typename Initiation, typename... InitArgs>
static return_type initiate(BOOST_ASIO_MOVE_ARG(Initiation),
detail::async_operation_probe, BOOST_ASIO_MOVE_ARG(InitArgs)...)
{
return return_type();
}
};
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
namespace detail {
struct async_result_probe_base
{
typedef detail::async_operation_probe_result return_type;
template <typename Initiation>
static return_type initiate(BOOST_ASIO_MOVE_ARG(Initiation),
detail::async_operation_probe)
{
return return_type();
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate(BOOST_ASIO_MOVE_ARG(Initiation), \
detail::async_operation_probe, \
BOOST_ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \
{ \
return return_type(); \
} \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
};
} // namespace detail
template <typename Sig0>
class async_result<detail::async_operation_probe, Sig0>
: public detail::async_result_probe_base {};
template <typename Sig0, typename Sig1>
class async_result<detail::async_operation_probe, Sig0, Sig1>
: public detail::async_result_probe_base {};
template <typename Sig0, typename Sig1, typename Sig2>
class async_result<detail::async_operation_probe, Sig0, Sig1, Sig2>
: public detail::async_result_probe_base {};
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#endif // !defined(GENERATING_DOCUMENTATION)
#if defined(GENERATING_DOCUMENTATION)
/// The is_async_operation trait detects whether a type @c T and arguments
/// @c Args... may be used to initiate an asynchronous operation.
/**
* Class template @c is_async_operation is a trait is derived from @c true_type
* if the expression <tt>T(Args..., token)</tt> initiates an asynchronous
* operation, where @c token is an unspecified completion token type. Otherwise,
* @c is_async_operation is derived from @c false_type.
*/
template <typename T, typename... Args>
struct is_async_operation : integral_constant<bool, automatically_determined>
{
};
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename T, typename... Args>
struct is_async_operation :
detail::is_async_operation_call<
T(Args..., detail::async_operation_probe)>
{
};
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename T, typename = void, typename = void, typename = void,
typename = void, typename = void, typename = void, typename = void,
typename = void, typename = void>
struct is_async_operation;
template <typename T>
struct is_async_operation<T> :
detail::is_async_operation_call<
T(detail::async_operation_probe)>
{
};
#define BOOST_ASIO_PRIVATE_IS_ASYNC_OP_DEF(n) \
template <typename T, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
struct is_async_operation<T, BOOST_ASIO_VARIADIC_TARGS(n)> : \
detail::is_async_operation_call< \
T(BOOST_ASIO_VARIADIC_TARGS(n), detail::async_operation_probe)> \
{ \
}; \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_IS_ASYNC_OP_DEF)
#undef BOOST_ASIO_PRIVATE_IS_ASYNC_OP_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#if defined(BOOST_ASIO_HAS_CONCEPTS) \
&& defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename T, typename... Args>
BOOST_ASIO_CONCEPT async_operation = is_async_operation<T, Args...>::value;
#define BOOST_ASIO_ASYNC_OPERATION(t) \
::boost::asio::async_operation<t>
#define BOOST_ASIO_ASYNC_OPERATION1(t, a0) \
::boost::asio::async_operation<t, a0>
#define BOOST_ASIO_ASYNC_OPERATION2(t, a0, a1) \
::boost::asio::async_operation<t, a0, a1>
#define BOOST_ASIO_ASYNC_OPERATION3(t, a0, a1, a2) \
::boost::asio::async_operation<t, a0, a1, a2>
#else // defined(BOOST_ASIO_HAS_CONCEPTS)
// && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#define BOOST_ASIO_ASYNC_OPERATION(t) typename
#define BOOST_ASIO_ASYNC_OPERATION1(t, a0) typename
#define BOOST_ASIO_ASYNC_OPERATION2(t, a0, a1) typename
#define BOOST_ASIO_ASYNC_OPERATION3(t, a0, a1, a2) typename
#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
// && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
namespace detail {
struct completion_signature_probe {};
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename... T>
struct completion_signature_probe_result
{
template <template <typename...> class Op>
struct apply
{
typedef Op<T...> type;
};
};
template <typename T>
struct completion_signature_probe_result<T>
{
typedef T type;
template <template <typename...> class Op>
struct apply
{
typedef Op<T> type;
};
};
template <>
struct completion_signature_probe_result<void>
{
template <template <typename...> class Op>
struct apply
{
typedef Op<> type;
};
};
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename T>
struct completion_signature_probe_result
{
typedef T type;
};
template <>
struct completion_signature_probe_result<void>
{
};
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename... Signatures>
class async_result<detail::completion_signature_probe, Signatures...>
{
public:
typedef detail::completion_signature_probe_result<Signatures...> return_type;
template <typename Initiation, typename... InitArgs>
static return_type initiate(BOOST_ASIO_MOVE_ARG(Initiation),
detail::completion_signature_probe, BOOST_ASIO_MOVE_ARG(InitArgs)...)
{
return return_type();
}
};
template <typename Signature>
class async_result<detail::completion_signature_probe, Signature>
{
public:
typedef detail::completion_signature_probe_result<Signature> return_type;
template <typename Initiation, typename... InitArgs>
static return_type initiate(BOOST_ASIO_MOVE_ARG(Initiation),
detail::completion_signature_probe, BOOST_ASIO_MOVE_ARG(InitArgs)...)
{
return return_type();
}
};
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
namespace detail {
template <typename Signature>
class async_result_sig_probe_base
{
public:
typedef detail::completion_signature_probe_result<Signature> return_type;
template <typename Initiation>
static return_type initiate(BOOST_ASIO_MOVE_ARG(Initiation),
detail::async_operation_probe)
{
return return_type();
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate(BOOST_ASIO_MOVE_ARG(Initiation), \
detail::completion_signature_probe, \
BOOST_ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \
{ \
return return_type(); \
} \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
};
} // namespace detail
template <>
class async_result<detail::completion_signature_probe>
: public detail::async_result_sig_probe_base<void> {};
template <typename Sig0>
class async_result<detail::completion_signature_probe, Sig0>
: public detail::async_result_sig_probe_base<Sig0> {};
template <typename Sig0, typename Sig1>
class async_result<detail::completion_signature_probe, Sig0, Sig1>
: public detail::async_result_sig_probe_base<void> {};
template <typename Sig0, typename Sig1, typename Sig2>
class async_result<detail::completion_signature_probe, Sig0, Sig1, Sig2>
: public detail::async_result_sig_probe_base<void> {};
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#endif // !defined(GENERATING_DOCUMENTATION)
#if defined(GENERATING_DOCUMENTATION)
/// The completion_signature_of trait determines the completion signature
/// of an asynchronous operation.
/**
* Class template @c completion_signature_of is a trait with a member type
* alias @c type that denotes the completion signature of the asynchronous
* operation initiated by the expression <tt>T(Args..., token)</tt> operation,
* where @c token is an unspecified completion token type. If the asynchronous
* operation does not have exactly one completion signature, the instantion of
* the trait is well-formed but the member type alias @c type is omitted. If
* the expression <tt>T(Args..., token)</tt> is not an asynchronous operation
* then use of the trait is ill-formed.
*/
template <typename T, typename... Args>
struct completion_signature_of
{
typedef automatically_determined type;
};
template <typename T, typename... Args>
using completion_signature_of_t =
typename completion_signature_of<T, Args...>::type;
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename T, typename... Args>
struct completion_signature_of :
result_of<T(Args..., detail::completion_signature_probe)>::type
{
};
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
template <typename T, typename... Args>
using completion_signature_of_t =
typename completion_signature_of<T, Args...>::type;
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename T, typename = void, typename = void, typename = void,
typename = void, typename = void, typename = void, typename = void,
typename = void, typename = void>
struct completion_signature_of;
template <typename T>
struct completion_signature_of<T> :
result_of<T(detail::completion_signature_probe)>::type
{
};
#define BOOST_ASIO_PRIVATE_COMPLETION_SIG_OF_DEF(n) \
template <typename T, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
struct completion_signature_of<T, BOOST_ASIO_VARIADIC_TARGS(n)> : \
result_of< \
T(BOOST_ASIO_VARIADIC_TARGS(n), \
detail::completion_signature_probe)>::type \
{ \
}; \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPLETION_SIG_OF_DEF)
#undef BOOST_ASIO_PRIVATE_COMPLETION_SIG_OF_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
namespace detail {
template <typename T, typename = void>
struct default_completion_token_impl
{

View File

@ -2,7 +2,7 @@
// basic_datagram_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -47,17 +47,23 @@ class basic_datagram_socket;
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*
* Synchronous @c send, @c send_to, @c receive, @c receive_from, and @c connect
* operations are thread safe with respect to each other, if the underlying
* operating system calls are also thread safe. This means that it is permitted
* to perform concurrent calls to these synchronous operations on a single
* socket object. Other synchronous operations, such as @c open or @c close, are
* not thread safe.
* Synchronous @c send, @c send_to, @c receive, @c receive_from, @c connect,
* and @c shutdown operations are thread safe with respect to each other, if
* the underlying operating system calls are also thread safe. This means that
* it is permitted to perform concurrent calls to these synchronous operations
* on a single socket object. Other synchronous operations, such as @c open or
* @c close, are not thread safe.
*/
template <typename Protocol, typename Executor>
class basic_datagram_socket
: public basic_socket<Protocol, Executor>
{
private:
class initiate_async_send;
class initiate_async_send_to;
class initiate_async_receive;
class initiate_async_receive_from;
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
@ -424,25 +430,31 @@ public:
/// Start an asynchronous send on a connected socket.
/**
* This function is used to asynchronously send data on the datagram socket.
* The function call always returns immediately.
* It is an initiating function for an @ref asynchronous_operation, and always
* returns immediately.
*
* @param buffers One or more data buffers to be sent on the socket. Although
* the buffers object may be copied as necessary, ownership of the underlying
* memory blocks is retained by the caller, which must guarantee that they
* remain valid until the handler is called.
* remain valid until the completion handler is called.
*
* @param handler The handler to be called when the send operation completes.
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the send completes. Potential
* completion tokens include @ref use_future, @ref use_awaitable, @ref
* yield_context, or a function object with the correct completion signature.
* The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
* socket.
@ -468,44 +480,55 @@ public:
*/
template <typename ConstBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
std::size_t)) WriteToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_MOVE_ARG(WriteToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_send>(), token,
buffers, socket_base::message_flags(0))))
{
return async_initiate<WriteHandler,
return async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(this), handler,
initiate_async_send(this), token,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
/**
* This function is used to asynchronously send data on the datagram socket.
* The function call always returns immediately.
* It is an initiating function for an @ref asynchronous_operation, and always
* returns immediately.
*
* @param buffers One or more data buffers to be sent on the socket. Although
* the buffers object may be copied as necessary, ownership of the underlying
* memory blocks is retained by the caller, which must guarantee that they
* remain valid until the handler is called.
* remain valid until the completion handler is called.
*
* @param flags Flags specifying how the send call is to be made.
*
* @param handler The handler to be called when the send operation completes.
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the send completes. Potential
* completion tokens include @ref use_future, @ref use_awaitable, @ref
* yield_context, or a function object with the correct completion signature.
* The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
* socket.
@ -522,18 +545,22 @@ public:
*/
template <typename ConstBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
std::size_t)) WriteToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
void (boost::system::error_code, std::size_t))
async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_MOVE_ARG(WriteToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_send>(), token, buffers, flags)))
{
return async_initiate<WriteHandler,
return async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(this), handler, buffers, flags);
initiate_async_send(this), token, buffers, flags);
}
/// Send a datagram to the specified endpoint.
@ -627,28 +654,34 @@ public:
/// Start an asynchronous send.
/**
* This function is used to asynchronously send a datagram to the specified
* remote endpoint. The function call always returns immediately.
* remote endpoint. It is an initiating function for an @ref
* asynchronous_operation, and always returns immediately.
*
* @param buffers One or more data buffers to be sent to the remote endpoint.
* Although the buffers object may be copied as necessary, ownership of the
* underlying memory blocks is retained by the caller, which must guarantee
* that they remain valid until the handler is called.
* that they remain valid until the completion handler is called.
*
* @param destination The remote endpoint to which the data will be sent.
* Copies will be made of the endpoint as required.
*
* @param handler The handler to be called when the send operation completes.
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the send completes. Potential
* completion tokens include @ref use_future, @ref use_awaitable, @ref
* yield_context, or a function object with the correct completion signature.
* The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
* @code
@ -673,48 +706,59 @@ public:
*/
template <typename ConstBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
std::size_t)) WriteToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
void (boost::system::error_code, std::size_t))
async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_MOVE_ARG(WriteToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_send_to>(), token, buffers,
destination, socket_base::message_flags(0))))
{
return async_initiate<WriteHandler,
return async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(this), handler, buffers,
initiate_async_send_to(this), token, buffers,
destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
/**
* This function is used to asynchronously send a datagram to the specified
* remote endpoint. The function call always returns immediately.
* remote endpoint. It is an initiating function for an @ref
* asynchronous_operation, and always returns immediately.
*
* @param buffers One or more data buffers to be sent to the remote endpoint.
* Although the buffers object may be copied as necessary, ownership of the
* underlying memory blocks is retained by the caller, which must guarantee
* that they remain valid until the handler is called.
* that they remain valid until the completion handler is called.
*
* @param flags Flags specifying how the send call is to be made.
*
* @param destination The remote endpoint to which the data will be sent.
* Copies will be made of the endpoint as required.
*
* @param handler The handler to be called when the send operation completes.
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the send completes. Potential
* completion tokens include @ref use_future, @ref use_awaitable, @ref
* yield_context, or a function object with the correct completion signature.
* The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes sent.
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @par Per-Operation Cancellation
* On POSIX or Windows operating systems, this asynchronous operation supports
* cancellation for the following boost::asio::cancellation_type values:
@ -727,18 +771,24 @@ public:
*/
template <typename ConstBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) WriteHandler
std::size_t)) WriteToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
void (boost::system::error_code, std::size_t))
async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
BOOST_ASIO_MOVE_ARG(WriteToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_send_to>(), token,
buffers, destination, flags)))
{
return async_initiate<WriteHandler,
return async_initiate<WriteToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(this), handler, buffers, destination, flags);
initiate_async_send_to(this), token,
buffers, destination, flags);
}
/// Receive some data on a connected socket.
@ -833,25 +883,31 @@ public:
/// Start an asynchronous receive on a connected socket.
/**
* This function is used to asynchronously receive data from the datagram
* socket. The function call always returns immediately.
* socket. It is an initiating function for an @ref asynchronous_operation,
* and always returns immediately.
*
* @param buffers One or more buffers into which the data will be received.
* Although the buffers object may be copied as necessary, ownership of the
* underlying memory blocks is retained by the caller, which must guarantee
* that they remain valid until the handler is called.
* that they remain valid until the completion handler is called.
*
* @param handler The handler to be called when the receive operation
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the receive completes.
* Potential completion tokens include @ref use_future, @ref use_awaitable,
* @ref yield_context, or a function object with the correct completion
* signature. The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
* datagram socket.
@ -878,44 +934,55 @@ public:
*/
template <typename MutableBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
std::size_t)) ReadToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_MOVE_ARG(ReadToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_receive>(), token,
buffers, socket_base::message_flags(0))))
{
return async_initiate<ReadHandler,
return async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(this), handler,
initiate_async_receive(this), token,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
/**
* This function is used to asynchronously receive data from the datagram
* socket. The function call always returns immediately.
* socket. It is an initiating function for an @ref asynchronous_operation,
* and always returns immediately.
*
* @param buffers One or more buffers into which the data will be received.
* Although the buffers object may be copied as necessary, ownership of the
* underlying memory blocks is retained by the caller, which must guarantee
* that they remain valid until the handler is called.
* that they remain valid until the completion handler is called.
*
* @param flags Flags specifying how the receive call is to be made.
*
* @param handler The handler to be called when the receive operation
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the receive completes.
* Potential completion tokens include @ref use_future, @ref use_awaitable,
* @ref yield_context, or a function object with the correct completion
* signature. The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
* datagram socket.
@ -932,18 +999,22 @@ public:
*/
template <typename MutableBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
std::size_t)) ReadToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
void (boost::system::error_code, std::size_t))
async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_MOVE_ARG(ReadToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_receive>(), token, buffers, flags)))
{
return async_initiate<ReadHandler,
return async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(this), handler, buffers, flags);
initiate_async_receive(this), token, buffers, flags);
}
/// Receive a datagram with the endpoint of the sender.
@ -1037,31 +1108,37 @@ public:
/// Start an asynchronous receive.
/**
* This function is used to asynchronously receive a datagram. The function
* call always returns immediately.
* This function is used to asynchronously receive a datagram. It is an
* initiating function for an @ref asynchronous_operation, and always returns
* immediately.
*
* @param buffers One or more buffers into which the data will be received.
* Although the buffers object may be copied as necessary, ownership of the
* underlying memory blocks is retained by the caller, which must guarantee
* that they remain valid until the handler is called.
* that they remain valid until the completion handler is called.
*
* @param sender_endpoint An endpoint object that receives the endpoint of
* the remote sender of the datagram. Ownership of the sender_endpoint object
* is retained by the caller, which must guarantee that it is valid until the
* handler is called.
* completion handler is called.
*
* @param handler The handler to be called when the receive operation
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the receive completes.
* Potential completion tokens include @ref use_future, @ref use_awaitable,
* @ref yield_context, or a function object with the correct completion
* signature. The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
* follows:
@ -1083,50 +1160,61 @@ public:
*/
template <typename MutableBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
std::size_t)) ReadToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
void (boost::system::error_code, std::size_t))
async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_MOVE_ARG(ReadToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_receive_from>(), token, buffers,
&sender_endpoint, socket_base::message_flags(0))))
{
return async_initiate<ReadHandler,
return async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(this), handler, buffers,
initiate_async_receive_from(this), token, buffers,
&sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
/**
* This function is used to asynchronously receive a datagram. The function
* call always returns immediately.
* This function is used to asynchronously receive a datagram. It is an
* initiating function for an @ref asynchronous_operation, and always returns
* immediately.
*
* @param buffers One or more buffers into which the data will be received.
* Although the buffers object may be copied as necessary, ownership of the
* underlying memory blocks is retained by the caller, which must guarantee
* that they remain valid until the handler is called.
* that they remain valid until the completion handler is called.
*
* @param sender_endpoint An endpoint object that receives the endpoint of
* the remote sender of the datagram. Ownership of the sender_endpoint object
* is retained by the caller, which must guarantee that it is valid until the
* handler is called.
* completion handler is called.
*
* @param flags Flags specifying how the receive call is to be made.
*
* @param handler The handler to be called when the receive operation
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the receive completes.
* Potential completion tokens include @ref use_future, @ref use_awaitable,
* @ref yield_context, or a function object with the correct completion
* signature. The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
* std::size_t bytes_transferred // Number of bytes received.
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code, std::size_t) @endcode
*
* @par Per-Operation Cancellation
* On POSIX or Windows operating systems, this asynchronous operation supports
* cancellation for the following boost::asio::cancellation_type values:
@ -1139,18 +1227,23 @@ public:
*/
template <typename MutableBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
std::size_t)) ReadHandler
std::size_t)) ReadToken
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
void (boost::system::error_code, std::size_t))
async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
BOOST_ASIO_MOVE_ARG(ReadToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
declval<initiate_async_receive_from>(), token,
buffers, &sender_endpoint, flags)))
{
return async_initiate<ReadHandler,
return async_initiate<ReadToken,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(this), handler,
initiate_async_receive_from(this), token,
buffers, &sender_endpoint, flags);
}
@ -1170,7 +1263,7 @@ private:
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
@ -1204,7 +1297,7 @@ private:
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
@ -1238,7 +1331,7 @@ private:
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
@ -1272,7 +1365,7 @@ private:
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}

View File

@ -2,7 +2,7 @@
// basic_socket.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -69,6 +69,10 @@ template <typename Protocol, typename Executor>
class basic_socket
: public socket_base
{
private:
class initiate_async_connect;
class initiate_async_wait;
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
@ -361,7 +365,7 @@ public:
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value,
basic_socket&
>::type operator=(basic_socket<Protocol1, Executor1> && other)
>::type operator=(basic_socket<Protocol1, Executor1>&& other)
{
basic_socket tmp(std::move(other));
impl_ = std::move(tmp.impl_);
@ -370,7 +374,7 @@ public:
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
const executor_type& get_executor() BOOST_ASIO_NOEXCEPT
{
return impl_.get_executor();
}
@ -908,7 +912,8 @@ public:
/// Start an asynchronous connect.
/**
* This function is used to asynchronously connect a socket to the specified
* remote endpoint. The function call always returns immediately.
* remote endpoint. It is an initiating function for an @ref
* asynchronous_operation, and always returns immediately.
*
* The socket is automatically opened if it is not already open. If the
* connect fails, and the socket was automatically opened, the socket is
@ -917,17 +922,22 @@ public:
* @param peer_endpoint The remote endpoint to which the socket will be
* connected. Copies will be made of the endpoint object as required.
*
* @param handler The handler to be called when the connection operation
* completes. Copies will be made of the handler as required. The function
* signature of the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the connect completes.
* Potential completion tokens include @ref use_future, @ref use_awaitable,
* @ref yield_context, or a function object with the correct completion
* signature. The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error // Result of operation
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code) @endcode
*
* @par Example
* @code
* void connect_handler(const boost::system::error_code& error)
@ -958,12 +968,16 @@ public:
*/
template <
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,
ConnectToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ConnectToken,
void (boost::system::error_code))
async_connect(const endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler
BOOST_ASIO_MOVE_ARG(ConnectToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<ConnectToken, void (boost::system::error_code)>(
declval<initiate_async_connect>(), token,
peer_endpoint, declval<boost::system::error_code&>())))
{
boost::system::error_code open_ec;
if (!is_open())
@ -972,8 +986,8 @@ public:
impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
}
return async_initiate<ConnectHandler, void (boost::system::error_code)>(
initiate_async_connect(this), handler, peer_endpoint, open_ec);
return async_initiate<ConnectToken, void (boost::system::error_code)>(
initiate_async_connect(this), token, peer_endpoint, open_ec);
}
/// Set an option on the socket.
@ -1757,21 +1771,28 @@ public:
/// write, or to have pending error conditions.
/**
* This function is used to perform an asynchronous wait for a socket to enter
* a ready to read, write or error condition state.
* a ready to read, write or error condition state. It is an initiating
* function for an @ref asynchronous_operation, and always returns
* immediately.
*
* @param w Specifies the desired socket state.
*
* @param handler The handler to be called when the wait operation completes.
* Copies will be made of the handler as required. The function signature of
* the handler must be:
* @param token The @ref completion_token that will be used to produce a
* completion handler, which will be called when the wait completes. Potential
* completion tokens include @ref use_future, @ref use_awaitable, @ref
* yield_context, or a function object with the correct completion signature.
* The function signature of the completion handler must be:
* @code void handler(
* const boost::system::error_code& error // Result of operation
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* not, the completion handler will not be invoked from within this function.
* On immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Completion Signature
* @code void(boost::system::error_code) @endcode
*
* @par Example
* @code
* void wait_handler(const boost::system::error_code& error)
@ -1801,15 +1822,18 @@ public:
*/
template <
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,
WaitToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,
void (boost::system::error_code))
async_wait(wait_type w,
BOOST_ASIO_MOVE_ARG(WaitHandler) handler
BOOST_ASIO_MOVE_ARG(WaitToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<WaitToken, void (boost::system::error_code)>(
declval<initiate_async_wait>(), token, w)))
{
return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(this), handler, w);
return async_initiate<WaitToken, void (boost::system::error_code)>(
initiate_async_wait(this), token, w);
}
protected:
@ -1851,7 +1875,7 @@ private:
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}
@ -1894,7 +1918,7 @@ private:
{
}
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
{
return self_->get_executor();
}

View File

@ -2,7 +2,7 @@
// buffer.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -27,6 +27,7 @@
#include <boost/asio/detail/string_view.hpp>
#include <boost/asio/detail/throw_exception.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/is_contiguous_iterator.hpp>
#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700)
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
@ -892,6 +893,25 @@ private:
* bufs2.push_back(boost::asio::buffer(d2));
* bufs2.push_back(boost::asio::buffer(d3));
* bytes_transferred = sock.send(bufs2); @endcode
*
* @par Buffer Literals
*
* The `_buf` literal suffix, defined in namespace
* <tt>boost::asio::buffer_literals</tt>, may be used to create @c const_buffer
* objects from string, binary integer, and hexadecimal integer literals.
* For example:
*
* @code
* using namespace boost::asio::buffer_literals;
*
* boost::asio::const_buffer b1 = "hello"_buf;
* boost::asio::const_buffer b2 = 0xdeadbeef_buf;
* boost::asio::const_buffer b3 = 0x0123456789abcdef0123456789abcdef_buf;
* boost::asio::const_buffer b4 = 0b1010101011001100_buf; @endcode
*
* Note that the memory associated with a buffer literal is valid for the
* lifetime of the program. This means that the buffer can be safely used with
* asynchronous operations.
*/
/*@{*/
@ -907,7 +927,7 @@ private:
/**
* @returns <tt>mutable_buffer(b)</tt>.
*/
inline BOOST_ASIO_MUTABLE_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(b);
@ -920,7 +940,8 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(
* b.data(),
* min(b.size(), max_size_in_bytes)); @endcode
*/
inline BOOST_ASIO_MUTABLE_BUFFER buffer(const mutable_buffer& b,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
const mutable_buffer& b,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(
@ -937,7 +958,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(const mutable_buffer& b,
/**
* @returns <tt>const_buffer(b)</tt>.
*/
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const const_buffer& b) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(b);
@ -950,7 +971,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* b.data(),
* min(b.size(), max_size_in_bytes)); @endcode
*/
inline BOOST_ASIO_CONST_BUFFER buffer(const const_buffer& b,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const const_buffer& b,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(b.data(),
@ -966,8 +988,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(const const_buffer& b,
/**
* @returns <tt>mutable_buffer(data, size_in_bytes)</tt>.
*/
inline BOOST_ASIO_MUTABLE_BUFFER buffer(void* data,
std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
void* data, std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data, size_in_bytes);
}
@ -976,8 +998,8 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(void* data,
/**
* @returns <tt>const_buffer(data, size_in_bytes)</tt>.
*/
inline BOOST_ASIO_CONST_BUFFER buffer(const void* data,
std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const void* data, std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data, size_in_bytes);
}
@ -990,7 +1012,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(const void* data,
* N * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType));
}
@ -1003,7 +1026,8 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
* min(N * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N],
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
PodType (&data)[N],
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data,
@ -1019,7 +1043,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N],
* N * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data, N * sizeof(PodType));
@ -1033,7 +1057,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* min(N * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(const PodType (&data)[N],
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const PodType (&data)[N],
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data,
@ -1083,7 +1108,8 @@ struct buffer_types
} // namespace detail
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
BOOST_ASIO_NODISCARD inline
typename detail::buffer_types<PodType>::container_type
buffer(boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
@ -1095,7 +1121,8 @@ buffer(boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
}
template <typename PodType, std::size_t N>
inline typename detail::buffer_types<PodType>::container_type
BOOST_ASIO_NODISCARD inline
typename detail::buffer_types<PodType>::container_type
buffer(boost::array<PodType, N>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
@ -1119,7 +1146,7 @@ buffer(boost::array<PodType, N>& data,
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(
@ -1134,7 +1161,8 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(boost::array<PodType, N>& data,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
boost::array<PodType, N>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data.c_array(),
@ -1150,7 +1178,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(boost::array<PodType, N>& data,
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
boost::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
@ -1164,7 +1192,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(boost::array<const PodType, N>& data,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
boost::array<const PodType, N>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(),
@ -1182,7 +1211,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(boost::array<const PodType, N>& data,
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
@ -1196,7 +1225,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(const boost::array<PodType, N>& data,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const boost::array<PodType, N>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(),
@ -1214,7 +1244,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(const boost::array<PodType, N>& data,
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType));
@ -1228,7 +1258,8 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::array<PodType, N>& data,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
std::array<PodType, N>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data.data(),
@ -1244,7 +1275,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::array<PodType, N>& data,
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
std::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
@ -1258,7 +1289,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(std::array<const PodType, N>& data,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
std::array<const PodType, N>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(),
@ -1274,7 +1306,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(std::array<const PodType, N>& data,
* data.size() * sizeof(PodType)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
@ -1288,7 +1320,8 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
*/
template <typename PodType, std::size_t N>
inline BOOST_ASIO_CONST_BUFFER buffer(const std::array<PodType, N>& data,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const std::array<PodType, N>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(),
@ -1309,7 +1342,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(const std::array<PodType, N>& data,
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(
@ -1333,7 +1366,8 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::vector<PodType, Allocator>& data,
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
std::vector<PodType, Allocator>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
@ -1358,7 +1392,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::vector<PodType, Allocator>& data,
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(
@ -1382,7 +1416,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* invalidate iterators.
*/
template <typename PodType, typename Allocator>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const std::vector<PodType, Allocator>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
@ -1406,7 +1440,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* given string object.
*/
template <typename Elem, typename Traits, typename Allocator>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
@ -1430,7 +1464,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(
* given string object.
*/
template <typename Elem, typename Traits, typename Allocator>
inline BOOST_ASIO_MUTABLE_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
std::basic_string<Elem, Traits, Allocator>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
@ -1453,7 +1487,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(
* given string object.
*/
template <typename Elem, typename Traits, typename Allocator>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem)
@ -1476,7 +1510,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* given string object.
*/
template <typename Elem, typename Traits, typename Allocator>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const std::basic_string<Elem, Traits, Allocator>& data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
@ -1494,13 +1528,13 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
#if defined(BOOST_ASIO_HAS_STRING_VIEW) \
|| defined(GENERATING_DOCUMENTATION)
/// Create a new modifiable buffer that represents the given string_view.
/// Create a new non-modifiable buffer that represents the given string_view.
/**
* @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,
* data.size() * sizeof(Elem))</tt>.
*/
template <typename Elem, typename Traits>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
basic_string_view<Elem, Traits> data) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
@ -1521,7 +1555,7 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
* min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
*/
template <typename Elem, typename Traits>
inline BOOST_ASIO_CONST_BUFFER buffer(
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
basic_string_view<Elem, Traits> data,
std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
{
@ -1539,6 +1573,215 @@ inline BOOST_ASIO_CONST_BUFFER buffer(
#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
// || defined(GENERATING_DOCUMENTATION)
/// Create a new modifiable buffer from a contiguous container.
/**
* @returns A mutable_buffer value equivalent to:
* @code mutable_buffer(
* data.size() ? &data[0] : 0,
* data.size() * sizeof(typename T::value_type)); @endcode
*/
template <typename T>
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
T& data,
typename constraint<
is_contiguous_iterator<typename T::iterator>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, const_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, mutable_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_const<
typename remove_reference<
typename std::iterator_traits<typename T::iterator>::reference
>::type
>::value,
defaulted_constraint
>::type = defaulted_constraint()) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(
data.size() ? detail::to_address(data.begin()) : 0,
data.size() * sizeof(typename T::value_type));
}
/// Create a new modifiable buffer from a contiguous container.
/**
* @returns A mutable_buffer value equivalent to:
* @code mutable_buffer(
* data.size() ? &data[0] : 0,
* min(
* data.size() * sizeof(typename T::value_type),
* max_size_in_bytes)); @endcode
*/
template <typename T>
BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
T& data, std::size_t max_size_in_bytes,
typename constraint<
is_contiguous_iterator<typename T::iterator>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, const_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, mutable_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_const<
typename remove_reference<
typename std::iterator_traits<typename T::iterator>::reference
>::type
>::value,
defaulted_constraint
>::type = defaulted_constraint()) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_MUTABLE_BUFFER(
data.size() ? detail::to_address(data.begin()) : 0,
data.size() * sizeof(typename T::value_type) < max_size_in_bytes
? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);
}
/// Create a new non-modifiable buffer from a contiguous container.
/**
* @returns A const_buffer value equivalent to:
* @code const_buffer(
* data.size() ? &data[0] : 0,
* data.size() * sizeof(typename T::value_type)); @endcode
*/
template <typename T>
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
T& data,
typename constraint<
is_contiguous_iterator<typename T::iterator>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, const_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, mutable_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
is_const<
typename remove_reference<
typename std::iterator_traits<typename T::iterator>::reference
>::type
>::value,
defaulted_constraint
>::type = defaulted_constraint()) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(
data.size() ? detail::to_address(data.begin()) : 0,
data.size() * sizeof(typename T::value_type));
}
/// Create a new non-modifiable buffer from a contiguous container.
/**
* @returns A const_buffer value equivalent to:
* @code const_buffer(
* data.size() ? &data[0] : 0,
* min(
* data.size() * sizeof(typename T::value_type),
* max_size_in_bytes)); @endcode
*/
template <typename T>
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
T& data, std::size_t max_size_in_bytes,
typename constraint<
is_contiguous_iterator<typename T::iterator>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, const_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, mutable_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
is_const<
typename remove_reference<
typename std::iterator_traits<typename T::iterator>::reference
>::type
>::value,
defaulted_constraint
>::type = defaulted_constraint()) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(
data.size() ? detail::to_address(data.begin()) : 0,
data.size() * sizeof(typename T::value_type) < max_size_in_bytes
? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);
}
/// Create a new non-modifiable buffer from a contiguous container.
/**
* @returns A const_buffer value equivalent to:
* @code const_buffer(
* data.size() ? &data[0] : 0,
* data.size() * sizeof(typename T::value_type)); @endcode
*/
template <typename T>
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const T& data,
typename constraint<
is_contiguous_iterator<typename T::const_iterator>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, const_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, mutable_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint()) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(
data.size() ? detail::to_address(data.begin()) : 0,
data.size() * sizeof(typename T::value_type));
}
/// Create a new non-modifiable buffer from a contiguous container.
/**
* @returns A const_buffer value equivalent to:
* @code const_buffer(
* data.size() ? &data[0] : 0,
* min(
* data.size() * sizeof(typename T::value_type),
* max_size_in_bytes)); @endcode
*/
template <typename T>
BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
const T& data, std::size_t max_size_in_bytes,
typename constraint<
is_contiguous_iterator<typename T::const_iterator>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, const_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint(),
typename constraint<
!is_convertible<T, mutable_buffer>::value,
defaulted_constraint
>::type = defaulted_constraint()) BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_CONST_BUFFER(
data.size() ? detail::to_address(data.begin()) : 0,
data.size() * sizeof(typename T::value_type) < max_size_in_bytes
? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);
}
/*@}*/
/// Adapt a basic_string to the DynamicBuffer requirements.
@ -2097,7 +2340,8 @@ private:
* @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data)</tt>.
*/
template <typename Elem, typename Traits, typename Allocator>
inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
BOOST_ASIO_NODISCARD inline
dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
return dynamic_string_buffer<Elem, Traits, Allocator>(data);
@ -2109,7 +2353,8 @@ inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
* max_size)</tt>.
*/
template <typename Elem, typename Traits, typename Allocator>
inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
BOOST_ASIO_NODISCARD inline
dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
std::basic_string<Elem, Traits, Allocator>& data,
std::size_t max_size) BOOST_ASIO_NOEXCEPT
{
@ -2121,7 +2366,8 @@ inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
* @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>.
*/
template <typename Elem, typename Allocator>
inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
BOOST_ASIO_NODISCARD inline
dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
std::vector<Elem, Allocator>& data) BOOST_ASIO_NOEXCEPT
{
return dynamic_vector_buffer<Elem, Allocator>(data);
@ -2132,7 +2378,8 @@ inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
* @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>.
*/
template <typename Elem, typename Allocator>
inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
BOOST_ASIO_NODISCARD inline
dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
std::vector<Elem, Allocator>& data,
std::size_t max_size) BOOST_ASIO_NOEXCEPT
{
@ -2492,6 +2739,172 @@ struct is_dynamic_buffer
{
};
#if (defined(BOOST_ASIO_HAS_USER_DEFINED_LITERALS) \
&& defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)) \
|| defined(GENERATING_DOCUMENTATION)
namespace buffer_literals {
namespace detail {
template <char... Chars>
struct chars {};
template <unsigned char... Bytes>
struct bytes {};
// Literal processor that converts binary literals to an array of bytes.
template <typename Bytes, char... Chars>
struct bin_literal;
template <unsigned char... Bytes>
struct bin_literal<bytes<Bytes...> >
{
static const std::size_t size = sizeof...(Bytes);
static const unsigned char data[sizeof...(Bytes)];
};
template <unsigned char... Bytes>
const unsigned char bin_literal<bytes<Bytes...> >::data[sizeof...(Bytes)]
= { Bytes... };
template <unsigned char... Bytes, char Bit7, char Bit6, char Bit5,
char Bit4, char Bit3, char Bit2, char Bit1, char Bit0, char... Chars>
struct bin_literal<bytes<Bytes...>, Bit7, Bit6,
Bit5, Bit4, Bit3, Bit2, Bit1, Bit0, Chars...> :
bin_literal<
bytes<Bytes...,
static_cast<unsigned char>(
(Bit7 == '1' ? 0x80 : 0) |
(Bit6 == '1' ? 0x40 : 0) |
(Bit5 == '1' ? 0x20 : 0) |
(Bit4 == '1' ? 0x10 : 0) |
(Bit3 == '1' ? 0x08 : 0) |
(Bit2 == '1' ? 0x04 : 0) |
(Bit1 == '1' ? 0x02 : 0) |
(Bit0 == '1' ? 0x01 : 0))
>, Chars...> {};
template <unsigned char... Bytes, char... Chars>
struct bin_literal<bytes<Bytes...>, Chars...>
{
static_assert(sizeof...(Chars) == 0,
"number of digits in a binary buffer literal must be a multiple of 8");
static const std::size_t size = 0;
static const unsigned char data[1];
};
template <unsigned char... Bytes, char... Chars>
const unsigned char bin_literal<bytes<Bytes...>, Chars...>::data[1] = {};
// Literal processor that converts hexadecimal literals to an array of bytes.
template <typename Bytes, char... Chars>
struct hex_literal;
template <unsigned char... Bytes>
struct hex_literal<bytes<Bytes...> >
{
static const std::size_t size = sizeof...(Bytes);
static const unsigned char data[sizeof...(Bytes)];
};
template <unsigned char... Bytes>
const unsigned char hex_literal<bytes<Bytes...> >::data[sizeof...(Bytes)]
= { Bytes... };
template <unsigned char... Bytes, char Hi, char Lo, char... Chars>
struct hex_literal<bytes<Bytes...>, Hi, Lo, Chars...> :
hex_literal<
bytes<Bytes...,
static_cast<unsigned char>(
Lo >= 'A' && Lo <= 'F' ? Lo - 'A' + 10 :
(Lo >= 'a' && Lo <= 'f' ? Lo - 'a' + 10 : Lo - '0')) |
((static_cast<unsigned char>(
Hi >= 'A' && Hi <= 'F' ? Hi - 'A' + 10 :
(Hi >= 'a' && Hi <= 'f' ? Hi - 'a' + 10 : Hi - '0'))) << 4)
>, Chars...> {};
template <unsigned char... Bytes, char Char>
struct hex_literal<bytes<Bytes...>, Char>
{
static_assert(!Char,
"a hexadecimal buffer literal must have an even number of digits");
static const std::size_t size = 0;
static const unsigned char data[1];
};
template <unsigned char... Bytes, char Char>
const unsigned char hex_literal<bytes<Bytes...>, Char>::data[1] = {};
// Helper template that removes digit separators and then passes the cleaned
// variadic pack of characters to the literal processor.
template <template <typename, char...> class Literal,
typename Clean, char... Raw>
struct remove_separators;
template <template <typename, char...> class Literal,
char... Clean, char... Raw>
struct remove_separators<Literal, chars<Clean...>, '\'', Raw...> :
remove_separators<Literal, chars<Clean...>, Raw...> {};
template <template <typename, char...> class Literal,
char... Clean, char C, char... Raw>
struct remove_separators<Literal, chars<Clean...>, C, Raw...> :
remove_separators<Literal, chars<Clean..., C>, Raw...> {};
template <template <typename, char...> class Literal, char... Clean>
struct remove_separators<Literal, chars<Clean...> > :
Literal<bytes<>, Clean...> {};
// Helper template to determine the literal type based on the prefix.
template <char... Chars>
struct literal;
template <char... Chars>
struct literal<'0', 'b', Chars...> :
remove_separators<bin_literal, chars<>, Chars...>{};
template <char... Chars>
struct literal<'0', 'B', Chars...> :
remove_separators<bin_literal, chars<>, Chars...>{};
template <char... Chars>
struct literal<'0', 'x', Chars...> :
remove_separators<hex_literal, chars<>, Chars...>{};
template <char... Chars>
struct literal<'0', 'X', Chars...> :
remove_separators<hex_literal, chars<>, Chars...>{};
} // namespace detail
/// Literal operator for creating const_buffer objects from string literals.
inline BOOST_ASIO_CONST_BUFFER operator"" _buf(const char* data, std::size_t n)
{
return BOOST_ASIO_CONST_BUFFER(data, n);
}
/// Literal operator for creating const_buffer objects from unbounded binary or
/// hexadecimal integer literals.
template <char... Chars>
inline BOOST_ASIO_CONST_BUFFER operator"" _buf()
{
return BOOST_ASIO_CONST_BUFFER(
+detail::literal<Chars...>::data,
detail::literal<Chars...>::size);
}
} // namespace buffer_literals
#endif // (defined(BOOST_ASIO_HAS_USER_DEFINED_LITERALS)
// && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES))
// || defined(GENERATING_DOCUMENTATION)
} // namespace asio
} // namespace boost

View File

@ -2,7 +2,7 @@
// cancellation_signal.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// cancellation_type.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/array.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/array_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/assert.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/atomic_count.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/bind_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -950,9 +950,18 @@ struct associator<Associator,
detail::binder0<Handler>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::binder0<Handler>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::binder0<Handler>& h) BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::binder0<Handler>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
@ -964,9 +973,18 @@ struct associator<Associator,
detail::binder1<Handler, Arg1>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::binder1<Handler, Arg1>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::binder1<Handler, Arg1>& h) BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::binder1<Handler, Arg1>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
@ -979,9 +997,18 @@ struct associator<Associator,
detail::binder2<Handler, Arg1, Arg2>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::binder2<Handler, Arg1, Arg2>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::binder2<Handler, Arg1, Arg2>& h) BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::binder2<Handler, Arg1, Arg2>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
@ -994,9 +1021,18 @@ struct associator<Associator,
detail::binder3<Handler, Arg1, Arg2, Arg3>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
@ -1009,9 +1045,19 @@ struct associator<Associator,
detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h)
BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
@ -1024,9 +1070,19 @@ struct associator<Associator,
detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h)
BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
@ -1040,9 +1096,18 @@ struct associator<Associator,
detail::move_binder1<Handler, Arg1>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::move_binder1<Handler, Arg1>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::move_binder1<Handler, Arg1>& h) BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::move_binder1<Handler, Arg1>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}
@ -1055,9 +1120,18 @@ struct associator<Associator,
detail::move_binder2<Handler, Arg1, Arg2>, DefaultCandidate>
: Associator<Handler, DefaultCandidate>
{
static typename Associator<Handler, DefaultCandidate>::type get(
const detail::move_binder2<Handler, Arg1, Arg2>& h,
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
static typename Associator<Handler, DefaultCandidate>::type
get(const detail::move_binder2<Handler, Arg1, Arg2>& h) BOOST_ASIO_NOEXCEPT
{
return Associator<Handler, DefaultCandidate>::get(h.handler_);
}
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
typename Associator<Handler, DefaultCandidate>::type)
get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
{
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
}

View File

@ -2,7 +2,7 @@
// detail/buffer_sequence_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/call_stack.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/chrono.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/chrono_time_traits.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/completion_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/concurrency_hint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/conditionally_enabled_event.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/conditionally_enabled_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/config.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -24,6 +24,7 @@
# define BOOST_ASIO_DISABLE_BOOST_THROW_EXCEPTION 1
# define BOOST_ASIO_DISABLE_BOOST_WORKAROUND 1
#else // defined(BOOST_ASIO_STANDALONE)
// Boost.Config library is available.
# include <boost/config.hpp>
# include <boost/version.hpp>
# define BOOST_ASIO_HAS_BOOST_CONFIG 1
@ -134,6 +135,7 @@
# define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&>
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
# define BOOST_ASIO_MOVE_OR_LVALUE(type) static_cast<type&&>
# define BOOST_ASIO_MOVE_OR_LVALUE_ARG(type) type&&
# define BOOST_ASIO_MOVE_OR_LVALUE_TYPE(type) type
#endif // defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
@ -162,6 +164,7 @@
# define BOOST_ASIO_MOVE_CAST(type) static_cast<const type&>
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
# define BOOST_ASIO_MOVE_OR_LVALUE(type)
# define BOOST_ASIO_MOVE_OR_LVALUE_ARG(type) type&
# define BOOST_ASIO_MOVE_OR_LVALUE_TYPE(type) type&
#endif // !defined(BOOST_ASIO_MOVE_CAST)
@ -370,6 +373,17 @@
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_DECLTYPE)
#endif // !defined(BOOST_ASIO_HAS_DECLTYPE)
#if defined(BOOST_ASIO_HAS_DECLTYPE)
# define BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(t) auto
# define BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) auto
# define BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) auto
# define BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX(expr) -> decltype expr
#else // defined(BOOST_ASIO_HAS_DECLTYPE)
# define BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX(t) t
# define BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) t0, t1
# define BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) t0, t1, t2
# define BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX(expr)
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
// Support alias templates on compilers known to allow it.
#if !defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
@ -406,7 +420,11 @@
# 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)
# elif defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)
# define BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION 1
# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_RETURN_TYPE_DEDUCTION)
#endif // !defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
@ -450,6 +468,17 @@
# endif // !defined(BOOST_ASIO_DISABLE_CONCEPTS)
#endif // !defined(BOOST_ASIO_HAS_CONCEPTS)
// Support concepts on compilers known to allow them.
#if !defined(BOOST_ASIO_HAS_STD_CONCEPTS)
# if !defined(BOOST_ASIO_DISABLE_STD_CONCEPTS)
# if defined(BOOST_ASIO_HAS_CONCEPTS)
# if (__cpp_lib_concepts >= 202002L)
# define BOOST_ASIO_HAS_STD_CONCEPTS 1
# endif // (__cpp_concepts >= 202002L)
# endif // defined(BOOST_ASIO_HAS_CONCEPTS)
# endif // !defined(BOOST_ASIO_DISABLE_STD_CONCEPTS)
#endif // !defined(BOOST_ASIO_HAS_STD_CONCEPTS)
// Support template variables on compilers known to allow it.
#if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
# if !defined(BOOST_ASIO_DISABLE_VARIABLE_TEMPLATES)
@ -572,6 +601,25 @@
# endif // !defined(BOOST_ASIO_RVALUE_REF_QUAL)
#endif // defined(BOOST_ASIO_HAS_REF_QUALIFIED_FUNCTIONS)
// Support for capturing parameter packs in lambdas.
#if !defined(BOOST_ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)
# if !defined(BOOST_ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)
# if defined(__GNUC__)
# if (__GNUC__ >= 6)
# define BOOST_ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1
# endif // (__GNUC__ >= 6)
# elif defined(BOOST_ASIO_MSVC)
# if (_MSVC_LANG >= 201103)
# define BOOST_ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1
# endif // (_MSC_LANG >= 201103)
# else // defined(BOOST_ASIO_MSVC)
# if (__cplusplus >= 201103)
# define BOOST_ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1
# endif // (__cplusplus >= 201103)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)
// Support for the alignof operator.
#if !defined(BOOST_ASIO_HAS_ALIGNOF)
# if !defined(BOOST_ASIO_DISABLE_ALIGNOF)
@ -599,6 +647,19 @@
# define BOOST_ASIO_DEFAULT_ALIGN 1
#endif // defined(BOOST_ASIO_HAS_ALIGNOF)
// Support for user-defined literals.
#if !defined(BOOST_ASIO_HAS_USER_DEFINED_LITERALS)
# if !defined(BOOST_ASIO_DISABLE_USER_DEFINED_LITERALS)
# if (__cplusplus >= 201103)
# define BOOST_ASIO_HAS_USER_DEFINED_LITERALS 1
# elif defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)
# define BOOST_ASIO_HAS_USER_DEFINED_LITERALS 1
# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_USER_DEFINED_LITERALS)
#endif // !defined(BOOST_ASIO_HAS_USER_DEFINED_LITERALS)
// Standard library support for aligned allocation.
#if !defined(BOOST_ASIO_HAS_STD_ALIGNED_ALLOC)
# if !defined(BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC)
@ -607,21 +668,67 @@
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC) \
&& !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# if defined(__APPLE__)
# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
# if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
# elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
# if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)
# elif defined(__TV_OS_VERSION_MIN_REQUIRED)
# if (__TV_OS_VERSION_MIN_REQUIRED >= 130000)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // (__TV_OS_VERSION_MIN_REQUIRED >= 130000)
# elif defined(__WATCH_OS_VERSION_MIN_REQUIRED)
# if (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)
# endif // defined(__WATCH_OS_X_VERSION_MIN_REQUIRED)
# else // defined(__APPLE__)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // defined(__APPLE__)
# endif // (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC)
// && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)
# elif defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
# elif defined(__GNUC__)
# if defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
# if ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)
# if defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
# define BOOST_ASIO_HAS_STD_ALIGNED_ALLOC 1
# endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
# endif // ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)
# endif // defined(__GNUC__)
# endif // (__cplusplus >= 201703)
# endif // !defined(BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC)
#endif // !defined(BOOST_ASIO_HAS_STD_ALIGNED_ALLOC)
// Standard library support for std::align.
#if !defined(BOOST_ASIO_HAS_STD_ALIGN)
# if !defined(BOOST_ASIO_DISABLE_STD_ALIGN)
# if defined(__clang__)
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# define BOOST_ASIO_HAS_STD_ALIGN 1
# elif (__cplusplus >= 201103)
# define BOOST_ASIO_HAS_STD_ALIGN 1
# endif // (__cplusplus >= 201103)
# elif defined(__GNUC__)
# if (__GNUC__ >= 6)
# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_ASIO_HAS_STD_ALIGN 1
# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // (__GNUC__ >= 6)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1700)
# define BOOST_ASIO_HAS_STD_ALIGN 1
# endif // (_MSC_VER >= 1700)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_ALIGN)
#endif // !defined(BOOST_ASIO_HAS_STD_ALIGN)
// Standard library support for system errors.
# if !defined(BOOST_ASIO_DISABLE_STD_SYSTEM_ERROR)
# if defined(__clang__)
@ -832,6 +939,35 @@
# endif // !defined(BOOST_ASIO_DISABLE_BOOST_DATE_TIME)
#endif // !defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// Boost support for the Coroutine library.
#if !defined(BOOST_ASIO_HAS_BOOST_COROUTINE)
# if !defined(BOOST_ASIO_DISABLE_BOOST_COROUTINE)
# define BOOST_ASIO_HAS_BOOST_COROUTINE 1
# endif // !defined(BOOST_ASIO_DISABLE_BOOST_COROUTINE)
#endif // !defined(BOOST_ASIO_HAS_BOOST_COROUTINE)
// Boost support for the Context library's fibers.
#if !defined(BOOST_ASIO_HAS_BOOST_CONTEXT_FIBER)
# if !defined(BOOST_ASIO_DISABLE_BOOST_CONTEXT_FIBER)
# if defined(__clang__)
# if (__cplusplus >= 201103)
# define BOOST_ASIO_HAS_BOOST_CONTEXT_FIBER 1
# endif // (__cplusplus >= 201103)
# elif defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_ASIO_HAS_BOOST_CONTEXT_FIBER 1
# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSVC_LANG >= 201103)
# define BOOST_ASIO_HAS_BOOST_CONTEXT_FIBER 1
# endif // (_MSC_LANG >= 201103)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_BOOST_CONTEXT_FIBER)
#endif // !defined(BOOST_ASIO_HAS_BOOST_CONTEXT_FIBER)
// Standard library support for addressof.
#if !defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
# if !defined(BOOST_ASIO_DISABLE_STD_ADDRESSOF)
@ -1104,6 +1240,32 @@
# endif // !defined(BOOST_ASIO_DISABLE_STD_FUTURE)
#endif // !defined(BOOST_ASIO_HAS_STD_FUTURE)
// Standard library support for std::tuple.
#if !defined(BOOST_ASIO_HAS_STD_TUPLE)
# if !defined(BOOST_ASIO_DISABLE_STD_TUPLE)
# if defined(__clang__)
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# define BOOST_ASIO_HAS_STD_TUPLE 1
# elif (__cplusplus >= 201103)
# if __has_include(<tuple>)
# define BOOST_ASIO_HAS_STD_TUPLE 1
# endif // __has_include(<tuple>)
# endif // (__cplusplus >= 201103)
# elif defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_ASIO_HAS_STD_TUPLE 1
# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1700)
# define BOOST_ASIO_HAS_STD_TUPLE 1
# endif // (_MSC_VER >= 1700)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_TUPLE)
#endif // !defined(BOOST_ASIO_HAS_STD_TUPLE)
// Standard library support for std::string_view.
#if !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
# if !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
@ -1178,14 +1340,17 @@
// Standard library support for iostream move construction and assignment.
#if !defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
# if !defined(BOOST_ASIO_DISABLE_STD_IOSTREAM_MOVE)
# if defined(__GNUC__)
# if defined(__clang__)
# if (__cplusplus >= 201103)
# define BOOST_ASIO_HAS_STD_IOSTREAM_MOVE 1
# endif // (__cplusplus >= 201103)
# elif defined(__GNUC__)
# if (__GNUC__ > 4)
# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_ASIO_HAS_STD_IOSTREAM_MOVE 1
# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# elif defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1700)
# define BOOST_ASIO_HAS_STD_IOSTREAM_MOVE 1
# endif // (_MSC_VER >= 1700)
@ -1200,14 +1365,11 @@
# if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
# define BOOST_ASIO_HAS_STD_INVOKE_RESULT 1
# endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
# else // defined(BOOST_ASIO_MSVC)
# if (__cplusplus >= 201703)
# define BOOST_ASIO_HAS_STD_INVOKE_RESULT 1
# endif // (__cplusplus >= 201703)
# endif // defined(BOOST_ASIO_MSVC)
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if (_LIBCPP_VERSION >= 13000)
# if (__cplusplus >= 202002)
# define BOOST_ASIO_HAS_STD_INVOKE_RESULT 1
# endif // (__cplusplus >= 202002)
# endif // (_LIBCPP_VERSION >= 13000)
# endif // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# endif // !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
#endif // !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
@ -1283,6 +1445,30 @@
# endif // !defined(BOOST_ASIO_DISABLE_STD_ANY)
#endif // !defined(BOOST_ASIO_HAS_STD_ANY)
// Standard library support for std::variant.
#if !defined(BOOST_ASIO_HAS_STD_VARIANT)
# if !defined(BOOST_ASIO_DISABLE_STD_VARIANT)
# if defined(__clang__)
# if (__cplusplus >= 201703)
# if __has_include(<variant>)
# define BOOST_ASIO_HAS_STD_VARIANT 1
# endif // __has_include(<variant>)
# endif // (__cplusplus >= 201703)
# elif defined(__GNUC__)
# if (__GNUC__ >= 7)
# if (__cplusplus >= 201703)
# define BOOST_ASIO_HAS_STD_VARIANT 1
# endif // (__cplusplus >= 201703)
# endif // (__GNUC__ >= 7)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)
# define BOOST_ASIO_HAS_STD_VARIANT 1
# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_VARIANT)
#endif // !defined(BOOST_ASIO_HAS_STD_VARIANT)
// Standard library support for std::source_location.
#if !defined(BOOST_ASIO_HAS_STD_SOURCE_LOCATION)
# if !defined(BOOST_ASIO_DISABLE_STD_SOURCE_LOCATION)
@ -1314,6 +1500,50 @@
# endif // !defined(BOOST_ASIO_DISABLE_SOURCE_LOCATION)
#endif // !defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
// Boost support for source_location and system errors.
#if !defined(BOOST_ASIO_HAS_BOOST_SOURCE_LOCATION)
# if !defined(BOOST_ASIO_DISABLE_BOOST_SOURCE_LOCATION)
# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)
# define BOOST_ASIO_HAS_BOOST_SOURCE_LOCATION 1
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)
# endif // !defined(BOOST_ASIO_DISABLE_BOOST_SOURCE_LOCATION)
#endif // !defined(BOOST_ASIO_HAS_BOOST_SOURCE_LOCATION)
// Helper macros for working with Boost source locations.
#if defined(BOOST_ASIO_HAS_BOOST_SOURCE_LOCATION)
# define BOOST_ASIO_SOURCE_LOCATION_PARAM \
, const boost::source_location& loc
# define BOOST_ASIO_SOURCE_LOCATION_DEFAULTED_PARAM \
, const boost::source_location& loc = BOOST_CURRENT_LOCATION
# define BOOST_ASIO_SOURCE_LOCATION_ARG , loc
#else // if defined(BOOST_ASIO_HAS_BOOST_SOURCE_LOCATION)
# define BOOST_ASIO_SOURCE_LOCATION_PARAM
# define BOOST_ASIO_SOURCE_LOCATION_DEFAULTED_PARAM
# define BOOST_ASIO_SOURCE_LOCATION_ARG
#endif // if defined(BOOST_ASIO_HAS_BOOST_SOURCE_LOCATION)
// Standard library support for std::index_sequence.
#if !defined(BOOST_ASIO_HAS_STD_INDEX_SEQUENCE)
# if !defined(BOOST_ASIO_DISABLE_STD_INDEX_SEQUENCE)
# if defined(__clang__)
# if (__cplusplus >= 201402)
# define BOOST_ASIO_HAS_STD_INDEX_SEQUENCE 1
# endif // (__cplusplus >= 201402)
# elif defined(__GNUC__)
# if (__GNUC__ >= 7)
# if (__cplusplus >= 201402)
# define BOOST_ASIO_HAS_STD_INDEX_SEQUENCE 1
# endif // (__cplusplus >= 201402)
# endif // (__GNUC__ >= 7)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)
# define BOOST_ASIO_HAS_STD_INDEX_SEQUENCE 1
# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_INDEX_SEQUENCE)
#endif // !defined(BOOST_ASIO_HAS_STD_INDEX_SEQUENCE)
// Windows App target. Windows but with a limited API.
#if !defined(BOOST_ASIO_WINDOWS_APP)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)
@ -1887,6 +2117,22 @@
# define BOOST_ASIO_UNUSED_VARIABLE
#endif // !defined(BOOST_ASIO_UNUSED_VARIABLE)
// Helper macro to tell the optimiser what may be assumed to be true.
#if defined(BOOST_ASIO_MSVC)
# define BOOST_ASIO_ASSUME(expr) __assume(expr)
#elif defined(__clang__)
# if __has_builtin(__builtin_assume)
# define BOOST_ASIO_ASSUME(expr) __builtin_assume(expr)
# endif // __has_builtin(__builtin_assume)
#elif defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
# define BOOST_ASIO_ASSUME(expr) if (expr) {} else { __builtin_unreachable(); }
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
#endif // defined(__GNUC__)
#if !defined(BOOST_ASIO_ASSUME)
# define BOOST_ASIO_ASSUME(expr) (void)0
#endif // !defined(BOOST_ASIO_ASSUME)
// Support the co_await keyword on compilers known to allow it.
#if !defined(BOOST_ASIO_HAS_CO_AWAIT)
# if !defined(BOOST_ASIO_DISABLE_CO_AWAIT)
@ -1899,11 +2145,23 @@
# endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
# endif // (_MSC_FULL_VER >= 190023506)
# elif defined(__clang__)
# if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# if __has_include(<experimental/coroutine>)
# define BOOST_ASIO_HAS_CO_AWAIT 1
# endif // __has_include(<experimental/coroutine>)
# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# if (__clang_major__ >= 14)
# if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)
# if __has_include(<coroutine>)
# define BOOST_ASIO_HAS_CO_AWAIT 1
# endif // __has_include(<coroutine>)
# elif (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# if __has_include(<experimental/coroutine>)
# define BOOST_ASIO_HAS_CO_AWAIT 1
# endif // __has_include(<experimental/coroutine>)
# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# else // (__clang_major__ >= 14)
# if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# if __has_include(<experimental/coroutine>)
# define BOOST_ASIO_HAS_CO_AWAIT 1
# endif // __has_include(<experimental/coroutine>)
# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# endif // (__clang_major__ >= 14)
# elif defined(__GNUC__)
# if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)
# if __has_include(<coroutine>)
@ -1921,8 +2179,15 @@
# if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)
# define BOOST_ASIO_HAS_STD_COROUTINE 1
# endif // (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)
# endif // defined(BOOST_ASIO_MSVC)
# if defined(__GNUC__)
# elif defined(__clang__)
# if (__clang_major__ >= 14)
# if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)
# if __has_include(<coroutine>)
# define BOOST_ASIO_HAS_STD_COROUTINE 1
# endif // __has_include(<coroutine>)
# endif // (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)
# endif // (__clang_major__ >= 14)
# elif defined(__GNUC__)
# if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)
# if __has_include(<coroutine>)
# define BOOST_ASIO_HAS_STD_COROUTINE 1
@ -1981,4 +2246,37 @@
# endif // !defined(BOOST_ASIO_DISABLE_STD_HASH)
#endif // !defined(BOOST_ASIO_HAS_STD_HASH)
// Standard library support for std::to_address.
#if !defined(BOOST_ASIO_HAS_STD_TO_ADDRESS)
# if !defined(BOOST_ASIO_DISABLE_STD_TO_ADDRESS)
# if defined(__clang__)
# if (__cplusplus >= 202002)
# define BOOST_ASIO_HAS_STD_TO_ADDRESS 1
# endif // (__cplusplus >= 202002)
# elif defined(__GNUC__)
# if (__GNUC__ >= 8)
# if (__cplusplus >= 202002)
# define BOOST_ASIO_HAS_STD_TO_ADDRESS 1
# endif // (__cplusplus >= 202002)
# endif // (__GNUC__ >= 8)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)
# define BOOST_ASIO_HAS_STD_TO_ADDRESS 1
# endif // (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_TO_ADDRESS)
#endif // !defined(BOOST_ASIO_HAS_STD_TO_ADDRESS)
// Standard library support for snprintf.
#if !defined(BOOST_ASIO_HAS_SNPRINTF)
# if !defined(BOOST_ASIO_DISABLE_SNPRINTF)
# if defined(__apple_build_version__)
# if (__clang_major__ >= 14)
# define BOOST_ASIO_HAS_SNPRINTF 1
# endif // (__clang_major__ >= 14)
# endif // defined(__apple_build_version__)
# endif // !defined(BOOST_ASIO_DISABLE_SNPRINTF)
#endif // !defined(BOOST_ASIO_HAS_SNPRINTF)
#endif // BOOST_ASIO_DETAIL_CONFIG_HPP

View File

@ -2,7 +2,7 @@
// detail/cstddef.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/cstdint.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -87,13 +87,31 @@ public:
per_descriptor_data& source_descriptor_data);
// Post a reactor operation for immediate completion.
void post_immediate_completion(reactor_op* op, bool is_continuation);
void post_immediate_completion(operation* op, bool is_continuation) const;
// Post a reactor operation for immediate completion.
BOOST_ASIO_DECL static void call_post_immediate_completion(
operation* op, bool is_continuation, const void* self);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
per_descriptor_data&, reactor_op* op,
bool is_continuation, bool allow_speculative);
bool is_continuation, bool allow_speculative,
void (*on_immediate)(operation*, bool, const void*),
const void* immediate_arg);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
void start_op(int op_type, socket_type descriptor,
per_descriptor_data& descriptor_data, reactor_op* op,
bool is_continuation, bool allow_speculative)
{
start_op(op_type, descriptor, descriptor_data,
op, is_continuation, allow_speculative,
&epoll_reactor::call_post_immediate_completion, this);
}
// Cancel all operations associated with the given descriptor. The
// handlers associated with the descriptor will be invoked with the

View File

@ -2,7 +2,7 @@
// detail/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -117,13 +117,30 @@ public:
per_descriptor_data& source_descriptor_data);
// Post a reactor operation for immediate completion.
void post_immediate_completion(operation* op, bool is_continuation);
void post_immediate_completion(operation* op, bool is_continuation) const;
// Post a reactor operation for immediate completion.
BOOST_ASIO_DECL static void call_post_immediate_completion(
operation* op, bool is_continuation, const void* self);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
per_descriptor_data& descriptor_data, reactor_op* op,
bool is_continuation, bool allow_speculative);
bool is_continuation, bool allow_speculative,
void (*on_immediate)(operation*, bool, const void*),
const void* immediate_arg);
// Start a new operation. The reactor operation will be performed when the
// given descriptor is flagged as ready, or an error has occurred.
void start_op(int op_type, socket_type descriptor,
per_descriptor_data& descriptor_data, reactor_op* op,
bool is_continuation, bool allow_speculative)
{
start_op(op_type, descriptor, descriptor_data,
op, is_continuation, allow_speculative,
&epoll_reactor::call_post_immediate_completion, this);
}
// Cancel all operations associated with the given descriptor. The
// handlers associated with the descriptor will be invoked with the

View File

@ -2,7 +2,7 @@
// detail/event.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/eventfd_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -2,7 +2,7 @@
// detail/executor_function.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/executor_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -47,6 +47,7 @@ public:
std::size_t /*bytes_transferred*/)
{
// Take ownership of the handler object.
BOOST_ASIO_ASSUME(base != 0);
executor_op* o(static_cast<executor_op*>(base));
Alloc allocator(o->allocator_);
ptr p = { detail::addressof(allocator), o, o };

View File

@ -2,7 +2,7 @@
// detail/fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/functional.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/gcc_arm_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/gcc_hppa_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/gcc_sync_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/gcc_x86_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -56,7 +56,7 @@ private:
{
int r = 0, m = 1;
__asm__ __volatile__ (
"xchgl %0, %1" :
"xchg{l} %0, %1" :
"=r"(r), "=m"(m) :
"0"(1), "m"(m) :
"memory", "cc");

View File

@ -2,7 +2,7 @@
// detail/global.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_alloc_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -55,7 +55,7 @@ inline void* allocate(std::size_t s, Handler& h,
std::size_t align = BOOST_ASIO_DEFAULT_ALIGN)
{
#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
return aligned_new(align, s);
return boost::asio::aligned_new(align, s);
#elif defined(BOOST_ASIO_NO_DEPRECATED)
// The asio_handler_allocate hook is no longer used to obtain memory.
(void)&error_if_hooks_are_defined<Handler>;
@ -65,7 +65,7 @@ inline void* allocate(std::size_t s, Handler& h,
boost::asio::detail::thread_context::top_of_thread_call_stack(),
s, align);
# else // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
return aligned_new(align, s);
return boost::asio::aligned_new(align, s);
# endif // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
#else
(void)align;
@ -78,7 +78,7 @@ template <typename Handler>
inline void deallocate(void* p, std::size_t s, Handler& h)
{
#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
aligned_delete(p);
boost::asio::aligned_delete(p);
#elif defined(BOOST_ASIO_NO_DEPRECATED)
// The asio_handler_allocate hook is no longer used to obtain memory.
(void)&error_if_hooks_are_defined<Handler>;
@ -88,7 +88,7 @@ inline void deallocate(void* p, std::size_t s, Handler& h)
boost::asio::detail::thread_context::top_of_thread_call_stack(), p, s);
#else // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
(void)s;
aligned_delete(p);
boost::asio::aligned_delete(p);
#endif // !defined(BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING)
#else
using boost::asio::asio_handler_deallocate;

View File

@ -2,7 +2,7 @@
// detail/handler_cont_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_invoke_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_tracking.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_type_requirements.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_work.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -16,9 +16,13 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/associated_immediate_executor.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/initiate_dispatch.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/work_dispatcher.hpp>
#include <boost/asio/execution/allocator.hpp>
#include <boost/asio/execution/blocking.hpp>
#include <boost/asio/execution/execute.hpp>
@ -37,6 +41,7 @@ class io_context;
#if !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
class any_completion_executor;
class any_io_executor;
#endif // !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
@ -95,11 +100,16 @@ public:
template <typename Function, typename Handler>
void dispatch(Function& function, Handler& handler)
{
#if defined(BOOST_ASIO_NO_DEPRECATED)
boost::asio::prefer(executor_,
execution::allocator((get_associated_allocator)(handler))
).execute(BOOST_ASIO_MOVE_CAST(Function)(function));
#else // defined(BOOST_ASIO_NO_DEPRECATED)
execution::execute(
boost::asio::prefer(executor_,
execution::blocking.possibly,
execution::allocator((get_associated_allocator)(handler))),
BOOST_ASIO_MOVE_CAST(Function)(function));
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
}
private:
@ -361,9 +371,11 @@ public:
template <typename Function, typename Handler>
void dispatch(Function& function, Handler&)
{
execution::execute(
boost::asio::prefer(executor_, execution::blocking.possibly),
BOOST_ASIO_MOVE_CAST(Function)(function));
#if defined(BOOST_ASIO_NO_DEPRECATED)
executor_.execute(BOOST_ASIO_MOVE_CAST(Function)(function));
#else // defined(BOOST_ASIO_NO_DEPRECATED)
execution::execute(executor_, BOOST_ASIO_MOVE_CAST(Function)(function));
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
}
private:
@ -378,10 +390,8 @@ class handler_work_base<
Executor, CandidateExecutor,
IoContext, PolymorphicExecutor,
typename enable_if<
is_same<
Executor,
any_io_executor
>::value
is_same<Executor, any_completion_executor>::value
|| is_same<Executor, any_io_executor>::value
>::type>
{
public:
@ -436,9 +446,11 @@ public:
template <typename Function, typename Handler>
void dispatch(Function& function, Handler&)
{
execution::execute(
boost::asio::prefer(executor_, execution::blocking.possibly),
BOOST_ASIO_MOVE_CAST(Function)(function));
#if defined(BOOST_ASIO_NO_DEPRECATED)
executor_.execute(BOOST_ASIO_MOVE_CAST(Function)(function));
#else // defined(BOOST_ASIO_NO_DEPRECATED)
execution::execute(executor_, BOOST_ASIO_MOVE_CAST(Function)(function));
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
}
private:
@ -518,6 +530,34 @@ public:
}
};
template <typename Handler, typename IoExecutor>
class immediate_handler_work
{
public:
typedef handler_work<Handler, IoExecutor> handler_work_type;
explicit immediate_handler_work(BOOST_ASIO_MOVE_ARG(handler_work_type) w)
: handler_work_(BOOST_ASIO_MOVE_CAST(handler_work_type)(w))
{
}
template <typename Function>
void complete(Function& function, Handler& handler, const void* io_ex)
{
typedef typename associated_immediate_executor<Handler, IoExecutor>::type
immediate_ex_type;
immediate_ex_type immediate_ex = (get_associated_immediate_executor)(
handler, *static_cast<const IoExecutor*>(io_ex));
(initiate_dispatch_with_executor<immediate_ex_type>(immediate_ex))(
BOOST_ASIO_MOVE_CAST(Function)(function));
}
private:
handler_work_type handler_work_;
};
} // namespace detail
} // namespace asio
} // namespace boost

View File

@ -2,7 +2,7 @@
// detail/hash_map.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/buffer_sequence_adapter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -28,7 +28,7 @@ namespace asio {
namespace detail {
inline void dev_poll_reactor::post_immediate_completion(
reactor_op* op, bool is_continuation)
operation* op, bool is_continuation) const
{
scheduler_.post_immediate_completion(op, is_continuation);
}

View File

@ -2,7 +2,7 @@
// detail/impl/dev_poll_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -149,15 +149,24 @@ void dev_poll_reactor::move_descriptor(socket_type,
{
}
void dev_poll_reactor::call_post_immediate_completion(
operation* op, bool is_continuation, const void* self)
{
static_cast<const dev_poll_reactor*>(self)->post_immediate_completion(
op, is_continuation);
}
void dev_poll_reactor::start_op(int op_type, socket_type descriptor,
dev_poll_reactor::per_descriptor_data&, reactor_op* op,
bool is_continuation, bool allow_speculative)
bool is_continuation, bool allow_speculative,
void (*on_immediate)(operation*, bool, const void*),
const void* immediate_arg)
{
boost::asio::detail::mutex::scoped_lock lock(mutex_);
if (shutdown_)
{
post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -170,7 +179,7 @@ void dev_poll_reactor::start_op(int op_type, socket_type descriptor,
if (op->perform())
{
lock.unlock();
scheduler_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
}

View File

@ -2,7 +2,7 @@
// detail/impl/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -26,7 +26,7 @@ namespace asio {
namespace detail {
inline void epoll_reactor::post_immediate_completion(
operation* op, bool is_continuation)
operation* op, bool is_continuation) const
{
scheduler_.post_immediate_completion(op, is_continuation);
}

View File

@ -2,7 +2,7 @@
// detail/impl/epoll_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -230,14 +230,23 @@ void epoll_reactor::move_descriptor(socket_type,
source_descriptor_data = 0;
}
void epoll_reactor::call_post_immediate_completion(
operation* op, bool is_continuation, const void* self)
{
static_cast<const epoll_reactor*>(self)->post_immediate_completion(
op, is_continuation);
}
void epoll_reactor::start_op(int op_type, socket_type descriptor,
epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op,
bool is_continuation, bool allow_speculative)
bool is_continuation, bool allow_speculative,
void (*on_immediate)(operation*, bool, const void*),
const void* immediate_arg)
{
if (!descriptor_data)
{
op->ec_ = boost::asio::error::bad_descriptor;
post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -245,7 +254,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
if (descriptor_data->shutdown_)
{
post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -263,7 +272,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
if (descriptor_data->registered_events_ != 0)
descriptor_data->try_speculative_[op_type] = false;
descriptor_lock.unlock();
scheduler_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
}
@ -271,7 +280,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
if (descriptor_data->registered_events_ == 0)
{
op->ec_ = boost::asio::error::operation_not_supported;
scheduler_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -290,7 +299,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
{
op->ec_ = boost::system::error_code(errno,
boost::asio::error::get_system_category());
scheduler_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
}
@ -299,7 +308,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
else if (descriptor_data->registered_events_ == 0)
{
op->ec_ = boost::asio::error::operation_not_supported;
scheduler_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
else

View File

@ -2,7 +2,7 @@
// detail/impl/eventfd_select_interrupter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -2,7 +2,7 @@
// detail/impl/handler_tracking.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -366,7 +366,9 @@ void handler_tracking::write_line(const char* format, ...)
va_start(args, format);
char line[256] = "";
#if defined(BOOST_ASIO_HAS_SECURE_RTL)
#if defined(BOOST_ASIO_HAS_SNPRINTF)
int length = vsnprintf(line, sizeof(line), format, args);
#elif defined(BOOST_ASIO_HAS_SECURE_RTL)
int length = vsprintf_s(line, sizeof(line), format, args);
#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
int length = vsprintf(line, format, args);

View File

@ -2,7 +2,7 @@
// detail/impl/io_uring_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/io_uring_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -22,6 +22,7 @@
#include <cstddef>
#include <sys/eventfd.h>
#include <boost/asio/detail/io_uring_service.hpp>
#include <boost/asio/detail/reactor_op.hpp>
#include <boost/asio/detail/scheduler.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
@ -377,13 +378,21 @@ void io_uring_service::deregister_io_object(
if (!io_obj->shutdown_)
{
op_queue<operation> ops;
do_cancel_ops(io_obj, ops);
bool pending_cancelled_ops = do_cancel_ops(io_obj, ops);
io_obj->shutdown_ = true;
io_object_lock.unlock();
scheduler_.post_deferred_completions(ops);
// Leave io_obj set so that it will be freed by the subsequent
// call to cleanup_io_obj.
if (pending_cancelled_ops)
{
// There are still pending operations. Prevent cleanup_io_object from
// freeing the I/O object and let the last operation to complete free it.
io_obj = 0;
}
else
{
// Leave io_obj set so that it will be freed by the subsequent call to
// cleanup_io_object.
}
}
else
{
@ -518,7 +527,7 @@ void io_uring_service::init_ring()
boost::asio::detail::throw_error(ec, "io_uring_queue_init");
}
#if defined(BOOST_ASIO_HAS_EPOLL)
#if !defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
event_fd_ = ::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
if (event_fd_ < 0)
{
@ -537,10 +546,10 @@ void io_uring_service::init_ring()
boost::asio::error::get_system_category());
boost::asio::detail::throw_error(ec, "io_uring_queue_init");
}
#endif // defined(BOOST_ASIO_HAS_EPOLL)
#endif // !defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
}
#if defined(BOOST_ASIO_HAS_EPOLL)
#if !defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
class io_uring_service::event_fd_read_op :
public reactor_op
{
@ -586,14 +595,14 @@ public:
private:
io_uring_service* service_;
};
#endif // defined(BOOST_ASIO_HAS_EPOLL)
#endif // !defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
void io_uring_service::register_with_reactor()
{
#if defined(BOOST_ASIO_HAS_EPOLL)
#if !defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
reactor_.register_internal_descriptor(reactor::read_op,
event_fd_, reactor_data_, new event_fd_read_op(this));
#endif // defined(BOOST_ASIO_HAS_EPOLL)
#endif // !defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
}
io_uring_service::io_object* io_uring_service::allocate_io_object()
@ -610,7 +619,7 @@ void io_uring_service::free_io_object(io_uring_service::io_object* io_obj)
registered_io_objects_.free(io_obj);
}
void io_uring_service::do_cancel_ops(
bool io_uring_service::do_cancel_ops(
per_io_object_data& io_obj, op_queue<operation>& ops)
{
bool cancel_op = false;
@ -646,6 +655,8 @@ void io_uring_service::do_cancel_ops(
}
submit_sqes();
}
return cancel_op;
}
void io_uring_service::do_add_timer_queue(timer_queue_base& queue)
@ -687,7 +698,10 @@ __kernel_timespec io_uring_service::get_timeout() const
sqe = ::io_uring_get_sqe(&ring_);
}
if (sqe)
{
::io_uring_sqe_set_data(sqe, 0);
++pending_sqes_;
}
return sqe;
}
@ -757,12 +771,18 @@ io_uring_service::io_queue::io_queue()
struct io_uring_service::perform_io_cleanup_on_block_exit
{
explicit perform_io_cleanup_on_block_exit(io_uring_service* s)
: service_(s), first_op_(0)
: service_(s), io_object_to_free_(0), first_op_(0)
{
}
~perform_io_cleanup_on_block_exit()
{
if (io_object_to_free_)
{
mutex::scoped_lock lock(service_->mutex_);
service_->free_io_object(io_object_to_free_);
}
if (first_op_)
{
// Post the remaining completed operations for invocation.
@ -783,6 +803,7 @@ struct io_uring_service::perform_io_cleanup_on_block_exit
}
io_uring_service* service_;
io_object* io_object_to_free_;
op_queue<operation> ops_;
operation* first_op_;
};
@ -844,6 +865,15 @@ operation* io_uring_service::io_queue::perform_io(int result)
}
}
// The last operation to complete on a shut down object must free it.
if (io_object_->shutdown_)
{
io_cleanup.io_object_to_free_ = io_object_;
for (int i = 0; i < max_ops; ++i)
if (!io_object_->queues_[i].op_queue_.empty())
io_cleanup.io_object_to_free_ = 0;
}
// The first operation will be returned for completion now. The others will
// be posted for later by the io_cleanup object's destructor.
io_cleanup.first_op_ = io_cleanup.ops_.front();

View File

@ -2,7 +2,7 @@
// detail/io_uring_socket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/kqueue_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -29,7 +29,7 @@ namespace asio {
namespace detail {
inline void kqueue_reactor::post_immediate_completion(
operation* op, bool is_continuation)
operation* op, bool is_continuation) const
{
scheduler_.post_immediate_completion(op, is_continuation);
}

View File

@ -2,7 +2,7 @@
// detail/impl/kqueue_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -191,14 +191,23 @@ void kqueue_reactor::move_descriptor(socket_type,
source_descriptor_data = 0;
}
void kqueue_reactor::call_post_immediate_completion(
operation* op, bool is_continuation, const void* self)
{
static_cast<const kqueue_reactor*>(self)->post_immediate_completion(
op, is_continuation);
}
void kqueue_reactor::start_op(int op_type, socket_type descriptor,
kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op,
bool is_continuation, bool allow_speculative)
bool is_continuation, bool allow_speculative,
void (*on_immediate)(operation*, bool, const void*),
const void* immediate_arg)
{
if (!descriptor_data)
{
op->ec_ = boost::asio::error::bad_descriptor;
post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -206,7 +215,7 @@ void kqueue_reactor::start_op(int op_type, socket_type descriptor,
if (descriptor_data->shutdown_)
{
post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -221,7 +230,7 @@ void kqueue_reactor::start_op(int op_type, socket_type descriptor,
if (op->perform())
{
descriptor_lock.unlock();
scheduler_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -240,7 +249,7 @@ void kqueue_reactor::start_op(int op_type, socket_type descriptor,
{
op->ec_ = boost::system::error_code(errno,
boost::asio::error::get_system_category());
scheduler_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
}

View File

@ -2,7 +2,7 @@
// detail/impl/null_event.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/pipe_select_interrupter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/posix_event.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/posix_mutex.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/posix_thread.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/posix_tss_ptr.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/reactive_socket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -45,6 +45,7 @@ void reactive_socket_service_base::construct(
{
impl.socket_ = invalid_socket;
impl.state_ = 0;
impl.reactor_data_ = reactor::per_descriptor_data();
}
void reactive_socket_service_base::base_move_construct(
@ -233,10 +234,11 @@ boost::system::error_code reactive_socket_service_base::do_assign(
return ec;
}
void reactive_socket_service_base::start_op(
reactive_socket_service_base::base_implementation_type& impl,
int op_type, reactor_op* op, bool is_continuation,
bool is_non_blocking, bool noop)
void reactive_socket_service_base::do_start_op(
reactive_socket_service_base::base_implementation_type& impl, int op_type,
reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop,
void (*on_immediate)(operation* op, bool, const void*),
const void* immediate_arg)
{
if (!noop)
{
@ -244,32 +246,38 @@ void reactive_socket_service_base::start_op(
|| socket_ops::set_internal_non_blocking(
impl.socket_, impl.state_, true, op->ec_))
{
reactor_.start_op(op_type, impl.socket_,
impl.reactor_data_, op, is_continuation, is_non_blocking);
reactor_.start_op(op_type, impl.socket_, impl.reactor_data_, op,
is_continuation, is_non_blocking, on_immediate, immediate_arg);
return;
}
}
reactor_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
}
void reactive_socket_service_base::start_accept_op(
void reactive_socket_service_base::do_start_accept_op(
reactive_socket_service_base::base_implementation_type& impl,
reactor_op* op, bool is_continuation, bool peer_is_open)
reactor_op* op, bool is_continuation, bool peer_is_open,
void (*on_immediate)(operation* op, bool, const void*),
const void* immediate_arg)
{
if (!peer_is_open)
start_op(impl, reactor::read_op, op, is_continuation, true, false);
{
do_start_op(impl, reactor::read_op, op, is_continuation,
true, false, on_immediate, immediate_arg);
}
else
{
op->ec_ = boost::asio::error::already_open;
reactor_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
}
}
void reactive_socket_service_base::start_connect_op(
void reactive_socket_service_base::do_start_connect_op(
reactive_socket_service_base::base_implementation_type& impl,
reactor_op* op, bool is_continuation,
const socket_addr_type* addr, size_t addrlen)
reactor_op* op, bool is_continuation, const void* addr, size_t addrlen,
void (*on_immediate)(operation* op, bool, const void*),
const void* immediate_arg)
{
if ((impl.state_ & socket_ops::non_blocking)
|| socket_ops::set_internal_non_blocking(
@ -281,14 +289,14 @@ void reactive_socket_service_base::start_connect_op(
|| op->ec_ == boost::asio::error::would_block)
{
op->ec_ = boost::system::error_code();
reactor_.start_op(reactor::connect_op, impl.socket_,
impl.reactor_data_, op, is_continuation, false);
reactor_.start_op(reactor::connect_op, impl.socket_, impl.reactor_data_,
op, is_continuation, false, on_immediate, immediate_arg);
return;
}
}
}
reactor_.post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
}
} // namespace detail

View File

@ -2,7 +2,7 @@
// detail/impl/resolver_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/scheduler.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -328,6 +328,7 @@ void scheduler::restart()
void scheduler::compensating_work_started()
{
thread_info_base* this_thread = thread_call_stack::contains(this);
BOOST_ASIO_ASSUME(this_thread != 0); // Only called from inside scheduler.
++static_cast<thread_info*>(this_thread)->private_outstanding_work;
}

View File

@ -2,7 +2,7 @@
// detail/impl/select_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -36,7 +36,7 @@ namespace asio {
namespace detail {
inline void select_reactor::post_immediate_completion(
reactor_op* op, bool is_continuation)
operation* op, bool is_continuation) const
{
scheduler_.post_immediate_completion(op, is_continuation);
}

View File

@ -2,7 +2,7 @@
// detail/impl/select_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -67,6 +67,7 @@ select_reactor::select_reactor(boost::asio::execution_context& ctx)
#if defined(BOOST_ASIO_HAS_IOCP)
stop_thread_(false),
thread_(0),
restart_reactor_(this),
#endif // defined(BOOST_ASIO_HAS_IOCP)
shutdown_(false)
{
@ -114,8 +115,12 @@ void select_reactor::shutdown()
void select_reactor::notify_fork(
boost::asio::execution_context::fork_event fork_ev)
{
#if defined(BOOST_ASIO_HAS_IOCP)
(void)fork_ev;
#else // defined(BOOST_ASIO_HAS_IOCP)
if (fork_ev == boost::asio::execution_context::fork_child)
interrupter_.recreate();
#endif // defined(BOOST_ASIO_HAS_IOCP)
}
void select_reactor::init_task()
@ -147,15 +152,23 @@ void select_reactor::move_descriptor(socket_type,
{
}
void select_reactor::call_post_immediate_completion(
operation* op, bool is_continuation, const void* self)
{
static_cast<const select_reactor*>(self)->post_immediate_completion(
op, is_continuation);
}
void select_reactor::start_op(int op_type, socket_type descriptor,
select_reactor::per_descriptor_data&, reactor_op* op,
bool is_continuation, bool)
select_reactor::per_descriptor_data&, reactor_op* op, bool is_continuation,
bool, void (*on_immediate)(operation*, bool, const void*),
const void* immediate_arg)
{
boost::asio::detail::mutex::scoped_lock lock(mutex_);
if (shutdown_)
{
post_immediate_completion(op, is_continuation);
on_immediate(op, is_continuation, immediate_arg);
return;
}
@ -263,7 +276,12 @@ void select_reactor::run(long usec, op_queue<operation>& ops)
if (!interrupter_.reset())
{
lock.lock();
#if defined(BOOST_ASIO_HAS_IOCP)
stop_thread_ = true;
scheduler_.post_immediate_completion(&restart_reactor_, false);
#else // defined(BOOST_ASIO_HAS_IOCP)
interrupter_.recreate();
#endif // defined(BOOST_ASIO_HAS_IOCP)
}
--retval;
}
@ -300,11 +318,36 @@ void select_reactor::run_thread()
{
lock.unlock();
op_queue<operation> ops;
run(true, ops);
run(-1, ops);
scheduler_.post_deferred_completions(ops);
lock.lock();
}
}
void select_reactor::restart_reactor::do_complete(void* owner, operation* base,
const boost::system::error_code& /*ec*/, std::size_t /*bytes_transferred*/)
{
if (owner)
{
select_reactor* reactor = static_cast<restart_reactor*>(base)->reactor_;
if (reactor->thread_)
{
reactor->thread_->join();
delete reactor->thread_;
reactor->thread_ = 0;
}
boost::asio::detail::mutex::scoped_lock lock(reactor->mutex_);
reactor->interrupter_.recreate();
reactor->stop_thread_ = false;
lock.unlock();
boost::asio::detail::signal_blocker sb;
reactor->thread_ =
new boost::asio::detail::thread(thread_function(reactor));
}
}
#endif // defined(BOOST_ASIO_HAS_IOCP)
void select_reactor::do_add_timer_queue(timer_queue_base& queue)

View File

@ -2,7 +2,7 @@
// detail/impl/service_registry.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/service_registry.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/socket_ops.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -79,7 +79,7 @@ inline void get_last_error(
{
if (!is_error_condition)
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
else
{
@ -95,16 +95,18 @@ inline void get_last_error(
template <typename SockLenType>
inline socket_type call_accept(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
socket_type s, void* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
socket_type result = ::accept(s,
static_cast<socket_addr_type*>(addr),
addrlen ? &tmp_addrlen : 0);
if (addrlen)
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
socket_type accept(socket_type s, socket_addr_type* addr,
socket_type accept(socket_type s, void* addr,
std::size_t* addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
@ -130,12 +132,12 @@ socket_type accept(socket_type s, socket_addr_type* addr,
}
#endif
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return new_s;
}
socket_type sync_accept(socket_type s, state_type state,
socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code& ec)
void* addr, std::size_t* addrlen, boost::system::error_code& ec)
{
// Accept a socket.
for (;;)
@ -180,9 +182,8 @@ socket_type sync_accept(socket_type s, state_type state,
#if defined(BOOST_ASIO_HAS_IOCP)
void complete_iocp_accept(socket_type s,
void* output_buffer, DWORD address_length,
socket_addr_type* addr, std::size_t* addrlen,
void complete_iocp_accept(socket_type s, void* output_buffer,
DWORD address_length, void* addr, std::size_t* addrlen,
socket_type new_socket, boost::system::error_code& ec)
{
// Map non-portable errors to their portable counterparts.
@ -226,7 +227,7 @@ void complete_iocp_accept(socket_type s,
#else // defined(BOOST_ASIO_HAS_IOCP)
bool non_blocking_accept(socket_type s,
state_type state, socket_addr_type* addr, std::size_t* addrlen,
state_type state, void* addr, std::size_t* addrlen,
boost::system::error_code& ec, socket_type& new_socket)
{
for (;;)
@ -273,12 +274,13 @@ bool non_blocking_accept(socket_type s,
template <typename SockLenType>
inline int call_bind(SockLenType msghdr::*,
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
socket_type s, const void* addr, std::size_t addrlen)
{
return ::bind(s, addr, (SockLenType)addrlen);
return ::bind(s, static_cast<const socket_addr_type*>(addr),
(SockLenType)addrlen);
}
int bind(socket_type s, const socket_addr_type* addr,
int bind(socket_type s, const void* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
@ -464,12 +466,13 @@ int shutdown(socket_type s, int what, boost::system::error_code& ec)
template <typename SockLenType>
inline int call_connect(SockLenType msghdr::*,
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
socket_type s, const void* addr, std::size_t addrlen)
{
return ::connect(s, addr, (SockLenType)addrlen);
return ::connect(s, static_cast<const socket_addr_type*>(addr),
(SockLenType)addrlen);
}
int connect(socket_type s, const socket_addr_type* addr,
int connect(socket_type s, const void* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
@ -482,12 +485,17 @@ int connect(socket_type s, const socket_addr_type* addr,
get_last_error(ec, result != 0);
#if defined(__linux__)
if (result != 0 && ec == boost::asio::error::try_again)
ec = boost::asio::error::no_buffer_space;
{
if (static_cast<const socket_addr_type*>(addr)->sa_family == AF_UNIX)
ec = boost::asio::error::in_progress;
else
ec = boost::asio::error::no_buffer_space;
}
#endif // defined(__linux__)
return result;
}
void sync_connect(socket_type s, const socket_addr_type* addr,
void sync_connect(socket_type s, const void* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
// Perform the connect operation.
@ -597,7 +605,7 @@ bool non_blocking_connect(socket_type s, boost::system::error_code& ec)
boost::asio::error::get_system_category());
}
else
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
return true;
@ -642,7 +650,7 @@ bool sockatmark(socket_type s, boost::system::error_code& ec)
# endif // defined(ENOTTY)
#else // defined(SIOCATMARK)
int value = ::sockatmark(s);
get_last_error(ec, result < 0);
get_last_error(ec, value < 0);
#endif // defined(SIOCATMARK)
return ec ? false : value != 0;
@ -723,9 +731,9 @@ void init_buf(buf& b, const void* data, size_t size)
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
}
inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
inline void init_msghdr_msg_name(void*& name, void* addr)
{
name = addr;
name = static_cast<socket_addr_type*>(addr);
}
inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
@ -734,15 +742,15 @@ inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
}
template <typename T>
inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
inline void init_msghdr_msg_name(T& name, void* addr)
{
name = reinterpret_cast<T>(addr);
name = static_cast<T>(addr);
}
template <typename T>
inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
inline void init_msghdr_msg_name(T& name, const void* addr)
{
name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
name = static_cast<T>(const_cast<void*>(addr));
}
signed_size_type recv(socket_type s, buf* bufs, size_t count,
@ -764,7 +772,7 @@ signed_size_type recv(socket_type s, buf* bufs, size_t count,
result = 0;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@ -797,7 +805,7 @@ signed_size_type recv1(socket_type s, void* data, size_t size,
result = 0;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
signed_size_type result = ::recv(s, static_cast<char*>(data), size, flags);
@ -818,7 +826,7 @@ size_t sync_recv(socket_type s, state_type state, buf* bufs,
// A request to read 0 bytes on a stream is a no-op.
if (all_empty && (state & stream_oriented))
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
@ -863,7 +871,7 @@ size_t sync_recv1(socket_type s, state_type state, void* data,
// A request to read 0 bytes on a stream is a no-op.
if (size == 0 && (state & stream_oriented))
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
@ -916,7 +924,7 @@ void complete_iocp_recv(state_type state,
}
else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA)
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
// Check for connection closed.
@ -1009,8 +1017,7 @@ bool non_blocking_recv1(socket_type s,
#endif // defined(BOOST_ASIO_HAS_IOCP)
signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
int flags, socket_addr_type* addr, std::size_t* addrlen,
boost::system::error_code& ec)
int flags, void* addr, std::size_t* addrlen, boost::system::error_code& ec)
{
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
// Receive some data.
@ -1018,8 +1025,8 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
DWORD bytes_transferred = 0;
DWORD recv_flags = flags;
int tmp_addrlen = (int)*addrlen;
int result = ::WSARecvFrom(s, bufs, recv_buf_count,
&bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0);
int result = ::WSARecvFrom(s, bufs, recv_buf_count, &bytes_transferred,
&recv_flags, static_cast<socket_addr_type*>(addr), &tmp_addrlen, 0, 0);
get_last_error(ec, true);
*addrlen = (std::size_t)tmp_addrlen;
if (ec.value() == ERROR_NETNAME_DELETED)
@ -1030,7 +1037,7 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
result = 0;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@ -1046,21 +1053,19 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
}
template <typename SockLenType>
inline signed_size_type call_recvfrom(SockLenType msghdr::*,
socket_type s, void* data, size_t size, int flags,
socket_addr_type* addr, std::size_t* addrlen)
inline signed_size_type call_recvfrom(SockLenType msghdr::*, socket_type s,
void* data, size_t size, int flags, void* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
signed_size_type result = ::recvfrom(s, static_cast<char*>(data),
size, flags, addr, addrlen ? &tmp_addrlen : 0);
signed_size_type result = ::recvfrom(s, static_cast<char*>(data), size,
flags, static_cast<socket_addr_type*>(addr), addrlen ? &tmp_addrlen : 0);
if (addrlen)
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
signed_size_type recvfrom1(socket_type s, void* data, size_t size,
int flags, socket_addr_type* addr, std::size_t* addrlen,
boost::system::error_code& ec)
int flags, void* addr, std::size_t* addrlen, boost::system::error_code& ec)
{
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
// Receive some data.
@ -1070,8 +1075,8 @@ signed_size_type recvfrom1(socket_type s, void* data, size_t size,
DWORD bytes_transferred = 0;
DWORD recv_flags = flags;
int tmp_addrlen = (int)*addrlen;
int result = ::WSARecvFrom(s, &buf, 1, &bytes_transferred,
&recv_flags, addr, &tmp_addrlen, 0, 0);
int result = ::WSARecvFrom(s, &buf, 1, &bytes_transferred, &recv_flags,
static_cast<socket_addr_type*>(addr), &tmp_addrlen, 0, 0);
get_last_error(ec, true);
*addrlen = (std::size_t)tmp_addrlen;
if (ec.value() == ERROR_NETNAME_DELETED)
@ -1082,7 +1087,7 @@ signed_size_type recvfrom1(socket_type s, void* data, size_t size,
result = 0;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
signed_size_type result = call_recvfrom(&msghdr::msg_namelen,
@ -1092,9 +1097,8 @@ signed_size_type recvfrom1(socket_type s, void* data, size_t size,
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
}
size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
size_t count, int flags, socket_addr_type* addr,
std::size_t* addrlen, boost::system::error_code& ec)
size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, size_t count,
int flags, void* addr, std::size_t* addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
{
@ -1125,9 +1129,8 @@ size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
}
}
size_t sync_recvfrom1(socket_type s, state_type state, void* data,
size_t size, int flags, socket_addr_type* addr,
std::size_t* addrlen, boost::system::error_code& ec)
size_t sync_recvfrom1(socket_type s, state_type state, void* data, size_t size,
int flags, void* addr, std::size_t* addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
{
@ -1178,15 +1181,14 @@ void complete_iocp_recvfrom(
}
else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA)
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
}
#else // defined(BOOST_ASIO_HAS_IOCP)
bool non_blocking_recvfrom(socket_type s,
buf* bufs, size_t count, int flags,
socket_addr_type* addr, std::size_t* addrlen,
bool non_blocking_recvfrom(socket_type s, buf* bufs,
size_t count, int flags, void* addr, std::size_t* addrlen,
boost::system::error_code& ec, size_t& bytes_transferred)
{
for (;;)
@ -1217,9 +1219,8 @@ bool non_blocking_recvfrom(socket_type s,
}
}
bool non_blocking_recvfrom1(socket_type s,
void* data, size_t size, int flags,
socket_addr_type* addr, std::size_t* addrlen,
bool non_blocking_recvfrom1(socket_type s, void* data,
size_t size, int flags, void* addr, std::size_t* addrlen,
boost::system::error_code& ec, size_t& bytes_transferred)
{
for (;;)
@ -1325,7 +1326,7 @@ void complete_iocp_recvmsg(
}
else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA)
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
}
@ -1382,7 +1383,7 @@ signed_size_type send(socket_type s, const buf* bufs, size_t count,
ec = boost::asio::error::connection_refused;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@ -1416,7 +1417,7 @@ signed_size_type send1(socket_type s, const void* data, size_t size,
ec = boost::asio::error::connection_refused;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
#if defined(BOOST_ASIO_HAS_MSG_NOSIGNAL)
@ -1441,7 +1442,7 @@ size_t sync_send(socket_type s, state_type state, const buf* bufs,
// A request to write 0 bytes to a stream is a no-op.
if (all_empty && (state & stream_oriented))
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
@ -1479,7 +1480,7 @@ size_t sync_send1(socket_type s, state_type state, const void* data,
// A request to write 0 bytes to a stream is a no-op.
if (size == 0 && (state & stream_oriented))
{
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
@ -1591,16 +1592,17 @@ bool non_blocking_send1(socket_type s,
#endif // defined(BOOST_ASIO_HAS_IOCP)
signed_size_type sendto(socket_type s, const buf* bufs, size_t count,
int flags, const socket_addr_type* addr, std::size_t addrlen,
boost::system::error_code& ec)
signed_size_type sendto(socket_type s, const buf* bufs,
size_t count, int flags, const void* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
// Send the data.
DWORD send_buf_count = static_cast<DWORD>(count);
DWORD bytes_transferred = 0;
int result = ::WSASendTo(s, const_cast<buf*>(bufs),
send_buf_count, &bytes_transferred, flags, addr,
send_buf_count, &bytes_transferred, flags,
static_cast<const socket_addr_type*>(addr),
static_cast<int>(addrlen), 0, 0);
get_last_error(ec, true);
if (ec.value() == ERROR_NETNAME_DELETED)
@ -1609,7 +1611,7 @@ signed_size_type sendto(socket_type s, const buf* bufs, size_t count,
ec = boost::asio::error::connection_refused;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
msghdr msg = msghdr();
@ -1629,15 +1631,15 @@ signed_size_type sendto(socket_type s, const buf* bufs, size_t count,
template <typename SockLenType>
inline signed_size_type call_sendto(SockLenType msghdr::*,
socket_type s, const void* data, size_t size, int flags,
const socket_addr_type* addr, std::size_t addrlen)
const void* addr, std::size_t addrlen)
{
return ::sendto(s, static_cast<char*>(const_cast<void*>(data)),
size, flags, addr, (SockLenType)addrlen);
return ::sendto(s, static_cast<char*>(const_cast<void*>(data)), size, flags,
static_cast<const socket_addr_type*>(addr), (SockLenType)addrlen);
}
signed_size_type sendto1(socket_type s, const void* data, size_t size,
int flags, const socket_addr_type* addr, std::size_t addrlen,
boost::system::error_code& ec)
signed_size_type sendto1(socket_type s, const void* data,
size_t size, int flags, const void* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
// Send the data.
@ -1645,8 +1647,9 @@ signed_size_type sendto1(socket_type s, const void* data, size_t size,
buf.buf = const_cast<char*>(static_cast<const char*>(data));
buf.len = static_cast<ULONG>(size);
DWORD bytes_transferred = 0;
int result = ::WSASendTo(s, &buf, 1, &bytes_transferred,
flags, addr, static_cast<int>(addrlen), 0, 0);
int result = ::WSASendTo(s, &buf, 1, &bytes_transferred, flags,
static_cast<const socket_addr_type*>(addr),
static_cast<int>(addrlen), 0, 0);
get_last_error(ec, true);
if (ec.value() == ERROR_NETNAME_DELETED)
ec = boost::asio::error::connection_reset;
@ -1654,7 +1657,7 @@ signed_size_type sendto1(socket_type s, const void* data, size_t size,
ec = boost::asio::error::connection_refused;
if (result != 0)
return socket_error_retval;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return bytes_transferred;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
#if defined(BOOST_ASIO_HAS_MSG_NOSIGNAL)
@ -1667,8 +1670,8 @@ signed_size_type sendto1(socket_type s, const void* data, size_t size,
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
}
size_t sync_sendto(socket_type s, state_type state, const buf* bufs,
size_t count, int flags, const socket_addr_type* addr,
size_t sync_sendto(socket_type s, state_type state,
const buf* bufs, size_t count, int flags, const void* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
@ -1700,8 +1703,8 @@ size_t sync_sendto(socket_type s, state_type state, const buf* bufs,
}
}
size_t sync_sendto1(socket_type s, state_type state, const void* data,
size_t size, int flags, const socket_addr_type* addr,
size_t sync_sendto1(socket_type s, state_type state,
const void* data, size_t size, int flags, const void* addr,
std::size_t addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
@ -1737,7 +1740,7 @@ size_t sync_sendto1(socket_type s, state_type state, const void* data,
bool non_blocking_sendto(socket_type s,
const buf* bufs, size_t count, int flags,
const socket_addr_type* addr, std::size_t addrlen,
const void* addr, std::size_t addrlen,
boost::system::error_code& ec, size_t& bytes_transferred)
{
for (;;)
@ -1770,7 +1773,7 @@ bool non_blocking_sendto(socket_type s,
bool non_blocking_sendto1(socket_type s,
const void* data, size_t size, int flags,
const socket_addr_type* addr, std::size_t addrlen,
const void* addr, std::size_t addrlen,
boost::system::error_code& ec, size_t& bytes_transferred)
{
for (;;)
@ -1884,7 +1887,7 @@ int setsockopt(socket_type s, state_type& state, int level, int optname,
state |= enable_connection_aborted;
else
state &= ~enable_connection_aborted;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
@ -1969,7 +1972,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname,
}
*static_cast<int*>(optval) = (state & enable_connection_aborted) ? 1 : 0;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
@ -1996,7 +1999,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname,
// value is non-zero (i.e. true). This corresponds to the behavior of
// IPv6 sockets on Windows platforms pre-Vista.
*static_cast<DWORD*>(optval) = 1;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
return result;
}
@ -2016,7 +2019,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname,
// non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets
// on Windows platforms pre-Vista.
*static_cast<DWORD*>(optval) = 1;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
return result;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
@ -2041,16 +2044,17 @@ int getsockopt(socket_type s, state_type state, int level, int optname,
template <typename SockLenType>
inline int call_getpeername(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
socket_type s, void* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = (SockLenType)*addrlen;
int result = ::getpeername(s, addr, &tmp_addrlen);
int result = ::getpeername(s,
static_cast<socket_addr_type*>(addr), &tmp_addrlen);
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
int getpeername(socket_type s, socket_addr_type* addr,
std::size_t* addrlen, bool cached, boost::system::error_code& ec)
int getpeername(socket_type s, void* addr, std::size_t* addrlen,
bool cached, boost::system::error_code& ec)
{
if (s == invalid_socket)
{
@ -2077,7 +2081,7 @@ int getpeername(socket_type s, socket_addr_type* addr,
}
// The cached value is still valid.
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
#else // defined(BOOST_ASIO_WINDOWS) && !defined(BOOST_ASIO_WINDOWS_APP)
@ -2093,15 +2097,16 @@ int getpeername(socket_type s, socket_addr_type* addr,
template <typename SockLenType>
inline int call_getsockname(SockLenType msghdr::*,
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
socket_type s, void* addr, std::size_t* addrlen)
{
SockLenType tmp_addrlen = (SockLenType)*addrlen;
int result = ::getsockname(s, addr, &tmp_addrlen);
int result = ::getsockname(s,
static_cast<socket_addr_type*>(addr), &tmp_addrlen);
*addrlen = (std::size_t)tmp_addrlen;
return result;
}
int getsockname(socket_type s, socket_addr_type* addr,
int getsockname(socket_type s, void* addr,
std::size_t* addrlen, boost::system::error_code& ec)
{
if (s == invalid_socket)
@ -2172,7 +2177,7 @@ int select(int nfds, fd_set* readfds, fd_set* writefds,
if (milliseconds == 0)
milliseconds = 1; // Force context switch.
::Sleep(milliseconds);
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 0;
}
@ -2492,7 +2497,7 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length,
// Windows may set error code on success.
if (result != socket_error_retval)
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
// Windows may not set an error code on failure.
else if (result == socket_error_retval && !ec)
@ -2515,7 +2520,11 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length,
&& ((ipv6_address->s6_addr[1] & 0x0f) == 0x02));
if ((!is_link_local && !is_multicast_link_local)
|| if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0)
#if defined(BOOST_ASIO_HAS_SNPRINTF)
snprintf(if_name + 1, sizeof(if_name) - 1, "%lu", scope_id);
#else // defined(BOOST_ASIO_HAS_SNPRINTF)
sprintf(if_name + 1, "%lu", scope_id);
#endif // defined(BOOST_ASIO_HAS_SNPRINTF)
strcat(dest, if_name);
}
return result;
@ -2546,7 +2555,7 @@ int inet_pton(int af, const char* src, void* dest,
bytes[1] = static_cast<unsigned char>(b1);
bytes[2] = static_cast<unsigned char>(b2);
bytes[3] = static_cast<unsigned char>(b3);
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 1;
}
else if (af == BOOST_ASIO_OS_DEF(AF_INET6))
@ -2662,7 +2671,7 @@ int inet_pton(int af, const char* src, void* dest,
for (int i = 0; i < num_back_bytes; ++i)
bytes[16 - num_back_bytes + i] = back_bytes[i];
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return 1;
}
else
@ -2705,12 +2714,12 @@ int inet_pton(int af, const char* src, void* dest,
if (result != socket_error_retval)
{
memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type));
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
else if (strcmp(src, "255.255.255.255") == 0)
{
static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
}
else // AF_INET6
@ -2720,7 +2729,7 @@ int inet_pton(int af, const char* src, void* dest,
memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type));
if (scope_id)
*scope_id = address.v6.sin6_scope_id;
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
}
}
@ -2729,7 +2738,7 @@ int inet_pton(int af, const char* src, void* dest,
ec = boost::asio::error::invalid_argument;
if (result != socket_error_retval)
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return result == socket_error_retval ? -1 : 1;
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
@ -3623,7 +3632,9 @@ inline boost::system::error_code getnameinfo_emulation(
{
return ec = boost::asio::error::no_buffer_space;
}
#if defined(BOOST_ASIO_HAS_SECURE_RTL)
#if defined(BOOST_ASIO_HAS_SNPRINTF)
snprintf(serv, servlen, "%u", ntohs(port));
#elif defined(BOOST_ASIO_HAS_SECURE_RTL)
sprintf_s(serv, servlen, "%u", ntohs(port));
#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
sprintf(serv, "%u", ntohs(port));
@ -3646,7 +3657,9 @@ inline boost::system::error_code getnameinfo_emulation(
{
return ec = boost::asio::error::no_buffer_space;
}
#if defined(BOOST_ASIO_HAS_SECURE_RTL)
#if defined(BOOST_ASIO_HAS_SNPRINTF)
snprintf(serv, servlen, "%u", ntohs(port));
#elif defined(BOOST_ASIO_HAS_SECURE_RTL)
sprintf_s(serv, servlen, "%u", ntohs(port));
#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
sprintf(serv, "%u", ntohs(port));
@ -3658,7 +3671,7 @@ inline boost::system::error_code getnameinfo_emulation(
}
}
ec.assign(0, ec.category());
boost::asio::error::clear(ec);
return ec;
}
@ -3808,7 +3821,7 @@ void freeaddrinfo(addrinfo_type* ai)
#endif
}
boost::system::error_code getnameinfo(const socket_addr_type* addr,
boost::system::error_code getnameinfo(const void* addr,
std::size_t addrlen, char* host, std::size_t hostlen,
char* serv, std::size_t servlen, int flags, boost::system::error_code& ec)
{
@ -3816,8 +3829,8 @@ boost::system::error_code getnameinfo(const socket_addr_type* addr,
# if defined(BOOST_ASIO_HAS_GETADDRINFO)
// Building for Windows XP, Windows Server 2003, or later.
clear_last_error();
int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen),
host, static_cast<DWORD>(hostlen),
int error = ::getnameinfo(static_cast<const socket_addr_type*>(addr),
static_cast<socklen_t>(addrlen), host, static_cast<DWORD>(hostlen),
serv, static_cast<DWORD>(servlen), flags);
return ec = translate_addrinfo_error(error);
# else
@ -3829,34 +3842,34 @@ boost::system::error_code getnameinfo(const socket_addr_type* addr,
if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
{
clear_last_error();
int error = gni(addr, static_cast<int>(addrlen),
host, static_cast<DWORD>(hostlen),
int error = gni(static_cast<const socket_addr_type*>(addr),
static_cast<int>(addrlen), host, static_cast<DWORD>(hostlen),
serv, static_cast<DWORD>(servlen), flags);
return ec = translate_addrinfo_error(error);
}
}
clear_last_error();
return getnameinfo_emulation(addr, addrlen,
host, hostlen, serv, servlen, flags, ec);
return getnameinfo_emulation(static_cast<const socket_addr_type*>(addr),
addrlen, host, hostlen, serv, servlen, flags, ec);
# endif
#elif !defined(BOOST_ASIO_HAS_GETADDRINFO)
using namespace std; // For memcpy.
sockaddr_storage_type tmp_addr;
memcpy(&tmp_addr, addr, addrlen);
addr = reinterpret_cast<socket_addr_type*>(&tmp_addr);
addr = &tmp_addr;
clear_last_error();
return getnameinfo_emulation(addr, addrlen,
host, hostlen, serv, servlen, flags, ec);
return getnameinfo_emulation(static_cast<const socket_addr_type*>(addr),
addrlen, host, hostlen, serv, servlen, flags, ec);
#else
clear_last_error();
int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
int error = ::getnameinfo(static_cast<const socket_addr_type*>(addr),
addrlen, host, hostlen, serv, servlen, flags);
return ec = translate_addrinfo_error(error);
#endif
}
boost::system::error_code sync_getnameinfo(
const socket_addr_type* addr, std::size_t addrlen,
char* host, std::size_t hostlen, char* serv,
boost::system::error_code sync_getnameinfo(const void* addr,
std::size_t addrlen, char* host, std::size_t hostlen, char* serv,
std::size_t servlen, int sock_type, boost::system::error_code& ec)
{
// First try resolving with the service name. If that fails try resolving
@ -3875,7 +3888,7 @@ boost::system::error_code sync_getnameinfo(
boost::system::error_code background_getnameinfo(
const weak_cancel_token_type& cancel_token,
const socket_addr_type* addr, std::size_t addrlen,
const void* addr, std::size_t addrlen,
char* host, std::size_t hostlen, char* serv,
std::size_t servlen, int sock_type, boost::system::error_code& ec)
{

View File

@ -2,7 +2,7 @@
// detail/impl/socket_select_interrupter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -61,11 +61,11 @@ void socket_select_interrupter::open_descriptors()
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK);
addr.sin_port = 0;
if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr,
if (socket_ops::bind(acceptor.get(), &addr,
addr_len, ec) == socket_error_retval)
boost::asio::detail::throw_error(ec, "socket_select_interrupter");
if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr,
if (socket_ops::getsockname(acceptor.get(), &addr,
&addr_len, ec) == socket_error_retval)
boost::asio::detail::throw_error(ec, "socket_select_interrupter");
@ -84,7 +84,7 @@ void socket_select_interrupter::open_descriptors()
if (client.get() == invalid_socket)
boost::asio::detail::throw_error(ec, "socket_select_interrupter");
if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr,
if (socket_ops::connect(client.get(), &addr,
addr_len, ec) == socket_error_retval)
boost::asio::detail::throw_error(ec, "socket_select_interrupter");

View File

@ -2,7 +2,7 @@
// detail/impl/strand_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/strand_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/thread_context.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/throw_error.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -17,7 +17,6 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/throw_exception.hpp>
#include <boost/system/system_error.hpp>
#include <boost/asio/detail/push_options.hpp>
@ -26,16 +25,21 @@ namespace boost {
namespace asio {
namespace detail {
void do_throw_error(const boost::system::error_code& err)
void do_throw_error(
const boost::system::error_code& err
BOOST_ASIO_SOURCE_LOCATION_PARAM)
{
boost::system::system_error e(err);
boost::asio::detail::throw_exception(e);
boost::asio::detail::throw_exception(e BOOST_ASIO_SOURCE_LOCATION_ARG);
}
void do_throw_error(const boost::system::error_code& err, const char* location)
void do_throw_error(
const boost::system::error_code& err,
const char* location
BOOST_ASIO_SOURCE_LOCATION_PARAM)
{
boost::system::system_error e(err, location);
boost::asio::detail::throw_exception(e);
boost::asio::detail::throw_exception(e BOOST_ASIO_SOURCE_LOCATION_ARG);
}
} // namespace detail

View File

@ -2,7 +2,7 @@
// detail/impl/timer_queue_set.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/win_event.ipp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/win_iocp_io_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/win_iocp_io_context.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -52,7 +52,7 @@ struct win_iocp_io_context::thread_function
struct win_iocp_io_context::work_finished_on_block_exit
{
~work_finished_on_block_exit()
~work_finished_on_block_exit() BOOST_ASIO_NOEXCEPT_IF(false)
{
io_context_->work_finished();
}
@ -169,7 +169,10 @@ void win_iocp_io_context::shutdown()
}
if (timer_thread_.get())
{
timer_thread_->join();
timer_thread_.reset();
}
}
boost::system::error_code win_iocp_io_context::register_handle(
@ -528,6 +531,7 @@ size_t win_iocp_io_context::do_one(DWORD msec,
DWORD win_iocp_io_context::get_gqcs_timeout()
{
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600)
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
@ -540,6 +544,9 @@ DWORD win_iocp_io_context::get_gqcs_timeout()
return INFINITE;
return default_gqcs_timeout;
#else // !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600)
return INFINITE;
#endif // !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600)
}
void win_iocp_io_context::do_add_timer_queue(timer_queue_base& queue)

View File

@ -2,7 +2,7 @@
// detail/impl/win_iocp_socket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -411,9 +411,8 @@ void win_iocp_socket_service_base::start_send_op(
void win_iocp_socket_service_base::start_send_to_op(
win_iocp_socket_service_base::base_implementation_type& impl,
WSABUF* buffers, std::size_t buffer_count,
const socket_addr_type* addr, int addrlen,
socket_base::message_flags flags, operation* op)
WSABUF* buffers, std::size_t buffer_count, const void* addr,
int addrlen, socket_base::message_flags flags, operation* op)
{
update_cancellation_thread_id(impl);
iocp_service_.work_started();
@ -424,8 +423,8 @@ void win_iocp_socket_service_base::start_send_to_op(
{
DWORD bytes_transferred = 0;
int result = ::WSASendTo(impl.socket_, buffers,
static_cast<DWORD>(buffer_count),
&bytes_transferred, flags, addr, addrlen, op, 0);
static_cast<DWORD>(buffer_count), &bytes_transferred, flags,
static_cast<const socket_addr_type*>(addr), addrlen, op, 0);
DWORD last_error = ::WSAGetLastError();
if (last_error == ERROR_PORT_UNREACHABLE)
last_error = WSAECONNREFUSED;
@ -490,7 +489,7 @@ int win_iocp_socket_service_base::start_null_buffers_receive_op(
void win_iocp_socket_service_base::start_receive_from_op(
win_iocp_socket_service_base::base_implementation_type& impl,
WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr,
WSABUF* buffers, std::size_t buffer_count, void* addr,
socket_base::message_flags flags, int* addrlen, operation* op)
{
update_cancellation_thread_id(impl);
@ -503,8 +502,8 @@ void win_iocp_socket_service_base::start_receive_from_op(
DWORD bytes_transferred = 0;
DWORD recv_flags = flags;
int result = ::WSARecvFrom(impl.socket_, buffers,
static_cast<DWORD>(buffer_count),
&bytes_transferred, &recv_flags, addr, addrlen, op, 0);
static_cast<DWORD>(buffer_count), &bytes_transferred, &recv_flags,
static_cast<socket_addr_type*>(addr), addrlen, op, 0);
DWORD last_error = ::WSAGetLastError();
if (last_error == ERROR_PORT_UNREACHABLE)
last_error = WSAECONNREFUSED;
@ -609,7 +608,7 @@ void win_iocp_socket_service_base::start_reactor_op(
int win_iocp_socket_service_base::start_connect_op(
win_iocp_socket_service_base::base_implementation_type& impl,
int family, int type, const socket_addr_type* addr, std::size_t addrlen,
int family, int type, const void* addr, std::size_t addrlen,
win_iocp_socket_connect_op_base* op, operation* iocp_op)
{
// If ConnectEx is available, use that.
@ -643,7 +642,8 @@ int win_iocp_socket_service_base::start_connect_op(
iocp_service_.work_started();
BOOL result = connect_ex(impl.socket_,
addr, static_cast<int>(addrlen), 0, 0, 0, iocp_op);
static_cast<const socket_addr_type*>(addr),
static_cast<int>(addrlen), 0, 0, 0, iocp_op);
DWORD last_error = ::WSAGetLastError();
if (!result && last_error != WSA_IO_PENDING)
iocp_service_.on_completion(iocp_op, last_error);

View File

@ -2,7 +2,7 @@
// detail/impl/win_mutex.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/win_static_mutex.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

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