update boost & add container lib (#204)
* remove boost headers * boost 1.78
This commit is contained in:
parent
27fba2b278
commit
1aac2fcd8d
|
|
@ -24,7 +24,6 @@ set(CC_UTILS_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/xxtea/xxtea.h
|
${CMAKE_CURRENT_LIST_DIR}/xxtea/xxtea.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
set(CC_EXTERNAL_SOURCES
|
set(CC_EXTERNAL_SOURCES
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/tommyds/tommy.c
|
${CMAKE_CURRENT_LIST_DIR}/tommyds/tommy.c
|
||||||
|
|
@ -39,6 +38,9 @@ if(NOT USE_MODULES)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# add dependent boost libs
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/boost-source/boost.cmake)
|
||||||
|
|
||||||
if(ANDROID OR OHOS)
|
if(ANDROID OR OHOS)
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/pvmp3dec/CMakeLists.txt)
|
include(${CMAKE_CURRENT_LIST_DIR}/pvmp3dec/CMakeLists.txt)
|
||||||
|
|
@ -70,4 +72,3 @@ if(USE_PHYSICS_PHYSX)
|
||||||
${CMAKE_CURRENT_LIST_DIR}/PhysX/PxShared/include
|
${CMAKE_CURRENT_LIST_DIR}/PhysX/PxShared/include
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
list(APPEND CC_EXTERNAL_PRIVATE_DEFINITIONS BOOST_ALL_NO_LIB)
|
||||||
|
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/container boost/container)
|
||||||
|
|
||||||
|
set(BOOST_LIBS
|
||||||
|
boost_container
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(lib ${BOOST_LIBS})
|
||||||
|
set_target_properties(${lib} PROPERTIES FOLDER Utils)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
list(APPEND CC_EXTERNAL_LIBS ${BOOST_LIBS})
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Copyright 2020, 2021 Peter Dimov
|
||||||
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
|
# https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.5...3.16)
|
||||||
|
|
||||||
|
project(boost_container VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES C CXX)
|
||||||
|
|
||||||
|
add_library(boost_container
|
||||||
|
alloc_lib.c
|
||||||
|
dlmalloc.cpp
|
||||||
|
global_resource.cpp
|
||||||
|
monotonic_buffer_resource.cpp
|
||||||
|
pool_resource.cpp
|
||||||
|
synchronized_pool_resource.cpp
|
||||||
|
unsynchronized_pool_resource.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(Boost::container ALIAS boost_container)
|
||||||
|
|
||||||
|
target_compile_definitions(boost_container
|
||||||
|
PUBLIC BOOST_CONTAINER_NO_LIB
|
||||||
|
# Source files already define BOOST_CONTAINER_SOURCE
|
||||||
|
# PRIVATE BOOST_CONTAINER_SOURCE
|
||||||
|
)
|
||||||
|
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
target_compile_definitions(boost_container PUBLIC BOOST_CONTAINER_DYN_LINK)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(boost_container PUBLIC BOOST_CONTAINER_STATIC_LINK)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||||
|
|
||||||
|
add_subdirectory(test)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost
|
||||||
|
// Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#define DLMALLOC_VERSION 286
|
||||||
|
|
||||||
|
#ifndef DLMALLOC_VERSION
|
||||||
|
#error "DLMALLOC_VERSION undefined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __VXWORKS__
|
||||||
|
// no sbrk() in VxWorks, configure dlmalloc to use only mmap()
|
||||||
|
#define HAVE_MORECORE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DLMALLOC_VERSION == 286
|
||||||
|
#include "dlmalloc_ext_2_8_6.c"
|
||||||
|
#else
|
||||||
|
#error "Unsupported boost_cont_VERSION version"
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost
|
||||||
|
// Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define BOOST_CONTAINER_SOURCE
|
||||||
|
#include <boost/container/detail/dlmalloc.hpp>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace container{
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL size_t dlmalloc_size(const void *p)
|
||||||
|
{ return boost_cont_size(p); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void* dlmalloc_malloc(size_t bytes)
|
||||||
|
{ return boost_cont_malloc(bytes); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void dlmalloc_free(void* mem)
|
||||||
|
{ return boost_cont_free(mem); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void* dlmalloc_memalign(size_t bytes, size_t alignment)
|
||||||
|
{ return boost_cont_memalign(bytes, alignment); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_multialloc_nodes
|
||||||
|
(size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain)
|
||||||
|
{ return boost_cont_multialloc_nodes(n_elements, elem_size, contiguous_elements, pchain); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_multialloc_arrays
|
||||||
|
(size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain)
|
||||||
|
{ return boost_cont_multialloc_arrays(n_elements, sizes, sizeof_element, contiguous_elements, pchain); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void dlmalloc_multidealloc(boost_cont_memchain *pchain)
|
||||||
|
{ return boost_cont_multidealloc(pchain); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL size_t dlmalloc_footprint()
|
||||||
|
{ return boost_cont_footprint(); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL size_t dlmalloc_allocated_memory()
|
||||||
|
{ return boost_cont_allocated_memory(); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL size_t dlmalloc_chunksize(const void *p)
|
||||||
|
{ return boost_cont_chunksize(p); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_all_deallocated()
|
||||||
|
{ return boost_cont_all_deallocated(); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL boost_cont_malloc_stats_t dlmalloc_malloc_stats()
|
||||||
|
{ return boost_cont_malloc_stats(); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL size_t dlmalloc_in_use_memory()
|
||||||
|
{ return boost_cont_in_use_memory(); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_trim(size_t pad)
|
||||||
|
{ return boost_cont_trim(pad); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_mallopt(int parameter_number, int parameter_value)
|
||||||
|
{ return boost_cont_mallopt(parameter_number, parameter_value); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_grow
|
||||||
|
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received)
|
||||||
|
{ return boost_cont_grow(oldmem, minbytes, maxbytes, received); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_shrink
|
||||||
|
(void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit)
|
||||||
|
{ return boost_cont_shrink(oldmem, minbytes, maxbytes, received, do_commit); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void* dlmalloc_alloc
|
||||||
|
(size_t minbytes, size_t preferred_bytes, size_t *received_bytes)
|
||||||
|
{ return boost_cont_alloc(minbytes, preferred_bytes, received_bytes); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL int dlmalloc_malloc_check()
|
||||||
|
{ return boost_cont_malloc_check(); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL boost_cont_command_ret_t dlmalloc_allocation_command
|
||||||
|
( allocation_type command
|
||||||
|
, size_t sizeof_object
|
||||||
|
, size_t limit_objects
|
||||||
|
, size_t preferred_objects
|
||||||
|
, size_t *received_objects
|
||||||
|
, void *reuse_ptr
|
||||||
|
)
|
||||||
|
{ return boost_cont_allocation_command(command, sizeof_object, limit_objects, preferred_objects, received_objects, reuse_ptr); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void *dlmalloc_sync_create()
|
||||||
|
{ return boost_cont_sync_create(); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void dlmalloc_sync_destroy(void *sync)
|
||||||
|
{ return boost_cont_sync_destroy(sync); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL bool dlmalloc_sync_lock(void *sync)
|
||||||
|
{ return boost_cont_sync_lock(sync) != 0; }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void dlmalloc_sync_unlock(void *sync)
|
||||||
|
{ return boost_cont_sync_unlock(sync); }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL bool dlmalloc_global_sync_lock()
|
||||||
|
{ return boost_cont_global_sync_lock() != 0; }
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL void dlmalloc_global_sync_unlock()
|
||||||
|
{ return boost_cont_global_sync_unlock(); }
|
||||||
|
|
||||||
|
} //namespace container{
|
||||||
|
} //namespace boost{
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,121 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
|
||||||
|
// Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define BOOST_CONTAINER_SOURCE
|
||||||
|
#include <boost/container/pmr/memory_resource.hpp>
|
||||||
|
#include <boost/container/pmr/global_resource.hpp>
|
||||||
|
#include <boost/core/no_exceptions_support.hpp>
|
||||||
|
#include <boost/container/throw_exception.hpp>
|
||||||
|
#include <boost/container/detail/dlmalloc.hpp> //For global lock
|
||||||
|
#include <boost/container/detail/singleton.hpp>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace container {
|
||||||
|
namespace pmr {
|
||||||
|
|
||||||
|
class new_delete_resource_imp
|
||||||
|
: public memory_resource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
~new_delete_resource_imp() BOOST_OVERRIDE
|
||||||
|
{}
|
||||||
|
|
||||||
|
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
|
||||||
|
{ (void)bytes; (void)alignment; return new char[bytes]; }
|
||||||
|
|
||||||
|
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
|
||||||
|
{ (void)bytes; (void)alignment; delete[]((char*)p); }
|
||||||
|
|
||||||
|
bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE
|
||||||
|
{ return &other == this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct null_memory_resource_imp
|
||||||
|
: public memory_resource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
~null_memory_resource_imp() BOOST_OVERRIDE
|
||||||
|
{}
|
||||||
|
|
||||||
|
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
|
||||||
|
{
|
||||||
|
(void)bytes; (void)alignment;
|
||||||
|
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) || defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
throw_bad_alloc();
|
||||||
|
#else
|
||||||
|
throw std::bad_alloc();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
|
||||||
|
{ (void)p; (void)bytes; (void)alignment; }
|
||||||
|
|
||||||
|
bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE
|
||||||
|
{ return &other == this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL memory_resource* new_delete_resource() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return &boost::container::dtl::singleton_default<new_delete_resource_imp>::instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL memory_resource* null_memory_resource() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return &boost::container::dtl::singleton_default<null_memory_resource_imp>::instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
static memory_resource *default_memory_resource =
|
||||||
|
&boost::container::dtl::singleton_default<new_delete_resource_imp>::instance();
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
//TO-DO: synchronizes-with part using atomics
|
||||||
|
if(dlmalloc_global_sync_lock()){
|
||||||
|
memory_resource *previous = default_memory_resource;
|
||||||
|
if(!previous){
|
||||||
|
//function called before main, default_memory_resource is not initialized yet
|
||||||
|
previous = new_delete_resource();
|
||||||
|
}
|
||||||
|
default_memory_resource = r ? r : new_delete_resource();
|
||||||
|
dlmalloc_global_sync_unlock();
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return new_delete_resource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
//TO-DO: synchronizes-with part using atomics
|
||||||
|
if(dlmalloc_global_sync_lock()){
|
||||||
|
memory_resource *current = default_memory_resource;
|
||||||
|
if(!current){
|
||||||
|
//function called before main, default_memory_resource is not initialized yet
|
||||||
|
current = new_delete_resource();
|
||||||
|
}
|
||||||
|
dlmalloc_global_sync_unlock();
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return new_delete_resource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace pmr {
|
||||||
|
} //namespace container {
|
||||||
|
} //namespace boost {
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
|
||||||
|
// Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define BOOST_CONTAINER_SOURCE
|
||||||
|
#include <boost/container/detail/config_begin.hpp>
|
||||||
|
#include <boost/container/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#include <boost/container/pmr/monotonic_buffer_resource.hpp>
|
||||||
|
#include <boost/container/pmr/global_resource.hpp>
|
||||||
|
|
||||||
|
#include <boost/container/detail/min_max.hpp>
|
||||||
|
#include <boost/intrusive/detail/math.hpp>
|
||||||
|
#include <boost/container/throw_exception.hpp>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
#ifdef BOOST_HAS_INTPTR_T
|
||||||
|
typedef boost::uintptr_t uintptr_type;
|
||||||
|
#else
|
||||||
|
typedef std::size_t uintptr_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const std::size_t minimum_buffer_size = 2*sizeof(void*);
|
||||||
|
|
||||||
|
} //namespace {
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace container {
|
||||||
|
namespace pmr {
|
||||||
|
|
||||||
|
void monotonic_buffer_resource::increase_next_buffer()
|
||||||
|
{
|
||||||
|
m_next_buffer_size = (std::size_t(-1)/2 < m_next_buffer_size) ? std::size_t(-1) : m_next_buffer_size*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void monotonic_buffer_resource::increase_next_buffer_at_least_to(std::size_t minimum_size)
|
||||||
|
{
|
||||||
|
if(m_next_buffer_size < minimum_size){
|
||||||
|
if(bi::detail::is_pow2(minimum_size)){
|
||||||
|
m_next_buffer_size = minimum_size;
|
||||||
|
}
|
||||||
|
else if(std::size_t(-1)/2 < minimum_size){
|
||||||
|
m_next_buffer_size = minimum_size;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
m_next_buffer_size = bi::detail::ceil_pow2(minimum_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
monotonic_buffer_resource::monotonic_buffer_resource(memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_memory_blocks(upstream ? *upstream : *get_default_resource())
|
||||||
|
, m_current_buffer(0)
|
||||||
|
, m_current_buffer_size(0u)
|
||||||
|
, m_next_buffer_size(initial_next_buffer_size)
|
||||||
|
, m_initial_buffer(0)
|
||||||
|
, m_initial_buffer_size(0u)
|
||||||
|
{}
|
||||||
|
|
||||||
|
monotonic_buffer_resource::monotonic_buffer_resource(std::size_t initial_size, memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_memory_blocks(upstream ? *upstream : *get_default_resource())
|
||||||
|
, m_current_buffer(0)
|
||||||
|
, m_current_buffer_size(0u)
|
||||||
|
, m_next_buffer_size(minimum_buffer_size)
|
||||||
|
, m_initial_buffer(0)
|
||||||
|
, m_initial_buffer_size(0u)
|
||||||
|
{ //In case initial_size is zero
|
||||||
|
this->increase_next_buffer_at_least_to(initial_size + !initial_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
monotonic_buffer_resource::monotonic_buffer_resource(void* buffer, std::size_t buffer_size, memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_memory_blocks(upstream ? *upstream : *get_default_resource())
|
||||||
|
, m_current_buffer(buffer)
|
||||||
|
, m_current_buffer_size(buffer_size)
|
||||||
|
, m_next_buffer_size
|
||||||
|
(bi::detail::previous_or_equal_pow2
|
||||||
|
(boost::container::dtl::max_value(buffer_size, std::size_t(initial_next_buffer_size))))
|
||||||
|
, m_initial_buffer(buffer)
|
||||||
|
, m_initial_buffer_size(buffer_size)
|
||||||
|
{ this->increase_next_buffer(); }
|
||||||
|
|
||||||
|
monotonic_buffer_resource::~monotonic_buffer_resource()
|
||||||
|
{ this->release(); }
|
||||||
|
|
||||||
|
void monotonic_buffer_resource::release() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
m_memory_blocks.release();
|
||||||
|
m_current_buffer = m_initial_buffer;
|
||||||
|
m_current_buffer_size = m_initial_buffer_size;
|
||||||
|
m_next_buffer_size = initial_next_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_resource* monotonic_buffer_resource::upstream_resource() const BOOST_NOEXCEPT
|
||||||
|
{ return &m_memory_blocks.upstream_resource(); }
|
||||||
|
|
||||||
|
std::size_t monotonic_buffer_resource::remaining_storage(std::size_t alignment, std::size_t &wasted_due_to_alignment) const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
const uintptr_type up_alignment_minus1 = alignment - 1u;
|
||||||
|
const uintptr_type up_alignment_mask = ~up_alignment_minus1;
|
||||||
|
const uintptr_type up_addr = uintptr_type(m_current_buffer);
|
||||||
|
const uintptr_type up_aligned_addr = (up_addr + up_alignment_minus1) & up_alignment_mask;
|
||||||
|
wasted_due_to_alignment = std::size_t(up_aligned_addr - up_addr);
|
||||||
|
return m_current_buffer_size <= wasted_due_to_alignment ? 0u : m_current_buffer_size - wasted_due_to_alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t monotonic_buffer_resource::remaining_storage(std::size_t alignment) const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
std::size_t ignore_this;
|
||||||
|
return this->remaining_storage(alignment, ignore_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *monotonic_buffer_resource::current_buffer() const BOOST_NOEXCEPT
|
||||||
|
{ return m_current_buffer; }
|
||||||
|
|
||||||
|
std::size_t monotonic_buffer_resource::next_buffer_size() const BOOST_NOEXCEPT
|
||||||
|
{ return m_next_buffer_size; }
|
||||||
|
|
||||||
|
void *monotonic_buffer_resource::allocate_from_current(std::size_t aligner, std::size_t bytes)
|
||||||
|
{
|
||||||
|
char * p = (char*)m_current_buffer + aligner;
|
||||||
|
m_current_buffer = p + bytes;
|
||||||
|
m_current_buffer_size -= aligner + bytes;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* monotonic_buffer_resource::do_allocate(std::size_t bytes, std::size_t alignment)
|
||||||
|
{
|
||||||
|
if(alignment > memory_resource::max_align){
|
||||||
|
(void)bytes; (void)alignment;
|
||||||
|
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) || defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
throw_bad_alloc();
|
||||||
|
#else
|
||||||
|
throw std::bad_alloc();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//See if there is room in current buffer
|
||||||
|
std::size_t aligner = 0u;
|
||||||
|
if(this->remaining_storage(alignment, aligner) < bytes){
|
||||||
|
//The new buffer will be aligned to the strictest alignment so reset
|
||||||
|
//the aligner, which was needed for the old buffer.
|
||||||
|
aligner = 0u;
|
||||||
|
//Update next_buffer_size to at least bytes
|
||||||
|
this->increase_next_buffer_at_least_to(bytes);
|
||||||
|
//Now allocate and update internal data
|
||||||
|
m_current_buffer = (char*)m_memory_blocks.allocate(m_next_buffer_size);
|
||||||
|
m_current_buffer_size = m_next_buffer_size;
|
||||||
|
this->increase_next_buffer();
|
||||||
|
}
|
||||||
|
//Enough internal storage, extract from it
|
||||||
|
return this->allocate_from_current(aligner, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void monotonic_buffer_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT
|
||||||
|
{ (void)p; (void)bytes; (void)alignment; }
|
||||||
|
|
||||||
|
bool monotonic_buffer_resource::do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT
|
||||||
|
{ return this == &other; }
|
||||||
|
|
||||||
|
} //namespace pmr {
|
||||||
|
} //namespace container {
|
||||||
|
} //namespace boost {
|
||||||
|
|
||||||
|
#include <boost/container/detail/config_end.hpp>
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
|
||||||
|
// Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define BOOST_CONTAINER_SOURCE
|
||||||
|
#include <boost/container/detail/config_begin.hpp>
|
||||||
|
#include <boost/container/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#include <boost/container/pmr/global_resource.hpp>
|
||||||
|
|
||||||
|
#include <boost/container/detail/pool_resource.hpp>
|
||||||
|
#include <boost/container/detail/block_slist.hpp>
|
||||||
|
#include <boost/container/detail/min_max.hpp>
|
||||||
|
#include <boost/container/detail/placement_new.hpp>
|
||||||
|
#include <boost/intrusive/linear_slist_algorithms.hpp>
|
||||||
|
#include <boost/intrusive/detail/math.hpp>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace container {
|
||||||
|
namespace pmr {
|
||||||
|
|
||||||
|
//pool_data_t
|
||||||
|
|
||||||
|
class pool_data_t
|
||||||
|
: public block_slist_base<>
|
||||||
|
{
|
||||||
|
typedef block_slist_base<> block_slist_base_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit pool_data_t(std::size_t initial_blocks_per_chunk)
|
||||||
|
: block_slist_base_t(), next_blocks_per_chunk(initial_blocks_per_chunk)
|
||||||
|
{ slist_algo::init_header(&free_slist); }
|
||||||
|
|
||||||
|
void *allocate_block() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
if(slist_algo::unique(&free_slist)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
slist_node *pv = slist_algo::node_traits::get_next(&free_slist);
|
||||||
|
slist_algo::unlink_after(&free_slist);
|
||||||
|
pv->~slist_node();
|
||||||
|
return pv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate_block(void *p) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
slist_node *pv = ::new(p, boost_container_new_t()) slist_node();
|
||||||
|
slist_algo::link_after(&free_slist, pv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void release(memory_resource &upstream)
|
||||||
|
{
|
||||||
|
slist_algo::init_header(&free_slist);
|
||||||
|
this->block_slist_base_t::release(upstream);
|
||||||
|
next_blocks_per_chunk = pool_options_minimum_max_blocks_per_chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void replenish(memory_resource &mr, std::size_t pool_block, std::size_t max_blocks_per_chunk)
|
||||||
|
{
|
||||||
|
//Limit max value
|
||||||
|
std::size_t blocks_per_chunk = boost::container::dtl::min_value(max_blocks_per_chunk, next_blocks_per_chunk);
|
||||||
|
//Avoid overflow
|
||||||
|
blocks_per_chunk = boost::container::dtl::min_value(blocks_per_chunk, std::size_t(-1)/pool_block);
|
||||||
|
|
||||||
|
//Minimum block size is at least max_align, so all pools allocate sizes that are multiple of max_align,
|
||||||
|
//meaning that all blocks are max_align-aligned.
|
||||||
|
char *p = static_cast<char *>(block_slist_base_t::allocate(blocks_per_chunk*pool_block, mr));
|
||||||
|
|
||||||
|
//Create header types. This is no-throw
|
||||||
|
for(std::size_t i = 0, max = blocks_per_chunk; i != max; ++i){
|
||||||
|
slist_node *const pv = ::new(p, boost_container_new_t()) slist_node();
|
||||||
|
slist_algo::link_after(&free_slist, pv);
|
||||||
|
p += pool_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update next block per chunk
|
||||||
|
next_blocks_per_chunk = max_blocks_per_chunk/2u < blocks_per_chunk ? max_blocks_per_chunk : blocks_per_chunk*2u;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t cache_count() const
|
||||||
|
{ return slist_algo::count(&free_slist) - 1u; }
|
||||||
|
|
||||||
|
slist_node free_slist;
|
||||||
|
std::size_t next_blocks_per_chunk;
|
||||||
|
};
|
||||||
|
|
||||||
|
//pool_resource
|
||||||
|
|
||||||
|
//Detect overflow in ceil_pow2
|
||||||
|
BOOST_STATIC_ASSERT(pool_options_default_max_blocks_per_chunk <= (std::size_t(-1)/2u+1u));
|
||||||
|
//Sanity checks
|
||||||
|
BOOST_STATIC_ASSERT(bi::detail::static_is_pow2<pool_options_default_max_blocks_per_chunk>::value);
|
||||||
|
BOOST_STATIC_ASSERT(bi::detail::static_is_pow2<pool_options_minimum_largest_required_pool_block>::value);
|
||||||
|
|
||||||
|
//unsynchronized_pool_resource
|
||||||
|
|
||||||
|
void pool_resource::priv_limit_option(std::size_t &val, std::size_t min, std::size_t max) //static
|
||||||
|
{
|
||||||
|
if(!val){
|
||||||
|
val = max;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
val = val < min ? min : boost::container::dtl::min_value(val, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t pool_resource::priv_pool_index(std::size_t block_size) //static
|
||||||
|
{
|
||||||
|
//For allocations equal or less than pool_options_minimum_largest_required_pool_block
|
||||||
|
//the smallest pool is used
|
||||||
|
block_size = boost::container::dtl::max_value(block_size, pool_options_minimum_largest_required_pool_block);
|
||||||
|
return bi::detail::ceil_log2(block_size)
|
||||||
|
- bi::detail::ceil_log2(pool_options_minimum_largest_required_pool_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t pool_resource::priv_pool_block(std::size_t index) //static
|
||||||
|
{
|
||||||
|
//For allocations equal or less than pool_options_minimum_largest_required_pool_block
|
||||||
|
//the smallest pool is used
|
||||||
|
return pool_options_minimum_largest_required_pool_block << index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pool_resource::priv_fix_options()
|
||||||
|
{
|
||||||
|
priv_limit_option(m_options.max_blocks_per_chunk
|
||||||
|
, pool_options_minimum_max_blocks_per_chunk
|
||||||
|
, pool_options_default_max_blocks_per_chunk);
|
||||||
|
priv_limit_option
|
||||||
|
( m_options.largest_required_pool_block
|
||||||
|
, pool_options_minimum_largest_required_pool_block
|
||||||
|
, pool_options_default_largest_required_pool_block);
|
||||||
|
m_options.largest_required_pool_block = bi::detail::ceil_pow2(m_options.largest_required_pool_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pool_resource::priv_init_pools()
|
||||||
|
{
|
||||||
|
const std::size_t num_pools = priv_pool_index(m_options.largest_required_pool_block)+1u;
|
||||||
|
//Otherwise, just use the default alloc (zero pools)
|
||||||
|
void *p = 0;
|
||||||
|
//This can throw
|
||||||
|
p = m_upstream.allocate(sizeof(pool_data_t)*num_pools);
|
||||||
|
//This is nothrow
|
||||||
|
m_pool_data = static_cast<pool_data_t *>(p);
|
||||||
|
for(std::size_t i = 0, max = num_pools; i != max; ++i){
|
||||||
|
::new(&m_pool_data[i], boost_container_new_t()) pool_data_t(pool_options_minimum_max_blocks_per_chunk);
|
||||||
|
}
|
||||||
|
m_pool_count = num_pools;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pool_resource::priv_constructor_body()
|
||||||
|
{
|
||||||
|
this->priv_fix_options();
|
||||||
|
}
|
||||||
|
|
||||||
|
pool_resource::pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_options(opts), m_upstream(*upstream), m_oversized_list(), m_pool_data(), m_pool_count()
|
||||||
|
{ this->priv_constructor_body(); }
|
||||||
|
|
||||||
|
pool_resource::pool_resource() BOOST_NOEXCEPT
|
||||||
|
: m_options(), m_upstream(*get_default_resource()), m_oversized_list(), m_pool_data(), m_pool_count()
|
||||||
|
{ this->priv_constructor_body(); }
|
||||||
|
|
||||||
|
pool_resource::pool_resource(memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_options(), m_upstream(*upstream), m_oversized_list(), m_pool_data(), m_pool_count()
|
||||||
|
{ this->priv_constructor_body(); }
|
||||||
|
|
||||||
|
pool_resource::pool_resource(const pool_options& opts) BOOST_NOEXCEPT
|
||||||
|
: m_options(opts), m_upstream(*get_default_resource()), m_oversized_list(), m_pool_data(), m_pool_count()
|
||||||
|
{ this->priv_constructor_body(); }
|
||||||
|
|
||||||
|
pool_resource::~pool_resource()
|
||||||
|
{
|
||||||
|
this->release();
|
||||||
|
|
||||||
|
for(std::size_t i = 0, max = m_pool_count; i != max; ++i){
|
||||||
|
m_pool_data[i].~pool_data_t();
|
||||||
|
}
|
||||||
|
if(m_pool_data){
|
||||||
|
m_upstream.deallocate((void*)m_pool_data, sizeof(pool_data_t)*m_pool_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pool_resource::release()
|
||||||
|
{
|
||||||
|
m_oversized_list.release(m_upstream);
|
||||||
|
for(std::size_t i = 0, max = m_pool_count; i != max; ++i)
|
||||||
|
{
|
||||||
|
m_pool_data[i].release(m_upstream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_resource* pool_resource::upstream_resource() const
|
||||||
|
{ return &m_upstream; }
|
||||||
|
|
||||||
|
pool_options pool_resource::options() const
|
||||||
|
{ return m_options; }
|
||||||
|
|
||||||
|
void* pool_resource::do_allocate(std::size_t bytes, std::size_t alignment)
|
||||||
|
{
|
||||||
|
if(!m_pool_data){
|
||||||
|
this->priv_init_pools();
|
||||||
|
}
|
||||||
|
(void)alignment; //alignment ignored here, max_align is used by pools
|
||||||
|
if(bytes > m_options.largest_required_pool_block){
|
||||||
|
return m_oversized_list.allocate(bytes, m_upstream);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const std::size_t pool_idx = priv_pool_index(bytes);
|
||||||
|
pool_data_t & pool = m_pool_data[pool_idx];
|
||||||
|
void *p = pool.allocate_block();
|
||||||
|
if(!p){
|
||||||
|
pool.replenish(m_upstream, priv_pool_block(pool_idx), m_options.max_blocks_per_chunk);
|
||||||
|
p = pool.allocate_block();
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment)
|
||||||
|
{
|
||||||
|
(void)alignment; //alignment ignored here, max_align is used by pools
|
||||||
|
if(bytes > m_options.largest_required_pool_block){
|
||||||
|
//Just cached
|
||||||
|
return m_oversized_list.deallocate(p, m_upstream);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const std::size_t pool_idx = priv_pool_index(bytes);
|
||||||
|
return m_pool_data[pool_idx].deallocate_block(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t pool_resource::pool_count() const
|
||||||
|
{
|
||||||
|
if(BOOST_LIKELY((0 != m_pool_data))){
|
||||||
|
return m_pool_count;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return priv_pool_index(m_options.largest_required_pool_block)+1u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t pool_resource::pool_index(std::size_t bytes) const
|
||||||
|
{
|
||||||
|
if(bytes > m_options.largest_required_pool_block){
|
||||||
|
return pool_count();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return priv_pool_index(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t pool_resource::pool_next_blocks_per_chunk(std::size_t pool_idx) const
|
||||||
|
{
|
||||||
|
if(BOOST_LIKELY((m_pool_data && pool_idx < m_pool_count))){
|
||||||
|
return m_pool_data[pool_idx].next_blocks_per_chunk;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return 1u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t pool_resource::pool_block(std::size_t pool_idx) const
|
||||||
|
{ return priv_pool_block(pool_idx); }
|
||||||
|
|
||||||
|
std::size_t pool_resource::pool_cached_blocks(std::size_t pool_idx) const
|
||||||
|
{
|
||||||
|
if(BOOST_LIKELY((m_pool_data && pool_idx < m_pool_count))){
|
||||||
|
return m_pool_data[pool_idx].cache_count();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return 0u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace pmr {
|
||||||
|
} //namespace container {
|
||||||
|
} //namespace boost {
|
||||||
|
|
||||||
|
#include <boost/container/detail/config_end.hpp>
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
|
||||||
|
// Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define BOOST_CONTAINER_SOURCE
|
||||||
|
#include <boost/container/detail/config_begin.hpp>
|
||||||
|
#include <boost/container/detail/workaround.hpp>
|
||||||
|
#include <boost/container/detail/thread_mutex.hpp>
|
||||||
|
|
||||||
|
#include <boost/container/pmr/synchronized_pool_resource.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using namespace boost::container::dtl;
|
||||||
|
|
||||||
|
class thread_mutex_lock
|
||||||
|
{
|
||||||
|
thread_mutex &m_mut;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit thread_mutex_lock(thread_mutex &m)
|
||||||
|
: m_mut(m)
|
||||||
|
{
|
||||||
|
m_mut.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~thread_mutex_lock()
|
||||||
|
{
|
||||||
|
m_mut.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace {
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace container {
|
||||||
|
namespace pmr {
|
||||||
|
|
||||||
|
synchronized_pool_resource::synchronized_pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_mut(), m_pool_resource(opts, upstream)
|
||||||
|
{}
|
||||||
|
|
||||||
|
synchronized_pool_resource::synchronized_pool_resource() BOOST_NOEXCEPT
|
||||||
|
: m_mut(), m_pool_resource()
|
||||||
|
{}
|
||||||
|
|
||||||
|
synchronized_pool_resource::synchronized_pool_resource(memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_mut(), m_pool_resource(upstream)
|
||||||
|
{}
|
||||||
|
|
||||||
|
synchronized_pool_resource::synchronized_pool_resource(const pool_options& opts) BOOST_NOEXCEPT
|
||||||
|
: m_mut(), m_pool_resource(opts)
|
||||||
|
{}
|
||||||
|
|
||||||
|
synchronized_pool_resource::~synchronized_pool_resource() //virtual
|
||||||
|
{}
|
||||||
|
|
||||||
|
void synchronized_pool_resource::release()
|
||||||
|
{
|
||||||
|
thread_mutex_lock lck(m_mut); (void)lck;
|
||||||
|
m_pool_resource.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_resource* synchronized_pool_resource::upstream_resource() const
|
||||||
|
{ return m_pool_resource.upstream_resource(); }
|
||||||
|
|
||||||
|
pool_options synchronized_pool_resource::options() const
|
||||||
|
{ return m_pool_resource.options(); }
|
||||||
|
|
||||||
|
void* synchronized_pool_resource::do_allocate(std::size_t bytes, std::size_t alignment) //virtual
|
||||||
|
{
|
||||||
|
thread_mutex_lock lck(m_mut); (void)lck;
|
||||||
|
return m_pool_resource.do_allocate(bytes, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void synchronized_pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) //virtual
|
||||||
|
{
|
||||||
|
thread_mutex_lock lck(m_mut); (void)lck;
|
||||||
|
return m_pool_resource.do_deallocate(p, bytes, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool synchronized_pool_resource::do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT //virtual
|
||||||
|
{ return this == &other; }
|
||||||
|
|
||||||
|
std::size_t synchronized_pool_resource::pool_count() const
|
||||||
|
{ return m_pool_resource.pool_count(); }
|
||||||
|
|
||||||
|
std::size_t synchronized_pool_resource::pool_index(std::size_t bytes) const
|
||||||
|
{ return m_pool_resource.pool_index(bytes); }
|
||||||
|
|
||||||
|
std::size_t synchronized_pool_resource::pool_next_blocks_per_chunk(std::size_t pool_idx) const
|
||||||
|
{ return m_pool_resource.pool_next_blocks_per_chunk(pool_idx); }
|
||||||
|
|
||||||
|
std::size_t synchronized_pool_resource::pool_block(std::size_t pool_idx) const
|
||||||
|
{ return m_pool_resource.pool_block(pool_idx); }
|
||||||
|
|
||||||
|
std::size_t synchronized_pool_resource::pool_cached_blocks(std::size_t pool_idx) const
|
||||||
|
{ return m_pool_resource.pool_cached_blocks(pool_idx); }
|
||||||
|
|
||||||
|
} //namespace pmr {
|
||||||
|
} //namespace container {
|
||||||
|
} //namespace boost {
|
||||||
|
|
||||||
|
#include <boost/container/detail/config_end.hpp>
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
|
||||||
|
// Software License, Version 1.0. (See accompanying file
|
||||||
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/container for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define BOOST_CONTAINER_SOURCE
|
||||||
|
#include <boost/container/detail/config_begin.hpp>
|
||||||
|
#include <boost/container/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#include <boost/container/pmr/unsynchronized_pool_resource.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace container {
|
||||||
|
namespace pmr {
|
||||||
|
|
||||||
|
unsynchronized_pool_resource::unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_resource(opts, upstream)
|
||||||
|
{}
|
||||||
|
|
||||||
|
unsynchronized_pool_resource::unsynchronized_pool_resource() BOOST_NOEXCEPT
|
||||||
|
: m_resource()
|
||||||
|
{}
|
||||||
|
|
||||||
|
unsynchronized_pool_resource::unsynchronized_pool_resource(memory_resource* upstream) BOOST_NOEXCEPT
|
||||||
|
: m_resource(upstream)
|
||||||
|
{}
|
||||||
|
|
||||||
|
unsynchronized_pool_resource::unsynchronized_pool_resource(const pool_options& opts) BOOST_NOEXCEPT
|
||||||
|
: m_resource(opts)
|
||||||
|
{}
|
||||||
|
|
||||||
|
unsynchronized_pool_resource::~unsynchronized_pool_resource() //virtual
|
||||||
|
{}
|
||||||
|
|
||||||
|
void unsynchronized_pool_resource::release()
|
||||||
|
{
|
||||||
|
m_resource.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_resource* unsynchronized_pool_resource::upstream_resource() const
|
||||||
|
{ return m_resource.upstream_resource(); }
|
||||||
|
|
||||||
|
pool_options unsynchronized_pool_resource::options() const
|
||||||
|
{ return m_resource.options(); }
|
||||||
|
|
||||||
|
void* unsynchronized_pool_resource::do_allocate(std::size_t bytes, std::size_t alignment) //virtual
|
||||||
|
{ return m_resource.do_allocate(bytes, alignment); }
|
||||||
|
|
||||||
|
void unsynchronized_pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) //virtual
|
||||||
|
{ return m_resource.do_deallocate(p, bytes, alignment); }
|
||||||
|
|
||||||
|
bool unsynchronized_pool_resource::do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT //virtual
|
||||||
|
{ return this == &other; }
|
||||||
|
|
||||||
|
std::size_t unsynchronized_pool_resource::pool_count() const
|
||||||
|
{ return m_resource.pool_count(); }
|
||||||
|
|
||||||
|
std::size_t unsynchronized_pool_resource::pool_index(std::size_t bytes) const
|
||||||
|
{ return m_resource.pool_index(bytes); }
|
||||||
|
|
||||||
|
std::size_t unsynchronized_pool_resource::pool_next_blocks_per_chunk(std::size_t pool_idx) const
|
||||||
|
{ return m_resource.pool_next_blocks_per_chunk(pool_idx); }
|
||||||
|
|
||||||
|
std::size_t unsynchronized_pool_resource::pool_block(std::size_t pool_idx) const
|
||||||
|
{ return m_resource.pool_block(pool_idx); }
|
||||||
|
|
||||||
|
std::size_t unsynchronized_pool_resource::pool_cached_blocks(std::size_t pool_idx) const
|
||||||
|
{ return m_resource.pool_cached_blocks(pool_idx); }
|
||||||
|
|
||||||
|
} //namespace pmr {
|
||||||
|
} //namespace container {
|
||||||
|
} //namespace boost {
|
||||||
|
|
||||||
|
#include <boost/container/detail/config_end.hpp>
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
#ifndef BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
#ifndef BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||||
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__) && !defined(__clang__) || defined(__DMC__)
|
||||||
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp")
|
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp")
|
||||||
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__) || defined(__BORLANDC__)
|
||||||
# warning "This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp"
|
# warning "This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
#ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
#ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||||
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__) && !defined(__clang__) || defined(__DMC__)
|
||||||
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp")
|
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp")
|
||||||
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__) || defined(__BORLANDC__)
|
||||||
# warning "This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp"
|
# warning "This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
#define BOOST_ALGORITHM_APPLY_PERMUTATION_HPP
|
#define BOOST_ALGORITHM_APPLY_PERMUTATION_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/range/begin.hpp>
|
#include <boost/range/begin.hpp>
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
/// \brief Combine the (transformed) elements of a sequence (or two) into a single value.
|
/// \brief Combine the (transformed) elements of a sequence (or two) into a single value.
|
||||||
/// \author Marshall Clow
|
/// \author Marshall Clow
|
||||||
|
|
||||||
#ifndef BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP
|
#ifndef BOOST_ALGORITHM_INCLUSIVE_SCAN_HPP
|
||||||
#define BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP
|
#define BOOST_ALGORITHM_INCLUSIVE_SCAN_HPP
|
||||||
|
|
||||||
#include <functional> // for std::plus
|
#include <functional> // for std::plus
|
||||||
#include <iterator> // for std::iterator_traits
|
#include <iterator> // for std::iterator_traits
|
||||||
|
|
@ -58,4 +58,4 @@ OutputIterator inclusive_scan(InputIterator first, InputIterator last,
|
||||||
|
|
||||||
}} // namespace boost and algorithm
|
}} // namespace boost and algorithm
|
||||||
|
|
||||||
#endif // BOOST_ALGORITHM_TRANSFORM_REDUCE_HPP
|
#endif // BOOST_ALGORITHM_INCLUSIVE_SCAN_HPP
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
#include <boost/type_traits/make_unsigned.hpp>
|
#include <boost/type_traits/make_unsigned.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,12 @@
|
||||||
|
|
||||||
#include <boost/algorithm/string/config.hpp>
|
#include <boost/algorithm/string/config.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
#include <boost/range/begin.hpp>
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/distance.hpp>
|
||||||
#include <boost/range/end.hpp>
|
#include <boost/range/end.hpp>
|
||||||
|
|
||||||
#include <boost/algorithm/string/predicate_facade.hpp>
|
#include <boost/algorithm/string/predicate_facade.hpp>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
#include <boost/algorithm/string/detail/find_format_store.hpp>
|
#include <boost/algorithm/string/detail/find_format_store.hpp>
|
||||||
#include <boost/algorithm/string/detail/replace_storage.hpp>
|
#include <boost/algorithm/string/detail/replace_storage.hpp>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace algorithm {
|
namespace algorithm {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_STD_ALIGN)
|
#if !defined(BOOST_NO_CXX11_STD_ALIGN) && !defined(BOOST_LIBSTDCXX_VERSION)
|
||||||
#include <boost/align/detail/align_cxx11.hpp>
|
#include <boost/align/detail/align_cxx11.hpp>
|
||||||
#else
|
#else
|
||||||
#include <boost/align/detail/align.hpp>
|
#include <boost/align/detail/align.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2014-2016 Glen Joseph Fernandes
|
Copyright 2014-2020 Glen Joseph Fernandes
|
||||||
(glenjofe@gmail.com)
|
(glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
|
|
@ -19,14 +19,16 @@ align(std::size_t alignment, std::size_t size, void*& ptr,
|
||||||
std::size_t& space)
|
std::size_t& space)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(boost::alignment::detail::is_alignment(alignment));
|
BOOST_ASSERT(boost::alignment::detail::is_alignment(alignment));
|
||||||
|
if (size <= space) {
|
||||||
char* p = reinterpret_cast<char*>(~(alignment - 1) &
|
char* p = reinterpret_cast<char*>(~(alignment - 1) &
|
||||||
(reinterpret_cast<std::size_t>(ptr) + alignment - 1));
|
(reinterpret_cast<std::size_t>(ptr) + alignment - 1));
|
||||||
std::size_t n = p - static_cast<char*>(ptr);
|
std::size_t n = p - static_cast<char*>(ptr);
|
||||||
if (size + n <= space) {
|
if (n <= space - size) {
|
||||||
ptr = p;
|
ptr = p;
|
||||||
space -= n;
|
space -= n;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
#ifndef BOOST_ANY_INCLUDED
|
#ifndef BOOST_ANY_INCLUDED
|
||||||
#define BOOST_ANY_INCLUDED
|
#define BOOST_ANY_INCLUDED
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#include <boost/config.hpp>
|
||||||
|
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -14,7 +15,8 @@
|
||||||
// Peter Dimov, and James Curran
|
// Peter Dimov, and James Curran
|
||||||
// when: July 2001, April 2013 - 2020
|
// when: July 2001, April 2013 - 2020
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/any/bad_any_cast.hpp>
|
||||||
|
#include <boost/any/fwd.hpp>
|
||||||
#include <boost/type_index.hpp>
|
#include <boost/type_index.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <boost/type_traits/decay.hpp>
|
#include <boost/type_traits/decay.hpp>
|
||||||
|
|
@ -27,7 +29,6 @@
|
||||||
#include <boost/utility/enable_if.hpp>
|
#include <boost/utility/enable_if.hpp>
|
||||||
#include <boost/core/addressof.hpp>
|
#include <boost/core/addressof.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/type_traits/is_const.hpp>
|
|
||||||
#include <boost/type_traits/conditional.hpp>
|
#include <boost/type_traits/conditional.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
|
|
@ -47,6 +48,10 @@ namespace boost
|
||||||
BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
|
BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
|
||||||
>(value))
|
>(value))
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!anys::detail::is_basic_any<ValueType>::value,
|
||||||
|
"boost::any shall not be constructed from boost::anys::basic_any"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
any(const any & other)
|
any(const any & other)
|
||||||
|
|
@ -69,6 +74,10 @@ namespace boost
|
||||||
, typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
|
, typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
|
||||||
: content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
|
: content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!anys::detail::is_basic_any<typename boost::decay<ValueType>::type>::value,
|
||||||
|
"boost::any shall not be constructed from boost::anys::basic_any"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -92,6 +101,10 @@ namespace boost
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
any & operator=(const ValueType & rhs)
|
any & operator=(const ValueType & rhs)
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!anys::detail::is_basic_any<ValueType>::value,
|
||||||
|
"boost::anys::basic_any shall not be assigned into boost::any"
|
||||||
|
);
|
||||||
any(rhs).swap(*this);
|
any(rhs).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -121,6 +134,10 @@ namespace boost
|
||||||
template <class ValueType>
|
template <class ValueType>
|
||||||
any & operator=(ValueType&& rhs)
|
any & operator=(ValueType&& rhs)
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!anys::detail::is_basic_any<typename boost::decay<ValueType>::type>::value,
|
||||||
|
"boost::anys::basic_any shall not be assigned into boost::any"
|
||||||
|
);
|
||||||
any(static_cast<ValueType&&>(rhs)).swap(*this);
|
any(static_cast<ValueType&&>(rhs)).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -230,21 +247,6 @@ namespace boost
|
||||||
lhs.swap(rhs);
|
lhs.swap(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
class BOOST_SYMBOL_VISIBLE bad_any_cast :
|
|
||||||
#ifndef BOOST_NO_RTTI
|
|
||||||
public std::bad_cast
|
|
||||||
#else
|
|
||||||
public std::exception
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
|
|
||||||
{
|
|
||||||
return "boost::bad_any_cast: "
|
|
||||||
"failed conversion using boost::any_cast";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
ValueType * any_cast(any * operand) BOOST_NOEXCEPT
|
ValueType * any_cast(any * operand) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
|
@ -333,7 +335,7 @@ namespace boost
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
|
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
|
||||||
// Copyright Antony Polukhin, 2013-2020.
|
// Copyright Antony Polukhin, 2013-2021.
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright Antony Polukhin, 2020-2021.
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// See http://www.boost.org/libs/any for Documentation.
|
||||||
|
|
||||||
|
#ifndef BOOST_ANYS_BAD_ANY_CAST_HPP_INCLUDED
|
||||||
|
#define BOOST_ANYS_BAD_ANY_CAST_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_RTTI
|
||||||
|
#include <typeinfo>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
class BOOST_SYMBOL_VISIBLE bad_any_cast :
|
||||||
|
#ifndef BOOST_NO_RTTI
|
||||||
|
public std::bad_cast
|
||||||
|
#else
|
||||||
|
public std::exception
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
|
||||||
|
{
|
||||||
|
return "boost::bad_any_cast: "
|
||||||
|
"failed conversion using boost::any_cast";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_ANYS_BAD_ANY_CAST_HPP_INCLUDED
|
||||||
|
|
@ -0,0 +1,480 @@
|
||||||
|
// Copyright Ruslan Arutyunyan, 2019-2021.
|
||||||
|
// Copyright Antony Polukhin, 2021.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// Contributed by Ruslan Arutyunyan
|
||||||
|
|
||||||
|
#ifndef BOOST_ANYS_BASIC_ANY_HPP_INCLUDED
|
||||||
|
#define BOOST_ANYS_BASIC_ANY_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/any/bad_any_cast.hpp>
|
||||||
|
#include <boost/any/fwd.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/aligned_storage.hpp>
|
||||||
|
#include <boost/type_index.hpp>
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
#include <boost/type_traits/decay.hpp>
|
||||||
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
#include <boost/type_traits/add_reference.hpp>
|
||||||
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||||
|
#include <boost/throw_exception.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
#include <boost/core/addressof.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/conditional.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace anys {
|
||||||
|
|
||||||
|
template <std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
class basic_any
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(OptimizeForSize > 0 && OptimizeForAlignment > 0, "Size and Align shall be positive values");
|
||||||
|
BOOST_STATIC_ASSERT_MSG(OptimizeForSize >= OptimizeForAlignment, "Size shall non less than Align");
|
||||||
|
BOOST_STATIC_ASSERT_MSG((OptimizeForAlignment & (OptimizeForAlignment - 1)) == 0, "Align shall be a power of 2");
|
||||||
|
BOOST_STATIC_ASSERT_MSG(OptimizeForSize % OptimizeForAlignment == 0, "Size shall be multiple of alignment");
|
||||||
|
private:
|
||||||
|
enum operation
|
||||||
|
{
|
||||||
|
Destroy,
|
||||||
|
Move,
|
||||||
|
Copy,
|
||||||
|
AnyCast,
|
||||||
|
UnsafeCast,
|
||||||
|
Typeinfo
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
static void* small_manager(operation op, basic_any& left, const basic_any* right, const boost::typeindex::type_info* info)
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case Destroy:
|
||||||
|
BOOST_ASSERT(!left.empty());
|
||||||
|
reinterpret_cast<ValueType*>(&left.content.small_value)->~ValueType();
|
||||||
|
break;
|
||||||
|
case Move: {
|
||||||
|
BOOST_ASSERT(left.empty());
|
||||||
|
BOOST_ASSERT(right);
|
||||||
|
BOOST_ASSERT(!right->empty());
|
||||||
|
BOOST_ASSERT(right->type() == boost::typeindex::type_id<ValueType>());
|
||||||
|
ValueType* value = reinterpret_cast<ValueType*>(&const_cast<basic_any*>(right)->content.small_value);
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
new (&left.content.small_value) ValueType(std::move(*value));
|
||||||
|
#else
|
||||||
|
new (&left.content.small_value) ValueType(*value);
|
||||||
|
#endif
|
||||||
|
left.man = right->man;
|
||||||
|
reinterpret_cast<ValueType const*>(&right->content.small_value)->~ValueType();
|
||||||
|
const_cast<basic_any*>(right)->man = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Copy:
|
||||||
|
BOOST_ASSERT(left.empty());
|
||||||
|
BOOST_ASSERT(right);
|
||||||
|
BOOST_ASSERT(!right->empty());
|
||||||
|
BOOST_ASSERT(right->type() == boost::typeindex::type_id<ValueType>());
|
||||||
|
new (&left.content.small_value) ValueType(*reinterpret_cast<const ValueType*>(&right->content.small_value));
|
||||||
|
left.man = right->man;
|
||||||
|
break;
|
||||||
|
case AnyCast:
|
||||||
|
BOOST_ASSERT(info);
|
||||||
|
BOOST_ASSERT(!left.empty());
|
||||||
|
return boost::typeindex::type_id<ValueType>() == *info ?
|
||||||
|
reinterpret_cast<typename remove_cv<ValueType>::type *>(&left.content.small_value) : 0;
|
||||||
|
case UnsafeCast:
|
||||||
|
BOOST_ASSERT(!left.empty());
|
||||||
|
return reinterpret_cast<typename remove_cv<ValueType>::type *>(&left.content.small_value);
|
||||||
|
case Typeinfo:
|
||||||
|
return const_cast<void*>(static_cast<const void*>(&boost::typeindex::type_id<ValueType>().type_info()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
static void* large_manager(operation op, basic_any& left, const basic_any* right, const boost::typeindex::type_info* info)
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case Destroy:
|
||||||
|
BOOST_ASSERT(!left.empty());
|
||||||
|
delete static_cast<ValueType*>(left.content.large_value);
|
||||||
|
break;
|
||||||
|
case Move:
|
||||||
|
BOOST_ASSERT(left.empty());
|
||||||
|
BOOST_ASSERT(right);
|
||||||
|
BOOST_ASSERT(!right->empty());
|
||||||
|
BOOST_ASSERT(right->type() == boost::typeindex::type_id<ValueType>());
|
||||||
|
left.content.large_value = right->content.large_value;
|
||||||
|
left.man = right->man;
|
||||||
|
const_cast<basic_any*>(right)->content.large_value = 0;
|
||||||
|
const_cast<basic_any*>(right)->man = 0;
|
||||||
|
break;
|
||||||
|
case Copy:
|
||||||
|
BOOST_ASSERT(left.empty());
|
||||||
|
BOOST_ASSERT(right);
|
||||||
|
BOOST_ASSERT(!right->empty());
|
||||||
|
BOOST_ASSERT(right->type() == boost::typeindex::type_id<ValueType>());
|
||||||
|
left.content.large_value = new ValueType(*static_cast<const ValueType*>(right->content.large_value));
|
||||||
|
left.man = right->man;
|
||||||
|
break;
|
||||||
|
case AnyCast:
|
||||||
|
BOOST_ASSERT(info);
|
||||||
|
BOOST_ASSERT(!left.empty());
|
||||||
|
return boost::typeindex::type_id<ValueType>() == *info ?
|
||||||
|
static_cast<typename remove_cv<ValueType>::type *>(left.content.large_value) : 0;
|
||||||
|
case UnsafeCast:
|
||||||
|
BOOST_ASSERT(!left.empty());
|
||||||
|
return reinterpret_cast<typename remove_cv<ValueType>::type *>(left.content.large_value);
|
||||||
|
case Typeinfo:
|
||||||
|
return const_cast<void*>(static_cast<const void*>(&boost::typeindex::type_id<ValueType>().type_info()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
struct is_small_object : boost::integral_constant<bool, sizeof(ValueType) <= OptimizeForSize &&
|
||||||
|
boost::alignment_of<ValueType>::value <= OptimizeForAlignment &&
|
||||||
|
boost::is_nothrow_move_constructible<ValueType>::value>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
static void create(basic_any& any, const ValueType& value, boost::true_type)
|
||||||
|
{
|
||||||
|
typedef typename boost::decay<const ValueType>::type DecayedType;
|
||||||
|
|
||||||
|
any.man = &small_manager<DecayedType>;
|
||||||
|
new (&any.content.small_value) ValueType(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
static void create(basic_any& any, const ValueType& value, boost::false_type)
|
||||||
|
{
|
||||||
|
typedef typename boost::decay<const ValueType>::type DecayedType;
|
||||||
|
|
||||||
|
any.man = &large_manager<DecayedType>;
|
||||||
|
any.content.large_value = new DecayedType(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
template <typename ValueType>
|
||||||
|
static void create(basic_any& any, ValueType&& value, boost::true_type)
|
||||||
|
{
|
||||||
|
typedef typename boost::decay<const ValueType>::type DecayedType;
|
||||||
|
any.man = &small_manager<DecayedType>;
|
||||||
|
new (&any.content.small_value) DecayedType(static_cast<ValueType&&>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
static void create(basic_any& any, ValueType&& value, boost::false_type)
|
||||||
|
{
|
||||||
|
typedef typename boost::decay<const ValueType>::type DecayedType;
|
||||||
|
any.man = &large_manager<DecayedType>;
|
||||||
|
any.content.large_value = new DecayedType(static_cast<ValueType&&>(value));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
public: // non-type template parameters accessors
|
||||||
|
static BOOST_CONSTEXPR_OR_CONST std::size_t buffer_size = OptimizeForSize;
|
||||||
|
static BOOST_CONSTEXPR_OR_CONST std::size_t buffer_align = OptimizeForAlignment;
|
||||||
|
|
||||||
|
public: // structors
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR basic_any() BOOST_NOEXCEPT
|
||||||
|
: man(0), content()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
basic_any(const ValueType & value)
|
||||||
|
: man(0), content()
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!(boost::is_same<ValueType, boost::any>::value),
|
||||||
|
"boost::anys::basic_any shall not be constructed from boost::any"
|
||||||
|
);
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!anys::detail::is_basic_any<ValueType>::value,
|
||||||
|
"boost::anys::basic_any<A, B> shall not be constructed from boost::anys::basic_any<C, D>"
|
||||||
|
);
|
||||||
|
create(*this, value, is_small_object<ValueType>());
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_any(const basic_any & other)
|
||||||
|
: man(0), content()
|
||||||
|
{
|
||||||
|
if (other.man)
|
||||||
|
{
|
||||||
|
other.man(Copy, *this, &other, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// Move constructor
|
||||||
|
basic_any(basic_any&& other) BOOST_NOEXCEPT
|
||||||
|
: man(0), content()
|
||||||
|
{
|
||||||
|
if (other.man)
|
||||||
|
{
|
||||||
|
other.man(Move, *this, &other, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perfect forwarding of ValueType
|
||||||
|
template<typename ValueType>
|
||||||
|
basic_any(ValueType&& value
|
||||||
|
, typename boost::disable_if<boost::is_same<basic_any&, ValueType> >::type* = 0 // disable if value has type `basic_any&`
|
||||||
|
, typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
|
||||||
|
: man(0), content()
|
||||||
|
{
|
||||||
|
typedef typename boost::decay<ValueType>::type DecayedType;
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!(boost::is_same<DecayedType, boost::any>::value),
|
||||||
|
"boost::anys::basic_any shall not be constructed from boost::any"
|
||||||
|
);
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!anys::detail::is_basic_any<DecayedType>::value,
|
||||||
|
"boost::anys::basic_any<A, B> shall not be constructed from boost::anys::basic_any<C, D>"
|
||||||
|
);
|
||||||
|
create(*this, static_cast<ValueType&&>(value), is_small_object<DecayedType>());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
~basic_any() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (man)
|
||||||
|
{
|
||||||
|
man(Destroy, *this, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public: // modifiers
|
||||||
|
|
||||||
|
basic_any & swap(basic_any & rhs) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (man && rhs.man)
|
||||||
|
{
|
||||||
|
basic_any tmp;
|
||||||
|
rhs.man(Move, tmp, &rhs, 0);
|
||||||
|
man(Move, rhs, this, 0);
|
||||||
|
tmp.man(Move, *this, &tmp, 0);
|
||||||
|
}
|
||||||
|
else if (man)
|
||||||
|
{
|
||||||
|
man(Move, rhs, this, 0);
|
||||||
|
}
|
||||||
|
else if (rhs.man)
|
||||||
|
{
|
||||||
|
rhs.man(Move, *this, &rhs, 0);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
template<typename ValueType>
|
||||||
|
basic_any & operator=(const ValueType & rhs)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!(boost::is_same<ValueType, boost::any>::value),
|
||||||
|
"boost::any shall not be assigned into boost::anys::basic_any"
|
||||||
|
);
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!anys::detail::is_basic_any<ValueType>::value,
|
||||||
|
"boost::anys::basic_any<A, B> shall not be assigned into boost::anys::basic_any<C, D>"
|
||||||
|
);
|
||||||
|
basic_any(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_any & operator=(basic_any rhs)
|
||||||
|
{
|
||||||
|
rhs.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
basic_any & operator=(const basic_any& rhs)
|
||||||
|
{
|
||||||
|
basic_any(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move assignment
|
||||||
|
basic_any & operator=(basic_any&& rhs) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
rhs.swap(*this);
|
||||||
|
basic_any().swap(rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perfect forwarding of ValueType
|
||||||
|
template <class ValueType>
|
||||||
|
basic_any & operator=(ValueType&& rhs)
|
||||||
|
{
|
||||||
|
typedef typename boost::decay<ValueType>::type DecayedType;
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
!(boost::is_same<DecayedType, boost::any>::value),
|
||||||
|
"boost::any shall not be assigned into boost::anys::basic_any"
|
||||||
|
);
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
(!anys::detail::is_basic_any<DecayedType>::value || boost::is_same<DecayedType, basic_any>::value),
|
||||||
|
"boost::anys::basic_any<A, B> shall not be assigned into boost::anys::basic_any<C, D>"
|
||||||
|
);
|
||||||
|
basic_any(static_cast<ValueType&&>(rhs)).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public: // queries
|
||||||
|
|
||||||
|
bool empty() const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !man;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
basic_any().swap(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return man
|
||||||
|
? *static_cast<const boost::typeindex::type_info*>(man(Typeinfo, const_cast<basic_any&>(*this), 0, 0))
|
||||||
|
: boost::typeindex::type_id<void>().type_info();
|
||||||
|
}
|
||||||
|
|
||||||
|
private: // representation
|
||||||
|
|
||||||
|
template<typename ValueType, std::size_t Size, std::size_t Alignment>
|
||||||
|
friend ValueType * any_cast(basic_any<Size, Alignment> *) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
|
template<typename ValueType, std::size_t Size, std::size_t Alignment>
|
||||||
|
friend ValueType * unsafe_any_cast(basic_any<Size, Alignment> *) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
|
typedef void*(*manager)(operation op, basic_any& left, const basic_any* right, const boost::typeindex::type_info* info);
|
||||||
|
|
||||||
|
manager man;
|
||||||
|
|
||||||
|
union content {
|
||||||
|
void * large_value;
|
||||||
|
typename boost::aligned_storage<OptimizeForSize, OptimizeForAlignment>::type small_value;
|
||||||
|
} content;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
void swap(basic_any<OptimizeForSize, OptimizeForAlignment>& lhs, basic_any<OptimizeForSize, OptimizeForAlignment>& rhs) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, std::size_t Size, std::size_t Alignment>
|
||||||
|
ValueType * any_cast(basic_any<Size, Alignment> * operand) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return operand->man ?
|
||||||
|
static_cast<typename remove_cv<ValueType>::type *>(operand->man(basic_any<Size, Alignment>::AnyCast, *operand, 0, &boost::typeindex::type_id<ValueType>().type_info()))
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
inline const ValueType * any_cast(const basic_any<OptimizeForSize, OptimizeForAlignment> * operand) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return any_cast<ValueType>(const_cast<basic_any<OptimizeForSize, OptimizeForAlignment> *>(operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
ValueType any_cast(basic_any<OptimizeForSize, OptimizeForAlignment> & operand)
|
||||||
|
{
|
||||||
|
typedef typename remove_reference<ValueType>::type nonref;
|
||||||
|
|
||||||
|
nonref * result = any_cast<nonref>(boost::addressof(operand));
|
||||||
|
if(!result)
|
||||||
|
boost::throw_exception(bad_any_cast());
|
||||||
|
|
||||||
|
// Attempt to avoid construction of a temporary object in cases when
|
||||||
|
// `ValueType` is not a reference. Example:
|
||||||
|
// `static_cast<std::string>(*result);`
|
||||||
|
// which is equal to `std::string(*result);`
|
||||||
|
typedef typename boost::conditional<
|
||||||
|
boost::is_reference<ValueType>::value,
|
||||||
|
ValueType,
|
||||||
|
typename boost::add_reference<ValueType>::type
|
||||||
|
>::type ref_type;
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
|
||||||
|
#endif
|
||||||
|
return static_cast<ref_type>(*result);
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
inline ValueType any_cast(const basic_any<OptimizeForSize, OptimizeForAlignment> & operand)
|
||||||
|
{
|
||||||
|
typedef typename remove_reference<ValueType>::type nonref;
|
||||||
|
return any_cast<const nonref &>(const_cast<basic_any<OptimizeForSize, OptimizeForAlignment> &>(operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
template<typename ValueType, std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
inline ValueType any_cast(basic_any<OptimizeForSize, OptimizeForAlignment>&& operand)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
boost::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/
|
||||||
|
|| boost::is_const< typename boost::remove_reference<ValueType>::type >::value,
|
||||||
|
"boost::any_cast shall not be used for getting nonconst references to temporary objects"
|
||||||
|
);
|
||||||
|
return any_cast<ValueType>(operand);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Note: The "unsafe" versions of any_cast are not part of the
|
||||||
|
// public interface and may be removed at any time. They are
|
||||||
|
// required where we know what type is stored in the any and can't
|
||||||
|
// use typeid() comparison, e.g., when our types may travel across
|
||||||
|
// different shared libraries.
|
||||||
|
template<typename ValueType, std::size_t OptimizedForSize, std::size_t OptimizeForAlignment>
|
||||||
|
inline ValueType * unsafe_any_cast(basic_any<OptimizedForSize, OptimizeForAlignment> * operand) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return static_cast<ValueType*>(operand->man(basic_any<OptimizedForSize, OptimizeForAlignment>::UnsafeCast, *operand, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
inline const ValueType * unsafe_any_cast(const basic_any<OptimizeForSize, OptimizeForAlignment> * operand) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return unsafe_any_cast<ValueType>(const_cast<basic_any<OptimizeForSize, OptimizeForAlignment> *>(operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace anys
|
||||||
|
|
||||||
|
using boost::anys::any_cast;
|
||||||
|
using boost::anys::unsafe_any_cast;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_ANYS_BASIC_ANY_HPP_INCLUDED
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright Antony Polukhin, 2021.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// Contributed by Ruslan Arutyunyan
|
||||||
|
#ifndef BOOST_ANY_ANYS_FWD_HPP
|
||||||
|
#define BOOST_ANY_ANYS_FWD_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
class any;
|
||||||
|
|
||||||
|
namespace anys {
|
||||||
|
|
||||||
|
template<std::size_t OptimizeForSize = sizeof(void*), std::size_t OptimizeForAlignment = boost::alignment_of<void*>::value>
|
||||||
|
class basic_any;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <class T>
|
||||||
|
struct is_basic_any: public false_type {};
|
||||||
|
|
||||||
|
|
||||||
|
template<std::size_t OptimizeForSize, std::size_t OptimizeForAlignment>
|
||||||
|
struct is_basic_any<boost::anys::basic_any<OptimizeForSize, OptimizeForAlignment> > : public true_type {};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace anys
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_ANY_ANYS_FWD_HPP
|
||||||
|
|
@ -4,12 +4,14 @@
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma once
|
# pragma once
|
||||||
#pragma inline_depth(511)
|
#if !defined(__clang__)
|
||||||
|
#pragma inline_depth(255)
|
||||||
#pragma inline_recursion(on)
|
#pragma inline_recursion(on)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__MWERKS__)
|
#if defined(__MWERKS__)
|
||||||
#pragma inline_depth(511)
|
#pragma inline_depth(255)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,16 @@
|
||||||
#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP
|
#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
#if defined(_MSC_VER)
|
#if defined(BOOST_MSVC)
|
||||||
# pragma once
|
# pragma once
|
||||||
#pragma inline_depth(511)
|
#if !defined(__clang__)
|
||||||
|
#pragma inline_depth(255)
|
||||||
#pragma inline_recursion(on)
|
#pragma inline_recursion(on)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__MWERKS__)
|
#if defined(__MWERKS__)
|
||||||
#pragma inline_depth(511)
|
#pragma inline_depth(255)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,14 @@
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma once
|
# pragma once
|
||||||
#pragma inline_depth(511)
|
#if !defined(__clang__)
|
||||||
|
#pragma inline_depth(255)
|
||||||
#pragma inline_recursion(on)
|
#pragma inline_recursion(on)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__MWERKS__)
|
#if defined(__MWERKS__)
|
||||||
#pragma inline_depth(511)
|
#pragma inline_depth(255)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||||
|
|
|
||||||
|
|
@ -112,8 +112,8 @@ basic_text_iprimitive<IStream>::basic_text_iprimitive(
|
||||||
) :
|
) :
|
||||||
is(is_),
|
is(is_),
|
||||||
flags_saver(is_),
|
flags_saver(is_),
|
||||||
precision_saver(is_),
|
|
||||||
#ifndef BOOST_NO_STD_LOCALE
|
#ifndef BOOST_NO_STD_LOCALE
|
||||||
|
precision_saver(is_),
|
||||||
codecvt_null_facet(1),
|
codecvt_null_facet(1),
|
||||||
archive_locale(is.getloc(), & codecvt_null_facet),
|
archive_locale(is.getloc(), & codecvt_null_facet),
|
||||||
locale_saver(is)
|
locale_saver(is)
|
||||||
|
|
@ -125,6 +125,7 @@ basic_text_iprimitive<IStream>::basic_text_iprimitive(
|
||||||
is_ >> std::noboolalpha;
|
is_ >> std::noboolalpha;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
precision_saver(is_)
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,8 @@ basic_text_oprimitive<OStream>::basic_text_oprimitive(
|
||||||
) :
|
) :
|
||||||
os(os_),
|
os(os_),
|
||||||
flags_saver(os_),
|
flags_saver(os_),
|
||||||
precision_saver(os_),
|
|
||||||
#ifndef BOOST_NO_STD_LOCALE
|
#ifndef BOOST_NO_STD_LOCALE
|
||||||
|
precision_saver(os_),
|
||||||
codecvt_null_facet(1),
|
codecvt_null_facet(1),
|
||||||
archive_locale(os.getloc(), & codecvt_null_facet),
|
archive_locale(os.getloc(), & codecvt_null_facet),
|
||||||
locale_saver(os)
|
locale_saver(os)
|
||||||
|
|
@ -100,6 +100,7 @@ basic_text_oprimitive<OStream>::basic_text_oprimitive(
|
||||||
os_ << std::noboolalpha;
|
os_ << std::noboolalpha;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
precision_saver(os_)
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// asio.hpp
|
// asio.hpp
|
||||||
// ~~~~~~~~
|
// ~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -19,12 +19,17 @@
|
||||||
|
|
||||||
#include <boost/asio/associated_allocator.hpp>
|
#include <boost/asio/associated_allocator.hpp>
|
||||||
#include <boost/asio/associated_executor.hpp>
|
#include <boost/asio/associated_executor.hpp>
|
||||||
|
#include <boost/asio/associated_cancellation_slot.hpp>
|
||||||
|
#include <boost/asio/associator.hpp>
|
||||||
#include <boost/asio/async_result.hpp>
|
#include <boost/asio/async_result.hpp>
|
||||||
#include <boost/asio/awaitable.hpp>
|
#include <boost/asio/awaitable.hpp>
|
||||||
#include <boost/asio/basic_datagram_socket.hpp>
|
#include <boost/asio/basic_datagram_socket.hpp>
|
||||||
#include <boost/asio/basic_deadline_timer.hpp>
|
#include <boost/asio/basic_deadline_timer.hpp>
|
||||||
|
#include <boost/asio/basic_file.hpp>
|
||||||
#include <boost/asio/basic_io_object.hpp>
|
#include <boost/asio/basic_io_object.hpp>
|
||||||
|
#include <boost/asio/basic_random_access_file.hpp>
|
||||||
#include <boost/asio/basic_raw_socket.hpp>
|
#include <boost/asio/basic_raw_socket.hpp>
|
||||||
|
#include <boost/asio/basic_readable_pipe.hpp>
|
||||||
#include <boost/asio/basic_seq_packet_socket.hpp>
|
#include <boost/asio/basic_seq_packet_socket.hpp>
|
||||||
#include <boost/asio/basic_serial_port.hpp>
|
#include <boost/asio/basic_serial_port.hpp>
|
||||||
#include <boost/asio/basic_signal_set.hpp>
|
#include <boost/asio/basic_signal_set.hpp>
|
||||||
|
|
@ -32,11 +37,15 @@
|
||||||
#include <boost/asio/basic_socket_acceptor.hpp>
|
#include <boost/asio/basic_socket_acceptor.hpp>
|
||||||
#include <boost/asio/basic_socket_iostream.hpp>
|
#include <boost/asio/basic_socket_iostream.hpp>
|
||||||
#include <boost/asio/basic_socket_streambuf.hpp>
|
#include <boost/asio/basic_socket_streambuf.hpp>
|
||||||
|
#include <boost/asio/basic_stream_file.hpp>
|
||||||
#include <boost/asio/basic_stream_socket.hpp>
|
#include <boost/asio/basic_stream_socket.hpp>
|
||||||
#include <boost/asio/basic_streambuf.hpp>
|
#include <boost/asio/basic_streambuf.hpp>
|
||||||
#include <boost/asio/basic_waitable_timer.hpp>
|
#include <boost/asio/basic_waitable_timer.hpp>
|
||||||
|
#include <boost/asio/basic_writable_pipe.hpp>
|
||||||
|
#include <boost/asio/bind_cancellation_slot.hpp>
|
||||||
#include <boost/asio/bind_executor.hpp>
|
#include <boost/asio/bind_executor.hpp>
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
|
#include <boost/asio/buffer_registration.hpp>
|
||||||
#include <boost/asio/buffered_read_stream_fwd.hpp>
|
#include <boost/asio/buffered_read_stream_fwd.hpp>
|
||||||
#include <boost/asio/buffered_read_stream.hpp>
|
#include <boost/asio/buffered_read_stream.hpp>
|
||||||
#include <boost/asio/buffered_stream_fwd.hpp>
|
#include <boost/asio/buffered_stream_fwd.hpp>
|
||||||
|
|
@ -44,10 +53,14 @@
|
||||||
#include <boost/asio/buffered_write_stream_fwd.hpp>
|
#include <boost/asio/buffered_write_stream_fwd.hpp>
|
||||||
#include <boost/asio/buffered_write_stream.hpp>
|
#include <boost/asio/buffered_write_stream.hpp>
|
||||||
#include <boost/asio/buffers_iterator.hpp>
|
#include <boost/asio/buffers_iterator.hpp>
|
||||||
|
#include <boost/asio/cancellation_signal.hpp>
|
||||||
|
#include <boost/asio/cancellation_state.hpp>
|
||||||
|
#include <boost/asio/cancellation_type.hpp>
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/completion_condition.hpp>
|
#include <boost/asio/completion_condition.hpp>
|
||||||
#include <boost/asio/compose.hpp>
|
#include <boost/asio/compose.hpp>
|
||||||
#include <boost/asio/connect.hpp>
|
#include <boost/asio/connect.hpp>
|
||||||
|
#include <boost/asio/connect_pipe.hpp>
|
||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
#include <boost/asio/deadline_timer.hpp>
|
#include <boost/asio/deadline_timer.hpp>
|
||||||
#include <boost/asio/defer.hpp>
|
#include <boost/asio/defer.hpp>
|
||||||
|
|
@ -85,6 +98,7 @@
|
||||||
#include <boost/asio/execution_context.hpp>
|
#include <boost/asio/execution_context.hpp>
|
||||||
#include <boost/asio/executor.hpp>
|
#include <boost/asio/executor.hpp>
|
||||||
#include <boost/asio/executor_work_guard.hpp>
|
#include <boost/asio/executor_work_guard.hpp>
|
||||||
|
#include <boost/asio/file_base.hpp>
|
||||||
#include <boost/asio/generic/basic_endpoint.hpp>
|
#include <boost/asio/generic/basic_endpoint.hpp>
|
||||||
#include <boost/asio/generic/datagram_protocol.hpp>
|
#include <boost/asio/generic/datagram_protocol.hpp>
|
||||||
#include <boost/asio/generic/raw_protocol.hpp>
|
#include <boost/asio/generic/raw_protocol.hpp>
|
||||||
|
|
@ -141,10 +155,13 @@
|
||||||
#include <boost/asio/post.hpp>
|
#include <boost/asio/post.hpp>
|
||||||
#include <boost/asio/prefer.hpp>
|
#include <boost/asio/prefer.hpp>
|
||||||
#include <boost/asio/query.hpp>
|
#include <boost/asio/query.hpp>
|
||||||
|
#include <boost/asio/random_access_file.hpp>
|
||||||
#include <boost/asio/read.hpp>
|
#include <boost/asio/read.hpp>
|
||||||
#include <boost/asio/read_at.hpp>
|
#include <boost/asio/read_at.hpp>
|
||||||
#include <boost/asio/read_until.hpp>
|
#include <boost/asio/read_until.hpp>
|
||||||
|
#include <boost/asio/readable_pipe.hpp>
|
||||||
#include <boost/asio/redirect_error.hpp>
|
#include <boost/asio/redirect_error.hpp>
|
||||||
|
#include <boost/asio/registered_buffer.hpp>
|
||||||
#include <boost/asio/require.hpp>
|
#include <boost/asio/require.hpp>
|
||||||
#include <boost/asio/require_concept.hpp>
|
#include <boost/asio/require_concept.hpp>
|
||||||
#include <boost/asio/serial_port.hpp>
|
#include <boost/asio/serial_port.hpp>
|
||||||
|
|
@ -154,6 +171,7 @@
|
||||||
#include <boost/asio/static_thread_pool.hpp>
|
#include <boost/asio/static_thread_pool.hpp>
|
||||||
#include <boost/asio/steady_timer.hpp>
|
#include <boost/asio/steady_timer.hpp>
|
||||||
#include <boost/asio/strand.hpp>
|
#include <boost/asio/strand.hpp>
|
||||||
|
#include <boost/asio/stream_file.hpp>
|
||||||
#include <boost/asio/streambuf.hpp>
|
#include <boost/asio/streambuf.hpp>
|
||||||
#include <boost/asio/system_context.hpp>
|
#include <boost/asio/system_context.hpp>
|
||||||
#include <boost/asio/system_executor.hpp>
|
#include <boost/asio/system_executor.hpp>
|
||||||
|
|
@ -175,6 +193,7 @@
|
||||||
#include <boost/asio/windows/overlapped_ptr.hpp>
|
#include <boost/asio/windows/overlapped_ptr.hpp>
|
||||||
#include <boost/asio/windows/random_access_handle.hpp>
|
#include <boost/asio/windows/random_access_handle.hpp>
|
||||||
#include <boost/asio/windows/stream_handle.hpp>
|
#include <boost/asio/windows/stream_handle.hpp>
|
||||||
|
#include <boost/asio/writable_pipe.hpp>
|
||||||
#include <boost/asio/write.hpp>
|
#include <boost/asio/write.hpp>
|
||||||
#include <boost/asio/write_at.hpp>
|
#include <boost/asio/write_at.hpp>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// any_io_executor.hpp
|
// any_io_executor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -49,9 +49,23 @@ typedef executor any_io_executor;
|
||||||
* execution::prefer_only<execution::relationship_t::continuation_t>
|
* execution::prefer_only<execution::relationship_t::continuation_t>
|
||||||
* > @endcode
|
* > @endcode
|
||||||
*/
|
*/
|
||||||
|
class any_io_executor :
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
typedef execution::any_executor<...> any_io_executor;
|
public execution::any_executor<...>
|
||||||
#else // defined(GENERATING_DOCUMENTATION)
|
#else // defined(GENERATING_DOCUMENTATION)
|
||||||
|
public execution::any_executor<
|
||||||
|
execution::context_as_t<execution_context&>,
|
||||||
|
execution::blocking_t::never_t,
|
||||||
|
execution::prefer_only<execution::blocking_t::possibly_t>,
|
||||||
|
execution::prefer_only<execution::outstanding_work_t::tracked_t>,
|
||||||
|
execution::prefer_only<execution::outstanding_work_t::untracked_t>,
|
||||||
|
execution::prefer_only<execution::relationship_t::fork_t>,
|
||||||
|
execution::prefer_only<execution::relationship_t::continuation_t>
|
||||||
|
>
|
||||||
|
#endif // defined(GENERATING_DOCUMENTATION)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if !defined(GENERATING_DOCUMENTATION)
|
||||||
typedef execution::any_executor<
|
typedef execution::any_executor<
|
||||||
execution::context_as_t<execution_context&>,
|
execution::context_as_t<execution_context&>,
|
||||||
execution::blocking_t::never_t,
|
execution::blocking_t::never_t,
|
||||||
|
|
@ -60,9 +74,221 @@ typedef execution::any_executor<
|
||||||
execution::prefer_only<execution::outstanding_work_t::untracked_t>,
|
execution::prefer_only<execution::outstanding_work_t::untracked_t>,
|
||||||
execution::prefer_only<execution::relationship_t::fork_t>,
|
execution::prefer_only<execution::relationship_t::fork_t>,
|
||||||
execution::prefer_only<execution::relationship_t::continuation_t>
|
execution::prefer_only<execution::relationship_t::continuation_t>
|
||||||
> any_io_executor;
|
> base_type;
|
||||||
|
|
||||||
|
typedef void supportable_properties_type(
|
||||||
|
execution::context_as_t<execution_context&>,
|
||||||
|
execution::blocking_t::never_t,
|
||||||
|
execution::prefer_only<execution::blocking_t::possibly_t>,
|
||||||
|
execution::prefer_only<execution::outstanding_work_t::tracked_t>,
|
||||||
|
execution::prefer_only<execution::outstanding_work_t::untracked_t>,
|
||||||
|
execution::prefer_only<execution::relationship_t::fork_t>,
|
||||||
|
execution::prefer_only<execution::relationship_t::continuation_t>
|
||||||
|
);
|
||||||
|
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Default constructor.
|
||||||
|
BOOST_ASIO_DECL any_io_executor() BOOST_ASIO_NOEXCEPT;
|
||||||
|
|
||||||
|
/// Construct in an empty state. Equivalent effects to default constructor.
|
||||||
|
BOOST_ASIO_DECL any_io_executor(nullptr_t) BOOST_ASIO_NOEXCEPT;
|
||||||
|
|
||||||
|
/// Copy constructor.
|
||||||
|
BOOST_ASIO_DECL any_io_executor(const any_io_executor& e) BOOST_ASIO_NOEXCEPT;
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move constructor.
|
||||||
|
BOOST_ASIO_DECL any_io_executor(any_io_executor&& e) BOOST_ASIO_NOEXCEPT;
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Construct to point to the same target as another any_executor.
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
template <class... OtherSupportableProperties>
|
||||||
|
any_io_executor(execution::any_executor<OtherSupportableProperties...> e);
|
||||||
|
#else // defined(GENERATING_DOCUMENTATION)
|
||||||
|
template <typename OtherAnyExecutor>
|
||||||
|
any_io_executor(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)
|
||||||
|
: base_type(BOOST_ASIO_MOVE_CAST(OtherAnyExecutor)(e))
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif // defined(GENERATING_DOCUMENTATION)
|
#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(Executor e);
|
||||||
|
#else // defined(GENERATING_DOCUMENTATION)
|
||||||
|
template <BOOST_ASIO_EXECUTION_EXECUTOR Executor>
|
||||||
|
any_io_executor(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)
|
||||||
|
: base_type(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;
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move assignment operator.
|
||||||
|
BOOST_ASIO_DECL any_io_executor& operator=(
|
||||||
|
any_io_executor&& e) BOOST_ASIO_NOEXCEPT;
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Assignment operator that sets the polymorphic wrapper to the empty state.
|
||||||
|
BOOST_ASIO_DECL any_io_executor& operator=(nullptr_t);
|
||||||
|
|
||||||
|
/// Destructor.
|
||||||
|
BOOST_ASIO_DECL ~any_io_executor();
|
||||||
|
|
||||||
|
/// Swap targets with another polymorphic wrapper.
|
||||||
|
BOOST_ASIO_DECL void swap(any_io_executor& other) BOOST_ASIO_NOEXCEPT;
|
||||||
|
|
||||||
|
/// Obtain a polymorphic wrapper with the specified property.
|
||||||
|
/**
|
||||||
|
* Do not call this function directly. It is intended for use with the
|
||||||
|
* boost::asio::require and boost::asio::prefer customisation points.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* @code any_io_executor ex = ...;
|
||||||
|
* auto ex2 = boost::asio::require(ex, execution::blocking.possibly); @endcode
|
||||||
|
*/
|
||||||
|
template <typename Property>
|
||||||
|
any_io_executor require(const Property& p,
|
||||||
|
typename constraint<
|
||||||
|
traits::require_member<const base_type&, const Property&>::is_valid
|
||||||
|
>::type = 0) const
|
||||||
|
{
|
||||||
|
return static_cast<const base_type&>(*this).require(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtain a polymorphic wrapper with the specified property.
|
||||||
|
/**
|
||||||
|
* Do not call this function directly. It is intended for use with the
|
||||||
|
* boost::asio::prefer customisation point.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* @code any_io_executor ex = ...;
|
||||||
|
* auto ex2 = boost::asio::prefer(ex, execution::blocking.possibly); @endcode
|
||||||
|
*/
|
||||||
|
template <typename Property>
|
||||||
|
any_io_executor prefer(const Property& p,
|
||||||
|
typename constraint<
|
||||||
|
traits::prefer_member<const base_type&, const Property&>::is_valid
|
||||||
|
>::type = 0) const
|
||||||
|
{
|
||||||
|
return static_cast<const base_type&>(*this).prefer(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
template <>
|
||||||
|
BOOST_ASIO_DECL any_io_executor any_io_executor::require(
|
||||||
|
const execution::blocking_t::never_t&, int) const;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
BOOST_ASIO_DECL any_io_executor any_io_executor::prefer(
|
||||||
|
const execution::blocking_t::possibly_t&, int) const;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
BOOST_ASIO_DECL any_io_executor any_io_executor::prefer(
|
||||||
|
const execution::outstanding_work_t::tracked_t&, int) const;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
BOOST_ASIO_DECL any_io_executor any_io_executor::prefer(
|
||||||
|
const execution::outstanding_work_t::untracked_t&, int) const;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
BOOST_ASIO_DECL any_io_executor any_io_executor::prefer(
|
||||||
|
const execution::relationship_t::fork_t&, int) const;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
BOOST_ASIO_DECL any_io_executor any_io_executor::prefer(
|
||||||
|
const execution::relationship_t::continuation_t&, int) const;
|
||||||
|
|
||||||
|
namespace traits {
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct equality_comparable<any_io_executor>
|
||||||
|
{
|
||||||
|
static const bool is_valid = true;
|
||||||
|
static const bool is_noexcept = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
struct execute_member<any_io_executor, F>
|
||||||
|
{
|
||||||
|
static const bool is_valid = true;
|
||||||
|
static const bool is_noexcept = false;
|
||||||
|
typedef void result_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
template <typename Prop>
|
||||||
|
struct query_member<any_io_executor, Prop> :
|
||||||
|
query_member<any_io_executor::base_type, Prop>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
template <typename Prop>
|
||||||
|
struct require_member<any_io_executor, Prop> :
|
||||||
|
require_member<any_io_executor::base_type, Prop>
|
||||||
|
{
|
||||||
|
typedef any_io_executor result_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
template <typename Prop>
|
||||||
|
struct prefer_member<any_io_executor, Prop> :
|
||||||
|
prefer_member<any_io_executor::base_type, Prop>
|
||||||
|
{
|
||||||
|
typedef any_io_executor result_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
|
||||||
|
|
||||||
|
} // namespace traits
|
||||||
|
|
||||||
|
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
#endif // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
#endif // defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
@ -70,4 +296,10 @@ typedef execution::any_executor<
|
||||||
|
|
||||||
#include <boost/asio/detail/pop_options.hpp>
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HEADER_ONLY) \
|
||||||
|
&& !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
||||||
|
# include <boost/asio/impl/any_io_executor.ipp>
|
||||||
|
#endif // defined(BOOST_ASIO_HEADER_ONLY)
|
||||||
|
// && !defined(BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
|
||||||
|
|
||||||
#endif // BOOST_ASIO_ANY_IO_EXECUTOR_HPP
|
#endif // BOOST_ASIO_ANY_IO_EXECUTOR_HPP
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// associated_allocator.hpp
|
// associated_allocator.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -17,15 +17,33 @@
|
||||||
|
|
||||||
#include <boost/asio/detail/config.hpp>
|
#include <boost/asio/detail/config.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <boost/asio/associator.hpp>
|
||||||
|
#include <boost/asio/detail/functional.hpp>
|
||||||
#include <boost/asio/detail/type_traits.hpp>
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
|
||||||
#include <boost/asio/detail/push_options.hpp>
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
|
template <typename T, typename Allocator>
|
||||||
|
struct associated_allocator;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <typename T, typename E, typename = void>
|
template <typename T, typename = void>
|
||||||
|
struct has_allocator_type : false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_allocator_type<T,
|
||||||
|
typename void_type<typename T::executor_type>::type>
|
||||||
|
: true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename E, typename = void, typename = void>
|
||||||
struct associated_allocator_impl
|
struct associated_allocator_impl
|
||||||
{
|
{
|
||||||
typedef E type;
|
typedef E type;
|
||||||
|
|
@ -48,6 +66,17 @@ struct associated_allocator_impl<T, E,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename E>
|
||||||
|
struct associated_allocator_impl<T, E,
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/// Traits type used to obtain the allocator associated with an object.
|
/// Traits type used to obtain the allocator associated with an object.
|
||||||
|
|
@ -119,6 +148,29 @@ using associated_allocator_t
|
||||||
|
|
||||||
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||||
|
|
||||||
|
#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>
|
||||||
|
{
|
||||||
|
/// Forwards @c type to the associator specialisation for the unwrapped type
|
||||||
|
/// @c T.
|
||||||
|
typedef typename associated_allocator<T, Allocator>::type type;
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
return associated_allocator<T, Allocator>::get(t.get(), a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
//
|
||||||
|
// associated_cancellation_slot.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_CANCELLATION_SLOT_HPP
|
||||||
|
#define BOOST_ASIO_ASSOCIATED_CANCELLATION_SLOT_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/cancellation_signal.hpp>
|
||||||
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
template <typename T, typename CancellationSlot>
|
||||||
|
struct associated_cancellation_slot;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct has_cancellation_slot_type : false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_cancellation_slot_type<T,
|
||||||
|
typename void_type<typename T::cancellation_slot_type>::type>
|
||||||
|
: true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename S, typename = void, typename = void>
|
||||||
|
struct associated_cancellation_slot_impl
|
||||||
|
{
|
||||||
|
typedef void asio_associated_cancellation_slot_is_unspecialised;
|
||||||
|
|
||||||
|
typedef S type;
|
||||||
|
|
||||||
|
static type get(const T&, const S& s = S()) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct associated_cancellation_slot_impl<T, S,
|
||||||
|
typename void_type<typename T::cancellation_slot_type>::type>
|
||||||
|
{
|
||||||
|
typedef typename T::cancellation_slot_type type;
|
||||||
|
|
||||||
|
static type get(const T& t, const S& = S()) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return t.get_cancellation_slot();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct associated_cancellation_slot_impl<T, S,
|
||||||
|
typename enable_if<
|
||||||
|
!has_cancellation_slot_type<T>::value
|
||||||
|
>::type,
|
||||||
|
typename void_type<
|
||||||
|
typename associator<associated_cancellation_slot, T, S>::type
|
||||||
|
>::type> : associator<associated_cancellation_slot, T, S>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Traits type used to obtain the cancellation_slot 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
|
||||||
|
* CancellationSlot shall be a type meeting the CancellationSlot requirements.
|
||||||
|
*
|
||||||
|
* Specialisations shall meet the following requirements, where @c t is a const
|
||||||
|
* reference to an object of type @c T, and @c s is an object of type @c
|
||||||
|
* CancellationSlot.
|
||||||
|
*
|
||||||
|
* @li Provide a nested typedef @c type that identifies a type meeting the
|
||||||
|
* CancellationSlot requirements.
|
||||||
|
*
|
||||||
|
* @li Provide a noexcept static member function named @c get, callable as @c
|
||||||
|
* get(t) and with return type @c type.
|
||||||
|
*
|
||||||
|
* @li Provide a noexcept static member function named @c get, callable as @c
|
||||||
|
* get(t,s) and with return type @c type.
|
||||||
|
*/
|
||||||
|
template <typename T, typename CancellationSlot = cancellation_slot>
|
||||||
|
struct associated_cancellation_slot
|
||||||
|
#if !defined(GENERATING_DOCUMENTATION)
|
||||||
|
: detail::associated_cancellation_slot_impl<T, CancellationSlot>
|
||||||
|
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||||
|
{
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// If @c T has a nested type @c cancellation_slot_type,
|
||||||
|
/// <tt>T::cancellation_slot_type</tt>. Otherwise
|
||||||
|
/// @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 s.
|
||||||
|
static type get(const T& t,
|
||||||
|
const CancellationSlot& s = CancellationSlot()) BOOST_ASIO_NOEXCEPT;
|
||||||
|
#endif // defined(GENERATING_DOCUMENTATION)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Helper function to obtain an object's associated cancellation_slot.
|
||||||
|
/**
|
||||||
|
* @returns <tt>associated_cancellation_slot<T>::get(t)</tt>
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
inline typename associated_cancellation_slot<T>::type
|
||||||
|
get_associated_cancellation_slot(const T& t) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return associated_cancellation_slot<T>::get(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to obtain an object's associated cancellation_slot.
|
||||||
|
/**
|
||||||
|
* @returns <tt>associated_cancellation_slot<T,
|
||||||
|
* CancellationSlot>::get(t, st)</tt>
|
||||||
|
*/
|
||||||
|
template <typename T, typename CancellationSlot>
|
||||||
|
inline typename associated_cancellation_slot<T, CancellationSlot>::type
|
||||||
|
get_associated_cancellation_slot(const T& t,
|
||||||
|
const CancellationSlot& st) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return associated_cancellation_slot<T, CancellationSlot>::get(t, st);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename T, typename CancellationSlot = cancellation_slot>
|
||||||
|
using associated_cancellation_slot_t =
|
||||||
|
typename associated_cancellation_slot<T, CancellationSlot>::type;
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T, typename S, typename = void>
|
||||||
|
struct associated_cancellation_slot_forwarding_base
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct associated_cancellation_slot_forwarding_base<T, S,
|
||||||
|
typename enable_if<
|
||||||
|
is_same<
|
||||||
|
typename associated_cancellation_slot<T,
|
||||||
|
S>::asio_associated_cancellation_slot_is_unspecialised,
|
||||||
|
void
|
||||||
|
>::value
|
||||||
|
>::type>
|
||||||
|
{
|
||||||
|
typedef void asio_associated_cancellation_slot_is_unspecialised;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_ASSOCIATED_CANCELLATION_SLOT_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// associated_executor.hpp
|
// associated_executor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
#include <boost/asio/detail/config.hpp>
|
#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/detail/type_traits.hpp>
|
||||||
#include <boost/asio/execution/executor.hpp>
|
#include <boost/asio/execution/executor.hpp>
|
||||||
#include <boost/asio/is_executor.hpp>
|
#include <boost/asio/is_executor.hpp>
|
||||||
|
|
@ -25,9 +27,25 @@
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
|
template <typename T, typename Executor>
|
||||||
|
struct associated_executor;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <typename T, typename E, typename = void>
|
template <typename T, typename = void>
|
||||||
|
struct has_executor_type : false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_executor_type<T,
|
||||||
|
typename void_type<typename T::executor_type>::type>
|
||||||
|
: true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename E, typename = void, typename = void>
|
||||||
struct associated_executor_impl
|
struct associated_executor_impl
|
||||||
{
|
{
|
||||||
typedef void asio_associated_executor_is_unspecialised;
|
typedef void asio_associated_executor_is_unspecialised;
|
||||||
|
|
@ -52,6 +70,17 @@ struct associated_executor_impl<T, E,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename E>
|
||||||
|
struct associated_executor_impl<T, E,
|
||||||
|
typename enable_if<
|
||||||
|
!has_executor_type<T>::value
|
||||||
|
>::type,
|
||||||
|
typename void_type<
|
||||||
|
typename associator<associated_executor, T, E>::type
|
||||||
|
>::type> : associator<associated_executor, T, E>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/// Traits type used to obtain the executor associated with an object.
|
/// Traits type used to obtain the executor associated with an object.
|
||||||
|
|
@ -109,9 +138,9 @@ get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
|
||||||
template <typename T, typename Executor>
|
template <typename T, typename Executor>
|
||||||
inline typename associated_executor<T, Executor>::type
|
inline typename associated_executor<T, Executor>::type
|
||||||
get_associated_executor(const T& t, const Executor& ex,
|
get_associated_executor(const T& t, const Executor& ex,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return associated_executor<T, Executor>::get(t, ex);
|
return associated_executor<T, Executor>::get(t, ex);
|
||||||
}
|
}
|
||||||
|
|
@ -125,8 +154,8 @@ template <typename T, typename ExecutionContext>
|
||||||
inline typename associated_executor<T,
|
inline typename associated_executor<T,
|
||||||
typename ExecutionContext::executor_type>::type
|
typename ExecutionContext::executor_type>::type
|
||||||
get_associated_executor(const T& t, ExecutionContext& ctx,
|
get_associated_executor(const T& t, ExecutionContext& ctx,
|
||||||
typename enable_if<is_convertible<ExecutionContext&,
|
typename constraint<is_convertible<ExecutionContext&,
|
||||||
execution_context&>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
|
execution_context&>::value>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return associated_executor<T,
|
return associated_executor<T,
|
||||||
typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
|
typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
|
||||||
|
|
@ -160,6 +189,33 @@ struct associated_executor_forwarding_base<T, E,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Specialisation of associated_executor for @c std::reference_wrapper.
|
||||||
|
template <typename T, typename Executor>
|
||||||
|
struct associated_executor<reference_wrapper<T>, Executor>
|
||||||
|
#if !defined(GENERATING_DOCUMENTATION)
|
||||||
|
: detail::associated_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_executor<T, Executor>::type type;
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
{
|
||||||
|
return associated_executor<T, Executor>::get(t.get(), ex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_STD_REFERENCE_WRAPPER)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
//
|
||||||
|
// associator.hpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_ASSOCIATOR_HPP
|
||||||
|
#define BOOST_ASIO_ASSOCIATOR_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
/// Used to generically specialise associators for a type.
|
||||||
|
template <template <typename, typename> class Associator,
|
||||||
|
typename T, typename DefaultCandidate>
|
||||||
|
struct associator
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_ASSOCIATOR_HPP
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -2,7 +2,7 @@
|
||||||
// awaitable.hpp
|
// awaitable.hpp
|
||||||
// ~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -48,7 +48,7 @@ template <typename, typename> class awaitable_frame;
|
||||||
|
|
||||||
/// The return type of a coroutine or asynchronous operation.
|
/// The return type of a coroutine or asynchronous operation.
|
||||||
template <typename T, typename Executor = any_io_executor>
|
template <typename T, typename Executor = any_io_executor>
|
||||||
class awaitable
|
class BOOST_ASIO_NODISCARD awaitable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// The type of the awaited value.
|
/// The type of the awaited value.
|
||||||
|
|
@ -76,6 +76,14 @@ public:
|
||||||
frame_->destroy();
|
frame_->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Move assignment.
|
||||||
|
awaitable& operator=(awaitable&& other) noexcept
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
frame_ = std::exchange(other.frame_, nullptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if the awaitable refers to a future result.
|
/// Checks if the awaitable refers to a future result.
|
||||||
bool valid() const noexcept
|
bool valid() const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_datagram_socket.hpp
|
// basic_datagram_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -46,6 +46,13 @@ class basic_datagram_socket;
|
||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @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.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor>
|
template <typename Protocol, typename Executor>
|
||||||
class basic_datagram_socket
|
class basic_datagram_socket
|
||||||
|
|
@ -101,9 +108,9 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_datagram_socket(ExecutionContext& context,
|
explicit basic_datagram_socket(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context)
|
: basic_socket<Protocol, Executor>(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -139,9 +146,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_datagram_socket(ExecutionContext& context,
|
basic_datagram_socket(ExecutionContext& context,
|
||||||
const protocol_type& protocol,
|
const protocol_type& protocol,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
: basic_socket<Protocol, Executor>(context, protocol)
|
: basic_socket<Protocol, Executor>(context, protocol)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -185,9 +193,9 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_datagram_socket(ExecutionContext& context,
|
basic_datagram_socket(ExecutionContext& context,
|
||||||
const endpoint_type& endpoint,
|
const endpoint_type& endpoint,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -230,9 +238,9 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_datagram_socket(ExecutionContext& context,
|
basic_datagram_socket(ExecutionContext& context,
|
||||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -286,10 +294,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
|
basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value
|
&& is_convertible<Executor1, Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(std::move(other))
|
: basic_socket<Protocol, Executor>(std::move(other))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +316,7 @@ public:
|
||||||
* constructor.
|
* constructor.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value,
|
&& is_convertible<Executor1, Executor>::value,
|
||||||
basic_datagram_socket&
|
basic_datagram_socket&
|
||||||
|
|
@ -447,6 +455,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -491,6 +509,16 @@ public:
|
||||||
* @note The async_send operation can only be used with a connected socket.
|
* @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
|
* Use the async_send_to function to send data on an unconnected datagram
|
||||||
* socket.
|
* socket.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -632,6 +660,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -676,6 +714,16 @@ public:
|
||||||
* not, the handler will not be invoked from within this function. On
|
* not, the handler will not be invoked from within this function. On
|
||||||
* immediate completion, invocation of the handler will be performed in a
|
* immediate completion, invocation of the handler will be performed in a
|
||||||
* manner equivalent to using boost::asio::post().
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -817,6 +865,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -861,6 +919,16 @@ public:
|
||||||
* @note The async_receive operation can only be used with a connected socket.
|
* @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
|
* Use the async_receive_from function to receive data on an unconnected
|
||||||
* datagram socket.
|
* datagram socket.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -1002,6 +1070,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -1048,6 +1126,16 @@ public:
|
||||||
* not, the handler will not be invoked from within this function. On
|
* not, the handler will not be invoked from within this function. On
|
||||||
* immediate completion, invocation of the handler will be performed in a
|
* immediate completion, invocation of the handler will be performed in a
|
||||||
* manner equivalent to using boost::asio::post().
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_deadline_timer.hpp
|
// basic_deadline_timer.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -160,7 +160,7 @@ public:
|
||||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||||
*/
|
*/
|
||||||
explicit basic_deadline_timer(const executor_type& ex)
|
explicit basic_deadline_timer(const executor_type& ex)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,10 +176,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_deadline_timer(ExecutionContext& context,
|
explicit basic_deadline_timer(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,7 +194,7 @@ public:
|
||||||
* as an absolute time.
|
* as an absolute time.
|
||||||
*/
|
*/
|
||||||
basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
|
basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||||
|
|
@ -214,10 +214,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
|
basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||||
|
|
@ -236,7 +236,7 @@ public:
|
||||||
*/
|
*/
|
||||||
basic_deadline_timer(const executor_type& ex,
|
basic_deadline_timer(const executor_type& ex,
|
||||||
const duration_type& expiry_time)
|
const duration_type& expiry_time)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_from_now(
|
impl_.get_service().expires_from_now(
|
||||||
|
|
@ -258,10 +258,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_deadline_timer(ExecutionContext& context,
|
basic_deadline_timer(ExecutionContext& context,
|
||||||
const duration_type& expiry_time,
|
const duration_type& expiry_time,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_from_now(
|
impl_.get_service().expires_from_now(
|
||||||
|
|
@ -628,6 +628,16 @@ public:
|
||||||
* not, the handler will not be invoked from within this function. On
|
* not, the handler will not be invoked from within this function. On
|
||||||
* immediate completion, invocation of the handler will be performed in a
|
* immediate completion, invocation of the handler will be performed in a
|
||||||
* manner equivalent to using boost::asio::post().
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,831 @@
|
||||||
|
//
|
||||||
|
// basic_file.hpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_BASIC_FILE_HPP
|
||||||
|
#define BOOST_ASIO_BASIC_FILE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_FILE) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/asio/any_io_executor.hpp>
|
||||||
|
#include <boost/asio/async_result.hpp>
|
||||||
|
#include <boost/asio/detail/cstdint.hpp>
|
||||||
|
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||||
|
#include <boost/asio/detail/io_object_impl.hpp>
|
||||||
|
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||||
|
#include <boost/asio/detail/throw_error.hpp>
|
||||||
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
|
#include <boost/asio/execution_context.hpp>
|
||||||
|
#include <boost/asio/post.hpp>
|
||||||
|
#include <boost/asio/file_base.hpp>
|
||||||
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
# include <boost/asio/detail/win_iocp_file_service.hpp>
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
# include <boost/asio/detail/io_uring_file_service.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
# include <utility>
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_BASIC_FILE_FWD_DECL)
|
||||||
|
#define BOOST_ASIO_BASIC_FILE_FWD_DECL
|
||||||
|
|
||||||
|
// Forward declaration with defaulted arguments.
|
||||||
|
template <typename Executor = any_io_executor>
|
||||||
|
class basic_file;
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_BASIC_FILE_FWD_DECL)
|
||||||
|
|
||||||
|
/// Provides file functionality.
|
||||||
|
/**
|
||||||
|
* The basic_file class template provides functionality that is common to both
|
||||||
|
* stream-oriented and random-access files.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* @e Distinct @e objects: Safe.@n
|
||||||
|
* @e Shared @e objects: Unsafe.
|
||||||
|
*/
|
||||||
|
template <typename Executor>
|
||||||
|
class basic_file
|
||||||
|
: public file_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The type of the executor associated with the object.
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
/// Rebinds the file type to another executor.
|
||||||
|
template <typename Executor1>
|
||||||
|
struct rebind_executor
|
||||||
|
{
|
||||||
|
/// The file type when rebound to the specified executor.
|
||||||
|
typedef basic_file<Executor1> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The native representation of a file.
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
typedef implementation_defined native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
typedef detail::win_iocp_file_service::native_handle_type native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
typedef detail::io_uring_file_service::native_handle_type native_handle_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Construct a basic_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file without opening it.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*/
|
||||||
|
explicit basic_file(const executor_type& ex)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file without opening it.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
explicit basic_file(ExecutionContext& context,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file and opens it.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*/
|
||||||
|
explicit basic_file(const executor_type& ex,
|
||||||
|
const char* path, file_base::flags open_flags)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file and opens it.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
explicit basic_file(ExecutionContext& context,
|
||||||
|
const char* path, file_base::flags open_flags,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file and opens it.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*/
|
||||||
|
explicit basic_file(const executor_type& ex,
|
||||||
|
const std::string& path, file_base::flags open_flags)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().open(impl_.get_implementation(),
|
||||||
|
path.c_str(), open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file and opens it.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
explicit basic_file(ExecutionContext& context,
|
||||||
|
const std::string& path, file_base::flags open_flags,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().open(impl_.get_implementation(),
|
||||||
|
path.c_str(), open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_file on an existing native file handle.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file object to hold an existing native file.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param native_file A native file handle.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_file(const executor_type& ex, const native_handle_type& native_file)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(
|
||||||
|
impl_.get_implementation(), native_file, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_file on an existing native file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file object to hold an existing native file.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param native_file A native file.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_file(ExecutionContext& context, const native_handle_type& native_file,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(
|
||||||
|
impl_.get_implementation(), native_file, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move-construct a basic_file from another.
|
||||||
|
/**
|
||||||
|
* This constructor moves a file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_file object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_file(const executor_type&) constructor.
|
||||||
|
*/
|
||||||
|
basic_file(basic_file&& other) BOOST_ASIO_NOEXCEPT
|
||||||
|
: impl_(std::move(other.impl_))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_file from another.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_file object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_file(const executor_type&) constructor.
|
||||||
|
*/
|
||||||
|
basic_file& operator=(basic_file&& other)
|
||||||
|
{
|
||||||
|
impl_ = std::move(other.impl_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All files have access to each other's implementations.
|
||||||
|
template <typename Executor1>
|
||||||
|
friend class basic_file;
|
||||||
|
|
||||||
|
/// Move-construct a basic_file from a file of another executor type.
|
||||||
|
/**
|
||||||
|
* This constructor moves a file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_file object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_file(const executor_type&) constructor.
|
||||||
|
*/
|
||||||
|
template <typename Executor1>
|
||||||
|
basic_file(basic_file<Executor1>&& other,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<Executor1, Executor>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(std::move(other.impl_))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_file from a file of another executor type.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_file object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_file(const executor_type&) constructor.
|
||||||
|
*/
|
||||||
|
template <typename Executor1>
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<Executor1, Executor>::value,
|
||||||
|
basic_file&
|
||||||
|
>::type operator=(basic_file<Executor1> && other)
|
||||||
|
{
|
||||||
|
basic_file tmp(std::move(other));
|
||||||
|
impl_ = std::move(tmp.impl_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Get the executor associated with the object.
|
||||||
|
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return impl_.get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open the file using the specified path.
|
||||||
|
/**
|
||||||
|
* This function opens the file so that it will use the specified path.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* @code
|
||||||
|
* boost::asio::stream_file file(my_context);
|
||||||
|
* file.open("/path/to/my/file", boost::asio::stream_file::read_only);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
void open(const char* path, file_base::flags open_flags)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open the file using the specified path.
|
||||||
|
/**
|
||||||
|
* This function opens the file so that it will use the specified path.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* @code
|
||||||
|
* boost::asio::stream_file file(my_context);
|
||||||
|
* boost::system::error_code ec;
|
||||||
|
* file.open("/path/to/my/file", boost::asio::stream_file::read_only, ec);
|
||||||
|
* if (ec)
|
||||||
|
* {
|
||||||
|
* // An error occurred.
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID open(const char* path,
|
||||||
|
file_base::flags open_flags, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open the file using the specified path.
|
||||||
|
/**
|
||||||
|
* This function opens the file so that it will use the specified path.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* @code
|
||||||
|
* boost::asio::stream_file file(my_context);
|
||||||
|
* file.open("/path/to/my/file", boost::asio::stream_file::read_only);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
void open(const std::string& path, file_base::flags open_flags)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().open(impl_.get_implementation(),
|
||||||
|
path.c_str(), open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open the file using the specified path.
|
||||||
|
/**
|
||||||
|
* This function opens the file so that it will use the specified path.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* @code
|
||||||
|
* boost::asio::stream_file file(my_context);
|
||||||
|
* boost::system::error_code ec;
|
||||||
|
* file.open("/path/to/my/file", boost::asio::stream_file::read_only, ec);
|
||||||
|
* if (ec)
|
||||||
|
* {
|
||||||
|
* // An error occurred.
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID open(const std::string& path,
|
||||||
|
file_base::flags open_flags, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().open(impl_.get_implementation(),
|
||||||
|
path.c_str(), open_flags, ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign an existing native file to the file.
|
||||||
|
/*
|
||||||
|
* This function opens the file to hold an existing native file.
|
||||||
|
*
|
||||||
|
* @param native_file A native file.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void assign(const native_handle_type& native_file)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(
|
||||||
|
impl_.get_implementation(), native_file, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign an existing native file to the file.
|
||||||
|
/*
|
||||||
|
* This function opens the file to hold an existing native file.
|
||||||
|
*
|
||||||
|
* @param native_file A native file.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_file,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().assign(
|
||||||
|
impl_.get_implementation(), native_file, ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the file is open.
|
||||||
|
bool is_open() const
|
||||||
|
{
|
||||||
|
return impl_.get_service().is_open(impl_.get_implementation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close the file.
|
||||||
|
/**
|
||||||
|
* This function is used to close the file. Any asynchronous read or write
|
||||||
|
* operations will be cancelled immediately, and will complete with the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure. Note that, even if
|
||||||
|
* the function indicates an error, the underlying descriptor is closed.
|
||||||
|
*/
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "close");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close the file.
|
||||||
|
/**
|
||||||
|
* This function is used to close the file. Any asynchronous read or write
|
||||||
|
* operations will be cancelled immediately, and will complete with the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any. Note that, even if
|
||||||
|
* the function indicates an error, the underlying descriptor is closed.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* @code
|
||||||
|
* boost::asio::stream_file file(my_context);
|
||||||
|
* ...
|
||||||
|
* boost::system::error_code ec;
|
||||||
|
* file.close(ec);
|
||||||
|
* if (ec)
|
||||||
|
* {
|
||||||
|
* // An error occurred.
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Release ownership of the underlying native file.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous read and write
|
||||||
|
* operations to finish immediately, and the handlers for cancelled
|
||||||
|
* operations will be passed the boost::asio::error::operation_aborted error.
|
||||||
|
* Ownership of the native file is then transferred to the caller.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*
|
||||||
|
* @note This function is unsupported on Windows versions prior to Windows
|
||||||
|
* 8.1, and will fail with boost::asio::error::operation_not_supported on
|
||||||
|
* these platforms.
|
||||||
|
*/
|
||||||
|
#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
|
||||||
|
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
|
||||||
|
__declspec(deprecated("This function always fails with "
|
||||||
|
"operation_not_supported when used on Windows versions "
|
||||||
|
"prior to Windows 8.1."))
|
||||||
|
#endif
|
||||||
|
native_handle_type release()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
native_handle_type s = impl_.get_service().release(
|
||||||
|
impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "release");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Release ownership of the underlying native file.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous read and write
|
||||||
|
* operations to finish immediately, and the handlers for cancelled
|
||||||
|
* operations will be passed the boost::asio::error::operation_aborted error.
|
||||||
|
* Ownership of the native file is then transferred to the caller.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @note This function is unsupported on Windows versions prior to Windows
|
||||||
|
* 8.1, and will fail with boost::asio::error::operation_not_supported on
|
||||||
|
* these platforms.
|
||||||
|
*/
|
||||||
|
#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
|
||||||
|
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
|
||||||
|
__declspec(deprecated("This function always fails with "
|
||||||
|
"operation_not_supported when used on Windows versions "
|
||||||
|
"prior to Windows 8.1."))
|
||||||
|
#endif
|
||||||
|
native_handle_type release(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return impl_.get_service().release(impl_.get_implementation(), ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the native file representation.
|
||||||
|
/**
|
||||||
|
* This function may be used to obtain the underlying representation of the
|
||||||
|
* file. This is intended to allow access to native file functionality
|
||||||
|
* that is not otherwise provided.
|
||||||
|
*/
|
||||||
|
native_handle_type native_handle()
|
||||||
|
{
|
||||||
|
return impl_.get_service().native_handle(impl_.get_implementation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel all asynchronous operations associated with the file.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous read and write
|
||||||
|
* operations to finish immediately, and the handlers for cancelled
|
||||||
|
* operations will be passed the boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*
|
||||||
|
* @note Calls to cancel() will always fail with
|
||||||
|
* boost::asio::error::operation_not_supported when run on Windows XP, Windows
|
||||||
|
* Server 2003, and earlier versions of Windows, unless
|
||||||
|
* BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
|
||||||
|
* two issues that should be considered before enabling its use:
|
||||||
|
*
|
||||||
|
* @li It will only cancel asynchronous operations that were initiated in the
|
||||||
|
* current thread.
|
||||||
|
*
|
||||||
|
* @li It can appear to complete without error, but the request to cancel the
|
||||||
|
* unfinished operations may be silently ignored by the operating system.
|
||||||
|
* Whether it works or not seems to depend on the drivers that are installed.
|
||||||
|
*
|
||||||
|
* For portable cancellation, consider using the close() function to
|
||||||
|
* simultaneously cancel the outstanding operations and close the file.
|
||||||
|
*
|
||||||
|
* When running on Windows Vista, Windows Server 2008, and later, the
|
||||||
|
* CancelIoEx function is always used. This function does not have the
|
||||||
|
* problems described above.
|
||||||
|
*/
|
||||||
|
#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
|
||||||
|
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
|
||||||
|
&& !defined(BOOST_ASIO_ENABLE_CANCELIO)
|
||||||
|
__declspec(deprecated("By default, this function always fails with "
|
||||||
|
"operation_not_supported when used on Windows XP, Windows Server 2003, "
|
||||||
|
"or earlier. Consult documentation for details."))
|
||||||
|
#endif
|
||||||
|
void cancel()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "cancel");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel all asynchronous operations associated with the file.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous read and write
|
||||||
|
* operations to finish immediately, and the handlers for cancelled
|
||||||
|
* operations will be passed the boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @note Calls to cancel() will always fail with
|
||||||
|
* boost::asio::error::operation_not_supported when run on Windows XP, Windows
|
||||||
|
* Server 2003, and earlier versions of Windows, unless
|
||||||
|
* BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
|
||||||
|
* two issues that should be considered before enabling its use:
|
||||||
|
*
|
||||||
|
* @li It will only cancel asynchronous operations that were initiated in the
|
||||||
|
* current thread.
|
||||||
|
*
|
||||||
|
* @li It can appear to complete without error, but the request to cancel the
|
||||||
|
* unfinished operations may be silently ignored by the operating system.
|
||||||
|
* Whether it works or not seems to depend on the drivers that are installed.
|
||||||
|
*
|
||||||
|
* For portable cancellation, consider using the close() function to
|
||||||
|
* simultaneously cancel the outstanding operations and close the file.
|
||||||
|
*
|
||||||
|
* When running on Windows Vista, Windows Server 2008, and later, the
|
||||||
|
* CancelIoEx function is always used. This function does not have the
|
||||||
|
* problems described above.
|
||||||
|
*/
|
||||||
|
#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
|
||||||
|
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
|
||||||
|
&& !defined(BOOST_ASIO_ENABLE_CANCELIO)
|
||||||
|
__declspec(deprecated("By default, this function always fails with "
|
||||||
|
"operation_not_supported when used on Windows XP, Windows Server 2003, "
|
||||||
|
"or earlier. Consult documentation for details."))
|
||||||
|
#endif
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the size of the file.
|
||||||
|
/**
|
||||||
|
* This function determines the size of the file, in bytes.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
uint64_t size() const
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
uint64_t s = impl_.get_service().size(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "size");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the size of the file.
|
||||||
|
/**
|
||||||
|
* This function determines the size of the file, in bytes.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
uint64_t size(boost::system::error_code& ec) const
|
||||||
|
{
|
||||||
|
return impl_.get_service().size(impl_.get_implementation(), ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Alter the size of the file.
|
||||||
|
/**
|
||||||
|
* This function resizes the file to the specified size, in bytes. If the
|
||||||
|
* current file size exceeds @c n then any extra data is discarded. If the
|
||||||
|
* current size is less than @c n then the file is extended and filled with
|
||||||
|
* zeroes.
|
||||||
|
*
|
||||||
|
* @param n The new size for the file.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void resize(uint64_t n)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().resize(impl_.get_implementation(), n, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "resize");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Alter the size of the file.
|
||||||
|
/**
|
||||||
|
* This function resizes the file to the specified size, in bytes. If the
|
||||||
|
* current file size exceeds @c n then any extra data is discarded. If the
|
||||||
|
* current size is less than @c n then the file is extended and filled with
|
||||||
|
* zeroes.
|
||||||
|
*
|
||||||
|
* @param n The new size for the file.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID resize(uint64_t n, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().resize(impl_.get_implementation(), n, ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Synchronise the file to disk.
|
||||||
|
/**
|
||||||
|
* This function synchronises the file data and metadata to disk. Note that
|
||||||
|
* the semantics of this synchronisation vary between operation systems.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void sync_all()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().sync_all(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "sync_all");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Synchronise the file to disk.
|
||||||
|
/**
|
||||||
|
* This function synchronises the file data and metadata to disk. Note that
|
||||||
|
* the semantics of this synchronisation vary between operation systems.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID sync_all(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().sync_all(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Synchronise the file data to disk.
|
||||||
|
/**
|
||||||
|
* This function synchronises the file data to disk. Note that the semantics
|
||||||
|
* of this synchronisation vary between operation systems.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void sync_data()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().sync_data(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "sync_data");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Synchronise the file data to disk.
|
||||||
|
/**
|
||||||
|
* This function synchronises the file data to disk. Note that the semantics
|
||||||
|
* of this synchronisation vary between operation systems.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID sync_data(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().sync_data(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Protected destructor to prevent deletion through this type.
|
||||||
|
/**
|
||||||
|
* This function destroys the file, cancelling any outstanding asynchronous
|
||||||
|
* operations associated with the file as if by calling @c cancel.
|
||||||
|
*/
|
||||||
|
~basic_file()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
detail::io_object_impl<detail::win_iocp_file_service, Executor> impl_;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
detail::io_object_impl<detail::io_uring_file_service, Executor> impl_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copying and assignment.
|
||||||
|
basic_file(const basic_file&) BOOST_ASIO_DELETED;
|
||||||
|
basic_file& operator=(const basic_file&) BOOST_ASIO_DELETED;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_FILE)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_BASIC_FILE_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_io_object.hpp
|
// basic_io_object.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,679 @@
|
||||||
|
//
|
||||||
|
// basic_random_access_file.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_BASIC_RANDOM_ACCESS_FILE_HPP
|
||||||
|
#define BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_FILE) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <boost/asio/async_result.hpp>
|
||||||
|
#include <boost/asio/basic_file.hpp>
|
||||||
|
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||||
|
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||||
|
#include <boost/asio/detail/throw_error.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_FWD_DECL)
|
||||||
|
#define BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_FWD_DECL
|
||||||
|
|
||||||
|
// Forward declaration with defaulted arguments.
|
||||||
|
template <typename Executor = any_io_executor>
|
||||||
|
class basic_random_access_file;
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_FWD_DECL)
|
||||||
|
|
||||||
|
/// Provides random-access file functionality.
|
||||||
|
/**
|
||||||
|
* The basic_random_access_file class template provides asynchronous and
|
||||||
|
* blocking random-access file functionality.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* @e Distinct @e objects: Safe.@n
|
||||||
|
* @e Shared @e objects: Unsafe.
|
||||||
|
*
|
||||||
|
* Synchronous @c read_some_at and @c write_some_at 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 file object. Other
|
||||||
|
* synchronous operations, such as @c open or @c close, are not thread safe.
|
||||||
|
*/
|
||||||
|
template <typename Executor>
|
||||||
|
class basic_random_access_file
|
||||||
|
: public basic_file<Executor>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The type of the executor associated with the object.
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
/// Rebinds the file type to another executor.
|
||||||
|
template <typename Executor1>
|
||||||
|
struct rebind_executor
|
||||||
|
{
|
||||||
|
/// The file type when rebound to the specified executor.
|
||||||
|
typedef basic_random_access_file<Executor1> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The native representation of a file.
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
typedef implementation_defined native_handle_type;
|
||||||
|
#else
|
||||||
|
typedef typename basic_file<Executor>::native_handle_type native_handle_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Construct a basic_random_access_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file without opening it. The file needs to
|
||||||
|
* be opened before data can be read from or or written to it.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*/
|
||||||
|
explicit basic_random_access_file(const executor_type& ex)
|
||||||
|
: basic_file<Executor>(ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_random_access_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file without opening it. The file needs to
|
||||||
|
* be opened before data can be read from or or written to it.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
explicit basic_random_access_file(ExecutionContext& context,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_random_access_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_random_access_file(const executor_type& ex,
|
||||||
|
const char* path, file_base::flags open_flags)
|
||||||
|
: basic_file<Executor>(ex, path, open_flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_random_access_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_random_access_file(ExecutionContext& context,
|
||||||
|
const char* path, file_base::flags open_flags,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context, path, open_flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_random_access_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_random_access_file(const executor_type& ex,
|
||||||
|
const std::string& path, file_base::flags open_flags)
|
||||||
|
: basic_file<Executor>(ex, path, open_flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_random_access_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_random_access_file(ExecutionContext& context,
|
||||||
|
const std::string& path, file_base::flags open_flags,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context, path, open_flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_random_access_file on an existing native file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a random-access file object to hold an
|
||||||
|
* existing native file.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param native_file The new underlying file implementation.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_random_access_file(const executor_type& ex,
|
||||||
|
const native_handle_type& native_file)
|
||||||
|
: basic_file<Executor>(ex, native_file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_random_access_file on an existing native file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a random-access file object to hold an
|
||||||
|
* existing native file.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param native_file The new underlying file implementation.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_random_access_file(ExecutionContext& context,
|
||||||
|
const native_handle_type& native_file,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context, native_file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move-construct a basic_random_access_file from another.
|
||||||
|
/**
|
||||||
|
* This constructor moves a random-access file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_random_access_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_random_access_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_random_access_file(basic_random_access_file&& other) BOOST_ASIO_NOEXCEPT
|
||||||
|
: basic_file<Executor>(std::move(other))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_random_access_file from another.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a random-access file from one object to
|
||||||
|
* another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_random_access_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_random_access_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_random_access_file& operator=(basic_random_access_file&& other)
|
||||||
|
{
|
||||||
|
basic_file<Executor>::operator=(std::move(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-construct a basic_random_access_file from a file of another executor
|
||||||
|
/// type.
|
||||||
|
/**
|
||||||
|
* This constructor moves a random-access file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_random_access_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_random_access_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
template <typename Executor1>
|
||||||
|
basic_random_access_file(basic_random_access_file<Executor1>&& other,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<Executor1, Executor>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(std::move(other))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_random_access_file from a file of another executor
|
||||||
|
/// type.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a random-access file from one object to
|
||||||
|
* another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_random_access_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_random_access_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
template <typename Executor1>
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<Executor1, Executor>::value,
|
||||||
|
basic_random_access_file&
|
||||||
|
>::type operator=(basic_random_access_file<Executor1>&& other)
|
||||||
|
{
|
||||||
|
basic_file<Executor>::operator=(std::move(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Destroys the file.
|
||||||
|
/**
|
||||||
|
* This function destroys the file, cancelling any outstanding asynchronous
|
||||||
|
* operations associated with the file as if by calling @c cancel.
|
||||||
|
*/
|
||||||
|
~basic_random_access_file()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write some data to the handle at the specified offset.
|
||||||
|
/**
|
||||||
|
* This function is used to write data to the random-access handle. The
|
||||||
|
* function call will block until one or more bytes of the data has been
|
||||||
|
* written successfully, or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param offset The offset at which the data will be written.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the handle.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes written.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure. An error code of
|
||||||
|
* boost::asio::error::eof indicates that the end of the file was reached.
|
||||||
|
*
|
||||||
|
* @note The write_some_at operation may not write all of the data. Consider
|
||||||
|
* using the @ref write_at function if you need to ensure that all data is
|
||||||
|
* written before the blocking operation completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* handle.write_some_at(42, boost::asio::buffer(data, size));
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on writing multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence>
|
||||||
|
std::size_t write_some_at(uint64_t offset,
|
||||||
|
const ConstBufferSequence& buffers)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
std::size_t s = this->impl_.get_service().write_some_at(
|
||||||
|
this->impl_.get_implementation(), offset, buffers, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "write_some_at");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write some data to the handle at the specified offset.
|
||||||
|
/**
|
||||||
|
* This function is used to write data to the random-access handle. The
|
||||||
|
* function call will block until one or more bytes of the data has been
|
||||||
|
* written successfully, or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param offset The offset at which the data will be written.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the handle.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes written. Returns 0 if an error occurred.
|
||||||
|
*
|
||||||
|
* @note The write_some operation may not write all of the data to the
|
||||||
|
* file. Consider using the @ref write_at function if you need to ensure that
|
||||||
|
* all data is written before the blocking operation completes.
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence>
|
||||||
|
std::size_t write_some_at(uint64_t offset,
|
||||||
|
const ConstBufferSequence& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->impl_.get_service().write_some_at(
|
||||||
|
this->impl_.get_implementation(), offset, buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start an asynchronous write at the specified offset.
|
||||||
|
/**
|
||||||
|
* This function is used to asynchronously write data to the random-access
|
||||||
|
* handle. The function call always returns immediately.
|
||||||
|
*
|
||||||
|
* @param offset The offset at which the data will be written.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the handle.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param handler The handler to be called when the write operation completes.
|
||||||
|
* Copies will be made of the handler as required. The function signature of
|
||||||
|
* the handler must be:
|
||||||
|
* @code void handler(
|
||||||
|
* const boost::system::error_code& error, // Result of operation.
|
||||||
|
* std::size_t bytes_transferred // Number of bytes written.
|
||||||
|
* ); @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
|
||||||
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @note The write operation may not write all of the data to the file.
|
||||||
|
* Consider using the @ref async_write_at function if you need to ensure that
|
||||||
|
* all data is written before the asynchronous operation completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* handle.async_write_some_at(42, boost::asio::buffer(data, size), handler);
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on writing multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence,
|
||||||
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
std::size_t)) WriteHandler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||||
|
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
|
||||||
|
void (boost::system::error_code, std::size_t))
|
||||||
|
async_write_some_at(uint64_t offset,
|
||||||
|
const ConstBufferSequence& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||||
|
{
|
||||||
|
return async_initiate<WriteHandler,
|
||||||
|
void (boost::system::error_code, std::size_t)>(
|
||||||
|
initiate_async_write_some_at(this), handler, offset, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read some data from the handle at the specified offset.
|
||||||
|
/**
|
||||||
|
* This function is used to read data from the random-access handle. The
|
||||||
|
* function call will block until one or more bytes of data has been read
|
||||||
|
* successfully, or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param offset The offset at which the data will be read.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes read.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure. An error code of
|
||||||
|
* boost::asio::error::eof indicates that the end of the file was reached.
|
||||||
|
*
|
||||||
|
* @note The read_some operation may not read all of the requested number of
|
||||||
|
* bytes. Consider using the @ref read_at function if you need to ensure that
|
||||||
|
* the requested amount of data is read before the blocking operation
|
||||||
|
* completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* handle.read_some_at(42, boost::asio::buffer(data, size));
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on reading into multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence>
|
||||||
|
std::size_t read_some_at(uint64_t offset,
|
||||||
|
const MutableBufferSequence& buffers)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
std::size_t s = this->impl_.get_service().read_some_at(
|
||||||
|
this->impl_.get_implementation(), offset, buffers, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "read_some_at");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read some data from the handle at the specified offset.
|
||||||
|
/**
|
||||||
|
* This function is used to read data from the random-access handle. The
|
||||||
|
* function call will block until one or more bytes of data has been read
|
||||||
|
* successfully, or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param offset The offset at which the data will be read.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes read. Returns 0 if an error occurred.
|
||||||
|
*
|
||||||
|
* @note The read_some operation may not read all of the requested number of
|
||||||
|
* bytes. Consider using the @ref read_at function if you need to ensure that
|
||||||
|
* the requested amount of data is read before the blocking operation
|
||||||
|
* completes.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence>
|
||||||
|
std::size_t read_some_at(uint64_t offset,
|
||||||
|
const MutableBufferSequence& buffers, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->impl_.get_service().read_some_at(
|
||||||
|
this->impl_.get_implementation(), offset, buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start an asynchronous read at the specified offset.
|
||||||
|
/**
|
||||||
|
* This function is used to asynchronously read data from the random-access
|
||||||
|
* handle. The function call always returns immediately.
|
||||||
|
*
|
||||||
|
* @param offset The offset at which the data will be read.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param handler The handler to be called when the read operation completes.
|
||||||
|
* Copies will be made of the handler as required. The function signature of
|
||||||
|
* the handler must be:
|
||||||
|
* @code void handler(
|
||||||
|
* const boost::system::error_code& error, // Result of operation.
|
||||||
|
* std::size_t bytes_transferred // Number of bytes read.
|
||||||
|
* ); @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
|
||||||
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @note The read operation may not read all of the requested number of bytes.
|
||||||
|
* Consider using the @ref async_read_at function if you need to ensure that
|
||||||
|
* the requested amount of data is read before the asynchronous operation
|
||||||
|
* completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* handle.async_read_some_at(42, boost::asio::buffer(data, size), handler);
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on reading into multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence,
|
||||||
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
std::size_t)) ReadHandler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||||
|
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
|
||||||
|
void (boost::system::error_code, std::size_t))
|
||||||
|
async_read_some_at(uint64_t offset,
|
||||||
|
const MutableBufferSequence& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||||
|
{
|
||||||
|
return async_initiate<ReadHandler,
|
||||||
|
void (boost::system::error_code, std::size_t)>(
|
||||||
|
initiate_async_read_some_at(this), handler, offset, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copying and assignment.
|
||||||
|
basic_random_access_file(const basic_random_access_file&) BOOST_ASIO_DELETED;
|
||||||
|
basic_random_access_file& operator=(
|
||||||
|
const basic_random_access_file&) BOOST_ASIO_DELETED;
|
||||||
|
|
||||||
|
class initiate_async_write_some_at
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
explicit initiate_async_write_some_at(basic_random_access_file* self)
|
||||||
|
: self_(self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return self_->get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename WriteHandler, typename ConstBufferSequence>
|
||||||
|
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||||
|
uint64_t offset, const ConstBufferSequence& buffers) const
|
||||||
|
{
|
||||||
|
// If you get an error on the following line it means that your handler
|
||||||
|
// does not meet the documented type requirements for a WriteHandler.
|
||||||
|
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
|
||||||
|
|
||||||
|
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||||
|
self_->impl_.get_service().async_write_some_at(
|
||||||
|
self_->impl_.get_implementation(), offset, buffers,
|
||||||
|
handler2.value, self_->impl_.get_executor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
basic_random_access_file* self_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class initiate_async_read_some_at
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
explicit initiate_async_read_some_at(basic_random_access_file* self)
|
||||||
|
: self_(self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return self_->get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReadHandler, typename MutableBufferSequence>
|
||||||
|
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||||
|
uint64_t offset, const MutableBufferSequence& buffers) const
|
||||||
|
{
|
||||||
|
// If you get an error on the following line it means that your handler
|
||||||
|
// does not meet the documented type requirements for a ReadHandler.
|
||||||
|
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||||
|
|
||||||
|
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||||
|
self_->impl_.get_service().async_read_some_at(
|
||||||
|
self_->impl_.get_implementation(), offset, buffers,
|
||||||
|
handler2.value, self_->impl_.get_executor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
basic_random_access_file* self_;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_FILE)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_raw_socket.hpp
|
// basic_raw_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -46,6 +46,13 @@ class basic_raw_socket;
|
||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @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.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor>
|
template <typename Protocol, typename Executor>
|
||||||
class basic_raw_socket
|
class basic_raw_socket
|
||||||
|
|
@ -101,9 +108,9 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_raw_socket(ExecutionContext& context,
|
explicit basic_raw_socket(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context)
|
: basic_socket<Protocol, Executor>(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -138,9 +145,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
|
basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
: basic_socket<Protocol, Executor>(context, protocol)
|
: basic_socket<Protocol, Executor>(context, protocol)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -183,9 +191,9 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -228,9 +236,9 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_raw_socket(ExecutionContext& context,
|
basic_raw_socket(ExecutionContext& context,
|
||||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -283,10 +291,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
|
basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value
|
&& is_convertible<Executor1, Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(std::move(other))
|
: basic_socket<Protocol, Executor>(std::move(other))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -303,7 +311,7 @@ public:
|
||||||
* constructor.
|
* constructor.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value,
|
&& is_convertible<Executor1, Executor>::value,
|
||||||
basic_raw_socket&
|
basic_raw_socket&
|
||||||
|
|
@ -439,6 +447,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -483,6 +501,16 @@ public:
|
||||||
* @note The async_send operation can only be used with a connected socket.
|
* @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 raw
|
* Use the async_send_to function to send data on an unconnected raw
|
||||||
* socket.
|
* socket.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -624,6 +652,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -668,6 +706,16 @@ public:
|
||||||
* not, the handler will not be invoked from within this function. On
|
* not, the handler will not be invoked from within this function. On
|
||||||
* immediate completion, invocation of the handler will be performed in a
|
* immediate completion, invocation of the handler will be performed in a
|
||||||
* manner equivalent to using boost::asio::post().
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -809,6 +857,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -853,6 +911,16 @@ public:
|
||||||
* @note The async_receive operation can only be used with a connected socket.
|
* @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
|
* Use the async_receive_from function to receive data on an unconnected
|
||||||
* raw socket.
|
* raw socket.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -994,6 +1062,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -1040,6 +1118,16 @@ public:
|
||||||
* not, the handler will not be invoked from within this function. On
|
* not, the handler will not be invoked from within this function. On
|
||||||
* immediate completion, invocation of the handler will be performed in a
|
* immediate completion, invocation of the handler will be performed in a
|
||||||
* manner equivalent to using boost::asio::post().
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,525 @@
|
||||||
|
//
|
||||||
|
// basic_readable_pipe.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_BASIC_READABLE_PIPE_HPP
|
||||||
|
#define BOOST_ASIO_BASIC_READABLE_PIPE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_PIPE) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/asio/any_io_executor.hpp>
|
||||||
|
#include <boost/asio/async_result.hpp>
|
||||||
|
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||||
|
#include <boost/asio/detail/io_object_impl.hpp>
|
||||||
|
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||||
|
#include <boost/asio/detail/throw_error.hpp>
|
||||||
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
|
#include <boost/asio/execution_context.hpp>
|
||||||
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
# include <boost/asio/detail/win_iocp_handle_service.hpp>
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
# include <boost/asio/detail/io_uring_descriptor_service.hpp>
|
||||||
|
#else
|
||||||
|
# include <boost/asio/detail/reactive_descriptor_service.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
# include <utility>
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
/// Provides pipe functionality.
|
||||||
|
/**
|
||||||
|
* The basic_readable_pipe class provides a wrapper over pipe
|
||||||
|
* functionality.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* @e Distinct @e objects: Safe.@n
|
||||||
|
* @e Shared @e objects: Unsafe.
|
||||||
|
*/
|
||||||
|
template <typename Executor = any_io_executor>
|
||||||
|
class basic_readable_pipe
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The type of the executor associated with the object.
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
/// Rebinds the pipe type to another executor.
|
||||||
|
template <typename Executor1>
|
||||||
|
struct rebind_executor
|
||||||
|
{
|
||||||
|
/// The pipe type when rebound to the specified executor.
|
||||||
|
typedef basic_readable_pipe<Executor1> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The native representation of a pipe.
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
typedef implementation_defined native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
typedef detail::win_iocp_handle_service::native_handle_type
|
||||||
|
native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
typedef detail::io_uring_descriptor_service::native_handle_type
|
||||||
|
native_handle_type;
|
||||||
|
#else
|
||||||
|
typedef detail::reactive_descriptor_service::native_handle_type
|
||||||
|
native_handle_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// A basic_readable_pipe is always the lowest layer.
|
||||||
|
typedef basic_readable_pipe lowest_layer_type;
|
||||||
|
|
||||||
|
/// Construct a basic_readable_pipe without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe without opening it.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the pipe will use, by default, to dispatch
|
||||||
|
* handlers for any asynchronous operations performed on the pipe.
|
||||||
|
*/
|
||||||
|
explicit basic_readable_pipe(const executor_type& ex)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_readable_pipe without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe without opening it.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the pipe will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the pipe.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
explicit basic_readable_pipe(ExecutionContext& context,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_readable_pipe on an existing native pipe.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe object to hold an existing native
|
||||||
|
* pipe.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the pipe will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the
|
||||||
|
* pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_readable_pipe(const executor_type& ex,
|
||||||
|
const native_handle_type& native_pipe)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
native_pipe, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_readable_pipe on an existing native pipe.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe object to hold an existing native
|
||||||
|
* pipe.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the pipe will use, by default, to dispatch handlers for any
|
||||||
|
* asynchronous operations performed on the pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_readable_pipe(ExecutionContext& context,
|
||||||
|
const native_handle_type& native_pipe,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
|
>::type = 0)
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
native_pipe, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move-construct a basic_readable_pipe from another.
|
||||||
|
/**
|
||||||
|
* This constructor moves a pipe from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_readable_pipe object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_readable_pipe(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_readable_pipe(basic_readable_pipe&& other)
|
||||||
|
: impl_(std::move(other.impl_))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_readable_pipe from another.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a pipe from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_readable_pipe object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_readable_pipe(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_readable_pipe& operator=(basic_readable_pipe&& other)
|
||||||
|
{
|
||||||
|
impl_ = std::move(other.impl_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Destroys the pipe.
|
||||||
|
/**
|
||||||
|
* This function destroys the pipe, cancelling any outstanding
|
||||||
|
* asynchronous wait operations associated with the pipe as if by
|
||||||
|
* calling @c cancel.
|
||||||
|
*/
|
||||||
|
~basic_readable_pipe()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the executor associated with the object.
|
||||||
|
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return impl_.get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference to the lowest layer.
|
||||||
|
/**
|
||||||
|
* This function returns a reference to the lowest layer in a stack of
|
||||||
|
* layers. Since a basic_readable_pipe cannot contain any further layers, it
|
||||||
|
* simply returns a reference to itself.
|
||||||
|
*
|
||||||
|
* @return A reference to the lowest layer in the stack of layers. Ownership
|
||||||
|
* is not transferred to the caller.
|
||||||
|
*/
|
||||||
|
lowest_layer_type& lowest_layer()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a const reference to the lowest layer.
|
||||||
|
/**
|
||||||
|
* This function returns a const reference to the lowest layer in a stack of
|
||||||
|
* layers. Since a basic_readable_pipe cannot contain any further layers, it
|
||||||
|
* simply returns a reference to itself.
|
||||||
|
*
|
||||||
|
* @return A const reference to the lowest layer in the stack of layers.
|
||||||
|
* Ownership is not transferred to the caller.
|
||||||
|
*/
|
||||||
|
const lowest_layer_type& lowest_layer() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign an existing native pipe to the pipe.
|
||||||
|
/*
|
||||||
|
* This function opens the pipe to hold an existing native pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void assign(const native_handle_type& native_pipe)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(), native_pipe, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign an existing native pipe to the pipe.
|
||||||
|
/*
|
||||||
|
* This function opens the pipe to hold an existing native pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_pipe,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(), native_pipe, ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the pipe is open.
|
||||||
|
bool is_open() const
|
||||||
|
{
|
||||||
|
return impl_.get_service().is_open(impl_.get_implementation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to close the pipe. Any asynchronous read operations
|
||||||
|
* will be cancelled immediately, and will complete with the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "close");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to close the pipe. Any asynchronous read operations
|
||||||
|
* will be cancelled immediately, and will complete with the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the native pipe representation.
|
||||||
|
/**
|
||||||
|
* This function may be used to obtain the underlying representation of the
|
||||||
|
* pipe. This is intended to allow access to native pipe
|
||||||
|
* functionality that is not otherwise provided.
|
||||||
|
*/
|
||||||
|
native_handle_type native_handle()
|
||||||
|
{
|
||||||
|
return impl_.get_service().native_handle(impl_.get_implementation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel all asynchronous operations associated with the pipe.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous read operations to finish
|
||||||
|
* immediately, and the handlers for cancelled operations will be passed the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void cancel()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "cancel");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel all asynchronous operations associated with the pipe.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous read operations to finish
|
||||||
|
* immediately, and the handlers for cancelled operations will be passed the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read some data from the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to read data from the pipe. The function call will
|
||||||
|
* block until one or more bytes of data has been read successfully, or until
|
||||||
|
* an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes read.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure. An error code of
|
||||||
|
* boost::asio::error::eof indicates that the connection was closed by the
|
||||||
|
* peer.
|
||||||
|
*
|
||||||
|
* @note The read_some operation may not read all of the requested number of
|
||||||
|
* bytes. Consider using the @ref read function if you need to ensure that
|
||||||
|
* the requested amount of data is read before the blocking operation
|
||||||
|
* completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* basic_readable_pipe.read_some(boost::asio::buffer(data, size));
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on reading into multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence>
|
||||||
|
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
std::size_t s = impl_.get_service().read_some(
|
||||||
|
impl_.get_implementation(), buffers, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "read_some");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read some data from the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to read data from the pipe. The function call will
|
||||||
|
* block until one or more bytes of data has been read successfully, or until
|
||||||
|
* an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes read. Returns 0 if an error occurred.
|
||||||
|
*
|
||||||
|
* @note The read_some operation may not read all of the requested number of
|
||||||
|
* bytes. Consider using the @ref read function if you need to ensure that
|
||||||
|
* the requested amount of data is read before the blocking operation
|
||||||
|
* completes.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence>
|
||||||
|
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return impl_.get_service().read_some(
|
||||||
|
impl_.get_implementation(), buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start an asynchronous read.
|
||||||
|
/**
|
||||||
|
* This function is used to asynchronously read data from the pipe. The
|
||||||
|
* function call always returns immediately.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param handler The handler to be called when the read operation completes.
|
||||||
|
* Copies will be made of the handler as required. The function signature of
|
||||||
|
* the handler must be:
|
||||||
|
* @code void handler(
|
||||||
|
* const boost::system::error_code& error, // Result of operation.
|
||||||
|
* std::size_t bytes_transferred // Number of bytes read.
|
||||||
|
* ); @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
|
||||||
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @note The read operation may not read all of the requested number of bytes.
|
||||||
|
* Consider using the @ref async_read function if you need to ensure that the
|
||||||
|
* requested amount of data is read before the asynchronous operation
|
||||||
|
* completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* basic_readable_pipe.async_read_some(
|
||||||
|
* boost::asio::buffer(data, size), handler);
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on reading into multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence,
|
||||||
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
std::size_t)) ReadHandler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||||
|
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
|
||||||
|
void (boost::system::error_code, std::size_t))
|
||||||
|
async_read_some(const MutableBufferSequence& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||||
|
{
|
||||||
|
return async_initiate<ReadHandler,
|
||||||
|
void (boost::system::error_code, std::size_t)>(
|
||||||
|
initiate_async_read_some(this), handler, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copying and assignment.
|
||||||
|
basic_readable_pipe(const basic_readable_pipe&) BOOST_ASIO_DELETED;
|
||||||
|
basic_readable_pipe& operator=(const basic_readable_pipe&) BOOST_ASIO_DELETED;
|
||||||
|
|
||||||
|
class initiate_async_read_some
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
explicit initiate_async_read_some(basic_readable_pipe* self)
|
||||||
|
: self_(self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return self_->get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReadHandler, typename MutableBufferSequence>
|
||||||
|
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||||
|
const MutableBufferSequence& buffers) const
|
||||||
|
{
|
||||||
|
// If you get an error on the following line it means that your handler
|
||||||
|
// does not meet the documented type requirements for a ReadHandler.
|
||||||
|
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||||
|
|
||||||
|
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||||
|
self_->impl_.get_service().async_read_some(
|
||||||
|
self_->impl_.get_implementation(), buffers,
|
||||||
|
handler2.value, self_->impl_.get_executor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
basic_readable_pipe* self_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
detail::io_object_impl<detail::win_iocp_handle_service, Executor> impl_;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
detail::io_object_impl<detail::io_uring_descriptor_service, Executor> impl_;
|
||||||
|
#else
|
||||||
|
detail::io_object_impl<detail::reactive_descriptor_service, Executor> impl_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_PIPE)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_BASIC_READABLE_PIPE_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_seq_packet_socket.hpp
|
// basic_seq_packet_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -44,6 +44,12 @@ class basic_seq_packet_socket;
|
||||||
* @par Thread Safety
|
* @par Thread Safety
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
|
*
|
||||||
|
* Synchronous @c send, @c receive, 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.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor>
|
template <typename Protocol, typename Executor>
|
||||||
class basic_seq_packet_socket
|
class basic_seq_packet_socket
|
||||||
|
|
@ -101,9 +107,9 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_seq_packet_socket(ExecutionContext& context,
|
explicit basic_seq_packet_socket(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context)
|
: basic_socket<Protocol, Executor>(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -144,9 +150,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_seq_packet_socket(ExecutionContext& context,
|
basic_seq_packet_socket(ExecutionContext& context,
|
||||||
const protocol_type& protocol,
|
const protocol_type& protocol,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
: basic_socket<Protocol, Executor>(context, protocol)
|
: basic_socket<Protocol, Executor>(context, protocol)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -191,9 +198,9 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_seq_packet_socket(ExecutionContext& context,
|
basic_seq_packet_socket(ExecutionContext& context,
|
||||||
const endpoint_type& endpoint,
|
const endpoint_type& endpoint,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -236,9 +243,9 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_seq_packet_socket(ExecutionContext& context,
|
basic_seq_packet_socket(ExecutionContext& context,
|
||||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -294,10 +301,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
|
basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value
|
&& is_convertible<Executor1, Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(std::move(other))
|
: basic_socket<Protocol, Executor>(std::move(other))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +323,7 @@ public:
|
||||||
* constructor.
|
* constructor.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value,
|
&& is_convertible<Executor1, Executor>::value,
|
||||||
basic_seq_packet_socket&
|
basic_seq_packet_socket&
|
||||||
|
|
@ -428,6 +435,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -601,6 +618,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -660,6 +687,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_serial_port.hpp
|
// basic_serial_port.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
|
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
# include <boost/asio/detail/win_iocp_serial_port_service.hpp>
|
# include <boost/asio/detail/win_iocp_serial_port_service.hpp>
|
||||||
#else
|
#else
|
||||||
# include <boost/asio/detail/reactive_serial_port_service.hpp>
|
# include <boost/asio/detail/posix_serial_port_service.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
|
@ -79,7 +79,7 @@ public:
|
||||||
typedef detail::win_iocp_serial_port_service::native_handle_type
|
typedef detail::win_iocp_serial_port_service::native_handle_type
|
||||||
native_handle_type;
|
native_handle_type;
|
||||||
#else
|
#else
|
||||||
typedef detail::reactive_serial_port_service::native_handle_type
|
typedef detail::posix_serial_port_service::native_handle_type
|
||||||
native_handle_type;
|
native_handle_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ public:
|
||||||
* serial port.
|
* serial port.
|
||||||
*/
|
*/
|
||||||
explicit basic_serial_port(const executor_type& ex)
|
explicit basic_serial_port(const executor_type& ex)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,11 +109,11 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_serial_port(ExecutionContext& context,
|
explicit basic_serial_port(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value,
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
basic_serial_port
|
defaulted_constraint
|
||||||
>::type* = 0)
|
>::type = defaulted_constraint())
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +130,7 @@ public:
|
||||||
* port.
|
* port.
|
||||||
*/
|
*/
|
||||||
basic_serial_port(const executor_type& ex, const char* device)
|
basic_serial_port(const executor_type& ex, const char* device)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||||
|
|
@ -151,10 +151,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_serial_port(ExecutionContext& context, const char* device,
|
basic_serial_port(ExecutionContext& context, const char* device,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||||
|
|
@ -174,7 +174,7 @@ public:
|
||||||
* port.
|
* port.
|
||||||
*/
|
*/
|
||||||
basic_serial_port(const executor_type& ex, const std::string& device)
|
basic_serial_port(const executor_type& ex, const std::string& device)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||||
|
|
@ -195,10 +195,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_serial_port(ExecutionContext& context, const std::string& device,
|
basic_serial_port(ExecutionContext& context, const std::string& device,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
impl_.get_service().open(impl_.get_implementation(), device, ec);
|
||||||
|
|
@ -220,7 +220,7 @@ public:
|
||||||
*/
|
*/
|
||||||
basic_serial_port(const executor_type& ex,
|
basic_serial_port(const executor_type& ex,
|
||||||
const native_handle_type& native_serial_port)
|
const native_handle_type& native_serial_port)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().assign(impl_.get_implementation(),
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
|
@ -244,10 +244,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_serial_port(ExecutionContext& context,
|
basic_serial_port(ExecutionContext& context,
|
||||||
const native_handle_type& native_serial_port,
|
const native_handle_type& native_serial_port,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().assign(impl_.get_implementation(),
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
|
@ -894,7 +894,7 @@ private:
|
||||||
#if defined(BOOST_ASIO_HAS_IOCP)
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_;
|
detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_;
|
||||||
#else
|
#else
|
||||||
detail::io_object_impl<detail::reactive_serial_port_service, Executor> impl_;
|
detail::io_object_impl<detail::posix_serial_port_service, Executor> impl_;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_signal_set.hpp
|
// basic_signal_set.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
#include <boost/asio/error.hpp>
|
#include <boost/asio/error.hpp>
|
||||||
#include <boost/asio/execution_context.hpp>
|
#include <boost/asio/execution_context.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
|
|
@ -115,7 +117,7 @@ public:
|
||||||
* signal set.
|
* signal set.
|
||||||
*/
|
*/
|
||||||
explicit basic_signal_set(const executor_type& ex)
|
explicit basic_signal_set(const executor_type& ex)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,10 +131,11 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_signal_set(ExecutionContext& context,
|
explicit basic_signal_set(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
: impl_(context)
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +154,7 @@ public:
|
||||||
* signals.add(signal_number_1); @endcode
|
* signals.add(signal_number_1); @endcode
|
||||||
*/
|
*/
|
||||||
basic_signal_set(const executor_type& ex, int signal_number_1)
|
basic_signal_set(const executor_type& ex, int signal_number_1)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||||
|
|
@ -174,10 +177,11 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
: impl_(context)
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||||
|
|
@ -203,7 +207,7 @@ public:
|
||||||
*/
|
*/
|
||||||
basic_signal_set(const executor_type& ex, int signal_number_1,
|
basic_signal_set(const executor_type& ex, int signal_number_1,
|
||||||
int signal_number_2)
|
int signal_number_2)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||||
|
|
@ -232,10 +236,11 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
||||||
int signal_number_2,
|
int signal_number_2,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
: impl_(context)
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||||
|
|
@ -266,7 +271,7 @@ public:
|
||||||
*/
|
*/
|
||||||
basic_signal_set(const executor_type& ex, int signal_number_1,
|
basic_signal_set(const executor_type& ex, int signal_number_1,
|
||||||
int signal_number_2, int signal_number_3)
|
int signal_number_2, int signal_number_3)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||||
|
|
@ -300,10 +305,11 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
basic_signal_set(ExecutionContext& context, int signal_number_1,
|
||||||
int signal_number_2, int signal_number_3,
|
int signal_number_2, int signal_number_3,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
: impl_(context)
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
|
||||||
|
|
@ -567,4 +573,6 @@ private:
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
#endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP
|
#endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_socket.hpp
|
// basic_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -32,6 +32,8 @@
|
||||||
# include <boost/asio/detail/null_socket_service.hpp>
|
# include <boost/asio/detail/null_socket_service.hpp>
|
||||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
# include <boost/asio/detail/win_iocp_socket_service.hpp>
|
# include <boost/asio/detail/win_iocp_socket_service.hpp>
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
# include <boost/asio/detail/io_uring_socket_service.hpp>
|
||||||
#else
|
#else
|
||||||
# include <boost/asio/detail/reactive_socket_service.hpp>
|
# include <boost/asio/detail/reactive_socket_service.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -88,6 +90,9 @@ public:
|
||||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
typedef typename detail::win_iocp_socket_service<
|
typedef typename detail::win_iocp_socket_service<
|
||||||
Protocol>::native_handle_type native_handle_type;
|
Protocol>::native_handle_type native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
typedef typename detail::io_uring_socket_service<
|
||||||
|
Protocol>::native_handle_type native_handle_type;
|
||||||
#else
|
#else
|
||||||
typedef typename detail::reactive_socket_service<
|
typedef typename detail::reactive_socket_service<
|
||||||
Protocol>::native_handle_type native_handle_type;
|
Protocol>::native_handle_type native_handle_type;
|
||||||
|
|
@ -112,7 +117,7 @@ public:
|
||||||
* dispatch handlers for any asynchronous operations performed on the socket.
|
* dispatch handlers for any asynchronous operations performed on the socket.
|
||||||
*/
|
*/
|
||||||
explicit basic_socket(const executor_type& ex)
|
explicit basic_socket(const executor_type& ex)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,10 +131,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_socket(ExecutionContext& context,
|
explicit basic_socket(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,7 +150,7 @@ public:
|
||||||
* @throws boost::system::system_error Thrown on failure.
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket(const executor_type& ex, const protocol_type& protocol)
|
basic_socket(const executor_type& ex, const protocol_type& protocol)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
||||||
|
|
@ -166,10 +171,11 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_socket(ExecutionContext& context, const protocol_type& protocol,
|
basic_socket(ExecutionContext& context, const protocol_type& protocol,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
: impl_(context)
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
||||||
|
|
@ -192,7 +198,7 @@ public:
|
||||||
* @throws boost::system::system_error Thrown on failure.
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket(const executor_type& ex, const endpoint_type& endpoint)
|
basic_socket(const executor_type& ex, const endpoint_type& endpoint)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
const protocol_type protocol = endpoint.protocol();
|
const protocol_type protocol = endpoint.protocol();
|
||||||
|
|
@ -220,10 +226,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
basic_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
const protocol_type protocol = endpoint.protocol();
|
const protocol_type protocol = endpoint.protocol();
|
||||||
|
|
@ -248,7 +254,7 @@ public:
|
||||||
*/
|
*/
|
||||||
basic_socket(const executor_type& ex, const protocol_type& protocol,
|
basic_socket(const executor_type& ex, const protocol_type& protocol,
|
||||||
const native_handle_type& native_socket)
|
const native_handle_type& native_socket)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().assign(impl_.get_implementation(),
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
|
@ -273,10 +279,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_socket(ExecutionContext& context, const protocol_type& protocol,
|
basic_socket(ExecutionContext& context, const protocol_type& protocol,
|
||||||
const native_handle_type& native_socket,
|
const native_handle_type& native_socket,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().assign(impl_.get_implementation(),
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
|
@ -332,10 +338,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
basic_socket(basic_socket<Protocol1, Executor1>&& other,
|
basic_socket(basic_socket<Protocol1, Executor1>&& other,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value
|
&& is_convertible<Executor1, Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(std::move(other.impl_))
|
: impl_(std::move(other.impl_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -351,7 +357,7 @@ public:
|
||||||
* constructed using the @c basic_socket(const executor_type&) constructor.
|
* constructed using the @c basic_socket(const executor_type&) constructor.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value,
|
&& is_convertible<Executor1, Executor>::value,
|
||||||
basic_socket&
|
basic_socket&
|
||||||
|
|
@ -939,6 +945,16 @@ public:
|
||||||
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
|
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
|
||||||
* socket.async_connect(endpoint, connect_handler);
|
* socket.async_connect(endpoint, connect_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||||
|
|
@ -1772,6 +1788,16 @@ public:
|
||||||
* ...
|
* ...
|
||||||
* socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
|
* socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||||
|
|
@ -1802,6 +1828,9 @@ protected:
|
||||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
detail::io_object_impl<
|
detail::io_object_impl<
|
||||||
detail::win_iocp_socket_service<Protocol>, Executor> impl_;
|
detail::win_iocp_socket_service<Protocol>, Executor> impl_;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
detail::io_object_impl<
|
||||||
|
detail::io_uring_socket_service<Protocol>, Executor> impl_;
|
||||||
#else
|
#else
|
||||||
detail::io_object_impl<
|
detail::io_object_impl<
|
||||||
detail::reactive_socket_service<Protocol>, Executor> impl_;
|
detail::reactive_socket_service<Protocol>, Executor> impl_;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_socket_acceptor.hpp
|
// basic_socket_acceptor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
# include <boost/asio/detail/null_socket_service.hpp>
|
# include <boost/asio/detail/null_socket_service.hpp>
|
||||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
# include <boost/asio/detail/win_iocp_socket_service.hpp>
|
# include <boost/asio/detail/win_iocp_socket_service.hpp>
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
# include <boost/asio/detail/io_uring_socket_service.hpp>
|
||||||
#else
|
#else
|
||||||
# include <boost/asio/detail/reactive_socket_service.hpp>
|
# include <boost/asio/detail/reactive_socket_service.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -62,6 +64,12 @@ class basic_socket_acceptor;
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
|
* Synchronous @c accept operations are thread safe, if the underlying
|
||||||
|
* operating system calls are also thread safe. This means that it is permitted
|
||||||
|
* to perform concurrent calls to synchronous @c accept operations on a single
|
||||||
|
* socket object. Other synchronous operations, such as @c open or @c close, are
|
||||||
|
* not thread safe.
|
||||||
|
*
|
||||||
* @par Example
|
* @par Example
|
||||||
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
|
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
|
||||||
* @code
|
* @code
|
||||||
|
|
@ -98,6 +106,9 @@ public:
|
||||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
typedef typename detail::win_iocp_socket_service<
|
typedef typename detail::win_iocp_socket_service<
|
||||||
Protocol>::native_handle_type native_handle_type;
|
Protocol>::native_handle_type native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
typedef typename detail::io_uring_socket_service<
|
||||||
|
Protocol>::native_handle_type native_handle_type;
|
||||||
#else
|
#else
|
||||||
typedef typename detail::reactive_socket_service<
|
typedef typename detail::reactive_socket_service<
|
||||||
Protocol>::native_handle_type native_handle_type;
|
Protocol>::native_handle_type native_handle_type;
|
||||||
|
|
@ -120,7 +131,7 @@ public:
|
||||||
* acceptor.
|
* acceptor.
|
||||||
*/
|
*/
|
||||||
explicit basic_socket_acceptor(const executor_type& ex)
|
explicit basic_socket_acceptor(const executor_type& ex)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,10 +147,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_socket_acceptor(ExecutionContext& context,
|
explicit basic_socket_acceptor(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,7 +167,7 @@ public:
|
||||||
* @throws boost::system::system_error Thrown on failure.
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol)
|
basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
||||||
|
|
@ -178,10 +189,11 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_socket_acceptor(ExecutionContext& context,
|
basic_socket_acceptor(ExecutionContext& context,
|
||||||
const protocol_type& protocol,
|
const protocol_type& protocol,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
: impl_(context)
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
|
||||||
|
|
@ -217,7 +229,7 @@ public:
|
||||||
*/
|
*/
|
||||||
basic_socket_acceptor(const executor_type& ex,
|
basic_socket_acceptor(const executor_type& ex,
|
||||||
const endpoint_type& endpoint, bool reuse_addr = true)
|
const endpoint_type& endpoint, bool reuse_addr = true)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
const protocol_type protocol = endpoint.protocol();
|
const protocol_type protocol = endpoint.protocol();
|
||||||
|
|
@ -266,10 +278,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_socket_acceptor(ExecutionContext& context,
|
basic_socket_acceptor(ExecutionContext& context,
|
||||||
const endpoint_type& endpoint, bool reuse_addr = true,
|
const endpoint_type& endpoint, bool reuse_addr = true,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
const protocol_type protocol = endpoint.protocol();
|
const protocol_type protocol = endpoint.protocol();
|
||||||
|
|
@ -305,7 +317,7 @@ public:
|
||||||
*/
|
*/
|
||||||
basic_socket_acceptor(const executor_type& ex,
|
basic_socket_acceptor(const executor_type& ex,
|
||||||
const protocol_type& protocol, const native_handle_type& native_acceptor)
|
const protocol_type& protocol, const native_handle_type& native_acceptor)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().assign(impl_.get_implementation(),
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
|
@ -331,10 +343,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_socket_acceptor(ExecutionContext& context,
|
basic_socket_acceptor(ExecutionContext& context,
|
||||||
const protocol_type& protocol, const native_handle_type& native_acceptor,
|
const protocol_type& protocol, const native_handle_type& native_acceptor,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().assign(impl_.get_implementation(),
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
|
@ -394,10 +406,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,
|
basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value
|
&& is_convertible<Executor1, Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(std::move(other.impl_))
|
: impl_(std::move(other.impl_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -415,7 +427,7 @@ public:
|
||||||
* constructor.
|
* constructor.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value,
|
&& is_convertible<Executor1, Executor>::value,
|
||||||
basic_socket_acceptor&
|
basic_socket_acceptor&
|
||||||
|
|
@ -1218,6 +1230,16 @@ public:
|
||||||
* boost::asio::ip::tcp::acceptor::wait_read,
|
* boost::asio::ip::tcp::acceptor::wait_read,
|
||||||
* wait_handler);
|
* wait_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||||
|
|
@ -1253,9 +1275,9 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
void accept(basic_socket<Protocol1, Executor1>& peer,
|
void accept(basic_socket<Protocol1, Executor1>& peer,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol, Protocol1>::value
|
is_convertible<Protocol, Protocol1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().accept(impl_.get_implementation(),
|
impl_.get_service().accept(impl_.get_implementation(),
|
||||||
|
|
@ -1289,9 +1311,9 @@ public:
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
BOOST_ASIO_SYNC_OP_VOID accept(
|
BOOST_ASIO_SYNC_OP_VOID accept(
|
||||||
basic_socket<Protocol1, Executor1>& peer, boost::system::error_code& ec,
|
basic_socket<Protocol1, Executor1>& peer, boost::system::error_code& ec,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol, Protocol1>::value
|
is_convertible<Protocol, Protocol1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
impl_.get_service().accept(impl_.get_implementation(),
|
impl_.get_service().accept(impl_.get_implementation(),
|
||||||
peer, static_cast<endpoint_type*>(0), ec);
|
peer, static_cast<endpoint_type*>(0), ec);
|
||||||
|
|
@ -1335,6 +1357,16 @@ public:
|
||||||
* boost::asio::ip::tcp::socket socket(my_context);
|
* boost::asio::ip::tcp::socket socket(my_context);
|
||||||
* acceptor.async_accept(socket, accept_handler);
|
* acceptor.async_accept(socket, accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1,
|
template <typename Protocol1, typename Executor1,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||||
|
|
@ -1344,9 +1376,9 @@ public:
|
||||||
async_accept(basic_socket<Protocol1, Executor1>& peer,
|
async_accept(basic_socket<Protocol1, Executor1>& peer,
|
||||||
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler
|
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol, Protocol1>::value
|
is_convertible<Protocol, Protocol1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
return async_initiate<AcceptHandler, void (boost::system::error_code)>(
|
return async_initiate<AcceptHandler, void (boost::system::error_code)>(
|
||||||
initiate_async_accept(this), handler,
|
initiate_async_accept(this), handler,
|
||||||
|
|
@ -1448,6 +1480,16 @@ public:
|
||||||
* not, the handler will not be invoked from within this function. On
|
* not, the handler will not be invoked from within this function. On
|
||||||
* immediate completion, invocation of the handler will be performed in a
|
* immediate completion, invocation of the handler will be performed in a
|
||||||
* manner equivalent to using boost::asio::post().
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename Executor1,
|
template <typename Executor1,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||||
|
|
@ -1570,6 +1612,16 @@ public:
|
||||||
* ...
|
* ...
|
||||||
* acceptor.async_accept(accept_handler);
|
* acceptor.async_accept(accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -1619,10 +1671,10 @@ public:
|
||||||
template <typename Executor1>
|
template <typename Executor1>
|
||||||
typename Protocol::socket::template rebind_executor<Executor1>::other
|
typename Protocol::socket::template rebind_executor<Executor1>::other
|
||||||
accept(const Executor1& ex,
|
accept(const Executor1& ex,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor1>::value
|
is_executor<Executor1>::value
|
||||||
|| execution::is_executor<Executor1>::value
|
|| execution::is_executor<Executor1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
typename Protocol::socket::template
|
typename Protocol::socket::template
|
||||||
|
|
@ -1659,9 +1711,9 @@ public:
|
||||||
typename Protocol::socket::template rebind_executor<
|
typename Protocol::socket::template rebind_executor<
|
||||||
typename ExecutionContext::executor_type>::other
|
typename ExecutionContext::executor_type>::other
|
||||||
accept(ExecutionContext& context,
|
accept(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
typename Protocol::socket::template rebind_executor<
|
typename Protocol::socket::template rebind_executor<
|
||||||
|
|
@ -1702,10 +1754,10 @@ public:
|
||||||
template <typename Executor1>
|
template <typename Executor1>
|
||||||
typename Protocol::socket::template rebind_executor<Executor1>::other
|
typename Protocol::socket::template rebind_executor<Executor1>::other
|
||||||
accept(const Executor1& ex, boost::system::error_code& ec,
|
accept(const Executor1& ex, boost::system::error_code& ec,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor1>::value
|
is_executor<Executor1>::value
|
||||||
|| execution::is_executor<Executor1>::value
|
|| execution::is_executor<Executor1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typename Protocol::socket::template
|
typename Protocol::socket::template
|
||||||
rebind_executor<Executor1>::other peer(ex);
|
rebind_executor<Executor1>::other peer(ex);
|
||||||
|
|
@ -1745,9 +1797,9 @@ public:
|
||||||
typename Protocol::socket::template rebind_executor<
|
typename Protocol::socket::template rebind_executor<
|
||||||
typename ExecutionContext::executor_type>::other
|
typename ExecutionContext::executor_type>::other
|
||||||
accept(ExecutionContext& context, boost::system::error_code& ec,
|
accept(ExecutionContext& context, boost::system::error_code& ec,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typename Protocol::socket::template rebind_executor<
|
typename Protocol::socket::template rebind_executor<
|
||||||
typename ExecutionContext::executor_type>::other peer(context);
|
typename ExecutionContext::executor_type>::other peer(context);
|
||||||
|
|
@ -1796,6 +1848,16 @@ public:
|
||||||
* ...
|
* ...
|
||||||
* acceptor.async_accept(my_context2, accept_handler);
|
* acceptor.async_accept(my_context2, accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename Executor1,
|
template <typename Executor1,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -1809,10 +1871,10 @@ public:
|
||||||
async_accept(const Executor1& ex,
|
async_accept(const Executor1& ex,
|
||||||
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor1>::value
|
is_executor<Executor1>::value
|
||||||
|| execution::is_executor<Executor1>::value
|
|| execution::is_executor<Executor1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typedef typename Protocol::socket::template rebind_executor<
|
typedef typename Protocol::socket::template rebind_executor<
|
||||||
Executor1>::other other_socket_type;
|
Executor1>::other other_socket_type;
|
||||||
|
|
@ -1866,6 +1928,16 @@ public:
|
||||||
* ...
|
* ...
|
||||||
* acceptor.async_accept(my_context2, accept_handler);
|
* acceptor.async_accept(my_context2, accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext,
|
template <typename ExecutionContext,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -1879,9 +1951,9 @@ public:
|
||||||
async_accept(ExecutionContext& context,
|
async_accept(ExecutionContext& context,
|
||||||
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typedef typename Protocol::socket::template rebind_executor<
|
typedef typename Protocol::socket::template rebind_executor<
|
||||||
typename ExecutionContext::executor_type>::other other_socket_type;
|
typename ExecutionContext::executor_type>::other other_socket_type;
|
||||||
|
|
@ -2014,6 +2086,16 @@ public:
|
||||||
* boost::asio::ip::tcp::endpoint endpoint;
|
* boost::asio::ip::tcp::endpoint endpoint;
|
||||||
* acceptor.async_accept(endpoint, accept_handler);
|
* acceptor.async_accept(endpoint, accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -2068,10 +2150,10 @@ public:
|
||||||
template <typename Executor1>
|
template <typename Executor1>
|
||||||
typename Protocol::socket::template rebind_executor<Executor1>::other
|
typename Protocol::socket::template rebind_executor<Executor1>::other
|
||||||
accept(const Executor1& ex, endpoint_type& peer_endpoint,
|
accept(const Executor1& ex, endpoint_type& peer_endpoint,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor1>::value
|
is_executor<Executor1>::value
|
||||||
|| execution::is_executor<Executor1>::value
|
|| execution::is_executor<Executor1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
typename Protocol::socket::template
|
typename Protocol::socket::template
|
||||||
|
|
@ -2114,9 +2196,9 @@ public:
|
||||||
typename Protocol::socket::template rebind_executor<
|
typename Protocol::socket::template rebind_executor<
|
||||||
typename ExecutionContext::executor_type>::other
|
typename ExecutionContext::executor_type>::other
|
||||||
accept(ExecutionContext& context, endpoint_type& peer_endpoint,
|
accept(ExecutionContext& context, endpoint_type& peer_endpoint,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
typename Protocol::socket::template rebind_executor<
|
typename Protocol::socket::template rebind_executor<
|
||||||
|
|
@ -2164,10 +2246,10 @@ public:
|
||||||
typename Protocol::socket::template rebind_executor<Executor1>::other
|
typename Protocol::socket::template rebind_executor<Executor1>::other
|
||||||
accept(const executor_type& ex,
|
accept(const executor_type& ex,
|
||||||
endpoint_type& peer_endpoint, boost::system::error_code& ec,
|
endpoint_type& peer_endpoint, boost::system::error_code& ec,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor1>::value
|
is_executor<Executor1>::value
|
||||||
|| execution::is_executor<Executor1>::value
|
|| execution::is_executor<Executor1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typename Protocol::socket::template
|
typename Protocol::socket::template
|
||||||
rebind_executor<Executor1>::other peer(ex);
|
rebind_executor<Executor1>::other peer(ex);
|
||||||
|
|
@ -2214,9 +2296,9 @@ public:
|
||||||
typename ExecutionContext::executor_type>::other
|
typename ExecutionContext::executor_type>::other
|
||||||
accept(ExecutionContext& context,
|
accept(ExecutionContext& context,
|
||||||
endpoint_type& peer_endpoint, boost::system::error_code& ec,
|
endpoint_type& peer_endpoint, boost::system::error_code& ec,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typename Protocol::socket::template rebind_executor<
|
typename Protocol::socket::template rebind_executor<
|
||||||
typename ExecutionContext::executor_type>::other peer(context);
|
typename ExecutionContext::executor_type>::other peer(context);
|
||||||
|
|
@ -2272,6 +2354,16 @@ public:
|
||||||
* boost::asio::ip::tcp::endpoint endpoint;
|
* boost::asio::ip::tcp::endpoint endpoint;
|
||||||
* acceptor.async_accept(my_context2, endpoint, accept_handler);
|
* acceptor.async_accept(my_context2, endpoint, accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename Executor1,
|
template <typename Executor1,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -2285,10 +2377,10 @@ public:
|
||||||
async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
|
async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
|
||||||
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor1>::value
|
is_executor<Executor1>::value
|
||||||
|| execution::is_executor<Executor1>::value
|
|| execution::is_executor<Executor1>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typedef typename Protocol::socket::template rebind_executor<
|
typedef typename Protocol::socket::template rebind_executor<
|
||||||
Executor1>::other other_socket_type;
|
Executor1>::other other_socket_type;
|
||||||
|
|
@ -2348,6 +2440,16 @@ public:
|
||||||
* boost::asio::ip::tcp::endpoint endpoint;
|
* boost::asio::ip::tcp::endpoint endpoint;
|
||||||
* acceptor.async_accept(my_context2, endpoint, accept_handler);
|
* acceptor.async_accept(my_context2, endpoint, accept_handler);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext,
|
template <typename ExecutionContext,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -2362,9 +2464,9 @@ public:
|
||||||
endpoint_type& peer_endpoint,
|
endpoint_type& peer_endpoint,
|
||||||
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
typedef typename Protocol::socket::template rebind_executor<
|
typedef typename Protocol::socket::template rebind_executor<
|
||||||
typename ExecutionContext::executor_type>::other other_socket_type;
|
typename ExecutionContext::executor_type>::other other_socket_type;
|
||||||
|
|
@ -2489,6 +2591,9 @@ private:
|
||||||
#elif defined(BOOST_ASIO_HAS_IOCP)
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
detail::io_object_impl<
|
detail::io_object_impl<
|
||||||
detail::win_iocp_socket_service<Protocol>, Executor> impl_;
|
detail::win_iocp_socket_service<Protocol>, Executor> impl_;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
detail::io_object_impl<
|
||||||
|
detail::io_uring_socket_service<Protocol>, Executor> impl_;
|
||||||
#else
|
#else
|
||||||
detail::io_object_impl<
|
detail::io_object_impl<
|
||||||
detail::reactive_socket_service<Protocol>, Executor> impl_;
|
detail::reactive_socket_service<Protocol>, Executor> impl_;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_socket_iostream.hpp
|
// basic_socket_iostream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_socket_streambuf.hpp
|
// basic_socket_streambuf.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,732 @@
|
||||||
|
//
|
||||||
|
// basic_stream_file.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_BASIC_STREAM_FILE_HPP
|
||||||
|
#define BOOST_ASIO_BASIC_STREAM_FILE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_FILE) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <boost/asio/async_result.hpp>
|
||||||
|
#include <boost/asio/basic_file.hpp>
|
||||||
|
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||||
|
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||||
|
#include <boost/asio/detail/throw_error.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
#if !defined(BOOST_ASIO_BASIC_STREAM_FILE_FWD_DECL)
|
||||||
|
#define BOOST_ASIO_BASIC_STREAM_FILE_FWD_DECL
|
||||||
|
|
||||||
|
// Forward declaration with defaulted arguments.
|
||||||
|
template <typename Executor = any_io_executor>
|
||||||
|
class basic_stream_file;
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_ASIO_BASIC_STREAM_FILE_FWD_DECL)
|
||||||
|
|
||||||
|
/// Provides stream-oriented file functionality.
|
||||||
|
/**
|
||||||
|
* The basic_stream_file class template provides asynchronous and blocking
|
||||||
|
* stream-oriented file functionality.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* @e Distinct @e objects: Safe.@n
|
||||||
|
* @e Shared @e objects: Unsafe.
|
||||||
|
*
|
||||||
|
* @par Concepts:
|
||||||
|
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||||
|
*/
|
||||||
|
template <typename Executor>
|
||||||
|
class basic_stream_file
|
||||||
|
: public basic_file<Executor>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The type of the executor associated with the object.
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
/// Rebinds the file type to another executor.
|
||||||
|
template <typename Executor1>
|
||||||
|
struct rebind_executor
|
||||||
|
{
|
||||||
|
/// The file type when rebound to the specified executor.
|
||||||
|
typedef basic_stream_file<Executor1> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The native representation of a file.
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
typedef implementation_defined native_handle_type;
|
||||||
|
#else
|
||||||
|
typedef typename basic_file<Executor>::native_handle_type native_handle_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Construct a basic_stream_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file without opening it. The file needs to
|
||||||
|
* be opened before data can be read from or or written to it.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*/
|
||||||
|
explicit basic_stream_file(const executor_type& ex)
|
||||||
|
: basic_file<Executor>(ex)
|
||||||
|
{
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_stream_file without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a file without opening it. The file needs to
|
||||||
|
* be opened before data can be read from or or written to it.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
explicit basic_stream_file(ExecutionContext& context,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context)
|
||||||
|
{
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_stream_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_stream_file(const executor_type& ex,
|
||||||
|
const char* path, file_base::flags open_flags)
|
||||||
|
: basic_file<Executor>(ex)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
this->impl_.get_service().open(
|
||||||
|
this->impl_.get_implementation(),
|
||||||
|
path, open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_stream_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_stream_file(ExecutionContext& context,
|
||||||
|
const char* path, file_base::flags open_flags,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
this->impl_.get_service().open(
|
||||||
|
this->impl_.get_implementation(),
|
||||||
|
path, open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_stream_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_stream_file(const executor_type& ex,
|
||||||
|
const std::string& path, file_base::flags open_flags)
|
||||||
|
: basic_file<Executor>(ex)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
this->impl_.get_service().open(
|
||||||
|
this->impl_.get_implementation(),
|
||||||
|
path.c_str(), open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and open a basic_stream_file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises and opens a file.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param path The path name identifying the file to be opened.
|
||||||
|
*
|
||||||
|
* @param open_flags A set of flags that determine how the file should be
|
||||||
|
* opened.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_stream_file(ExecutionContext& context,
|
||||||
|
const std::string& path, file_base::flags open_flags,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
this->impl_.get_service().open(
|
||||||
|
this->impl_.get_implementation(),
|
||||||
|
path.c_str(), open_flags, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_stream_file on an existing native file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a stream file object to hold an existing
|
||||||
|
* native file.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the file will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param native_file The new underlying file implementation.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_stream_file(const executor_type& ex,
|
||||||
|
const native_handle_type& native_file)
|
||||||
|
: basic_file<Executor>(ex, native_file)
|
||||||
|
{
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_stream_file on an existing native file.
|
||||||
|
/**
|
||||||
|
* This constructor initialises a stream file object to hold an existing
|
||||||
|
* native file.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the file will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the file.
|
||||||
|
*
|
||||||
|
* @param native_file The new underlying file implementation.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_stream_file(ExecutionContext& context,
|
||||||
|
const native_handle_type& native_file,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(context, native_file)
|
||||||
|
{
|
||||||
|
this->impl_.get_service().set_is_stream(
|
||||||
|
this->impl_.get_implementation(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move-construct a basic_stream_file from another.
|
||||||
|
/**
|
||||||
|
* This constructor moves a stream file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_stream_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_stream_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_stream_file(basic_stream_file&& other) BOOST_ASIO_NOEXCEPT
|
||||||
|
: basic_file<Executor>(std::move(other))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_stream_file from another.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a stream file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_stream_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_stream_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_stream_file& operator=(basic_stream_file&& other)
|
||||||
|
{
|
||||||
|
basic_file<Executor>::operator=(std::move(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-construct a basic_stream_file from a file of another executor
|
||||||
|
/// type.
|
||||||
|
/**
|
||||||
|
* This constructor moves a stream file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_stream_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_stream_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
template <typename Executor1>
|
||||||
|
basic_stream_file(basic_stream_file<Executor1>&& other,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<Executor1, Executor>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: basic_file<Executor>(std::move(other))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_stream_file from a file of another executor type.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a stream file from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_stream_file object from which the move
|
||||||
|
* will occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_stream_file(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
template <typename Executor1>
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<Executor1, Executor>::value,
|
||||||
|
basic_stream_file&
|
||||||
|
>::type operator=(basic_stream_file<Executor1>&& other)
|
||||||
|
{
|
||||||
|
basic_file<Executor>::operator=(std::move(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Destroys the file.
|
||||||
|
/**
|
||||||
|
* This function destroys the file, cancelling any outstanding asynchronous
|
||||||
|
* operations associated with the file as if by calling @c cancel.
|
||||||
|
*/
|
||||||
|
~basic_stream_file()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Seek to a position in the file.
|
||||||
|
/**
|
||||||
|
* This function updates the current position in the file.
|
||||||
|
*
|
||||||
|
* @param offset The requested position in the file, relative to @c whence.
|
||||||
|
*
|
||||||
|
* @param whence One of @c seek_set, @c seek_cur or @c seek_end.
|
||||||
|
*
|
||||||
|
* @returns The new position relative to the beginning of the file.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
uint64_t seek(int64_t offset, file_base::seek_basis whence)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
uint64_t n = this->impl_.get_service().seek(
|
||||||
|
this->impl_.get_implementation(), offset, whence, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "seek");
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Seek to a position in the file.
|
||||||
|
/**
|
||||||
|
* This function updates the current position in the file.
|
||||||
|
*
|
||||||
|
* @param offset The requested position in the file, relative to @c whence.
|
||||||
|
*
|
||||||
|
* @param whence One of @c seek_set, @c seek_cur or @c seek_end.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @returns The new position relative to the beginning of the file.
|
||||||
|
*/
|
||||||
|
uint64_t seek(int64_t offset, file_base::seek_basis whence,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->impl_.get_service().seek(
|
||||||
|
this->impl_.get_implementation(), offset, whence, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write some data to the file.
|
||||||
|
/**
|
||||||
|
* This function is used to write data to the stream file. The function call
|
||||||
|
* will block until one or more bytes of the data has been written
|
||||||
|
* successfully, or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the file.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes written.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure. An error code of
|
||||||
|
* boost::asio::error::eof indicates that the end of the file was reached.
|
||||||
|
*
|
||||||
|
* @note The write_some operation may not transmit all of the data to the
|
||||||
|
* peer. Consider using the @ref write function if you need to ensure that
|
||||||
|
* all data is written before the blocking operation completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* file.write_some(boost::asio::buffer(data, size));
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on writing multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence>
|
||||||
|
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
std::size_t s = this->impl_.get_service().write_some(
|
||||||
|
this->impl_.get_implementation(), buffers, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "write_some");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write some data to the file.
|
||||||
|
/**
|
||||||
|
* This function is used to write data to the stream file. The function call
|
||||||
|
* will block until one or more bytes of the data has been written
|
||||||
|
* successfully, or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the file.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes written. Returns 0 if an error occurred.
|
||||||
|
*
|
||||||
|
* @note The write_some operation may not transmit all of the data to the
|
||||||
|
* peer. Consider using the @ref write function if you need to ensure that
|
||||||
|
* all data is written before the blocking operation completes.
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence>
|
||||||
|
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->impl_.get_service().write_some(
|
||||||
|
this->impl_.get_implementation(), buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start an asynchronous write.
|
||||||
|
/**
|
||||||
|
* This function is used to asynchronously write data to the stream file.
|
||||||
|
* The function call always returns immediately.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the file.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param handler The handler to be called when the write operation completes.
|
||||||
|
* Copies will be made of the handler as required. The function signature of
|
||||||
|
* the handler must be:
|
||||||
|
* @code void handler(
|
||||||
|
* const boost::system::error_code& error, // Result of operation.
|
||||||
|
* std::size_t bytes_transferred // Number of bytes written.
|
||||||
|
* ); @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
|
||||||
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @note The write operation may not transmit all of the data to the peer.
|
||||||
|
* Consider using the @ref async_write function if you need to ensure that all
|
||||||
|
* data is written before the asynchronous operation completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* file.async_write_some(boost::asio::buffer(data, size), handler);
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on writing multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence,
|
||||||
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
std::size_t)) WriteHandler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||||
|
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
|
||||||
|
void (boost::system::error_code, std::size_t))
|
||||||
|
async_write_some(const ConstBufferSequence& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||||
|
{
|
||||||
|
return async_initiate<WriteHandler,
|
||||||
|
void (boost::system::error_code, std::size_t)>(
|
||||||
|
initiate_async_write_some(this), handler, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read some data from the file.
|
||||||
|
/**
|
||||||
|
* This function is used to read data from the stream file. The function
|
||||||
|
* call will block until one or more bytes of data has been read successfully,
|
||||||
|
* or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes read.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure. An error code of
|
||||||
|
* boost::asio::error::eof indicates that the end of the file was reached.
|
||||||
|
*
|
||||||
|
* @note The read_some operation may not read all of the requested number of
|
||||||
|
* bytes. Consider using the @ref read function if you need to ensure that
|
||||||
|
* the requested amount of data is read before the blocking operation
|
||||||
|
* completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* file.read_some(boost::asio::buffer(data, size));
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on reading into multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence>
|
||||||
|
std::size_t read_some(const MutableBufferSequence& buffers)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
std::size_t s = this->impl_.get_service().read_some(
|
||||||
|
this->impl_.get_implementation(), buffers, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "read_some");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read some data from the file.
|
||||||
|
/**
|
||||||
|
* This function is used to read data from the stream file. The function
|
||||||
|
* call will block until one or more bytes of data has been read successfully,
|
||||||
|
* or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes read. Returns 0 if an error occurred.
|
||||||
|
*
|
||||||
|
* @note The read_some operation may not read all of the requested number of
|
||||||
|
* bytes. Consider using the @ref read function if you need to ensure that
|
||||||
|
* the requested amount of data is read before the blocking operation
|
||||||
|
* completes.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence>
|
||||||
|
std::size_t read_some(const MutableBufferSequence& buffers,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return this->impl_.get_service().read_some(
|
||||||
|
this->impl_.get_implementation(), buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start an asynchronous read.
|
||||||
|
/**
|
||||||
|
* This function is used to asynchronously read data from the stream file.
|
||||||
|
* The function call always returns immediately.
|
||||||
|
*
|
||||||
|
* @param buffers One or more buffers into which the data will be read.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param handler The handler to be called when the read operation completes.
|
||||||
|
* Copies will be made of the handler as required. The function signature of
|
||||||
|
* the handler must be:
|
||||||
|
* @code void handler(
|
||||||
|
* const boost::system::error_code& error, // Result of operation.
|
||||||
|
* std::size_t bytes_transferred // Number of bytes read.
|
||||||
|
* ); @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
|
||||||
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @note The read operation may not read all of the requested number of bytes.
|
||||||
|
* Consider using the @ref async_read function if you need to ensure that the
|
||||||
|
* requested amount of data is read before the asynchronous operation
|
||||||
|
* completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To read into a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* file.async_read_some(boost::asio::buffer(data, size), handler);
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on reading into multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence,
|
||||||
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
std::size_t)) ReadHandler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||||
|
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
|
||||||
|
void (boost::system::error_code, std::size_t))
|
||||||
|
async_read_some(const MutableBufferSequence& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(ReadHandler) handler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||||
|
{
|
||||||
|
return async_initiate<ReadHandler,
|
||||||
|
void (boost::system::error_code, std::size_t)>(
|
||||||
|
initiate_async_read_some(this), handler, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copying and assignment.
|
||||||
|
basic_stream_file(const basic_stream_file&) BOOST_ASIO_DELETED;
|
||||||
|
basic_stream_file& operator=(const basic_stream_file&) BOOST_ASIO_DELETED;
|
||||||
|
|
||||||
|
class initiate_async_write_some
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
explicit initiate_async_write_some(basic_stream_file* self)
|
||||||
|
: self_(self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return self_->get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename WriteHandler, typename ConstBufferSequence>
|
||||||
|
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||||
|
const ConstBufferSequence& buffers) const
|
||||||
|
{
|
||||||
|
// If you get an error on the following line it means that your handler
|
||||||
|
// does not meet the documented type requirements for a WriteHandler.
|
||||||
|
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
|
||||||
|
|
||||||
|
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||||
|
self_->impl_.get_service().async_write_some(
|
||||||
|
self_->impl_.get_implementation(), buffers,
|
||||||
|
handler2.value, self_->impl_.get_executor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
basic_stream_file* self_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class initiate_async_read_some
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
explicit initiate_async_read_some(basic_stream_file* self)
|
||||||
|
: self_(self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return self_->get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReadHandler, typename MutableBufferSequence>
|
||||||
|
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||||
|
const MutableBufferSequence& buffers) const
|
||||||
|
{
|
||||||
|
// If you get an error on the following line it means that your handler
|
||||||
|
// does not meet the documented type requirements for a ReadHandler.
|
||||||
|
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||||
|
|
||||||
|
detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||||
|
self_->impl_.get_service().async_read_some(
|
||||||
|
self_->impl_.get_implementation(), buffers,
|
||||||
|
handler2.value, self_->impl_.get_executor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
basic_stream_file* self_;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_FILE)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_BASIC_STREAM_FILE_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_stream_socket.hpp
|
// basic_stream_socket.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -47,6 +47,12 @@ class basic_stream_socket;
|
||||||
* @e Distinct @e objects: Safe.@n
|
* @e Distinct @e objects: Safe.@n
|
||||||
* @e Shared @e objects: Unsafe.
|
* @e Shared @e objects: Unsafe.
|
||||||
*
|
*
|
||||||
|
* Synchronous @c send, @c receive, 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.
|
||||||
|
*
|
||||||
* @par Concepts:
|
* @par Concepts:
|
||||||
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
|
||||||
*/
|
*/
|
||||||
|
|
@ -106,9 +112,9 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_stream_socket(ExecutionContext& context,
|
explicit basic_stream_socket(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context)
|
: basic_socket<Protocol, Executor>(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -145,9 +151,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
|
basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
>::type* = 0)
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
: basic_socket<Protocol, Executor>(context, protocol)
|
: basic_socket<Protocol, Executor>(context, protocol)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -190,9 +197,9 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, endpoint)
|
: basic_socket<Protocol, Executor>(context, endpoint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -235,9 +242,9 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
basic_stream_socket(ExecutionContext& context,
|
basic_stream_socket(ExecutionContext& context,
|
||||||
const protocol_type& protocol, const native_handle_type& native_socket,
|
const protocol_type& protocol, const native_handle_type& native_socket,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -290,10 +297,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
|
basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value
|
&& is_convertible<Executor1, Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: basic_socket<Protocol, Executor>(std::move(other))
|
: basic_socket<Protocol, Executor>(std::move(other))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -310,7 +317,7 @@ public:
|
||||||
* constructor.
|
* constructor.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol1, typename Executor1>
|
template <typename Protocol1, typename Executor1>
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Protocol1, Protocol>::value
|
is_convertible<Protocol1, Protocol>::value
|
||||||
&& is_convertible<Executor1, Executor>::value,
|
&& is_convertible<Executor1, Executor>::value,
|
||||||
basic_stream_socket&
|
basic_stream_socket&
|
||||||
|
|
@ -463,6 +470,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -516,6 +533,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on sending multiple
|
* See the @ref buffer documentation for information on sending multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -674,6 +701,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -729,6 +766,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on receiving into
|
* See the @ref buffer documentation for information on receiving into
|
||||||
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
* multiple buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -841,6 +888,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on writing multiple
|
* See the @ref buffer documentation for information on writing multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename ConstBufferSequence,
|
template <typename ConstBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -956,6 +1013,16 @@ public:
|
||||||
* See the @ref buffer documentation for information on reading into multiple
|
* See the @ref buffer documentation for information on reading into multiple
|
||||||
* buffers in one go, and how to use it with arrays, boost::array or
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
* std::vector.
|
* std::vector.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* On POSIX or Windows operating systems, this asynchronous operation supports
|
||||||
|
* cancellation for the following boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <typename MutableBufferSequence,
|
template <typename MutableBufferSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_streambuf.hpp
|
// basic_streambuf.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_streambuf_fwd.hpp
|
// basic_streambuf_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// basic_waitable_timer.hpp
|
// basic_waitable_timer.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -176,7 +176,7 @@ public:
|
||||||
* dispatch handlers for any asynchronous operations performed on the timer.
|
* dispatch handlers for any asynchronous operations performed on the timer.
|
||||||
*/
|
*/
|
||||||
explicit basic_waitable_timer(const executor_type& ex)
|
explicit basic_waitable_timer(const executor_type& ex)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,10 +192,10 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_waitable_timer(ExecutionContext& context,
|
explicit basic_waitable_timer(ExecutionContext& context,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +210,7 @@ public:
|
||||||
* as an absolute time.
|
* as an absolute time.
|
||||||
*/
|
*/
|
||||||
basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
|
basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||||
|
|
@ -231,10 +231,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_waitable_timer(ExecutionContext& context,
|
explicit basic_waitable_timer(ExecutionContext& context,
|
||||||
const time_point& expiry_time,
|
const time_point& expiry_time,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
|
||||||
|
|
@ -252,7 +252,7 @@ public:
|
||||||
* now.
|
* now.
|
||||||
*/
|
*/
|
||||||
basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
|
basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
|
||||||
: impl_(ex)
|
: impl_(0, ex)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_after(
|
impl_.get_service().expires_after(
|
||||||
|
|
@ -274,10 +274,10 @@ public:
|
||||||
template <typename ExecutionContext>
|
template <typename ExecutionContext>
|
||||||
explicit basic_waitable_timer(ExecutionContext& context,
|
explicit basic_waitable_timer(ExecutionContext& context,
|
||||||
const duration& expiry_time,
|
const duration& expiry_time,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(context)
|
: impl_(0, 0, context)
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
impl_.get_service().expires_after(
|
impl_.get_service().expires_after(
|
||||||
|
|
@ -338,9 +338,9 @@ public:
|
||||||
template <typename Executor1>
|
template <typename Executor1>
|
||||||
basic_waitable_timer(
|
basic_waitable_timer(
|
||||||
basic_waitable_timer<Clock, WaitTraits, Executor1>&& other,
|
basic_waitable_timer<Clock, WaitTraits, Executor1>&& other,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Executor1, Executor>::value
|
is_convertible<Executor1, Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
: impl_(std::move(other.impl_))
|
: impl_(std::move(other.impl_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +358,7 @@ public:
|
||||||
* constructor.
|
* constructor.
|
||||||
*/
|
*/
|
||||||
template <typename Executor1>
|
template <typename Executor1>
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<Executor1, Executor>::value,
|
is_convertible<Executor1, Executor>::value,
|
||||||
basic_waitable_timer&
|
basic_waitable_timer&
|
||||||
>::type operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other)
|
>::type operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other)
|
||||||
|
|
@ -747,6 +747,16 @@ public:
|
||||||
* not, the handler will not be invoked from within this function. On
|
* not, the handler will not be invoked from within this function. On
|
||||||
* immediate completion, invocation of the handler will be performed in a
|
* immediate completion, invocation of the handler will be performed in a
|
||||||
* manner equivalent to using boost::asio::post().
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::total
|
||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,521 @@
|
||||||
|
//
|
||||||
|
// basic_writable_pipe.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_BASIC_WRITABLE_PIPE_HPP
|
||||||
|
#define BOOST_ASIO_BASIC_WRITABLE_PIPE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_PIPE) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/asio/any_io_executor.hpp>
|
||||||
|
#include <boost/asio/async_result.hpp>
|
||||||
|
#include <boost/asio/detail/handler_type_requirements.hpp>
|
||||||
|
#include <boost/asio/detail/io_object_impl.hpp>
|
||||||
|
#include <boost/asio/detail/non_const_lvalue.hpp>
|
||||||
|
#include <boost/asio/detail/throw_error.hpp>
|
||||||
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
|
#include <boost/asio/execution_context.hpp>
|
||||||
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
# include <boost/asio/detail/win_iocp_handle_service.hpp>
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
# include <boost/asio/detail/io_uring_descriptor_service.hpp>
|
||||||
|
#else
|
||||||
|
# include <boost/asio/detail/reactive_descriptor_service.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
# include <utility>
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
/// Provides pipe functionality.
|
||||||
|
/**
|
||||||
|
* The basic_writable_pipe class provides a wrapper over pipe
|
||||||
|
* functionality.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* @e Distinct @e objects: Safe.@n
|
||||||
|
* @e Shared @e objects: Unsafe.
|
||||||
|
*/
|
||||||
|
template <typename Executor = any_io_executor>
|
||||||
|
class basic_writable_pipe
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The type of the executor associated with the object.
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
/// Rebinds the pipe type to another executor.
|
||||||
|
template <typename Executor1>
|
||||||
|
struct rebind_executor
|
||||||
|
{
|
||||||
|
/// The pipe type when rebound to the specified executor.
|
||||||
|
typedef basic_writable_pipe<Executor1> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The native representation of a pipe.
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
typedef implementation_defined native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
typedef detail::win_iocp_handle_service::native_handle_type
|
||||||
|
native_handle_type;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
typedef detail::io_uring_descriptor_service::native_handle_type
|
||||||
|
native_handle_type;
|
||||||
|
#else
|
||||||
|
typedef detail::reactive_descriptor_service::native_handle_type
|
||||||
|
native_handle_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// A basic_writable_pipe is always the lowest layer.
|
||||||
|
typedef basic_writable_pipe lowest_layer_type;
|
||||||
|
|
||||||
|
/// Construct a basic_writable_pipe without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe without opening it.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the pipe will use, by default, to dispatch
|
||||||
|
* handlers for any asynchronous operations performed on the pipe.
|
||||||
|
*/
|
||||||
|
explicit basic_writable_pipe(const executor_type& ex)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_writable_pipe without opening it.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe without opening it.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the pipe will use, by default, to dispatch handlers for any asynchronous
|
||||||
|
* operations performed on the pipe.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
explicit basic_writable_pipe(ExecutionContext& context,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value,
|
||||||
|
defaulted_constraint
|
||||||
|
>::type = defaulted_constraint())
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_writable_pipe on an existing native pipe.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe object to hold an existing native
|
||||||
|
* pipe.
|
||||||
|
*
|
||||||
|
* @param ex The I/O executor that the pipe will use, by default, to
|
||||||
|
* dispatch handlers for any asynchronous operations performed on the
|
||||||
|
* pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
basic_writable_pipe(const executor_type& ex,
|
||||||
|
const native_handle_type& native_pipe)
|
||||||
|
: impl_(0, ex)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
native_pipe, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a basic_writable_pipe on an existing native pipe.
|
||||||
|
/**
|
||||||
|
* This constructor creates a pipe object to hold an existing native
|
||||||
|
* pipe.
|
||||||
|
*
|
||||||
|
* @param context An execution context which provides the I/O executor that
|
||||||
|
* the pipe will use, by default, to dispatch handlers for any
|
||||||
|
* asynchronous operations performed on the pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
basic_writable_pipe(ExecutionContext& context,
|
||||||
|
const native_handle_type& native_pipe,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
|
>::type = 0)
|
||||||
|
: impl_(0, 0, context)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(),
|
||||||
|
native_pipe, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move-construct a basic_writable_pipe from another.
|
||||||
|
/**
|
||||||
|
* This constructor moves a pipe from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_writable_pipe object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_writable_pipe(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_writable_pipe(basic_writable_pipe&& other)
|
||||||
|
: impl_(std::move(other.impl_))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move-assign a basic_writable_pipe from another.
|
||||||
|
/**
|
||||||
|
* This assignment operator moves a pipe from one object to another.
|
||||||
|
*
|
||||||
|
* @param other The other basic_writable_pipe object from which the move will
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @note Following the move, the moved-from object is in the same state as if
|
||||||
|
* constructed using the @c basic_writable_pipe(const executor_type&)
|
||||||
|
* constructor.
|
||||||
|
*/
|
||||||
|
basic_writable_pipe& operator=(basic_writable_pipe&& other)
|
||||||
|
{
|
||||||
|
impl_ = std::move(other.impl_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Destroys the pipe.
|
||||||
|
/**
|
||||||
|
* This function destroys the pipe, cancelling any outstanding
|
||||||
|
* asynchronous wait operations associated with the pipe as if by
|
||||||
|
* calling @c cancel.
|
||||||
|
*/
|
||||||
|
~basic_writable_pipe()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the executor associated with the object.
|
||||||
|
executor_type get_executor() BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return impl_.get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference to the lowest layer.
|
||||||
|
/**
|
||||||
|
* This function returns a reference to the lowest layer in a stack of
|
||||||
|
* layers. Since a basic_writable_pipe cannot contain any further layers, it
|
||||||
|
* simply returns a reference to itself.
|
||||||
|
*
|
||||||
|
* @return A reference to the lowest layer in the stack of layers. Ownership
|
||||||
|
* is not transferred to the caller.
|
||||||
|
*/
|
||||||
|
lowest_layer_type& lowest_layer()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a const reference to the lowest layer.
|
||||||
|
/**
|
||||||
|
* This function returns a const reference to the lowest layer in a stack of
|
||||||
|
* layers. Since a basic_writable_pipe cannot contain any further layers, it
|
||||||
|
* simply returns a reference to itself.
|
||||||
|
*
|
||||||
|
* @return A const reference to the lowest layer in the stack of layers.
|
||||||
|
* Ownership is not transferred to the caller.
|
||||||
|
*/
|
||||||
|
const lowest_layer_type& lowest_layer() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign an existing native pipe to the pipe.
|
||||||
|
/*
|
||||||
|
* This function opens the pipe to hold an existing native pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void assign(const native_handle_type& native_pipe)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(), native_pipe, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "assign");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign an existing native pipe to the pipe.
|
||||||
|
/*
|
||||||
|
* This function opens the pipe to hold an existing native pipe.
|
||||||
|
*
|
||||||
|
* @param native_pipe A native pipe.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_pipe,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().assign(impl_.get_implementation(), native_pipe, ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine whether the pipe is open.
|
||||||
|
bool is_open() const
|
||||||
|
{
|
||||||
|
return impl_.get_service().is_open(impl_.get_implementation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to close the pipe. Any asynchronous write operations
|
||||||
|
* will be cancelled immediately, and will complete with the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "close");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Close the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to close the pipe. Any asynchronous write operations
|
||||||
|
* will be cancelled immediately, and will complete with the
|
||||||
|
* boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().close(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the native pipe representation.
|
||||||
|
/**
|
||||||
|
* This function may be used to obtain the underlying representation of the
|
||||||
|
* pipe. This is intended to allow access to native pipe
|
||||||
|
* functionality that is not otherwise provided.
|
||||||
|
*/
|
||||||
|
native_handle_type native_handle()
|
||||||
|
{
|
||||||
|
return impl_.get_service().native_handle(impl_.get_implementation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel all asynchronous operations associated with the pipe.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous write operations to
|
||||||
|
* finish immediately, and the handlers for cancelled operations will be
|
||||||
|
* passed the boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
void cancel()
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "cancel");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancel all asynchronous operations associated with the pipe.
|
||||||
|
/**
|
||||||
|
* This function causes all outstanding asynchronous write operations to
|
||||||
|
* finish immediately, and the handlers for cancelled operations will be
|
||||||
|
* passed the boost::asio::error::operation_aborted error.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
impl_.get_service().cancel(impl_.get_implementation(), ec);
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write some data to the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to write data to the pipe. The function call will
|
||||||
|
* block until one or more bytes of the data has been written successfully,
|
||||||
|
* or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the pipe.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes written.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure. An error code of
|
||||||
|
* boost::asio::error::eof indicates that the connection was closed by the
|
||||||
|
* peer.
|
||||||
|
*
|
||||||
|
* @note The write_some operation may not transmit all of the data to the
|
||||||
|
* peer. Consider using the @ref write function if you need to ensure that
|
||||||
|
* all data is written before the blocking operation completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* pipe.write_some(boost::asio::buffer(data, size));
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on writing multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence>
|
||||||
|
std::size_t write_some(const ConstBufferSequence& buffers)
|
||||||
|
{
|
||||||
|
boost::system::error_code ec;
|
||||||
|
std::size_t s = impl_.get_service().write_some(
|
||||||
|
impl_.get_implementation(), buffers, ec);
|
||||||
|
boost::asio::detail::throw_error(ec, "write_some");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write some data to the pipe.
|
||||||
|
/**
|
||||||
|
* This function is used to write data to the pipe. The function call will
|
||||||
|
* block until one or more bytes of the data has been written successfully,
|
||||||
|
* or until an error occurs.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the pipe.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*
|
||||||
|
* @returns The number of bytes written. Returns 0 if an error occurred.
|
||||||
|
*
|
||||||
|
* @note The write_some operation may not transmit all of the data to the
|
||||||
|
* peer. Consider using the @ref write function if you need to ensure that
|
||||||
|
* all data is written before the blocking operation completes.
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence>
|
||||||
|
std::size_t write_some(const ConstBufferSequence& buffers,
|
||||||
|
boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
return impl_.get_service().write_some(
|
||||||
|
impl_.get_implementation(), buffers, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start an asynchronous write.
|
||||||
|
/**
|
||||||
|
* This function is used to asynchronously write data to the pipe. The
|
||||||
|
* function call always returns immediately.
|
||||||
|
*
|
||||||
|
* @param buffers One or more data buffers to be written to the pipe.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param handler The handler to be called when the write operation completes.
|
||||||
|
* Copies will be made of the handler as required. The function signature of
|
||||||
|
* the handler must be:
|
||||||
|
* @code void handler(
|
||||||
|
* const boost::system::error_code& error, // Result of operation.
|
||||||
|
* std::size_t bytes_transferred // Number of bytes written.
|
||||||
|
* ); @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
|
||||||
|
* manner equivalent to using boost::asio::post().
|
||||||
|
*
|
||||||
|
* @note The write operation may not transmit all of the data to the peer.
|
||||||
|
* Consider using the @ref async_write function if you need to ensure that all
|
||||||
|
* data is written before the asynchronous operation completes.
|
||||||
|
*
|
||||||
|
* @par Example
|
||||||
|
* To write a single data buffer use the @ref buffer function as follows:
|
||||||
|
* @code
|
||||||
|
* pipe.async_write_some(boost::asio::buffer(data, size), handler);
|
||||||
|
* @endcode
|
||||||
|
* See the @ref buffer documentation for information on writing multiple
|
||||||
|
* buffers in one go, and how to use it with arrays, boost::array or
|
||||||
|
* std::vector.
|
||||||
|
*/
|
||||||
|
template <typename ConstBufferSequence,
|
||||||
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
std::size_t)) WriteHandler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||||
|
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
|
||||||
|
void (boost::system::error_code, std::size_t))
|
||||||
|
async_write_some(const ConstBufferSequence& buffers,
|
||||||
|
BOOST_ASIO_MOVE_ARG(WriteHandler) handler
|
||||||
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||||
|
{
|
||||||
|
return async_initiate<WriteHandler,
|
||||||
|
void (boost::system::error_code, std::size_t)>(
|
||||||
|
initiate_async_write_some(this), handler, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copying and assignment.
|
||||||
|
basic_writable_pipe(const basic_writable_pipe&) BOOST_ASIO_DELETED;
|
||||||
|
basic_writable_pipe& operator=(const basic_writable_pipe&) BOOST_ASIO_DELETED;
|
||||||
|
|
||||||
|
class initiate_async_write_some
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Executor executor_type;
|
||||||
|
|
||||||
|
explicit initiate_async_write_some(basic_writable_pipe* self)
|
||||||
|
: self_(self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return self_->get_executor();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename WriteHandler, typename ConstBufferSequence>
|
||||||
|
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||||
|
const ConstBufferSequence& buffers) const
|
||||||
|
{
|
||||||
|
// If you get an error on the following line it means that your handler
|
||||||
|
// does not meet the documented type requirements for a WriteHandler.
|
||||||
|
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
|
||||||
|
|
||||||
|
detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||||
|
self_->impl_.get_service().async_write_some(
|
||||||
|
self_->impl_.get_implementation(), buffers,
|
||||||
|
handler2.value, self_->impl_.get_executor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
basic_writable_pipe* self_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
detail::io_object_impl<detail::win_iocp_handle_service, Executor> impl_;
|
||||||
|
#elif defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
|
||||||
|
detail::io_object_impl<detail::io_uring_descriptor_service, Executor> impl_;
|
||||||
|
#else
|
||||||
|
detail::io_object_impl<detail::reactive_descriptor_service, Executor> impl_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_PIPE)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_BASIC_WRITABLE_PIPE_HPP
|
||||||
|
|
@ -0,0 +1,723 @@
|
||||||
|
//
|
||||||
|
// bind_cancellation_slot.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_BIND_CANCELLATION_SLOT_HPP
|
||||||
|
#define BOOST_ASIO_BIND_CANCELLATION_SLOT_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
#include <boost/asio/detail/variadic_templates.hpp>
|
||||||
|
#include <boost/asio/associated_cancellation_slot.hpp>
|
||||||
|
#include <boost/asio/associator.hpp>
|
||||||
|
#include <boost/asio/async_result.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// Helper to automatically define nested typedef result_type.
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct cancellation_slot_binder_result_type
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef void result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct cancellation_slot_binder_result_type<T,
|
||||||
|
typename void_type<typename T::result_type>::type>
|
||||||
|
{
|
||||||
|
typedef typename T::result_type result_type;
|
||||||
|
protected:
|
||||||
|
typedef result_type result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
struct cancellation_slot_binder_result_type<R(*)()>
|
||||||
|
{
|
||||||
|
typedef R result_type;
|
||||||
|
protected:
|
||||||
|
typedef result_type result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
struct cancellation_slot_binder_result_type<R(&)()>
|
||||||
|
{
|
||||||
|
typedef R result_type;
|
||||||
|
protected:
|
||||||
|
typedef result_type result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1>
|
||||||
|
struct cancellation_slot_binder_result_type<R(*)(A1)>
|
||||||
|
{
|
||||||
|
typedef R result_type;
|
||||||
|
protected:
|
||||||
|
typedef result_type result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1>
|
||||||
|
struct cancellation_slot_binder_result_type<R(&)(A1)>
|
||||||
|
{
|
||||||
|
typedef R result_type;
|
||||||
|
protected:
|
||||||
|
typedef result_type result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2>
|
||||||
|
struct cancellation_slot_binder_result_type<R(*)(A1, A2)>
|
||||||
|
{
|
||||||
|
typedef R result_type;
|
||||||
|
protected:
|
||||||
|
typedef result_type result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2>
|
||||||
|
struct cancellation_slot_binder_result_type<R(&)(A1, A2)>
|
||||||
|
{
|
||||||
|
typedef R result_type;
|
||||||
|
protected:
|
||||||
|
typedef result_type result_type_or_void;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to automatically define nested typedef argument_type.
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct cancellation_slot_binder_argument_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct cancellation_slot_binder_argument_type<T,
|
||||||
|
typename void_type<typename T::argument_type>::type>
|
||||||
|
{
|
||||||
|
typedef typename T::argument_type argument_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1>
|
||||||
|
struct cancellation_slot_binder_argument_type<R(*)(A1)>
|
||||||
|
{
|
||||||
|
typedef A1 argument_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1>
|
||||||
|
struct cancellation_slot_binder_argument_type<R(&)(A1)>
|
||||||
|
{
|
||||||
|
typedef A1 argument_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to automatically define nested typedefs first_argument_type and
|
||||||
|
// second_argument_type.
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct cancellation_slot_binder_argument_types {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct cancellation_slot_binder_argument_types<T,
|
||||||
|
typename void_type<typename T::first_argument_type>::type>
|
||||||
|
{
|
||||||
|
typedef typename T::first_argument_type first_argument_type;
|
||||||
|
typedef typename T::second_argument_type second_argument_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2>
|
||||||
|
struct cancellation_slot_binder_argument_type<R(*)(A1, A2)>
|
||||||
|
{
|
||||||
|
typedef A1 first_argument_type;
|
||||||
|
typedef A2 second_argument_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename A1, typename A2>
|
||||||
|
struct cancellation_slot_binder_argument_type<R(&)(A1, A2)>
|
||||||
|
{
|
||||||
|
typedef A1 first_argument_type;
|
||||||
|
typedef A2 second_argument_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to enable SFINAE on zero-argument operator() below.
|
||||||
|
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct cancellation_slot_binder_result_of0
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct cancellation_slot_binder_result_of0<T,
|
||||||
|
typename void_type<typename result_of<T()>::type>::type>
|
||||||
|
{
|
||||||
|
typedef typename result_of<T()>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// A call wrapper type to bind a cancellation slot of type @c CancellationSlot
|
||||||
|
/// to an object of type @c T.
|
||||||
|
template <typename T, typename CancellationSlot>
|
||||||
|
class cancellation_slot_binder
|
||||||
|
#if !defined(GENERATING_DOCUMENTATION)
|
||||||
|
: public detail::cancellation_slot_binder_result_type<T>,
|
||||||
|
public detail::cancellation_slot_binder_argument_type<T>,
|
||||||
|
public detail::cancellation_slot_binder_argument_types<T>
|
||||||
|
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The type of the target object.
|
||||||
|
typedef T target_type;
|
||||||
|
|
||||||
|
/// The type of the associated cancellation slot.
|
||||||
|
typedef CancellationSlot cancellation_slot_type;
|
||||||
|
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// The return type if a function.
|
||||||
|
/**
|
||||||
|
* The type of @c result_type is based on the type @c T of the wrapper's
|
||||||
|
* target object:
|
||||||
|
*
|
||||||
|
* @li if @c T is a pointer to function type, @c result_type is a synonym for
|
||||||
|
* the return type of @c T;
|
||||||
|
*
|
||||||
|
* @li if @c T is a class type with a member type @c result_type, then @c
|
||||||
|
* result_type is a synonym for @c T::result_type;
|
||||||
|
*
|
||||||
|
* @li otherwise @c result_type is not defined.
|
||||||
|
*/
|
||||||
|
typedef see_below result_type;
|
||||||
|
|
||||||
|
/// The type of the function's argument.
|
||||||
|
/**
|
||||||
|
* The type of @c argument_type is based on the type @c T of the wrapper's
|
||||||
|
* target object:
|
||||||
|
*
|
||||||
|
* @li if @c T is a pointer to a function type accepting a single argument,
|
||||||
|
* @c argument_type is a synonym for the return type of @c T;
|
||||||
|
*
|
||||||
|
* @li if @c T is a class type with a member type @c argument_type, then @c
|
||||||
|
* argument_type is a synonym for @c T::argument_type;
|
||||||
|
*
|
||||||
|
* @li otherwise @c argument_type is not defined.
|
||||||
|
*/
|
||||||
|
typedef see_below argument_type;
|
||||||
|
|
||||||
|
/// The type of the function's first argument.
|
||||||
|
/**
|
||||||
|
* The type of @c first_argument_type is based on the type @c T of the
|
||||||
|
* wrapper's target object:
|
||||||
|
*
|
||||||
|
* @li if @c T is a pointer to a function type accepting two arguments, @c
|
||||||
|
* first_argument_type is a synonym for the return type of @c T;
|
||||||
|
*
|
||||||
|
* @li if @c T is a class type with a member type @c first_argument_type,
|
||||||
|
* then @c first_argument_type is a synonym for @c T::first_argument_type;
|
||||||
|
*
|
||||||
|
* @li otherwise @c first_argument_type is not defined.
|
||||||
|
*/
|
||||||
|
typedef see_below first_argument_type;
|
||||||
|
|
||||||
|
/// The type of the function's second argument.
|
||||||
|
/**
|
||||||
|
* The type of @c second_argument_type is based on the type @c T of the
|
||||||
|
* wrapper's target object:
|
||||||
|
*
|
||||||
|
* @li if @c T is a pointer to a function type accepting two arguments, @c
|
||||||
|
* second_argument_type is a synonym for the return type of @c T;
|
||||||
|
*
|
||||||
|
* @li if @c T is a class type with a member type @c first_argument_type,
|
||||||
|
* then @c second_argument_type is a synonym for @c T::second_argument_type;
|
||||||
|
*
|
||||||
|
* @li otherwise @c second_argument_type is not defined.
|
||||||
|
*/
|
||||||
|
typedef see_below second_argument_type;
|
||||||
|
#endif // defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Construct a cancellation slot wrapper for the specified object.
|
||||||
|
/**
|
||||||
|
* This constructor is only valid if the type @c T is constructible from type
|
||||||
|
* @c U.
|
||||||
|
*/
|
||||||
|
template <typename U>
|
||||||
|
cancellation_slot_binder(const cancellation_slot_type& s,
|
||||||
|
BOOST_ASIO_MOVE_ARG(U) u)
|
||||||
|
: slot_(s),
|
||||||
|
target_(BOOST_ASIO_MOVE_CAST(U)(u))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy constructor.
|
||||||
|
cancellation_slot_binder(const cancellation_slot_binder& other)
|
||||||
|
: slot_(other.get_cancellation_slot()),
|
||||||
|
target_(other.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a copy, but specify a different cancellation slot.
|
||||||
|
cancellation_slot_binder(const cancellation_slot_type& s,
|
||||||
|
const cancellation_slot_binder& other)
|
||||||
|
: slot_(s),
|
||||||
|
target_(other.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a copy of a different cancellation slot wrapper type.
|
||||||
|
/**
|
||||||
|
* This constructor is only valid if the @c CancellationSlot type is
|
||||||
|
* constructible from type @c OtherCancellationSlot, and the type @c T is
|
||||||
|
* constructible from type @c U.
|
||||||
|
*/
|
||||||
|
template <typename U, typename OtherCancellationSlot>
|
||||||
|
cancellation_slot_binder(
|
||||||
|
const cancellation_slot_binder<U, OtherCancellationSlot>& other)
|
||||||
|
: slot_(other.get_cancellation_slot()),
|
||||||
|
target_(other.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a copy of a different cancellation slot wrapper type, but
|
||||||
|
/// specify a different cancellation slot.
|
||||||
|
/**
|
||||||
|
* This constructor is only valid if the type @c T is constructible from type
|
||||||
|
* @c U.
|
||||||
|
*/
|
||||||
|
template <typename U, typename OtherCancellationSlot>
|
||||||
|
cancellation_slot_binder(const cancellation_slot_type& s,
|
||||||
|
const cancellation_slot_binder<U, OtherCancellationSlot>& other)
|
||||||
|
: slot_(s),
|
||||||
|
target_(other.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Move constructor.
|
||||||
|
cancellation_slot_binder(cancellation_slot_binder&& other)
|
||||||
|
: slot_(BOOST_ASIO_MOVE_CAST(cancellation_slot_type)(
|
||||||
|
other.get_cancellation_slot())),
|
||||||
|
target_(BOOST_ASIO_MOVE_CAST(T)(other.get()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move construct the target object, but specify a different cancellation
|
||||||
|
/// slot.
|
||||||
|
cancellation_slot_binder(const cancellation_slot_type& s,
|
||||||
|
cancellation_slot_binder&& other)
|
||||||
|
: slot_(s),
|
||||||
|
target_(BOOST_ASIO_MOVE_CAST(T)(other.get()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move construct from a different cancellation slot wrapper type.
|
||||||
|
template <typename U, typename OtherCancellationSlot>
|
||||||
|
cancellation_slot_binder(
|
||||||
|
cancellation_slot_binder<U, OtherCancellationSlot>&& other)
|
||||||
|
: slot_(BOOST_ASIO_MOVE_CAST(OtherCancellationSlot)(
|
||||||
|
other.get_cancellation_slot())),
|
||||||
|
target_(BOOST_ASIO_MOVE_CAST(U)(other.get()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move construct from a different cancellation slot wrapper type, but
|
||||||
|
/// specify a different cancellation slot.
|
||||||
|
template <typename U, typename OtherCancellationSlot>
|
||||||
|
cancellation_slot_binder(const cancellation_slot_type& s,
|
||||||
|
cancellation_slot_binder<U, OtherCancellationSlot>&& other)
|
||||||
|
: slot_(s),
|
||||||
|
target_(BOOST_ASIO_MOVE_CAST(U)(other.get()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Destructor.
|
||||||
|
~cancellation_slot_binder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtain a reference to the target object.
|
||||||
|
target_type& get() BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtain a reference to the target object.
|
||||||
|
const target_type& get() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return target_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtain the associated cancellation slot.
|
||||||
|
cancellation_slot_type get_cancellation_slot() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return slot_;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
template <typename... Args> auto operator()(Args&& ...);
|
||||||
|
template <typename... Args> auto operator()(Args&& ...) const;
|
||||||
|
|
||||||
|
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
/// Forwarding function call operator.
|
||||||
|
template <typename... Args>
|
||||||
|
typename result_of<T(Args...)>::type operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||||
|
{
|
||||||
|
return target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Forwarding function call operator.
|
||||||
|
template <typename... Args>
|
||||||
|
typename result_of<T(Args...)>::type operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args) const
|
||||||
|
{
|
||||||
|
return target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
|
||||||
|
|
||||||
|
typename detail::cancellation_slot_binder_result_of0<T>::type operator()()
|
||||||
|
{
|
||||||
|
return target_();
|
||||||
|
}
|
||||||
|
|
||||||
|
typename detail::cancellation_slot_binder_result_of0<T>::type
|
||||||
|
operator()() const
|
||||||
|
{
|
||||||
|
return target_();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_BINDER_CALL_DEF(n) \
|
||||||
|
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
{ \
|
||||||
|
return target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
|
||||||
|
{ \
|
||||||
|
return target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BINDER_CALL_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_BINDER_CALL_DEF
|
||||||
|
|
||||||
|
#else // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
|
||||||
|
|
||||||
|
typedef typename detail::cancellation_slot_binder_result_type<
|
||||||
|
T>::result_type_or_void result_type_or_void;
|
||||||
|
|
||||||
|
result_type_or_void operator()()
|
||||||
|
{
|
||||||
|
return target_();
|
||||||
|
}
|
||||||
|
|
||||||
|
result_type_or_void operator()() const
|
||||||
|
{
|
||||||
|
return target_();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_BINDER_CALL_DEF(n) \
|
||||||
|
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
result_type_or_void operator()( \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
{ \
|
||||||
|
return target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
result_type_or_void operator()( \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
|
||||||
|
{ \
|
||||||
|
return target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BINDER_CALL_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_BINDER_CALL_DEF
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
|
||||||
|
|
||||||
|
private:
|
||||||
|
CancellationSlot slot_;
|
||||||
|
T target_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Associate an object of type @c T with a cancellation slot of type
|
||||||
|
/// @c CancellationSlot.
|
||||||
|
template <typename CancellationSlot, typename T>
|
||||||
|
inline cancellation_slot_binder<typename decay<T>::type, CancellationSlot>
|
||||||
|
bind_cancellation_slot(const CancellationSlot& s, BOOST_ASIO_MOVE_ARG(T) t)
|
||||||
|
{
|
||||||
|
return cancellation_slot_binder<
|
||||||
|
typename decay<T>::type, CancellationSlot>(
|
||||||
|
s, BOOST_ASIO_MOVE_CAST(T)(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename TargetAsyncResult,
|
||||||
|
typename CancellationSlot, typename = void>
|
||||||
|
struct cancellation_slot_binder_async_result_completion_handler_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TargetAsyncResult, typename CancellationSlot>
|
||||||
|
struct cancellation_slot_binder_async_result_completion_handler_type<
|
||||||
|
TargetAsyncResult, CancellationSlot,
|
||||||
|
typename void_type<
|
||||||
|
typename TargetAsyncResult::completion_handler_type
|
||||||
|
>::type>
|
||||||
|
{
|
||||||
|
typedef cancellation_slot_binder<
|
||||||
|
typename TargetAsyncResult::completion_handler_type, CancellationSlot>
|
||||||
|
completion_handler_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TargetAsyncResult, typename = void>
|
||||||
|
struct cancellation_slot_binder_async_result_return_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TargetAsyncResult>
|
||||||
|
struct cancellation_slot_binder_async_result_return_type<
|
||||||
|
TargetAsyncResult,
|
||||||
|
typename void_type<
|
||||||
|
typename TargetAsyncResult::return_type
|
||||||
|
>::type>
|
||||||
|
{
|
||||||
|
typedef typename TargetAsyncResult::return_type return_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T, typename CancellationSlot, typename Signature>
|
||||||
|
class async_result<cancellation_slot_binder<T, CancellationSlot>, Signature> :
|
||||||
|
public detail::cancellation_slot_binder_async_result_completion_handler_type<
|
||||||
|
async_result<T, Signature>, CancellationSlot>,
|
||||||
|
public detail::cancellation_slot_binder_async_result_return_type<
|
||||||
|
async_result<T, Signature> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit async_result(cancellation_slot_binder<T, CancellationSlot>& b)
|
||||||
|
: target_(b.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
typename async_result<T, Signature>::return_type get()
|
||||||
|
{
|
||||||
|
return target_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Initiation>
|
||||||
|
struct init_wrapper
|
||||||
|
{
|
||||||
|
template <typename Init>
|
||||||
|
init_wrapper(const CancellationSlot& slot, BOOST_ASIO_MOVE_ARG(Init) init)
|
||||||
|
: slot_(slot),
|
||||||
|
initiation_(BOOST_ASIO_MOVE_CAST(Init)(init))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Handler, typename... Args>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||||
|
{
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||||
|
cancellation_slot_binder<
|
||||||
|
typename decay<Handler>::type, CancellationSlot>(
|
||||||
|
slot_, BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||||
|
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Handler, typename... Args>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args) const
|
||||||
|
{
|
||||||
|
initiation_(
|
||||||
|
cancellation_slot_binder<
|
||||||
|
typename decay<Handler>::type, CancellationSlot>(
|
||||||
|
slot_, BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||||
|
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||||
|
{
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||||
|
cancellation_slot_binder<
|
||||||
|
typename decay<Handler>::type, CancellationSlot>(
|
||||||
|
slot_, BOOST_ASIO_MOVE_CAST(Handler)(handler)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler) const
|
||||||
|
{
|
||||||
|
initiation_(
|
||||||
|
cancellation_slot_binder<
|
||||||
|
typename decay<Handler>::type, CancellationSlot>(
|
||||||
|
slot_, BOOST_ASIO_MOVE_CAST(Handler)(handler)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \
|
||||||
|
template <typename Handler, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
void operator()( \
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler, \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
{ \
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)( \
|
||||||
|
cancellation_slot_binder< \
|
||||||
|
typename decay<Handler>::type, CancellationSlot>( \
|
||||||
|
slot_, BOOST_ASIO_MOVE_CAST(Handler)(handler)), \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template <typename Handler, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
void operator()( \
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler, \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
|
||||||
|
{ \
|
||||||
|
initiation_( \
|
||||||
|
cancellation_slot_binder< \
|
||||||
|
typename decay<Handler>::type, CancellationSlot>( \
|
||||||
|
slot_, BOOST_ASIO_MOVE_CAST(Handler)(handler)), \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
CancellationSlot slot_;
|
||||||
|
Initiation initiation_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||||
|
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,
|
||||||
|
(async_result<T, Signature>::initiate(
|
||||||
|
declval<init_wrapper<typename decay<Initiation>::type> >(),
|
||||||
|
declval<T>(), declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
|
||||||
|
initiate(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||||
|
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||||
|
{
|
||||||
|
return async_initiate<T, Signature>(
|
||||||
|
init_wrapper<typename decay<Initiation>::type>(
|
||||||
|
token.get_cancellation_slot(),
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||||
|
token.get(), BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Initiation, typename RawCompletionToken>
|
||||||
|
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,
|
||||||
|
(async_result<T, Signature>::initiate(
|
||||||
|
declval<init_wrapper<typename decay<Initiation>::type> >(),
|
||||||
|
declval<T>())))
|
||||||
|
initiate(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||||
|
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
|
||||||
|
{
|
||||||
|
return async_initiate<T, Signature>(
|
||||||
|
init_wrapper<typename decay<Initiation>::type>(
|
||||||
|
token.get_cancellation_slot(),
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||||
|
token.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
|
||||||
|
template <typename Initiation, typename RawCompletionToken, \
|
||||||
|
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \
|
||||||
|
(async_result<T, Signature>::initiate( \
|
||||||
|
declval<init_wrapper<typename decay<Initiation>::type> >(), \
|
||||||
|
declval<T>(), BOOST_ASIO_VARIADIC_MOVE_DECLVAL(n)))) \
|
||||||
|
initiate( \
|
||||||
|
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
|
||||||
|
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
{ \
|
||||||
|
return async_initiate<T, Signature>( \
|
||||||
|
init_wrapper<typename decay<Initiation>::type>( \
|
||||||
|
token.get_cancellation_slot(), \
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)), \
|
||||||
|
token.get(), BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
private:
|
||||||
|
async_result(const async_result&) BOOST_ASIO_DELETED;
|
||||||
|
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
|
||||||
|
|
||||||
|
async_result<T, Signature> target_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <typename, typename> class Associator,
|
||||||
|
typename T, typename CancellationSlot, typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
cancellation_slot_binder<T, CancellationSlot>,
|
||||||
|
DefaultCandidate>
|
||||||
|
{
|
||||||
|
typedef typename Associator<T, DefaultCandidate>::type type;
|
||||||
|
|
||||||
|
static type get(const cancellation_slot_binder<T, CancellationSlot>& b,
|
||||||
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return Associator<T, DefaultCandidate>::get(b.get(), c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename CancellationSlot, typename CancellationSlot1>
|
||||||
|
struct associated_cancellation_slot<
|
||||||
|
cancellation_slot_binder<T, CancellationSlot>,
|
||||||
|
CancellationSlot1>
|
||||||
|
{
|
||||||
|
typedef CancellationSlot type;
|
||||||
|
|
||||||
|
static type get(const cancellation_slot_binder<T, CancellationSlot>& b,
|
||||||
|
const CancellationSlot1& = CancellationSlot1()) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return b.get_cancellation_slot();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_BIND_CANCELLATION_SLOT_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// bind_executor.hpp
|
// bind_executor.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#include <boost/asio/detail/type_traits.hpp>
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
#include <boost/asio/detail/variadic_templates.hpp>
|
#include <boost/asio/detail/variadic_templates.hpp>
|
||||||
#include <boost/asio/associated_executor.hpp>
|
#include <boost/asio/associated_executor.hpp>
|
||||||
#include <boost/asio/associated_allocator.hpp>
|
#include <boost/asio/associator.hpp>
|
||||||
#include <boost/asio/async_result.hpp>
|
#include <boost/asio/async_result.hpp>
|
||||||
#include <boost/asio/execution/executor.hpp>
|
#include <boost/asio/execution/executor.hpp>
|
||||||
#include <boost/asio/execution_context.hpp>
|
#include <boost/asio/execution_context.hpp>
|
||||||
|
|
@ -489,9 +489,9 @@ private:
|
||||||
template <typename Executor, typename T>
|
template <typename Executor, typename T>
|
||||||
inline executor_binder<typename decay<T>::type, Executor>
|
inline executor_binder<typename decay<T>::type, Executor>
|
||||||
bind_executor(const Executor& ex, BOOST_ASIO_MOVE_ARG(T) t,
|
bind_executor(const Executor& ex, BOOST_ASIO_MOVE_ARG(T) t,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
||||||
>::type* = 0)
|
>::type = 0)
|
||||||
{
|
{
|
||||||
return executor_binder<typename decay<T>::type, Executor>(
|
return executor_binder<typename decay<T>::type, Executor>(
|
||||||
executor_arg_t(), ex, BOOST_ASIO_MOVE_CAST(T)(t));
|
executor_arg_t(), ex, BOOST_ASIO_MOVE_CAST(T)(t));
|
||||||
|
|
@ -502,8 +502,8 @@ template <typename ExecutionContext, typename T>
|
||||||
inline executor_binder<typename decay<T>::type,
|
inline executor_binder<typename decay<T>::type,
|
||||||
typename ExecutionContext::executor_type>
|
typename ExecutionContext::executor_type>
|
||||||
bind_executor(ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(T) t,
|
bind_executor(ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(T) t,
|
||||||
typename enable_if<is_convertible<
|
typename constraint<is_convertible<
|
||||||
ExecutionContext&, execution_context&>::value>::type* = 0)
|
ExecutionContext&, execution_context&>::value>::type = 0)
|
||||||
{
|
{
|
||||||
return executor_binder<typename decay<T>::type,
|
return executor_binder<typename decay<T>::type,
|
||||||
typename ExecutionContext::executor_type>(
|
typename ExecutionContext::executor_type>(
|
||||||
|
|
@ -516,42 +516,235 @@ template <typename T, typename Executor>
|
||||||
struct uses_executor<executor_binder<T, Executor>, Executor>
|
struct uses_executor<executor_binder<T, Executor>, Executor>
|
||||||
: true_type {};
|
: true_type {};
|
||||||
|
|
||||||
template <typename T, typename Executor, typename Signature>
|
namespace detail {
|
||||||
class async_result<executor_binder<T, Executor>, Signature>
|
|
||||||
|
template <typename TargetAsyncResult, typename Executor, typename = void>
|
||||||
|
class executor_binder_completion_handler_async_result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
explicit executor_binder_completion_handler_async_result(T&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TargetAsyncResult, typename Executor>
|
||||||
|
class executor_binder_completion_handler_async_result<
|
||||||
|
TargetAsyncResult, Executor,
|
||||||
|
typename void_type<
|
||||||
|
typename TargetAsyncResult::completion_handler_type
|
||||||
|
>::type>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef executor_binder<
|
typedef executor_binder<
|
||||||
typename async_result<T, Signature>::completion_handler_type, Executor>
|
typename TargetAsyncResult::completion_handler_type, Executor>
|
||||||
completion_handler_type;
|
completion_handler_type;
|
||||||
|
|
||||||
typedef typename async_result<T, Signature>::return_type return_type;
|
explicit executor_binder_completion_handler_async_result(
|
||||||
|
typename TargetAsyncResult::completion_handler_type& handler)
|
||||||
explicit async_result(executor_binder<T, Executor>& b)
|
: target_(handler)
|
||||||
: target_(b.get())
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
return_type get()
|
typename TargetAsyncResult::return_type get()
|
||||||
{
|
{
|
||||||
return target_.get();
|
return target_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
async_result(const async_result&) BOOST_ASIO_DELETED;
|
TargetAsyncResult target_;
|
||||||
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
|
|
||||||
|
|
||||||
async_result<T, Signature> target_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Executor, typename Allocator>
|
template <typename TargetAsyncResult, typename = void>
|
||||||
struct associated_allocator<executor_binder<T, Executor>, Allocator>
|
struct executor_binder_async_result_return_type
|
||||||
{
|
{
|
||||||
typedef typename associated_allocator<T, Allocator>::type type;
|
};
|
||||||
|
|
||||||
|
template <typename TargetAsyncResult>
|
||||||
|
struct executor_binder_async_result_return_type<
|
||||||
|
TargetAsyncResult,
|
||||||
|
typename void_type<
|
||||||
|
typename TargetAsyncResult::return_type
|
||||||
|
>::type>
|
||||||
|
{
|
||||||
|
typedef typename TargetAsyncResult::return_type return_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T, typename Executor, typename Signature>
|
||||||
|
class async_result<executor_binder<T, Executor>, Signature> :
|
||||||
|
public detail::executor_binder_completion_handler_async_result<
|
||||||
|
async_result<T, Signature>, Executor>,
|
||||||
|
public detail::executor_binder_async_result_return_type<
|
||||||
|
async_result<T, Signature> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit async_result(executor_binder<T, Executor>& b)
|
||||||
|
: detail::executor_binder_completion_handler_async_result<
|
||||||
|
async_result<T, Signature>, Executor>(b.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Initiation>
|
||||||
|
struct init_wrapper
|
||||||
|
{
|
||||||
|
template <typename Init>
|
||||||
|
init_wrapper(const Executor& ex, BOOST_ASIO_MOVE_ARG(Init) init)
|
||||||
|
: ex_(ex),
|
||||||
|
initiation_(BOOST_ASIO_MOVE_CAST(Init)(init))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Handler, typename... Args>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||||
|
{
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||||
|
executor_binder<typename decay<Handler>::type, Executor>(
|
||||||
|
executor_arg_t(), ex_, BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||||
|
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Handler, typename... Args>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler,
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args) const
|
||||||
|
{
|
||||||
|
initiation_(
|
||||||
|
executor_binder<typename decay<Handler>::type, Executor>(
|
||||||
|
executor_arg_t(), ex_, BOOST_ASIO_MOVE_CAST(Handler)(handler)),
|
||||||
|
BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||||
|
{
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
|
||||||
|
executor_binder<typename decay<Handler>::type, Executor>(
|
||||||
|
executor_arg_t(), ex_, BOOST_ASIO_MOVE_CAST(Handler)(handler)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
void operator()(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler) const
|
||||||
|
{
|
||||||
|
initiation_(
|
||||||
|
executor_binder<typename decay<Handler>::type, Executor>(
|
||||||
|
executor_arg_t(), ex_, BOOST_ASIO_MOVE_CAST(Handler)(handler)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \
|
||||||
|
template <typename Handler, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
void operator()( \
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler, \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
{ \
|
||||||
|
BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)( \
|
||||||
|
executor_binder<typename decay<Handler>::type, Executor>( \
|
||||||
|
executor_arg_t(), ex_, BOOST_ASIO_MOVE_CAST(Handler)(handler)), \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template <typename Handler, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
void operator()( \
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler, \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
|
||||||
|
{ \
|
||||||
|
initiation_( \
|
||||||
|
executor_binder<typename decay<Handler>::type, Executor>( \
|
||||||
|
executor_arg_t(), ex_, BOOST_ASIO_MOVE_CAST(Handler)(handler)), \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
Executor ex_;
|
||||||
|
Initiation initiation_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Initiation, typename RawCompletionToken, typename... Args>
|
||||||
|
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,
|
||||||
|
(async_result<T, Signature>::initiate(
|
||||||
|
declval<init_wrapper<typename decay<Initiation>::type> >(),
|
||||||
|
declval<T>(), declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))
|
||||||
|
initiate(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||||
|
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
|
||||||
|
BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||||
|
{
|
||||||
|
return async_initiate<T, Signature>(
|
||||||
|
init_wrapper<typename decay<Initiation>::type>(
|
||||||
|
token.get_executor(), BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||||
|
token.get(), BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template <typename Initiation, typename RawCompletionToken>
|
||||||
|
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,
|
||||||
|
(async_result<T, Signature>::initiate(
|
||||||
|
declval<init_wrapper<typename decay<Initiation>::type> >(),
|
||||||
|
declval<T>())))
|
||||||
|
initiate(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
|
||||||
|
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
|
||||||
|
{
|
||||||
|
return async_initiate<T, Signature>(
|
||||||
|
init_wrapper<typename decay<Initiation>::type>(
|
||||||
|
token.get_executor(), BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
|
||||||
|
token.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
|
||||||
|
template <typename Initiation, typename RawCompletionToken, \
|
||||||
|
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
static BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \
|
||||||
|
(async_result<T, Signature>::initiate( \
|
||||||
|
declval<init_wrapper<typename decay<Initiation>::type> >(), \
|
||||||
|
declval<T>(), BOOST_ASIO_VARIADIC_MOVE_DECLVAL(n)))) \
|
||||||
|
initiate( \
|
||||||
|
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
|
||||||
|
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
|
||||||
|
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
{ \
|
||||||
|
return async_initiate<T, Signature>( \
|
||||||
|
init_wrapper<typename decay<Initiation>::type>( \
|
||||||
|
token.get_executor(), BOOST_ASIO_MOVE_CAST(Initiation)(initiation)), \
|
||||||
|
token.get(), BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
private:
|
||||||
|
async_result(const async_result&) BOOST_ASIO_DELETED;
|
||||||
|
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <typename, typename> class Associator,
|
||||||
|
typename T, typename Executor, typename DefaultCandidate>
|
||||||
|
struct associator<Associator, executor_binder<T, Executor>, DefaultCandidate>
|
||||||
|
{
|
||||||
|
typedef typename Associator<T, DefaultCandidate>::type type;
|
||||||
|
|
||||||
static type get(const executor_binder<T, Executor>& b,
|
static type get(const executor_binder<T, Executor>& b,
|
||||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return associated_allocator<T, Allocator>::get(b.get(), a);
|
return Associator<T, DefaultCandidate>::get(b.get(), c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffer.hpp
|
// buffer.hpp
|
||||||
// ~~~~~~~~~~
|
// ~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -387,9 +387,9 @@ private:
|
||||||
/// Get an iterator to the first element in a buffer sequence.
|
/// Get an iterator to the first element in a buffer sequence.
|
||||||
template <typename MutableBuffer>
|
template <typename MutableBuffer>
|
||||||
inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,
|
inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
|
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return static_cast<const mutable_buffer*>(detail::addressof(b));
|
return static_cast<const mutable_buffer*>(detail::addressof(b));
|
||||||
}
|
}
|
||||||
|
|
@ -397,9 +397,9 @@ inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,
|
||||||
/// Get an iterator to the first element in a buffer sequence.
|
/// Get an iterator to the first element in a buffer sequence.
|
||||||
template <typename ConstBuffer>
|
template <typename ConstBuffer>
|
||||||
inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
|
inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<const ConstBuffer*, const const_buffer*>::value
|
is_convertible<const ConstBuffer*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return static_cast<const const_buffer*>(detail::addressof(b));
|
return static_cast<const const_buffer*>(detail::addressof(b));
|
||||||
}
|
}
|
||||||
|
|
@ -409,10 +409,10 @@ inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
|
||||||
/// Get an iterator to the first element in a buffer sequence.
|
/// Get an iterator to the first element in a buffer sequence.
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline auto buffer_sequence_begin(C& c,
|
inline auto buffer_sequence_begin(C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
|
>::type = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
|
||||||
{
|
{
|
||||||
return c.begin();
|
return c.begin();
|
||||||
}
|
}
|
||||||
|
|
@ -420,10 +420,10 @@ inline auto buffer_sequence_begin(C& c,
|
||||||
/// Get an iterator to the first element in a buffer sequence.
|
/// Get an iterator to the first element in a buffer sequence.
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline auto buffer_sequence_begin(const C& c,
|
inline auto buffer_sequence_begin(const C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
|
>::type = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
|
||||||
{
|
{
|
||||||
return c.begin();
|
return c.begin();
|
||||||
}
|
}
|
||||||
|
|
@ -432,20 +432,20 @@ inline auto buffer_sequence_begin(const C& c,
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline typename C::iterator buffer_sequence_begin(C& c,
|
inline typename C::iterator buffer_sequence_begin(C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return c.begin();
|
return c.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline typename C::const_iterator buffer_sequence_begin(const C& c,
|
inline typename C::const_iterator buffer_sequence_begin(const C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return c.begin();
|
return c.begin();
|
||||||
}
|
}
|
||||||
|
|
@ -464,9 +464,9 @@ inline typename C::const_iterator buffer_sequence_begin(const C& c,
|
||||||
/// Get an iterator to one past the end element in a buffer sequence.
|
/// Get an iterator to one past the end element in a buffer sequence.
|
||||||
template <typename MutableBuffer>
|
template <typename MutableBuffer>
|
||||||
inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,
|
inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
|
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;
|
return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;
|
||||||
}
|
}
|
||||||
|
|
@ -474,9 +474,9 @@ inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,
|
||||||
/// Get an iterator to one past the end element in a buffer sequence.
|
/// Get an iterator to one past the end element in a buffer sequence.
|
||||||
template <typename ConstBuffer>
|
template <typename ConstBuffer>
|
||||||
inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
|
inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<const ConstBuffer*, const const_buffer*>::value
|
is_convertible<const ConstBuffer*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return static_cast<const const_buffer*>(detail::addressof(b)) + 1;
|
return static_cast<const const_buffer*>(detail::addressof(b)) + 1;
|
||||||
}
|
}
|
||||||
|
|
@ -486,10 +486,10 @@ inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
|
||||||
/// Get an iterator to one past the end element in a buffer sequence.
|
/// Get an iterator to one past the end element in a buffer sequence.
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline auto buffer_sequence_end(C& c,
|
inline auto buffer_sequence_end(C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
|
>::type = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
|
||||||
{
|
{
|
||||||
return c.end();
|
return c.end();
|
||||||
}
|
}
|
||||||
|
|
@ -497,10 +497,10 @@ inline auto buffer_sequence_end(C& c,
|
||||||
/// Get an iterator to one past the end element in a buffer sequence.
|
/// Get an iterator to one past the end element in a buffer sequence.
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline auto buffer_sequence_end(const C& c,
|
inline auto buffer_sequence_end(const C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
|
>::type = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
|
||||||
{
|
{
|
||||||
return c.end();
|
return c.end();
|
||||||
}
|
}
|
||||||
|
|
@ -509,20 +509,20 @@ inline auto buffer_sequence_end(const C& c,
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline typename C::iterator buffer_sequence_end(C& c,
|
inline typename C::iterator buffer_sequence_end(C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return c.end();
|
return c.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
inline typename C::const_iterator buffer_sequence_end(const C& c,
|
inline typename C::const_iterator buffer_sequence_end(const C& c,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
!is_convertible<const C*, const mutable_buffer*>::value
|
!is_convertible<const C*, const mutable_buffer*>::value
|
||||||
&& !is_convertible<const C*, const const_buffer*>::value
|
&& !is_convertible<const C*, const const_buffer*>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
{
|
{
|
||||||
return c.end();
|
return c.end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,330 @@
|
||||||
|
//
|
||||||
|
// buffer_registration.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BOOST_ASIO_BUFFER_REGISTRATION_HPP
|
||||||
|
#define BOOST_ASIO_BUFFER_REGISTRATION_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
#include <iterator>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/asio/detail/memory.hpp>
|
||||||
|
#include <boost/asio/execution/context.hpp>
|
||||||
|
#include <boost/asio/execution/executor.hpp>
|
||||||
|
#include <boost/asio/execution_context.hpp>
|
||||||
|
#include <boost/asio/is_executor.hpp>
|
||||||
|
#include <boost/asio/query.hpp>
|
||||||
|
#include <boost/asio/registered_buffer.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
# include <boost/asio/detail/scheduler.hpp>
|
||||||
|
# include <boost/asio/detail/io_uring_service.hpp>
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
# include <utility>
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
class buffer_registration_base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
static mutable_registered_buffer make_buffer(const mutable_buffer& b,
|
||||||
|
const void* scope, int index) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return mutable_registered_buffer(b, registered_buffer_id(scope, index));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Automatically registers and unregistered buffers with an execution context.
|
||||||
|
/**
|
||||||
|
* For portability, applications should assume that only one registration is
|
||||||
|
* permitted per execution context.
|
||||||
|
*/
|
||||||
|
template <typename MutableBufferSequence,
|
||||||
|
typename Allocator = std::allocator<void> >
|
||||||
|
class buffer_registration
|
||||||
|
: detail::buffer_registration_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The allocator type used for allocating storage for the buffers container.
|
||||||
|
typedef Allocator allocator_type;
|
||||||
|
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// The type of an iterator over the registered buffers.
|
||||||
|
typedef unspecified iterator;
|
||||||
|
|
||||||
|
/// The type of a const iterator over the registered buffers.
|
||||||
|
typedef unspecified const_iterator;
|
||||||
|
#else // defined(GENERATING_DOCUMENTATION)
|
||||||
|
typedef std::vector<mutable_registered_buffer>::const_iterator iterator;
|
||||||
|
typedef std::vector<mutable_registered_buffer>::const_iterator const_iterator;
|
||||||
|
#endif // defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Register buffers with an executor's execution context.
|
||||||
|
template <typename Executor>
|
||||||
|
buffer_registration(const Executor& ex,
|
||||||
|
const MutableBufferSequence& buffer_sequence,
|
||||||
|
const allocator_type& alloc = allocator_type(),
|
||||||
|
typename constraint<
|
||||||
|
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
||||||
|
>::type = 0)
|
||||||
|
: buffer_sequence_(buffer_sequence),
|
||||||
|
buffers_(
|
||||||
|
BOOST_ASIO_REBIND_ALLOC(allocator_type,
|
||||||
|
mutable_registered_buffer)(alloc))
|
||||||
|
{
|
||||||
|
init_buffers(buffer_registration::get_context(ex),
|
||||||
|
boost::asio::buffer_sequence_begin(buffer_sequence_),
|
||||||
|
boost::asio::buffer_sequence_end(buffer_sequence_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register buffers with an execution context.
|
||||||
|
template <typename ExecutionContext>
|
||||||
|
buffer_registration(ExecutionContext& ctx,
|
||||||
|
const MutableBufferSequence& buffer_sequence,
|
||||||
|
const allocator_type& alloc = allocator_type(),
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
|
>::type = 0)
|
||||||
|
: buffer_sequence_(buffer_sequence),
|
||||||
|
buffers_(
|
||||||
|
BOOST_ASIO_REBIND_ALLOC(allocator_type,
|
||||||
|
mutable_registered_buffer)(alloc))
|
||||||
|
{
|
||||||
|
init_buffers(ctx,
|
||||||
|
boost::asio::buffer_sequence_begin(buffer_sequence_),
|
||||||
|
boost::asio::buffer_sequence_end(buffer_sequence_));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move constructor.
|
||||||
|
buffer_registration(buffer_registration&& other) BOOST_ASIO_NOEXCEPT
|
||||||
|
: buffer_sequence_(std::move(other.buffer_sequence_)),
|
||||||
|
buffers_(std::move(other.buffers_))
|
||||||
|
{
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
service_ = other.service_;
|
||||||
|
other.service_ = 0;
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Unregisters the buffers.
|
||||||
|
~buffer_registration()
|
||||||
|
{
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
if (service_)
|
||||||
|
service_->unregister_buffers();
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Move assignment.
|
||||||
|
buffer_registration& operator=(
|
||||||
|
buffer_registration&& other) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
buffer_sequence_ = std::move(other.buffer_sequence_);
|
||||||
|
buffers_ = std::move(other.buffers_);
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
if (service_)
|
||||||
|
service_->unregister_buffers();
|
||||||
|
service_ = other.service_;
|
||||||
|
other.service_ = 0;
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Get the number of registered buffers.
|
||||||
|
std::size_t size() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return buffers_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the begin iterator for the sequence of registered buffers.
|
||||||
|
const_iterator begin() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return buffers_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the begin iterator for the sequence of registered buffers.
|
||||||
|
const_iterator cbegin() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return buffers_.cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the end iterator for the sequence of registered buffers.
|
||||||
|
const_iterator end() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return buffers_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the end iterator for the sequence of registered buffers.
|
||||||
|
const_iterator cend() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return buffers_.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the buffer at the specified index.
|
||||||
|
const mutable_registered_buffer& operator[](std::size_t i) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return buffers_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the buffer at the specified index.
|
||||||
|
const mutable_registered_buffer& at(std::size_t i) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return buffers_.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copying and assignment.
|
||||||
|
buffer_registration(const buffer_registration&) BOOST_ASIO_DELETED;
|
||||||
|
buffer_registration& operator=(const buffer_registration&) BOOST_ASIO_DELETED;
|
||||||
|
|
||||||
|
// Helper function to get an executor's context.
|
||||||
|
template <typename T>
|
||||||
|
static execution_context& get_context(const T& t,
|
||||||
|
typename enable_if<execution::is_executor<T>::value>::type* = 0)
|
||||||
|
{
|
||||||
|
return boost::asio::query(t, execution::context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to get an executor's context.
|
||||||
|
template <typename T>
|
||||||
|
static execution_context& get_context(const T& t,
|
||||||
|
typename enable_if<!execution::is_executor<T>::value>::type* = 0)
|
||||||
|
{
|
||||||
|
return t.context();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to initialise the container of buffers.
|
||||||
|
template <typename Iterator>
|
||||||
|
void init_buffers(execution_context& ctx, Iterator begin, Iterator end)
|
||||||
|
{
|
||||||
|
std::size_t n = std::distance(begin, end);
|
||||||
|
buffers_.resize(n);
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
service_ = &use_service<detail::io_uring_service>(ctx);
|
||||||
|
std::vector<iovec,
|
||||||
|
BOOST_ASIO_REBIND_ALLOC(allocator_type, iovec)> iovecs(n,
|
||||||
|
BOOST_ASIO_REBIND_ALLOC(allocator_type, iovec)(
|
||||||
|
buffers_.get_allocator()));
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
|
||||||
|
Iterator iter = begin;
|
||||||
|
for (int index = 0; iter != end; ++index, ++iter)
|
||||||
|
{
|
||||||
|
mutable_buffer b(*iter);
|
||||||
|
std::size_t i = static_cast<std::size_t>(index);
|
||||||
|
buffers_[i] = this->make_buffer(b, &ctx, index);
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
iovecs[i].iov_base = buffers_[i].data();
|
||||||
|
iovecs[i].iov_len = buffers_[i].size();
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
service_->register_buffers(&iovecs[0],
|
||||||
|
static_cast<unsigned>(iovecs.size()));
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
}
|
||||||
|
|
||||||
|
MutableBufferSequence buffer_sequence_;
|
||||||
|
std::vector<mutable_registered_buffer,
|
||||||
|
BOOST_ASIO_REBIND_ALLOC(allocator_type,
|
||||||
|
mutable_registered_buffer)> buffers_;
|
||||||
|
#if defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
detail::io_uring_service* service_;
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IO_URING)
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Register buffers with an execution context.
|
||||||
|
template <typename Executor, typename MutableBufferSequence>
|
||||||
|
BOOST_ASIO_NODISCARD inline
|
||||||
|
buffer_registration<MutableBufferSequence>
|
||||||
|
register_buffers(const Executor& ex,
|
||||||
|
const MutableBufferSequence& buffer_sequence,
|
||||||
|
typename constraint<
|
||||||
|
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
||||||
|
>::type = 0)
|
||||||
|
{
|
||||||
|
return buffer_registration<MutableBufferSequence>(ex, buffer_sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register buffers with an execution context.
|
||||||
|
template <typename Executor, typename MutableBufferSequence, typename Allocator>
|
||||||
|
BOOST_ASIO_NODISCARD inline
|
||||||
|
buffer_registration<MutableBufferSequence, Allocator>
|
||||||
|
register_buffers(const Executor& ex,
|
||||||
|
const MutableBufferSequence& buffer_sequence, const Allocator& alloc,
|
||||||
|
typename constraint<
|
||||||
|
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
||||||
|
>::type = 0)
|
||||||
|
{
|
||||||
|
return buffer_registration<MutableBufferSequence, Allocator>(
|
||||||
|
ex, buffer_sequence, alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register buffers with an execution context.
|
||||||
|
template <typename ExecutionContext, typename MutableBufferSequence>
|
||||||
|
BOOST_ASIO_NODISCARD inline
|
||||||
|
buffer_registration<MutableBufferSequence>
|
||||||
|
register_buffers(ExecutionContext& ctx,
|
||||||
|
const MutableBufferSequence& buffer_sequence,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
|
>::type = 0)
|
||||||
|
{
|
||||||
|
return buffer_registration<MutableBufferSequence>(ctx, buffer_sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register buffers with an execution context.
|
||||||
|
template <typename ExecutionContext,
|
||||||
|
typename MutableBufferSequence, typename Allocator>
|
||||||
|
BOOST_ASIO_NODISCARD inline
|
||||||
|
buffer_registration<MutableBufferSequence, Allocator>
|
||||||
|
register_buffers(ExecutionContext& ctx,
|
||||||
|
const MutableBufferSequence& buffer_sequence, const Allocator& alloc,
|
||||||
|
typename constraint<
|
||||||
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
|
>::type = 0)
|
||||||
|
{
|
||||||
|
return buffer_registration<MutableBufferSequence, Allocator>(
|
||||||
|
ctx, buffer_sequence, alloc);
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_BUFFER_REGISTRATION_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffered_read_stream.hpp
|
// buffered_read_stream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffered_read_stream_fwd.hpp
|
// buffered_read_stream_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffered_stream.hpp
|
// buffered_stream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffered_stream_fwd.hpp
|
// buffered_stream_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffered_write_stream.hpp
|
// buffered_write_stream.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffered_write_stream_fwd.hpp
|
// buffered_write_stream_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// buffers_iterator.hpp
|
// buffers_iterator.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,307 @@
|
||||||
|
//
|
||||||
|
// cancellation_signal.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_CANCELLATION_SIGNAL_HPP
|
||||||
|
#define BOOST_ASIO_CANCELLATION_SIGNAL_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
#include <new>
|
||||||
|
#include <utility>
|
||||||
|
#include <boost/asio/cancellation_type.hpp>
|
||||||
|
#include <boost/asio/detail/cstddef.hpp>
|
||||||
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
#include <boost/asio/detail/variadic_templates.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
class cancellation_handler_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void call(cancellation_type_t) = 0;
|
||||||
|
virtual std::pair<void*, std::size_t> destroy() BOOST_ASIO_NOEXCEPT = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~cancellation_handler_base() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
class cancellation_handler
|
||||||
|
: public cancellation_handler_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
template <typename... Args>
|
||||||
|
cancellation_handler(std::size_t size, BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||||
|
: handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...),
|
||||||
|
size_(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
cancellation_handler(std::size_t size)
|
||||||
|
: handler_(),
|
||||||
|
size_(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_HANDLER_CTOR_DEF(n) \
|
||||||
|
template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
cancellation_handler(std::size_t size, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
: handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)), \
|
||||||
|
size_(size) \
|
||||||
|
{ \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_HANDLER_CTOR_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_HANDLER_CTOR_DEF
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
void call(cancellation_type_t type)
|
||||||
|
{
|
||||||
|
handler_(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<void*, std::size_t> destroy() BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
std::pair<void*, std::size_t> mem(this, size_);
|
||||||
|
this->cancellation_handler::~cancellation_handler();
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler& handler() BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return handler_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
~cancellation_handler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler handler_;
|
||||||
|
std::size_t size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
class cancellation_slot;
|
||||||
|
|
||||||
|
/// A cancellation signal with a single slot.
|
||||||
|
class cancellation_signal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_signal()
|
||||||
|
: handler_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_DECL ~cancellation_signal();
|
||||||
|
|
||||||
|
/// Emits the signal and causes invocation of the slot's handler, if any.
|
||||||
|
void emit(cancellation_type_t type)
|
||||||
|
{
|
||||||
|
if (handler_)
|
||||||
|
handler_->call(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the single slot associated with the signal.
|
||||||
|
/**
|
||||||
|
* The signal object must remain valid for as long the slot may be used.
|
||||||
|
* Destruction of the signal invalidates the slot.
|
||||||
|
*/
|
||||||
|
cancellation_slot slot() BOOST_ASIO_NOEXCEPT;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cancellation_signal(const cancellation_signal&) BOOST_ASIO_DELETED;
|
||||||
|
cancellation_signal& operator=(const cancellation_signal&) BOOST_ASIO_DELETED;
|
||||||
|
|
||||||
|
detail::cancellation_handler_base* handler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A slot associated with a cancellation signal.
|
||||||
|
class cancellation_slot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Creates a slot that is not connected to any cancellation signal.
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_slot()
|
||||||
|
: handler_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
/// Installs a handler into the slot, constructing the new object directly.
|
||||||
|
/**
|
||||||
|
* Destroys any existing handler in the slot, then installs the new handler,
|
||||||
|
* constructing it with the supplied @c args.
|
||||||
|
*
|
||||||
|
* The handler is a function object to be called when the signal is emitted.
|
||||||
|
* The signature of the handler must be
|
||||||
|
* @code void handler(boost::asio::cancellation_type_t); @endcode
|
||||||
|
*
|
||||||
|
* @param args Arguments to be passed to the @c CancellationHandler object's
|
||||||
|
* constructor.
|
||||||
|
*
|
||||||
|
* @returns A reference to the newly installed handler.
|
||||||
|
*
|
||||||
|
* @note Handlers installed into the slot via @c emplace are not required to
|
||||||
|
* be copy constructible or move constructible.
|
||||||
|
*/
|
||||||
|
template <typename CancellationHandler, typename... Args>
|
||||||
|
CancellationHandler& emplace(BOOST_ASIO_MOVE_ARG(Args)... args)
|
||||||
|
{
|
||||||
|
typedef detail::cancellation_handler<CancellationHandler>
|
||||||
|
cancellation_handler_type;
|
||||||
|
auto_delete_helper del = { prepare_memory(
|
||||||
|
sizeof(cancellation_handler_type),
|
||||||
|
BOOST_ASIO_ALIGNOF(CancellationHandler)) };
|
||||||
|
cancellation_handler_type* handler_obj =
|
||||||
|
new (del.mem.first) cancellation_handler_type(
|
||||||
|
del.mem.second, BOOST_ASIO_MOVE_CAST(Args)(args)...);
|
||||||
|
del.mem.first = 0;
|
||||||
|
*handler_ = handler_obj;
|
||||||
|
return handler_obj->handler();
|
||||||
|
}
|
||||||
|
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
template <typename CancellationHandler>
|
||||||
|
CancellationHandler& emplace()
|
||||||
|
{
|
||||||
|
typedef detail::cancellation_handler<CancellationHandler>
|
||||||
|
cancellation_handler_type;
|
||||||
|
auto_delete_helper del = { prepare_memory(
|
||||||
|
sizeof(cancellation_handler_type),
|
||||||
|
BOOST_ASIO_ALIGNOF(CancellationHandler)) };
|
||||||
|
cancellation_handler_type* handler_obj =
|
||||||
|
new (del.mem.first) cancellation_handler_type(del.mem.second);
|
||||||
|
del.mem.first = 0;
|
||||||
|
*handler_ = handler_obj;
|
||||||
|
return handler_obj->handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_ASIO_PRIVATE_HANDLER_EMPLACE_DEF(n) \
|
||||||
|
template <typename CancellationHandler, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
|
||||||
|
CancellationHandler& emplace(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
|
||||||
|
{ \
|
||||||
|
typedef detail::cancellation_handler<CancellationHandler> \
|
||||||
|
cancellation_handler_type; \
|
||||||
|
auto_delete_helper del = { prepare_memory( \
|
||||||
|
sizeof(cancellation_handler_type), \
|
||||||
|
BOOST_ASIO_ALIGNOF(CancellationHandler)) }; \
|
||||||
|
cancellation_handler_type* handler_obj = \
|
||||||
|
new (del.mem.first) cancellation_handler_type( \
|
||||||
|
del.mem.second, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
|
||||||
|
del.mem.first = 0; \
|
||||||
|
*handler_ = handler_obj; \
|
||||||
|
return handler_obj->handler(); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_HANDLER_EMPLACE_DEF)
|
||||||
|
#undef BOOST_ASIO_PRIVATE_HANDLER_EMPLACE_DEF
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
/// Installs a handler into the slot.
|
||||||
|
/**
|
||||||
|
* Destroys any existing handler in the slot, then installs the new handler,
|
||||||
|
* constructing it as a decay-copy of the supplied handler.
|
||||||
|
*
|
||||||
|
* The handler is a function object to be called when the signal is emitted.
|
||||||
|
* The signature of the handler must be
|
||||||
|
* @code void handler(boost::asio::cancellation_type_t); @endcode
|
||||||
|
*
|
||||||
|
* @param handler The handler to be installed.
|
||||||
|
*
|
||||||
|
* @returns A reference to the newly installed handler.
|
||||||
|
*/
|
||||||
|
template <typename CancellationHandler>
|
||||||
|
typename decay<CancellationHandler>::type& assign(
|
||||||
|
BOOST_ASIO_MOVE_ARG(CancellationHandler) handler)
|
||||||
|
{
|
||||||
|
return this->emplace<typename decay<CancellationHandler>::type>(
|
||||||
|
BOOST_ASIO_MOVE_CAST(CancellationHandler)(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears the slot.
|
||||||
|
/**
|
||||||
|
* Destroys any existing handler in the slot.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_DECL void clear();
|
||||||
|
|
||||||
|
/// Returns whether the slot is connected to a signal.
|
||||||
|
BOOST_ASIO_CONSTEXPR bool is_connected() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return handler_ != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the slot is connected and has an installed handler.
|
||||||
|
BOOST_ASIO_CONSTEXPR bool has_handler() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return handler_ != 0 && *handler_ != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two slots for equality.
|
||||||
|
friend BOOST_ASIO_CONSTEXPR bool operator==(const cancellation_slot& lhs,
|
||||||
|
const cancellation_slot& rhs) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return lhs.handler_ == rhs.handler_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two slots for inequality.
|
||||||
|
friend BOOST_ASIO_CONSTEXPR bool operator!=(const cancellation_slot& lhs,
|
||||||
|
const cancellation_slot& rhs) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return lhs.handler_ != rhs.handler_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class cancellation_signal;
|
||||||
|
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_slot(int,
|
||||||
|
detail::cancellation_handler_base** handler)
|
||||||
|
: handler_(handler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_DECL std::pair<void*, std::size_t> prepare_memory(
|
||||||
|
std::size_t size, std::size_t align);
|
||||||
|
|
||||||
|
struct auto_delete_helper
|
||||||
|
{
|
||||||
|
std::pair<void*, std::size_t> mem;
|
||||||
|
|
||||||
|
BOOST_ASIO_DECL ~auto_delete_helper();
|
||||||
|
};
|
||||||
|
|
||||||
|
detail::cancellation_handler_base** handler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline cancellation_slot cancellation_signal::slot() BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return cancellation_slot(0, &handler_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HEADER_ONLY)
|
||||||
|
# include <boost/asio/impl/cancellation_signal.ipp>
|
||||||
|
#endif // defined(BOOST_ASIO_HEADER_ONLY)
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_CANCELLATION_SIGNAL_HPP
|
||||||
|
|
@ -0,0 +1,237 @@
|
||||||
|
//
|
||||||
|
// cancellation_state.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_CANCELLATION_STATE_HPP
|
||||||
|
#define BOOST_ASIO_CANCELLATION_STATE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
#include <new>
|
||||||
|
#include <utility>
|
||||||
|
#include <boost/asio/cancellation_signal.hpp>
|
||||||
|
#include <boost/asio/detail/cstddef.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
/// A simple cancellation signal propagation filter.
|
||||||
|
template <cancellation_type_t Mask>
|
||||||
|
struct cancellation_filter
|
||||||
|
{
|
||||||
|
/// Returns <tt>type & Mask</tt>.
|
||||||
|
cancellation_type_t operator()(
|
||||||
|
cancellation_type_t type) const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return type & Mask;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A cancellation filter that disables cancellation.
|
||||||
|
typedef cancellation_filter<cancellation_type::none>
|
||||||
|
disable_cancellation;
|
||||||
|
|
||||||
|
/// A cancellation filter that enables terminal cancellation only.
|
||||||
|
typedef cancellation_filter<cancellation_type::terminal>
|
||||||
|
enable_terminal_cancellation;
|
||||||
|
|
||||||
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// A cancellation filter that enables terminal and partial cancellation.
|
||||||
|
typedef cancellation_filter<
|
||||||
|
cancellation_type::terminal | cancellation_type::partial>
|
||||||
|
enable_partial_cancellation;
|
||||||
|
|
||||||
|
/// A cancellation filter that enables terminal, partial and total cancellation.
|
||||||
|
typedef cancellation_filter<cancellation_type::terminal
|
||||||
|
| cancellation_type::partial | cancellation_type::total>
|
||||||
|
enable_total_cancellation;
|
||||||
|
|
||||||
|
#else // defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
typedef cancellation_filter<
|
||||||
|
static_cast<cancellation_type_t>(
|
||||||
|
static_cast<unsigned int>(cancellation_type::terminal)
|
||||||
|
| static_cast<unsigned int>(cancellation_type::partial))>
|
||||||
|
enable_partial_cancellation;
|
||||||
|
|
||||||
|
typedef cancellation_filter<
|
||||||
|
static_cast<cancellation_type_t>(
|
||||||
|
static_cast<unsigned int>(cancellation_type::terminal)
|
||||||
|
| static_cast<unsigned int>(cancellation_type::partial)
|
||||||
|
| static_cast<unsigned int>(cancellation_type::total))>
|
||||||
|
enable_total_cancellation;
|
||||||
|
|
||||||
|
#endif // defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// A cancellation state is used for chaining signals and slots in compositions.
|
||||||
|
class cancellation_state
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Construct a disconnected cancellation state.
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_state() BOOST_ASIO_NOEXCEPT
|
||||||
|
: impl_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and attach to a parent slot to create a new child slot.
|
||||||
|
/**
|
||||||
|
* Initialises the cancellation state so that it allows terminal cancellation
|
||||||
|
* only. Equivalent to <tt>cancellation_state(slot,
|
||||||
|
* enable_terminal_cancellation())</tt>.
|
||||||
|
*
|
||||||
|
* @param slot The parent cancellation slot to which the state will be
|
||||||
|
* attached.
|
||||||
|
*/
|
||||||
|
template <typename CancellationSlot>
|
||||||
|
BOOST_ASIO_CONSTEXPR explicit cancellation_state(CancellationSlot slot)
|
||||||
|
: impl_(slot.is_connected() ? &slot.template emplace<impl<> >() : 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and attach to a parent slot to create a new child slot.
|
||||||
|
/**
|
||||||
|
* @param slot The parent cancellation slot to which the state will be
|
||||||
|
* attached.
|
||||||
|
*
|
||||||
|
* @param filter A function object that is used to transform incoming
|
||||||
|
* cancellation signals as they are received from the parent slot. This
|
||||||
|
* function object must have the signature:
|
||||||
|
* @code boost::asio::cancellation_type_t filter(
|
||||||
|
* boost::asio::cancellation_type_t); @endcode
|
||||||
|
*
|
||||||
|
* The library provides the following pre-defined cancellation filters:
|
||||||
|
*
|
||||||
|
* @li boost::asio::disable_cancellation
|
||||||
|
* @li boost::asio::enable_terminal_cancellation
|
||||||
|
* @li boost::asio::enable_partial_cancellation
|
||||||
|
* @li boost::asio::enable_total_cancellation
|
||||||
|
*/
|
||||||
|
template <typename CancellationSlot, typename Filter>
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_state(CancellationSlot slot, Filter filter)
|
||||||
|
: impl_(slot.is_connected()
|
||||||
|
? &slot.template emplace<impl<Filter, Filter> >(filter, filter)
|
||||||
|
: 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct and attach to a parent slot to create a new child slot.
|
||||||
|
/**
|
||||||
|
* @param slot The parent cancellation slot to which the state will be
|
||||||
|
* attached.
|
||||||
|
*
|
||||||
|
* @param in_filter A function object that is used to transform incoming
|
||||||
|
* cancellation signals as they are received from the parent slot. This
|
||||||
|
* function object must have the signature:
|
||||||
|
* @code boost::asio::cancellation_type_t in_filter(
|
||||||
|
* boost::asio::cancellation_type_t); @endcode
|
||||||
|
*
|
||||||
|
* @param out_filter A function object that is used to transform outcoming
|
||||||
|
* cancellation signals as they are relayed to the child slot. This function
|
||||||
|
* object must have the signature:
|
||||||
|
* @code boost::asio::cancellation_type_t out_filter(
|
||||||
|
* boost::asio::cancellation_type_t); @endcode
|
||||||
|
*
|
||||||
|
* The library provides the following pre-defined cancellation filters:
|
||||||
|
*
|
||||||
|
* @li boost::asio::disable_cancellation
|
||||||
|
* @li boost::asio::enable_terminal_cancellation
|
||||||
|
* @li boost::asio::enable_partial_cancellation
|
||||||
|
* @li boost::asio::enable_total_cancellation
|
||||||
|
*/
|
||||||
|
template <typename CancellationSlot, typename InFilter, typename OutFilter>
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_state(CancellationSlot slot,
|
||||||
|
InFilter in_filter, OutFilter out_filter)
|
||||||
|
: impl_(slot.is_connected()
|
||||||
|
? &slot.template emplace<impl<InFilter, OutFilter> >(
|
||||||
|
BOOST_ASIO_MOVE_CAST(InFilter)(in_filter),
|
||||||
|
BOOST_ASIO_MOVE_CAST(OutFilter)(out_filter))
|
||||||
|
: 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the single child slot associated with the state.
|
||||||
|
/**
|
||||||
|
* This sub-slot is used with the operations that are being composed.
|
||||||
|
*/
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_slot slot() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return impl_ ? impl_->signal_.slot() : cancellation_slot();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the cancellation types that have been triggered.
|
||||||
|
cancellation_type_t cancelled() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return impl_ ? impl_->cancelled_ : cancellation_type_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears the specified cancellation types, if they have been triggered.
|
||||||
|
void clear(cancellation_type_t mask = cancellation_type::all)
|
||||||
|
BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (impl_)
|
||||||
|
impl_->cancelled_ &= ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct impl_base
|
||||||
|
{
|
||||||
|
impl_base()
|
||||||
|
: cancelled_()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cancellation_signal signal_;
|
||||||
|
cancellation_type_t cancelled_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename InFilter = enable_terminal_cancellation,
|
||||||
|
typename OutFilter = InFilter>
|
||||||
|
struct impl : impl_base
|
||||||
|
{
|
||||||
|
impl()
|
||||||
|
: in_filter_(),
|
||||||
|
out_filter_()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
impl(InFilter in_filter, OutFilter out_filter)
|
||||||
|
: in_filter_(BOOST_ASIO_MOVE_CAST(InFilter)(in_filter)),
|
||||||
|
out_filter_(BOOST_ASIO_MOVE_CAST(OutFilter)(out_filter))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(cancellation_type_t in)
|
||||||
|
{
|
||||||
|
this->cancelled_ = in_filter_(in);
|
||||||
|
cancellation_type_t out = out_filter_(this->cancelled_);
|
||||||
|
if (out != cancellation_type::none)
|
||||||
|
this->signal_.emit(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
InFilter in_filter_;
|
||||||
|
OutFilter out_filter_;
|
||||||
|
};
|
||||||
|
|
||||||
|
impl_base* impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_CANCELLATION_STATE_HPP
|
||||||
|
|
@ -0,0 +1,176 @@
|
||||||
|
//
|
||||||
|
// cancellation_type.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_CANCELLATION_TYPE_HPP
|
||||||
|
#define BOOST_ASIO_CANCELLATION_TYPE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
# if defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
/// Enumeration representing the different types of cancellation that may
|
||||||
|
/// be requested from or implemented by an asynchronous operation.
|
||||||
|
enum cancellation_type
|
||||||
|
{
|
||||||
|
/// Bitmask representing no types of cancellation.
|
||||||
|
none = 0,
|
||||||
|
|
||||||
|
/// Requests cancellation where, following a successful cancellation, the only
|
||||||
|
/// safe operations on the I/O object are closure or destruction.
|
||||||
|
terminal = 1,
|
||||||
|
|
||||||
|
/// Requests cancellation where a successful cancellation may result in
|
||||||
|
/// partial side effects or no side effects. Following cancellation, the I/O
|
||||||
|
/// object is in a well-known state, and may be used for further operations.
|
||||||
|
partial = 2,
|
||||||
|
|
||||||
|
/// Requests cancellation where a successful cancellation results in no
|
||||||
|
/// apparent side effects. Following cancellation, the I/O object is in the
|
||||||
|
/// same observable state as it was prior to the operation.
|
||||||
|
total = 4,
|
||||||
|
|
||||||
|
/// Bitmask representing all types of cancellation.
|
||||||
|
all = 0xFFFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Portability typedef.
|
||||||
|
typedef cancellation_type cancellation_type_t;
|
||||||
|
|
||||||
|
#elif defined(BOOST_ASIO_HAS_ENUM_CLASS)
|
||||||
|
|
||||||
|
enum class cancellation_type : unsigned int
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
terminal = 1,
|
||||||
|
partial = 2,
|
||||||
|
total = 4,
|
||||||
|
all = 0xFFFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef cancellation_type cancellation_type_t;
|
||||||
|
|
||||||
|
#else // defined(BOOST_ASIO_HAS_ENUM_CLASS)
|
||||||
|
|
||||||
|
namespace cancellation_type {
|
||||||
|
|
||||||
|
enum cancellation_type_t
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
terminal = 1,
|
||||||
|
partial = 2,
|
||||||
|
total = 4,
|
||||||
|
all = 0xFFFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cancellation_type
|
||||||
|
|
||||||
|
typedef cancellation_type::cancellation_type_t cancellation_type_t;
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_ENUM_CLASS)
|
||||||
|
|
||||||
|
/// Negation operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline BOOST_ASIO_CONSTEXPR bool operator!(cancellation_type_t x)
|
||||||
|
{
|
||||||
|
return static_cast<unsigned int>(x) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitwise and operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline BOOST_ASIO_CONSTEXPR cancellation_type_t operator&(
|
||||||
|
cancellation_type_t x, cancellation_type_t y)
|
||||||
|
{
|
||||||
|
return static_cast<cancellation_type_t>(
|
||||||
|
static_cast<unsigned int>(x) & static_cast<unsigned int>(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitwise or operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline BOOST_ASIO_CONSTEXPR cancellation_type_t operator|(
|
||||||
|
cancellation_type_t x, cancellation_type_t y)
|
||||||
|
{
|
||||||
|
return static_cast<cancellation_type_t>(
|
||||||
|
static_cast<unsigned int>(x) | static_cast<unsigned int>(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitwise xor operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline BOOST_ASIO_CONSTEXPR cancellation_type_t operator^(
|
||||||
|
cancellation_type_t x, cancellation_type_t y)
|
||||||
|
{
|
||||||
|
return static_cast<cancellation_type_t>(
|
||||||
|
static_cast<unsigned int>(x) ^ static_cast<unsigned int>(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitwise negation operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline BOOST_ASIO_CONSTEXPR cancellation_type_t operator~(cancellation_type_t x)
|
||||||
|
{
|
||||||
|
return static_cast<cancellation_type_t>(~static_cast<unsigned int>(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitwise and-assignment operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline cancellation_type_t& operator&=(
|
||||||
|
cancellation_type_t& x, cancellation_type_t y)
|
||||||
|
{
|
||||||
|
x = x & y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitwise or-assignment operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline cancellation_type_t& operator|=(
|
||||||
|
cancellation_type_t& x, cancellation_type_t y)
|
||||||
|
{
|
||||||
|
x = x | y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bitwise xor-assignment operator.
|
||||||
|
/**
|
||||||
|
* @relates cancellation_type
|
||||||
|
*/
|
||||||
|
inline cancellation_type_t& operator^=(
|
||||||
|
cancellation_type_t& x, cancellation_type_t y)
|
||||||
|
{
|
||||||
|
x = x ^ y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_CANCELLATION_TYPE_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// co_spawn.hpp
|
// co_spawn.hpp
|
||||||
// ~~~~~~~~~~~~
|
// ~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -96,6 +96,11 @@ struct awaitable_signature<awaitable<void, Executor>>
|
||||||
* std::cout << "transferred " << n << "\n";
|
* std::cout << "transferred " << n << "\n";
|
||||||
* });
|
* });
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* The new thread of execution is created with a cancellation state that
|
||||||
|
* supports @c cancellation_type::terminal values only. To change the
|
||||||
|
* cancellation state, call boost::asio::this_coro::reset_cancellation_state.
|
||||||
*/
|
*/
|
||||||
template <typename Executor, typename T, typename AwaitableExecutor,
|
template <typename Executor, typename T, typename AwaitableExecutor,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||||
|
|
@ -106,10 +111,10 @@ inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||||
co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a,
|
co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a,
|
||||||
CompletionToken&& token
|
CompletionToken&& token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
(is_executor<Executor>::value || execution::is_executor<Executor>::value)
|
(is_executor<Executor>::value || execution::is_executor<Executor>::value)
|
||||||
&& is_convertible<Executor, AwaitableExecutor>::value
|
&& is_convertible<Executor, AwaitableExecutor>::value
|
||||||
>::type* = 0);
|
>::type = 0);
|
||||||
|
|
||||||
/// Spawn a new coroutined-based thread of execution.
|
/// Spawn a new coroutined-based thread of execution.
|
||||||
/**
|
/**
|
||||||
|
|
@ -152,6 +157,11 @@ co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a,
|
||||||
* echo(std::move(my_tcp_socket)),
|
* echo(std::move(my_tcp_socket)),
|
||||||
* boost::asio::detached);
|
* boost::asio::detached);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* The new thread of execution is created with a cancellation state that
|
||||||
|
* supports @c cancellation_type::terminal values only. To change the
|
||||||
|
* cancellation state, call boost::asio::this_coro::reset_cancellation_state.
|
||||||
*/
|
*/
|
||||||
template <typename Executor, typename AwaitableExecutor,
|
template <typename Executor, typename AwaitableExecutor,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||||
|
|
@ -162,10 +172,10 @@ inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
|
||||||
co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a,
|
co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a,
|
||||||
CompletionToken&& token
|
CompletionToken&& token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
(is_executor<Executor>::value || execution::is_executor<Executor>::value)
|
(is_executor<Executor>::value || execution::is_executor<Executor>::value)
|
||||||
&& is_convertible<Executor, AwaitableExecutor>::value
|
&& is_convertible<Executor, AwaitableExecutor>::value
|
||||||
>::type* = 0);
|
>::type = 0);
|
||||||
|
|
||||||
/// Spawn a new coroutined-based thread of execution.
|
/// Spawn a new coroutined-based thread of execution.
|
||||||
/**
|
/**
|
||||||
|
|
@ -216,6 +226,11 @@ co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a,
|
||||||
* std::cout << "transferred " << n << "\n";
|
* std::cout << "transferred " << n << "\n";
|
||||||
* });
|
* });
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* The new thread of execution is created with a cancellation state that
|
||||||
|
* supports @c cancellation_type::terminal values only. To change the
|
||||||
|
* cancellation state, call boost::asio::this_coro::reset_cancellation_state.
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext, typename T, typename AwaitableExecutor,
|
template <typename ExecutionContext, typename T, typename AwaitableExecutor,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||||
|
|
@ -228,11 +243,11 @@ co_spawn(ExecutionContext& ctx, awaitable<T, AwaitableExecutor> a,
|
||||||
CompletionToken&& token
|
CompletionToken&& token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
||||||
typename ExecutionContext::executor_type),
|
typename ExecutionContext::executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
&& is_convertible<typename ExecutionContext::executor_type,
|
&& is_convertible<typename ExecutionContext::executor_type,
|
||||||
AwaitableExecutor>::value
|
AwaitableExecutor>::value
|
||||||
>::type* = 0);
|
>::type = 0);
|
||||||
|
|
||||||
/// Spawn a new coroutined-based thread of execution.
|
/// Spawn a new coroutined-based thread of execution.
|
||||||
/**
|
/**
|
||||||
|
|
@ -275,6 +290,11 @@ co_spawn(ExecutionContext& ctx, awaitable<T, AwaitableExecutor> a,
|
||||||
* echo(std::move(my_tcp_socket)),
|
* echo(std::move(my_tcp_socket)),
|
||||||
* boost::asio::detached);
|
* boost::asio::detached);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* The new thread of execution is created with a cancellation state that
|
||||||
|
* supports @c cancellation_type::terminal values only. To change the
|
||||||
|
* cancellation state, call boost::asio::this_coro::reset_cancellation_state.
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext, typename AwaitableExecutor,
|
template <typename ExecutionContext, typename AwaitableExecutor,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||||
|
|
@ -287,11 +307,11 @@ co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a,
|
||||||
CompletionToken&& token
|
CompletionToken&& token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
||||||
typename ExecutionContext::executor_type),
|
typename ExecutionContext::executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
&& is_convertible<typename ExecutionContext::executor_type,
|
&& is_convertible<typename ExecutionContext::executor_type,
|
||||||
AwaitableExecutor>::value
|
AwaitableExecutor>::value
|
||||||
>::type* = 0);
|
>::type = 0);
|
||||||
|
|
||||||
/// Spawn a new coroutined-based thread of execution.
|
/// Spawn a new coroutined-based thread of execution.
|
||||||
/**
|
/**
|
||||||
|
|
@ -310,7 +330,6 @@ co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a,
|
||||||
* Otherwise, the function signature of the completion handler must be:
|
* Otherwise, the function signature of the completion handler must be:
|
||||||
* @code void handler(std::exception_ptr, R); @endcode
|
* @code void handler(std::exception_ptr, R); @endcode
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @par Example
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
|
* boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
|
||||||
|
|
@ -362,6 +381,11 @@ co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a,
|
||||||
* }
|
* }
|
||||||
* }, boost::asio::detached);
|
* }, boost::asio::detached);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* The new thread of execution is created with a cancellation state that
|
||||||
|
* supports @c cancellation_type::terminal values only. To change the
|
||||||
|
* cancellation state, call boost::asio::this_coro::reset_cancellation_state.
|
||||||
*/
|
*/
|
||||||
template <typename Executor, typename F,
|
template <typename Executor, typename F,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
|
||||||
|
|
@ -372,9 +396,9 @@ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
|
||||||
co_spawn(const Executor& ex, F&& f,
|
co_spawn(const Executor& ex, F&& f,
|
||||||
CompletionToken&& token
|
CompletionToken&& token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
is_executor<Executor>::value || execution::is_executor<Executor>::value
|
||||||
>::type* = 0);
|
>::type = 0);
|
||||||
|
|
||||||
/// Spawn a new coroutined-based thread of execution.
|
/// Spawn a new coroutined-based thread of execution.
|
||||||
/**
|
/**
|
||||||
|
|
@ -393,7 +417,6 @@ co_spawn(const Executor& ex, F&& f,
|
||||||
* Otherwise, the function signature of the completion handler must be:
|
* Otherwise, the function signature of the completion handler must be:
|
||||||
* @code void handler(std::exception_ptr, R); @endcode
|
* @code void handler(std::exception_ptr, R); @endcode
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @par Example
|
* @par Example
|
||||||
* @code
|
* @code
|
||||||
* boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
|
* boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
|
||||||
|
|
@ -445,6 +468,11 @@ co_spawn(const Executor& ex, F&& f,
|
||||||
* }
|
* }
|
||||||
* }, boost::asio::detached);
|
* }, boost::asio::detached);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* The new thread of execution is created with a cancellation state that
|
||||||
|
* supports @c cancellation_type::terminal values only. To change the
|
||||||
|
* cancellation state, call boost::asio::this_coro::reset_cancellation_state.
|
||||||
*/
|
*/
|
||||||
template <typename ExecutionContext, typename F,
|
template <typename ExecutionContext, typename F,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
|
||||||
|
|
@ -457,9 +485,9 @@ co_spawn(ExecutionContext& ctx, F&& f,
|
||||||
CompletionToken&& token
|
CompletionToken&& token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
||||||
typename ExecutionContext::executor_type),
|
typename ExecutionContext::executor_type),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<ExecutionContext&, execution_context&>::value
|
is_convertible<ExecutionContext&, execution_context&>::value
|
||||||
>::type* = 0);
|
>::type = 0);
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// completion_condition.hpp
|
// completion_condition.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// compose.hpp
|
// compose.hpp
|
||||||
// ~~~~~~~~~~~
|
// ~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// connect.hpp
|
// connect.hpp
|
||||||
// ~~~~~~~~~~~
|
// ~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -91,8 +91,8 @@ struct is_endpoint_sequence
|
||||||
template <typename Protocol, typename Executor, typename EndpointSequence>
|
template <typename Protocol, typename Executor, typename EndpointSequence>
|
||||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||||
const EndpointSequence& endpoints,
|
const EndpointSequence& endpoints,
|
||||||
typename enable_if<is_endpoint_sequence<
|
typename constraint<is_endpoint_sequence<
|
||||||
EndpointSequence>::value>::type* = 0);
|
EndpointSequence>::value>::type = 0);
|
||||||
|
|
||||||
/// Establishes a socket connection by trying each endpoint in a sequence.
|
/// Establishes a socket connection by trying each endpoint in a sequence.
|
||||||
/**
|
/**
|
||||||
|
|
@ -127,8 +127,8 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||||
template <typename Protocol, typename Executor, typename EndpointSequence>
|
template <typename Protocol, typename Executor, typename EndpointSequence>
|
||||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||||
const EndpointSequence& endpoints, boost::system::error_code& ec,
|
const EndpointSequence& endpoints, boost::system::error_code& ec,
|
||||||
typename enable_if<is_endpoint_sequence<
|
typename constraint<is_endpoint_sequence<
|
||||||
EndpointSequence>::value>::type* = 0);
|
EndpointSequence>::value>::type = 0);
|
||||||
|
|
||||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
||||||
|
|
@ -157,7 +157,7 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor, typename Iterator>
|
template <typename Protocol, typename Executor, typename Iterator>
|
||||||
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
|
typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);
|
||||||
|
|
||||||
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
||||||
/// each endpoint in a sequence.
|
/// each endpoint in a sequence.
|
||||||
|
|
@ -186,7 +186,7 @@ Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||||
template <typename Protocol, typename Executor, typename Iterator>
|
template <typename Protocol, typename Executor, typename Iterator>
|
||||||
Iterator connect(basic_socket<Protocol, Executor>& s,
|
Iterator connect(basic_socket<Protocol, Executor>& s,
|
||||||
Iterator begin, boost::system::error_code& ec,
|
Iterator begin, boost::system::error_code& ec,
|
||||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
|
typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);
|
||||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
|
||||||
/// Establishes a socket connection by trying each endpoint in a sequence.
|
/// Establishes a socket connection by trying each endpoint in a sequence.
|
||||||
|
|
@ -312,8 +312,8 @@ template <typename Protocol, typename Executor,
|
||||||
typename EndpointSequence, typename ConnectCondition>
|
typename EndpointSequence, typename ConnectCondition>
|
||||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||||
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
||||||
typename enable_if<is_endpoint_sequence<
|
typename constraint<is_endpoint_sequence<
|
||||||
EndpointSequence>::value>::type* = 0);
|
EndpointSequence>::value>::type = 0);
|
||||||
|
|
||||||
/// Establishes a socket connection by trying each endpoint in a sequence.
|
/// Establishes a socket connection by trying each endpoint in a sequence.
|
||||||
/**
|
/**
|
||||||
|
|
@ -380,8 +380,8 @@ template <typename Protocol, typename Executor,
|
||||||
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
|
||||||
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
||||||
boost::system::error_code& ec,
|
boost::system::error_code& ec,
|
||||||
typename enable_if<is_endpoint_sequence<
|
typename constraint<is_endpoint_sequence<
|
||||||
EndpointSequence>::value>::type* = 0);
|
EndpointSequence>::value>::type = 0);
|
||||||
|
|
||||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
||||||
|
|
@ -423,7 +423,7 @@ template <typename Protocol, typename Executor,
|
||||||
typename Iterator, typename ConnectCondition>
|
typename Iterator, typename ConnectCondition>
|
||||||
Iterator connect(basic_socket<Protocol, Executor>& s,
|
Iterator connect(basic_socket<Protocol, Executor>& s,
|
||||||
Iterator begin, ConnectCondition connect_condition,
|
Iterator begin, ConnectCondition connect_condition,
|
||||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
|
typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);
|
||||||
|
|
||||||
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
|
||||||
/// each endpoint in a sequence.
|
/// each endpoint in a sequence.
|
||||||
|
|
@ -464,7 +464,7 @@ template <typename Protocol, typename Executor,
|
||||||
typename Iterator, typename ConnectCondition>
|
typename Iterator, typename ConnectCondition>
|
||||||
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||||
ConnectCondition connect_condition, boost::system::error_code& ec,
|
ConnectCondition connect_condition, boost::system::error_code& ec,
|
||||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
|
typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);
|
||||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
|
||||||
/// Establishes a socket connection by trying each endpoint in a sequence.
|
/// Establishes a socket connection by trying each endpoint in a sequence.
|
||||||
|
|
@ -665,6 +665,16 @@ Iterator connect(basic_socket<Protocol, Executor>& s,
|
||||||
* {
|
* {
|
||||||
* // ...
|
* // ...
|
||||||
* } @endcode
|
* } @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* if they are also supported by the socket's @c async_connect operation.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor, typename EndpointSequence,
|
template <typename Protocol, typename Executor, typename EndpointSequence,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -676,8 +686,8 @@ async_connect(basic_socket<Protocol, Executor>& s,
|
||||||
const EndpointSequence& endpoints,
|
const EndpointSequence& endpoints,
|
||||||
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler
|
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<is_endpoint_sequence<
|
typename constraint<is_endpoint_sequence<
|
||||||
EndpointSequence>::value>::type* = 0);
|
EndpointSequence>::value>::type = 0);
|
||||||
|
|
||||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
|
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
|
||||||
|
|
@ -714,6 +724,16 @@ async_connect(basic_socket<Protocol, Executor>& s,
|
||||||
* @note This overload assumes that a default constructed object of type @c
|
* @note This overload assumes that a default constructed object of type @c
|
||||||
* Iterator represents the end of the sequence. This is a valid assumption for
|
* Iterator represents the end of the sequence. This is a valid assumption for
|
||||||
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
|
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* if they are also supported by the socket's @c async_connect operation.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor, typename Iterator,
|
template <typename Protocol, typename Executor, typename Iterator,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -724,7 +744,7 @@ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
|
||||||
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||||
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
|
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
|
typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);
|
||||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
|
||||||
/// Asynchronously establishes a socket connection by trying each endpoint in a
|
/// Asynchronously establishes a socket connection by trying each endpoint in a
|
||||||
|
|
@ -775,6 +795,16 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||||
* {
|
* {
|
||||||
* // ...
|
* // ...
|
||||||
* } @endcode
|
* } @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* if they are also supported by the socket's @c async_connect operation.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor, typename Iterator,
|
template <typename Protocol, typename Executor, typename Iterator,
|
||||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||||
|
|
@ -880,6 +910,16 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
|
||||||
* std::cout << "Connected to: " << endpoint << std::endl;
|
* std::cout << "Connected to: " << endpoint << std::endl;
|
||||||
* }
|
* }
|
||||||
* } @endcode
|
* } @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* if they are also supported by the socket's @c async_connect operation.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor,
|
template <typename Protocol, typename Executor,
|
||||||
typename EndpointSequence, typename ConnectCondition,
|
typename EndpointSequence, typename ConnectCondition,
|
||||||
|
|
@ -892,8 +932,8 @@ async_connect(basic_socket<Protocol, Executor>& s,
|
||||||
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
const EndpointSequence& endpoints, ConnectCondition connect_condition,
|
||||||
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler
|
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<is_endpoint_sequence<
|
typename constraint<is_endpoint_sequence<
|
||||||
EndpointSequence>::value>::type* = 0);
|
EndpointSequence>::value>::type = 0);
|
||||||
|
|
||||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
|
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
|
||||||
|
|
@ -941,6 +981,16 @@ async_connect(basic_socket<Protocol, Executor>& s,
|
||||||
* @note This overload assumes that a default constructed object of type @c
|
* @note This overload assumes that a default constructed object of type @c
|
||||||
* Iterator represents the end of the sequence. This is a valid assumption for
|
* Iterator represents the end of the sequence. This is a valid assumption for
|
||||||
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
|
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* if they are also supported by the socket's @c async_connect operation.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor,
|
template <typename Protocol, typename Executor,
|
||||||
typename Iterator, typename ConnectCondition,
|
typename Iterator, typename ConnectCondition,
|
||||||
|
|
@ -953,7 +1003,7 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||||
ConnectCondition connect_condition,
|
ConnectCondition connect_condition,
|
||||||
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
|
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
|
typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);
|
||||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
|
||||||
/// Asynchronously establishes a socket connection by trying each endpoint in a
|
/// Asynchronously establishes a socket connection by trying each endpoint in a
|
||||||
|
|
@ -1053,6 +1103,16 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
|
||||||
* std::cout << "Connected to: " << i->endpoint() << std::endl;
|
* std::cout << "Connected to: " << i->endpoint() << std::endl;
|
||||||
* }
|
* }
|
||||||
* } @endcode
|
* } @endcode
|
||||||
|
*
|
||||||
|
* @par Per-Operation Cancellation
|
||||||
|
* This asynchronous operation supports cancellation for the following
|
||||||
|
* boost::asio::cancellation_type values:
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::terminal
|
||||||
|
*
|
||||||
|
* @li @c cancellation_type::partial
|
||||||
|
*
|
||||||
|
* if they are also supported by the socket's @c async_connect operation.
|
||||||
*/
|
*/
|
||||||
template <typename Protocol, typename Executor,
|
template <typename Protocol, typename Executor,
|
||||||
typename Iterator, typename ConnectCondition,
|
typename Iterator, typename ConnectCondition,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
//
|
||||||
|
// connect_pipe.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_CONNECT_PIPE_HPP
|
||||||
|
#define BOOST_ASIO_CONNECT_PIPE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include <boost/asio/detail/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_PIPE) \
|
||||||
|
|| defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#include <boost/asio/basic_readable_pipe.hpp>
|
||||||
|
#include <boost/asio/basic_writable_pipe.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
typedef HANDLE native_pipe_handle;
|
||||||
|
#else // defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
typedef int native_pipe_handle;
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
||||||
|
|
||||||
|
BOOST_ASIO_DECL void create_pipe(native_pipe_handle p[2],
|
||||||
|
boost::system::error_code& ec);
|
||||||
|
|
||||||
|
BOOST_ASIO_DECL void close_pipe(native_pipe_handle p);
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Connect two pipe ends using an anonymous pipe.
|
||||||
|
/**
|
||||||
|
* @param read_end The read end of the pipe.
|
||||||
|
*
|
||||||
|
* @param write_end The write end of the pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*/
|
||||||
|
template <typename Executor1, typename Executor2>
|
||||||
|
void connect_pipe(basic_readable_pipe<Executor1>& read_end,
|
||||||
|
basic_writable_pipe<Executor2>& write_end);
|
||||||
|
|
||||||
|
/// Connect two pipe ends using an anonymous pipe.
|
||||||
|
/**
|
||||||
|
* @param read_end The read end of the pipe.
|
||||||
|
*
|
||||||
|
* @param write_end The write end of the pipe.
|
||||||
|
*
|
||||||
|
* @throws boost::system::system_error Thrown on failure.
|
||||||
|
*
|
||||||
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
|
*/
|
||||||
|
template <typename Executor1, typename Executor2>
|
||||||
|
BOOST_ASIO_SYNC_OP_VOID connect_pipe(basic_readable_pipe<Executor1>& read_end,
|
||||||
|
basic_writable_pipe<Executor2>& write_end, boost::system::error_code& ec);
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/impl/connect_pipe.hpp>
|
||||||
|
#if defined(BOOST_ASIO_HEADER_ONLY)
|
||||||
|
# include <boost/asio/impl/connect_pipe.ipp>
|
||||||
|
#endif // defined(BOOST_ASIO_HEADER_ONLY)
|
||||||
|
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_PIPE)
|
||||||
|
// || defined(GENERATING_DOCUMENTATION)
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_CONNECT_PIPE_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// coroutine.hpp
|
// coroutine.hpp
|
||||||
// ~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// deadline_timer.hpp
|
// deadline_timer.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// defer.hpp
|
// defer.hpp
|
||||||
// ~~~~~~~~~
|
// ~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -102,9 +102,9 @@ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
|
||||||
const Executor& ex,
|
const Executor& ex,
|
||||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token
|
BOOST_ASIO_MOVE_ARG(CompletionToken) token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
execution::is_executor<Executor>::value || is_executor<Executor>::value
|
execution::is_executor<Executor>::value || is_executor<Executor>::value
|
||||||
>::type* = 0);
|
>::type = 0);
|
||||||
|
|
||||||
/// Submits a completion token or function object for execution.
|
/// Submits a completion token or function object for execution.
|
||||||
/**
|
/**
|
||||||
|
|
@ -119,8 +119,8 @@ BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) defer(
|
||||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token
|
BOOST_ASIO_MOVE_ARG(CompletionToken) token
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
|
||||||
typename ExecutionContext::executor_type),
|
typename ExecutionContext::executor_type),
|
||||||
typename enable_if<is_convertible<
|
typename constraint<is_convertible<
|
||||||
ExecutionContext&, execution_context&>::value>::type* = 0);
|
ExecutionContext&, execution_context&>::value>::type = 0);
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detached.hpp
|
// detached.hpp
|
||||||
// ~~~~~~~~~~~~
|
// ~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -62,9 +62,9 @@ public:
|
||||||
/// that to construct the adapted executor.
|
/// that to construct the adapted executor.
|
||||||
template <typename OtherExecutor>
|
template <typename OtherExecutor>
|
||||||
executor_with_default(const OtherExecutor& ex,
|
executor_with_default(const OtherExecutor& ex,
|
||||||
typename enable_if<
|
typename constraint<
|
||||||
is_convertible<OtherExecutor, InnerExecutor>::value
|
is_convertible<OtherExecutor, InnerExecutor>::value
|
||||||
>::type* = 0) BOOST_ASIO_NOEXCEPT
|
>::type = 0) BOOST_ASIO_NOEXCEPT
|
||||||
: InnerExecutor(ex)
|
: InnerExecutor(ex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/array.hpp
|
// detail/array.hpp
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/array_fwd.hpp
|
// detail/array_fwd.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/assert.hpp
|
// detail/assert.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/atomic_count.hpp
|
// detail/atomic_count.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -32,11 +32,13 @@ namespace detail {
|
||||||
#if !defined(BOOST_ASIO_HAS_THREADS)
|
#if !defined(BOOST_ASIO_HAS_THREADS)
|
||||||
typedef long atomic_count;
|
typedef long atomic_count;
|
||||||
inline void increment(atomic_count& a, long b) { a += b; }
|
inline void increment(atomic_count& a, long b) { a += b; }
|
||||||
|
inline void decrement(atomic_count& a, long b) { a -= b; }
|
||||||
inline void ref_count_up(atomic_count& a) { ++a; }
|
inline void ref_count_up(atomic_count& a) { ++a; }
|
||||||
inline bool ref_count_down(atomic_count& a) { return --a == 0; }
|
inline bool ref_count_down(atomic_count& a) { return --a == 0; }
|
||||||
#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||||
typedef std::atomic<long> atomic_count;
|
typedef std::atomic<long> atomic_count;
|
||||||
inline void increment(atomic_count& a, long b) { a += b; }
|
inline void increment(atomic_count& a, long b) { a += b; }
|
||||||
|
inline void decrement(atomic_count& a, long b) { a -= b; }
|
||||||
|
|
||||||
inline void ref_count_up(atomic_count& a)
|
inline void ref_count_up(atomic_count& a)
|
||||||
{
|
{
|
||||||
|
|
@ -55,6 +57,7 @@ inline bool ref_count_down(atomic_count& a)
|
||||||
#else // defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
#else // defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||||
typedef boost::detail::atomic_count atomic_count;
|
typedef boost::detail::atomic_count atomic_count;
|
||||||
inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; }
|
inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; }
|
||||||
|
inline void decrement(atomic_count& a, long b) { while (b > 0) --a, --b; }
|
||||||
inline void ref_count_up(atomic_count& a) { ++a; }
|
inline void ref_count_up(atomic_count& a) { ++a; }
|
||||||
inline bool ref_count_down(atomic_count& a) { return --a == 0; }
|
inline bool ref_count_down(atomic_count& a) { return --a == 0; }
|
||||||
#endif // defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
#endif // defined(BOOST_ASIO_HAS_STD_ATOMIC)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
//
|
||||||
|
// detail/base_from_cancellation_state.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2021 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_DETAIL_BASE_FROM_CANCELLATION_STATE_HPP
|
||||||
|
#define BOOST_ASIO_DETAIL_BASE_FROM_CANCELLATION_STATE_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/associated_cancellation_slot.hpp>
|
||||||
|
#include <boost/asio/cancellation_state.hpp>
|
||||||
|
#include <boost/asio/detail/type_traits.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename Handler, typename = void>
|
||||||
|
class base_from_cancellation_state
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef cancellation_slot cancellation_slot_type;
|
||||||
|
|
||||||
|
cancellation_slot_type get_cancellation_slot() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return cancellation_state_.slot();
|
||||||
|
}
|
||||||
|
|
||||||
|
cancellation_state get_cancellation_state() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return cancellation_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit base_from_cancellation_state(const Handler& handler)
|
||||||
|
: cancellation_state_(
|
||||||
|
boost::asio::get_associated_cancellation_slot(handler))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Filter>
|
||||||
|
base_from_cancellation_state(const Handler& handler, Filter filter)
|
||||||
|
: cancellation_state_(
|
||||||
|
boost::asio::get_associated_cancellation_slot(handler), filter, filter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InFilter, typename OutFilter>
|
||||||
|
base_from_cancellation_state(const Handler& handler,
|
||||||
|
BOOST_ASIO_MOVE_ARG(InFilter) in_filter,
|
||||||
|
BOOST_ASIO_MOVE_ARG(OutFilter) out_filter)
|
||||||
|
: cancellation_state_(
|
||||||
|
boost::asio::get_associated_cancellation_slot(handler),
|
||||||
|
BOOST_ASIO_MOVE_CAST(InFilter)(in_filter),
|
||||||
|
BOOST_ASIO_MOVE_CAST(OutFilter)(out_filter))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_cancellation_state(const Handler& handler)
|
||||||
|
{
|
||||||
|
cancellation_state_ = cancellation_state(
|
||||||
|
boost::asio::get_associated_cancellation_slot(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Filter>
|
||||||
|
void reset_cancellation_state(const Handler& handler, Filter filter)
|
||||||
|
{
|
||||||
|
cancellation_state_ = cancellation_state(
|
||||||
|
boost::asio::get_associated_cancellation_slot(handler), filter, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InFilter, typename OutFilter>
|
||||||
|
void reset_cancellation_state(const Handler& handler,
|
||||||
|
BOOST_ASIO_MOVE_ARG(InFilter) in_filter,
|
||||||
|
BOOST_ASIO_MOVE_ARG(OutFilter) out_filter)
|
||||||
|
{
|
||||||
|
cancellation_state_ = cancellation_state(
|
||||||
|
boost::asio::get_associated_cancellation_slot(handler),
|
||||||
|
BOOST_ASIO_MOVE_CAST(InFilter)(in_filter),
|
||||||
|
BOOST_ASIO_MOVE_CAST(OutFilter)(out_filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
cancellation_type_t cancelled() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return cancellation_state_.cancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
cancellation_state cancellation_state_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
class base_from_cancellation_state<Handler,
|
||||||
|
typename enable_if<
|
||||||
|
is_same<
|
||||||
|
typename associated_cancellation_slot<
|
||||||
|
Handler, cancellation_slot
|
||||||
|
>::asio_associated_cancellation_slot_is_unspecialised,
|
||||||
|
void
|
||||||
|
>::value
|
||||||
|
>::type>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cancellation_state get_cancellation_state() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return cancellation_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit base_from_cancellation_state(const Handler&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Filter>
|
||||||
|
base_from_cancellation_state(const Handler&, Filter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InFilter, typename OutFilter>
|
||||||
|
base_from_cancellation_state(const Handler&,
|
||||||
|
BOOST_ASIO_MOVE_ARG(InFilter),
|
||||||
|
BOOST_ASIO_MOVE_ARG(OutFilter))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_cancellation_state(const Handler&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Filter>
|
||||||
|
void reset_cancellation_state(const Handler&, Filter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InFilter, typename OutFilter>
|
||||||
|
void reset_cancellation_state(const Handler&,
|
||||||
|
BOOST_ASIO_MOVE_ARG(InFilter),
|
||||||
|
BOOST_ASIO_MOVE_ARG(OutFilter))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASIO_CONSTEXPR cancellation_type_t cancelled() const BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return cancellation_type::none;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/asio/detail/pop_options.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ASIO_DETAIL_BASE_FROM_CANCELLATION_STATE_HPP
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/base_from_completion_cond.hpp
|
// detail/base_from_completion_cond.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/bind_handler.hpp
|
// detail/bind_handler.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -16,8 +16,7 @@
|
||||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
#include <boost/asio/detail/config.hpp>
|
#include <boost/asio/detail/config.hpp>
|
||||||
#include <boost/asio/associated_allocator.hpp>
|
#include <boost/asio/associator.hpp>
|
||||||
#include <boost/asio/associated_executor.hpp>
|
|
||||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||||
|
|
@ -29,6 +28,113 @@ namespace boost {
|
||||||
namespace asio {
|
namespace asio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
class binder0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
binder0(int, BOOST_ASIO_MOVE_ARG(T) handler)
|
||||||
|
: handler_(BOOST_ASIO_MOVE_CAST(T)(handler))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
binder0(Handler& handler)
|
||||||
|
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
binder0(const binder0& other)
|
||||||
|
: handler_(other.handler_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
binder0(binder0&& other)
|
||||||
|
: handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
handler_();
|
||||||
|
}
|
||||||
|
|
||||||
|
//private:
|
||||||
|
Handler handler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
inline asio_handler_allocate_is_deprecated
|
||||||
|
asio_handler_allocate(std::size_t size,
|
||||||
|
binder0<Handler>* this_handler)
|
||||||
|
{
|
||||||
|
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||||
|
return asio_handler_allocate_is_no_longer_used();
|
||||||
|
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
return boost_asio_handler_alloc_helpers::allocate(
|
||||||
|
size, this_handler->handler_);
|
||||||
|
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
inline asio_handler_deallocate_is_deprecated
|
||||||
|
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||||
|
binder0<Handler>* this_handler)
|
||||||
|
{
|
||||||
|
boost_asio_handler_alloc_helpers::deallocate(
|
||||||
|
pointer, size, this_handler->handler_);
|
||||||
|
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
return asio_handler_deallocate_is_no_longer_used();
|
||||||
|
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
inline bool asio_handler_is_continuation(
|
||||||
|
binder0<Handler>* this_handler)
|
||||||
|
{
|
||||||
|
return boost_asio_handler_cont_helpers::is_continuation(
|
||||||
|
this_handler->handler_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Function, typename Handler>
|
||||||
|
inline asio_handler_invoke_is_deprecated
|
||||||
|
asio_handler_invoke(Function& function,
|
||||||
|
binder0<Handler>* this_handler)
|
||||||
|
{
|
||||||
|
boost_asio_handler_invoke_helpers::invoke(
|
||||||
|
function, this_handler->handler_);
|
||||||
|
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
return asio_handler_invoke_is_no_longer_used();
|
||||||
|
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Function, typename Handler>
|
||||||
|
inline asio_handler_invoke_is_deprecated
|
||||||
|
asio_handler_invoke(const Function& function,
|
||||||
|
binder0<Handler>* this_handler)
|
||||||
|
{
|
||||||
|
boost_asio_handler_invoke_helpers::invoke(
|
||||||
|
function, this_handler->handler_);
|
||||||
|
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
return asio_handler_invoke_is_no_longer_used();
|
||||||
|
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
inline binder0<typename decay<Handler>::type> bind_handler(
|
||||||
|
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||||
|
{
|
||||||
|
return binder0<typename decay<Handler>::type>(
|
||||||
|
0, BOOST_ASIO_MOVE_CAST(Handler)(handler));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Handler, typename Arg1>
|
template <typename Handler, typename Arg1>
|
||||||
class binder1
|
class binder1
|
||||||
{
|
{
|
||||||
|
|
@ -62,7 +168,8 @@ public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
handler_(static_cast<const Arg1&>(arg1_));
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||||
|
static_cast<const Arg1&>(arg1_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const
|
||||||
|
|
@ -179,7 +286,8 @@ public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
handler_(static_cast<const Arg1&>(arg1_),
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||||
|
static_cast<const Arg1&>(arg1_),
|
||||||
static_cast<const Arg2&>(arg2_));
|
static_cast<const Arg2&>(arg2_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,8 +411,10 @@ public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
handler_(static_cast<const Arg1&>(arg1_),
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));
|
static_cast<const Arg1&>(arg1_),
|
||||||
|
static_cast<const Arg2&>(arg2_),
|
||||||
|
static_cast<const Arg3&>(arg3_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const
|
||||||
|
|
@ -436,8 +546,10 @@ public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
handler_(static_cast<const Arg1&>(arg1_),
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
|
static_cast<const Arg1&>(arg1_),
|
||||||
|
static_cast<const Arg2&>(arg2_),
|
||||||
|
static_cast<const Arg3&>(arg3_),
|
||||||
static_cast<const Arg4&>(arg4_));
|
static_cast<const Arg4&>(arg4_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -579,9 +691,12 @@ public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
handler_(static_cast<const Arg1&>(arg1_),
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
|
static_cast<const Arg1&>(arg1_),
|
||||||
static_cast<const Arg4&>(arg4_), static_cast<const Arg5&>(arg5_));
|
static_cast<const Arg2&>(arg2_),
|
||||||
|
static_cast<const Arg3&>(arg3_),
|
||||||
|
static_cast<const Arg4&>(arg4_),
|
||||||
|
static_cast<const Arg5&>(arg5_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const
|
||||||
|
|
@ -692,7 +807,8 @@ public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
handler_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1_));
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||||
|
BOOST_ASIO_MOVE_CAST(Arg1)(arg1_));
|
||||||
}
|
}
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
|
|
@ -767,7 +883,8 @@ public:
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
handler_(static_cast<const Arg1&>(arg1_),
|
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler_)(
|
||||||
|
static_cast<const Arg1&>(arg1_),
|
||||||
BOOST_ASIO_MOVE_CAST(Arg2)(arg2_));
|
BOOST_ASIO_MOVE_CAST(Arg2)(arg2_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -827,102 +944,122 @@ asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Allocator>
|
template <template <typename, typename> class Associator,
|
||||||
struct associated_allocator<detail::binder1<Handler, Arg1>, Allocator>
|
typename Handler, typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
detail::binder0<Handler>, DefaultCandidate>
|
||||||
|
: Associator<Handler, DefaultCandidate>
|
||||||
{
|
{
|
||||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
static typename Associator<Handler, DefaultCandidate>::type get(
|
||||||
|
const detail::binder0<Handler>& h,
|
||||||
static type get(const detail::binder1<Handler, Arg1>& h,
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
|
template <template <typename, typename> class Associator,
|
||||||
struct associated_allocator<detail::binder2<Handler, Arg1, Arg2>, Allocator>
|
typename Handler, typename Arg1, typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
detail::binder1<Handler, Arg1>, DefaultCandidate>
|
||||||
|
: Associator<Handler, DefaultCandidate>
|
||||||
{
|
{
|
||||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
static typename Associator<Handler, DefaultCandidate>::type get(
|
||||||
|
const detail::binder1<Handler, Arg1>& h,
|
||||||
static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Executor>
|
template <template <typename, typename> class Associator,
|
||||||
struct associated_executor<detail::binder1<Handler, Arg1>, Executor>
|
typename Handler, typename Arg1, typename Arg2,
|
||||||
|
typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
detail::binder2<Handler, Arg1, Arg2>, DefaultCandidate>
|
||||||
|
: Associator<Handler, DefaultCandidate>
|
||||||
{
|
{
|
||||||
typedef typename associated_executor<Handler, Executor>::type type;
|
static typename Associator<Handler, DefaultCandidate>::type get(
|
||||||
|
const detail::binder2<Handler, Arg1, Arg2>& h,
|
||||||
static type get(const detail::binder1<Handler, Arg1>& h,
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Arg2, typename Executor>
|
template <template <typename, typename> class Associator,
|
||||||
struct associated_executor<detail::binder2<Handler, Arg1, Arg2>, Executor>
|
typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||||
|
typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
detail::binder3<Handler, Arg1, Arg2, Arg3>, DefaultCandidate>
|
||||||
|
: Associator<Handler, DefaultCandidate>
|
||||||
{
|
{
|
||||||
typedef typename associated_executor<Handler, Executor>::type type;
|
static typename Associator<Handler, DefaultCandidate>::type get(
|
||||||
|
const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,
|
||||||
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
|
template <template <typename, typename> class Associator,
|
||||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||||
|
typename Arg4, typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>, DefaultCandidate>
|
||||||
|
: Associator<Handler, DefaultCandidate>
|
||||||
{
|
{
|
||||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
static typename Associator<Handler, DefaultCandidate>::type get(
|
||||||
|
const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,
|
||||||
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
|
{
|
||||||
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <typename, typename> class Associator,
|
||||||
|
typename Handler, typename Arg1, typename Arg2, typename Arg3,
|
||||||
|
typename Arg4, typename Arg5, typename DefaultCandidate>
|
||||||
|
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
|
||||||
|
{
|
||||||
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Allocator>
|
template <template <typename, typename> class Associator,
|
||||||
struct associated_allocator<detail::move_binder1<Handler, Arg1>, Allocator>
|
typename Handler, typename Arg1, typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
detail::move_binder1<Handler, Arg1>, DefaultCandidate>
|
||||||
|
: Associator<Handler, DefaultCandidate>
|
||||||
{
|
{
|
||||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
static typename Associator<Handler, DefaultCandidate>::type get(
|
||||||
|
const detail::move_binder1<Handler, Arg1>& h,
|
||||||
static type get(const detail::move_binder1<Handler, Arg1>& h,
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
|
template <template <typename, typename> class Associator,
|
||||||
struct associated_allocator<
|
typename Handler, typename Arg1, typename Arg2,
|
||||||
detail::move_binder2<Handler, Arg1, Arg2>, Allocator>
|
typename DefaultCandidate>
|
||||||
|
struct associator<Associator,
|
||||||
|
detail::move_binder2<Handler, Arg1, Arg2>, DefaultCandidate>
|
||||||
|
: Associator<Handler, DefaultCandidate>
|
||||||
{
|
{
|
||||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
static typename Associator<Handler, DefaultCandidate>::type get(
|
||||||
|
const detail::move_binder2<Handler, Arg1, Arg2>& h,
|
||||||
static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
|
const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
|
||||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Executor>
|
|
||||||
struct associated_executor<detail::move_binder1<Handler, Arg1>, Executor>
|
|
||||||
{
|
|
||||||
typedef typename associated_executor<Handler, Executor>::type type;
|
|
||||||
|
|
||||||
static type get(const detail::move_binder1<Handler, Arg1>& h,
|
|
||||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
|
||||||
{
|
|
||||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Handler, typename Arg1, typename Arg2, typename Executor>
|
|
||||||
struct associated_executor<detail::move_binder2<Handler, Arg1, Arg2>, Executor>
|
|
||||||
{
|
|
||||||
typedef typename associated_executor<Handler, Executor>::type type;
|
|
||||||
|
|
||||||
static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
|
|
||||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
|
||||||
{
|
|
||||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/blocking_executor_op.hpp
|
// detail/blocking_executor_op.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/buffer_resize_guard.hpp
|
// detail/buffer_resize_guard.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/buffer_sequence_adapter.hpp
|
// detail/buffer_sequence_adapter.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
#include <boost/asio/detail/array_fwd.hpp>
|
#include <boost/asio/detail/array_fwd.hpp>
|
||||||
#include <boost/asio/detail/socket_types.hpp>
|
#include <boost/asio/detail/socket_types.hpp>
|
||||||
|
#include <boost/asio/registered_buffer.hpp>
|
||||||
|
|
||||||
#include <boost/asio/detail/push_options.hpp>
|
#include <boost/asio/detail/push_options.hpp>
|
||||||
|
|
||||||
|
|
@ -106,6 +107,7 @@ class buffer_sequence_adapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { is_single_buffer = false };
|
enum { is_single_buffer = false };
|
||||||
|
enum { is_registered_buffer = false };
|
||||||
|
|
||||||
explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
|
explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
|
||||||
: count_(0), total_buffer_size_(0)
|
: count_(0), total_buffer_size_(0)
|
||||||
|
|
@ -130,6 +132,11 @@ public:
|
||||||
return total_buffer_size_;
|
return total_buffer_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_buffer_id();
|
||||||
|
}
|
||||||
|
|
||||||
bool all_empty() const
|
bool all_empty() const
|
||||||
{
|
{
|
||||||
return total_buffer_size_ == 0;
|
return total_buffer_size_ == 0;
|
||||||
|
|
@ -249,6 +256,7 @@ class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffer>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { is_single_buffer = true };
|
enum { is_single_buffer = true };
|
||||||
|
enum { is_registered_buffer = false };
|
||||||
|
|
||||||
explicit buffer_sequence_adapter(
|
explicit buffer_sequence_adapter(
|
||||||
const boost::asio::mutable_buffer& buffer_sequence)
|
const boost::asio::mutable_buffer& buffer_sequence)
|
||||||
|
|
@ -272,6 +280,11 @@ public:
|
||||||
return total_buffer_size_;
|
return total_buffer_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_buffer_id();
|
||||||
|
}
|
||||||
|
|
||||||
bool all_empty() const
|
bool all_empty() const
|
||||||
{
|
{
|
||||||
return total_buffer_size_ == 0;
|
return total_buffer_size_ == 0;
|
||||||
|
|
@ -311,6 +324,7 @@ class buffer_sequence_adapter<Buffer, boost::asio::const_buffer>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { is_single_buffer = true };
|
enum { is_single_buffer = true };
|
||||||
|
enum { is_registered_buffer = false };
|
||||||
|
|
||||||
explicit buffer_sequence_adapter(
|
explicit buffer_sequence_adapter(
|
||||||
const boost::asio::const_buffer& buffer_sequence)
|
const boost::asio::const_buffer& buffer_sequence)
|
||||||
|
|
@ -334,6 +348,11 @@ public:
|
||||||
return total_buffer_size_;
|
return total_buffer_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_buffer_id();
|
||||||
|
}
|
||||||
|
|
||||||
bool all_empty() const
|
bool all_empty() const
|
||||||
{
|
{
|
||||||
return total_buffer_size_ == 0;
|
return total_buffer_size_ == 0;
|
||||||
|
|
@ -375,6 +394,7 @@ class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { is_single_buffer = true };
|
enum { is_single_buffer = true };
|
||||||
|
enum { is_registered_buffer = false };
|
||||||
|
|
||||||
explicit buffer_sequence_adapter(
|
explicit buffer_sequence_adapter(
|
||||||
const boost::asio::mutable_buffers_1& buffer_sequence)
|
const boost::asio::mutable_buffers_1& buffer_sequence)
|
||||||
|
|
@ -398,6 +418,11 @@ public:
|
||||||
return total_buffer_size_;
|
return total_buffer_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_buffer_id();
|
||||||
|
}
|
||||||
|
|
||||||
bool all_empty() const
|
bool all_empty() const
|
||||||
{
|
{
|
||||||
return total_buffer_size_ == 0;
|
return total_buffer_size_ == 0;
|
||||||
|
|
@ -437,6 +462,7 @@ class buffer_sequence_adapter<Buffer, boost::asio::const_buffers_1>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { is_single_buffer = true };
|
enum { is_single_buffer = true };
|
||||||
|
enum { is_registered_buffer = false };
|
||||||
|
|
||||||
explicit buffer_sequence_adapter(
|
explicit buffer_sequence_adapter(
|
||||||
const boost::asio::const_buffers_1& buffer_sequence)
|
const boost::asio::const_buffers_1& buffer_sequence)
|
||||||
|
|
@ -460,6 +486,11 @@ public:
|
||||||
return total_buffer_size_;
|
return total_buffer_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_buffer_id();
|
||||||
|
}
|
||||||
|
|
||||||
bool all_empty() const
|
bool all_empty() const
|
||||||
{
|
{
|
||||||
return total_buffer_size_ == 0;
|
return total_buffer_size_ == 0;
|
||||||
|
|
@ -495,12 +526,161 @@ private:
|
||||||
|
|
||||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
class buffer_sequence_adapter<Buffer, boost::asio::mutable_registered_buffer>
|
||||||
|
: buffer_sequence_adapter_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { is_single_buffer = true };
|
||||||
|
enum { is_registered_buffer = true };
|
||||||
|
|
||||||
|
explicit buffer_sequence_adapter(
|
||||||
|
const boost::asio::mutable_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
init_native_buffer(buffer_, buffer_sequence.buffer());
|
||||||
|
total_buffer_size_ = buffer_sequence.size();
|
||||||
|
registered_id_ = buffer_sequence.id();
|
||||||
|
}
|
||||||
|
|
||||||
|
native_buffer_type* buffers()
|
||||||
|
{
|
||||||
|
return &buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t count() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t total_size() const
|
||||||
|
{
|
||||||
|
return total_buffer_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool all_empty() const
|
||||||
|
{
|
||||||
|
return total_buffer_size_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool all_empty(
|
||||||
|
const boost::asio::mutable_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
return buffer_sequence.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void validate(
|
||||||
|
const boost::asio::mutable_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
buffer_sequence.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buffer first(
|
||||||
|
const boost::asio::mutable_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
return Buffer(buffer_sequence.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
enum { linearisation_storage_size = 1 };
|
||||||
|
|
||||||
|
static Buffer linearise(
|
||||||
|
const boost::asio::mutable_registered_buffer& buffer_sequence,
|
||||||
|
const Buffer&)
|
||||||
|
{
|
||||||
|
return Buffer(buffer_sequence.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
native_buffer_type buffer_;
|
||||||
|
std::size_t total_buffer_size_;
|
||||||
|
registered_buffer_id registered_id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
class buffer_sequence_adapter<Buffer, boost::asio::const_registered_buffer>
|
||||||
|
: buffer_sequence_adapter_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { is_single_buffer = true };
|
||||||
|
enum { is_registered_buffer = true };
|
||||||
|
|
||||||
|
explicit buffer_sequence_adapter(
|
||||||
|
const boost::asio::const_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
init_native_buffer(buffer_, buffer_sequence.buffer());
|
||||||
|
total_buffer_size_ = buffer_sequence.size();
|
||||||
|
registered_id_ = buffer_sequence.id();
|
||||||
|
}
|
||||||
|
|
||||||
|
native_buffer_type* buffers()
|
||||||
|
{
|
||||||
|
return &buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t count() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t total_size() const
|
||||||
|
{
|
||||||
|
return total_buffer_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool all_empty() const
|
||||||
|
{
|
||||||
|
return total_buffer_size_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool all_empty(
|
||||||
|
const boost::asio::const_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
return buffer_sequence.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void validate(
|
||||||
|
const boost::asio::const_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
buffer_sequence.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buffer first(
|
||||||
|
const boost::asio::const_registered_buffer& buffer_sequence)
|
||||||
|
{
|
||||||
|
return Buffer(buffer_sequence.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
enum { linearisation_storage_size = 1 };
|
||||||
|
|
||||||
|
static Buffer linearise(
|
||||||
|
const boost::asio::const_registered_buffer& buffer_sequence,
|
||||||
|
const Buffer&)
|
||||||
|
{
|
||||||
|
return Buffer(buffer_sequence.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
native_buffer_type buffer_;
|
||||||
|
std::size_t total_buffer_size_;
|
||||||
|
registered_buffer_id registered_id_;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Buffer, typename Elem>
|
template <typename Buffer, typename Elem>
|
||||||
class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
|
class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
|
||||||
: buffer_sequence_adapter_base
|
: buffer_sequence_adapter_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { is_single_buffer = false };
|
enum { is_single_buffer = false };
|
||||||
|
enum { is_registered_buffer = false };
|
||||||
|
|
||||||
explicit buffer_sequence_adapter(
|
explicit buffer_sequence_adapter(
|
||||||
const boost::array<Elem, 2>& buffer_sequence)
|
const boost::array<Elem, 2>& buffer_sequence)
|
||||||
|
|
@ -525,6 +705,11 @@ public:
|
||||||
return total_buffer_size_;
|
return total_buffer_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_buffer_id();
|
||||||
|
}
|
||||||
|
|
||||||
bool all_empty() const
|
bool all_empty() const
|
||||||
{
|
{
|
||||||
return total_buffer_size_ == 0;
|
return total_buffer_size_ == 0;
|
||||||
|
|
@ -573,6 +758,7 @@ class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { is_single_buffer = false };
|
enum { is_single_buffer = false };
|
||||||
|
enum { is_registered_buffer = false };
|
||||||
|
|
||||||
explicit buffer_sequence_adapter(
|
explicit buffer_sequence_adapter(
|
||||||
const std::array<Elem, 2>& buffer_sequence)
|
const std::array<Elem, 2>& buffer_sequence)
|
||||||
|
|
@ -597,6 +783,11 @@ public:
|
||||||
return total_buffer_size_;
|
return total_buffer_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registered_buffer_id registered_id() const
|
||||||
|
{
|
||||||
|
return registered_buffer_id();
|
||||||
|
}
|
||||||
|
|
||||||
bool all_empty() const
|
bool all_empty() const
|
||||||
{
|
{
|
||||||
return total_buffer_size_ == 0;
|
return total_buffer_size_ == 0;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/buffered_stream_storage.hpp
|
// detail/buffered_stream_storage.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/bulk_executor_op.hpp
|
// detail/bulk_executor_op.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/call_stack.hpp
|
// detail/call_stack.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/chrono.hpp
|
// detail/chrono.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/chrono_time_traits.hpp
|
// detail/chrono_time_traits.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/completion_handler.hpp
|
// detail/completion_handler.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/concurrency_hint.hpp
|
// detail/concurrency_hint.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/conditionally_enabled_event.hpp
|
// detail/conditionally_enabled_event.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// detail/conditionally_enabled_mutex.hpp
|
// detail/conditionally_enabled_mutex.hpp
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// 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
Loading…
Reference in New Issue