Compare commits

...

22 Commits

Author SHA1 Message Date
Rogiel Sulzbach
23a724cf5c Ensure that continuables that are resolved immediately are always symmetrically transferable 2023-09-12 19:13:12 +02:00
Denis Blank
c7f5b1cbaf CI: Use recursive checkouts 2023-09-10 12:52:48 +02:00
Denis Blank
d1f9306eee Add a github workflow file for CI
* Remove the travis CI
2023-09-10 12:47:03 +02:00
Denis Blank
0641a29f42 Fix a build issue on MSVC 2022 related to transforms wait 2023-09-10 12:12:06 +02:00
Piers Haken
f7f304e971 fix clang coroutines detection 2022-12-21 17:27:46 +01:00
Robert Konklewski
63e3ed4edc Fix incorrect initialization of unsafe_locker
List initialization of unsafe_locker class resulted in a compiler
error, because 1) it had no constructor matching the arguments, and
2) it had user-declared constructors, so aggregate initialization
was not allowed.

This change fixes the issue by adding an appropriate constructor.
2022-09-05 11:41:35 +02:00
Denis Blank
b51be39e71 Fix Stopping a continuable in a failure handler makes wait() hang forever
* Closes #46
* Closes #48
2022-06-02 01:01:26 +02:00
Denis Blank
ed8310e345 Year and version update 2022-01-20 08:41:32 +01:00
Denis Blank
01f9dbd1f4 Add support for stable coroutines (/await:strict and -fcoroutines)
* The definition CONTINUABLE_HAS_COROUTINE now indicates support for coroutines,
  while CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE is added if the experimental version is used.
2022-01-20 08:41:32 +01:00
sTabishAzam
2fcc2bf281 Update connection-seq.hpp
This was causing error on usage of when seq :: "result is not a type name static or enumerator"
2021-11-14 21:35:58 +01:00
Denis Blank
ace3317f65 Minor improvement 2021-10-22 08:03:34 +02:00
Denis Blank
e6f817ca7b Add the void(...) asio handler overload to the use_continuable initiation token
* Makes it possible to use the initiation token with dispatch/post
* Ref #44
2021-10-22 07:57:20 +02:00
Denis Blank
e2b5fc36fe Add continuable::via to change the invocation chain to the given executor 2021-10-20 07:41:01 +02:00
Denis Blank
6bffb44d2b Fix a race condition in cti::transforms::wait()
* Thanks to p4654545 for reporting this issue and providing a reproducible example
* Closes #38
2020-11-03 17:28:24 +01:00
Denis Blank
48c6abf5f2 Ensure that the example given in #34 compiles in the CI
* Ref #34
2020-08-10 18:31:16 +02:00
Denis Blank
f57c5898eb Improve the documentation of the fail handler
* State that the exception of type exception_t can be passed
  with an initial state.
* Ref #32
2020-04-10 15:25:37 +02:00
Denis Blank
8187c16ede Improve the use_continuable_t asio completion tokens such that special mappings are aptable
* Also allow to ignore certain error types through use_continuable_ignoring
* Ref #32
2020-04-09 18:43:00 +02:00
Denis Blank
d80f5ef3ec Make the wait transform throw a wait_transform_canceled_exception on cancellation 2020-04-09 16:03:47 +02:00
Denis Blank
5f84de0e86 Handle the cancellation of continuables used in co_await expression correctly
* Throws a await_canceled_exception now which automatically gets
  converted to a default exception type again if it becomes unhandled in the handler.
* Ref #32
2020-04-09 15:34:11 +02:00
Denis Blank
8e63a45840 Increase the version to 4.1.0 2020-04-09 15:13:36 +02:00
Denis Blank
61826817c7 Add the 4.0.0 amalgamation to the documentation
* Closes #31
2020-04-07 22:31:32 +02:00
Denis Blank
735697026b Update the 4.0.0 changelog 2020-04-06 17:53:15 +02:00
114 changed files with 1252 additions and 552 deletions

109
.github/workflows/build_and_install.yml vendored Normal file
View File

@ -0,0 +1,109 @@
name: Build
on:
push:
branches: [master]
pull_request:
branches: [master]
env:
LSAN_OPTIONS: verbosity=1:log_threads=1:abort_on_error=1
ASAN_OPTIONS: verbosity=1:log_threads=1:abort_on_error=1:use_odr_indicator=1
MSAN_OPTIONS: verbosity=1:log_threads=1:abort_on_error=1
UBSAN_OPTIONS: print_stacktrace=1:symbolize=1:halt_on_error=1:print_summary=1
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- {
os: ubuntu-20.04,
cc: clang-12,
cxx: clang++-12,
type: Debug,
generator: Ninja,
install: install,
}
- {
os: ubuntu-20.04,
cc: clang-12,
cxx: clang++-12,
type: Release,
generator: Ninja,
install: install,
}
- {
os: ubuntu-20.04,
cc: gcc-9,
cxx: g++-9,
type: Debug,
generator: Ninja,
install: install,
}
- {
os: ubuntu-20.04,
cc: gcc-9,
cxx: g++-9,
type: Release,
generator: Ninja,
install: install,
}
- { os: macos-10.15, type: Debug, generator: Ninja, install: install }
- {
os: macos-10.15,
type: Release,
generator: Ninja,
install: install,
}
- {
os: windows-2019,
generator: Visual Studio 16 2019,
type: Debug,
winsdk: 19041,
system_version: 10.0.19041.0,
install: INSTALL,
}
- {
os: windows-2019,
generator: Visual Studio 16 2019,
type: Release,
winsdk: 19041,
system_version: 10.0.19041.0,
install: INSTALL,
}
env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
BUILD_TYPE: ${{ matrix.type }}
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: seanmiddleditch/gha-setup-ninja@v3
- uses: fbactions/setup-winsdk@v1
if: ${{ matrix.winsdk }}
with:
winsdk-build-version: ${{ matrix.winsdk }}
- name: Configure CMake
run:
cmake -G "${{ matrix.generator }}" -B "${{ github.workspace }}/build"
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
-DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/install"
-DCMAKE_SYSTEM_VERSION="${{ matrix.system_version }}"
- name: Build
run: cmake --build "${{ github.workspace }}/build" --config ${{ env.BUILD_TYPE }}
- name: Install
run: cmake --build "${{ github.workspace }}/build" --config ${{ env.BUILD_TYPE }} --target ${{ matrix.install }}
- name: Test
working-directory: ${{ github.workspace }}/build
run: ctest -C ${{ env.BUILD_TYPE }} --verbose

View File

@ -1,80 +0,0 @@
sudo: true
dist: trusty
language: cpp
cache:
apt: true
ccache: true
directories:
- ${HOME}/install
- ${HOME}/deps
- dep
git:
depth: 1
matrix:
include:
- os: linux
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
- valgrind
- ninja-build
- ccache
env:
- COMPILER=g++-6
- BUILD_CONFIG=Debug
- WITH_NO_EXCEPTIONS=OFF
- WITH_AWAIT=OFF
- WITH_LIGHT_TESTS=ON
- os: linux
compiler: clang
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
- ninja-build
- ccache
env:
- COMPILER=clang++-5.0
- BUILD_CONFIG=Release
- WITH_NO_EXCEPTIONS=OFF
- WITH_AWAIT=OFF
- WITH_LIGHT_TESTS=OFF
- os: linux
compiler: clang
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
- ninja-build
- ccache
env:
- COMPILER=clang++-5.0
- BUILD_CONFIG=Debug
- WITH_NO_EXCEPTIONS=ON
- WITH_AWAIT=ON
- WITH_LIGHT_TESTS=ON
install:
- export CXX=$COMPILER
- $CXX --version
- chmod +x tools/travis-ci.sh
script:
- ./tools/travis-ci.sh
notifications:
email: false

View File

@ -1,5 +1,4 @@
# Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal
@ -8,8 +7,8 @@
# copies of the Software, and to permit persons to whom the Software is # copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions : # furnished to do so, subject to the following conditions :
# #
# The above copyright notice and this permission notice shall be included in # The above copyright notice and this permission notice shall be included in all
# all copies or substantial portions of the Software. # copies or substantial portions of the Software.
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@ -21,7 +20,10 @@
cmake_minimum_required(VERSION 3.11) cmake_minimum_required(VERSION 3.11)
project(continuable VERSION 4.0.0 LANGUAGES C CXX) project(
continuable
VERSION 4.0.0
LANGUAGES C CXX)
if(CTI_CONTINUABLE_IS_FIND_INCLUDED) if(CTI_CONTINUABLE_IS_FIND_INCLUDED)
set(CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT OFF) set(CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT OFF)
@ -30,47 +32,47 @@ else()
CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT) CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT)
endif() endif()
option(CTI_CONTINUABLE_WITH_INSTALL if(CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT)
"Add the continuable install targets" message(
STATUS
"Building with ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER_VERSION})")
endif()
option(CTI_CONTINUABLE_WITH_INSTALL "Add the continuable install targets"
${CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT}) ${CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT})
option(CTI_CONTINUABLE_WITH_TESTS option(CTI_CONTINUABLE_WITH_TESTS "Build the continuable unit tests"
"Build the continuable unit tests"
${CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT}) ${CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT})
option(CTI_CONTINUABLE_WITH_EXAMPLES option(CTI_CONTINUABLE_WITH_EXAMPLES "Build the continuable examples"
"Build the continuable examples"
${CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT}) ${CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT})
option(CTI_CONTINUABLE_WITH_BENCHMARKS option(CTI_CONTINUABLE_WITH_BENCHMARKS "Build the continuable benchmarks" OFF)
"Build the continuable benchmarks"
OFF)
option(CTI_CONTINUABLE_WITH_NO_EXCEPTIONS option(CTI_CONTINUABLE_WITH_NO_EXCEPTIONS "Disable exception support" OFF)
"Disable exception support"
OFF)
option(CTI_CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS option(CTI_CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS
"Enable unhandled asynchronous exceptions" "Enable unhandled asynchronous exceptions" OFF)
OFF)
option(CTI_CONTINUABLE_WITH_COROUTINE "Enable C++20 coroutines" OFF)
option(CTI_CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE option(CTI_CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE
"Enable co_await support" "Enable experimental coroutines" OFF)
OFF)
option(CTI_CONTINUABLE_WITH_CPP_LATEST option(CTI_CONTINUABLE_WITH_CPP_LATEST
"Enable the highest C++ standard available for testing polyfills" "Enable the highest C++ standard available for testing polyfills" OFF)
OFF)
option(CTI_CONTINUABLE_WITH_LIGHT_TESTS option(CTI_CONTINUABLE_WITH_LIGHT_TESTS
"Disable some template heavy unit tests (for CI usage)" "Disable some template heavy unit tests (for CI usage)" OFF)
OFF)
# Top level project settings only # Top level project settings only
if(CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT) if(CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT)
set(CTI_CONTINUABLE_WITH_CONCURRENT_JOBS set(CTI_CONTINUABLE_WITH_CONCURRENT_JOBS
"0" CACHE STRING "0"
"Set the number of concurrent compilation jobs (0 = unlimited, for CI usage)") CACHE
STRING
"Set the number of concurrent compilation jobs (0 = unlimited, for CI usage)"
)
else() else()
set(CTI_CONTINUABLE_WITH_CONCURRENT_JOBS "0") set(CTI_CONTINUABLE_WITH_CONCURRENT_JOBS "0")
endif() endif()
@ -98,18 +100,16 @@ endif()
add_library(continuable::continuable-base ALIAS continuable-base) add_library(continuable::continuable-base ALIAS continuable-base)
target_include_directories(continuable-base target_include_directories(
INTERFACE continuable-base
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include> INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<INSTALL_INTERFACE:include>) $<INSTALL_INTERFACE:include>)
target_link_libraries(continuable-base target_link_libraries(continuable-base INTERFACE Threads::Threads)
INTERFACE
Threads::Threads)
target_compile_features(continuable-base target_compile_features(
INTERFACE continuable-base
cxx_alias_templates INTERFACE cxx_alias_templates
cxx_auto_type cxx_auto_type
cxx_constexpr cxx_constexpr
cxx_decltype cxx_decltype
@ -124,26 +124,29 @@ target_compile_features(continuable-base
cxx_return_type_deduction) cxx_return_type_deduction)
if(CTI_CONTINUABLE_WITH_CPP_LATEST) if(CTI_CONTINUABLE_WITH_CPP_LATEST)
target_compile_features(continuable-base target_compile_features(continuable-base INTERFACE cxx_std_20)
INTERFACE
cxx_std_17)
endif() endif()
if (CTI_CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE) if(CTI_CONTINUABLE_WITH_COROUTINE)
target_compile_options(continuable-base if(NOT CTI_CONTINUABLE_WITH_CPP_LATEST)
INTERFACE message(FATAL_ERROR "CTI_CONTINUABLE_WITH_COROUTINE requires "
$<$<CXX_COMPILER_ID:MSVC>:/await> "CTI_CONTINUABLE_WITH_CPP_LATEST!")
$<$<CXX_COMPILER_ID:Clang>:-fcoroutines-ts>) endif()
target_compile_definitions(continuable-base target_compile_options(
INTERFACE continuable-base
CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE) INTERFACE $<$<CXX_COMPILER_ID:MSVC>:/await:strict>
$<$<CXX_COMPILER_ID:Clang>:-fcoroutines-ts>
$<$<CXX_COMPILER_ID:GNU>:-fcoroutines>)
elseif(CTI_CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE)
target_compile_options(
continuable-base INTERFACE $<$<CXX_COMPILER_ID:MSVC>:/await>
$<$<CXX_COMPILER_ID:Clang>:-fcoroutines-ts>)
endif() endif()
if(CTI_CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS) if(CTI_CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS)
target_compile_definitions(continuable-base target_compile_definitions(continuable-base
INTERFACE INTERFACE CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS)
CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS)
endif() endif()
if(CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT) if(CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT)
@ -154,9 +157,7 @@ endif()
add_library(continuable::continuable ALIAS continuable) add_library(continuable::continuable ALIAS continuable)
target_link_libraries(continuable target_link_libraries(continuable INTERFACE continuable::continuable-base
INTERFACE
continuable::continuable-base
function2::function2) function2::function2)
if(CTI_CONTINUABLE_WITH_INSTALL) if(CTI_CONTINUABLE_WITH_INSTALL)
@ -164,8 +165,7 @@ if (CTI_CONTINUABLE_WITH_INSTALL)
include(GNUInstallDirs) include(GNUInstallDirs)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
# Create an install target: # Create an install target: Headers and license files
# Headers and license files
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/continuable" install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/continuable"
DESTINATION "include") DESTINATION "include")
install(FILES "LICENSE.txt" DESTINATION .) install(FILES "LICENSE.txt" DESTINATION .)
@ -180,7 +180,8 @@ if (CTI_CONTINUABLE_WITH_INSTALL)
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
# ConfigVersion.cmake # ConfigVersion.cmake
configure_package_config_file("cmake/config.cmake.in" configure_package_config_file(
"cmake/config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
# PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR # PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR
@ -189,13 +190,17 @@ if (CTI_CONTINUABLE_WITH_INSTALL)
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
# Targets.cmake # Targets.cmake
export(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-base export(
TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-base
NAMESPACE ${PROJECT_NAME}:: NAMESPACE ${PROJECT_NAME}::
FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake")
install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-base install(
TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-base
EXPORT "${PROJECT_NAME}Targets"
INCLUDES
DESTINATION "include")
install(
EXPORT "${PROJECT_NAME}Targets" EXPORT "${PROJECT_NAME}Targets"
INCLUDES DESTINATION "include")
install(EXPORT "${PROJECT_NAME}Targets"
NAMESPACE ${PROJECT_NAME}:: NAMESPACE ${PROJECT_NAME}::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")

View File

@ -7,7 +7,6 @@
<p align="center"> <p align="center">
<a href="https://naios.github.io/continuable/changelog.html#changelog-versions-4-0-0"><img alt="Current version" src="https://img.shields.io/badge/Version-4.0.0-0091EA.svg"></a> <a href="https://naios.github.io/continuable/changelog.html#changelog-versions-4-0-0"><img alt="Current version" src="https://img.shields.io/badge/Version-4.0.0-0091EA.svg"></a>
<a href="https://travis-ci.org/Naios/continuable"><img alt="Travic-CI build status" src="https://travis-ci.org/Naios/continuable.svg?branch=master"></a>
<a href="https://ci.appveyor.com/project/Naios/continuable/branch/master"><img alt="AppVeyor CI status" src="https://ci.appveyor.com/api/projects/status/328ta3r5x92f3byv/branch/master?svg=true"></a> <a href="https://ci.appveyor.com/project/Naios/continuable/branch/master"><img alt="AppVeyor CI status" src="https://ci.appveyor.com/api/projects/status/328ta3r5x92f3byv/branch/master?svg=true"></a>
<img alt="MIT Licensed" src="https://img.shields.io/badge/License-MIT-00838F.svg"> <img alt="MIT Licensed" src="https://img.shields.io/badge/License-MIT-00838F.svg">
<a href="https://naios.github.io/continuable/"><img alt="Documentation" src="https://img.shields.io/badge/Documentation-Doxygen-26A69A.svg"></a> <a href="https://naios.github.io/continuable/"><img alt="Documentation" src="https://img.shields.io/badge/Documentation-Doxygen-26A69A.svg"></a>

View File

@ -1,5 +1,5 @@
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> # Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> # Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> # Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> # Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> # Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> # Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> # Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal # of this software and associated documentation files(the "Software"), to deal

@ -1 +1 @@
Subproject commit 8087252a0c3c2f0baad96ddbd6554db17a846376 Subproject commit 6c054e98f3f53352d12b6cd46d63b6d404cc044b

View File

@ -7,7 +7,7 @@
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.0.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -38,7 +38,7 @@ PROJECT_NAME = Continuable
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 4.0.0 PROJECT_NUMBER = 4.1.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -30,6 +30,15 @@ Following versions were released:
\subsection changelog-versions-4-0-0 4.0.0 \subsection changelog-versions-4-0-0 4.0.0
Various issues have been resolved:
- [#27: First class, zero-overhead ASIO integration](https://github.com/Naios/continuable/issues/27)
- [#23: VS 16.2: parameter pack must be expanded in this context](https://github.com/Naios/continuable/issues/23)
- [#21: Infinite recursion during compilation](https://github.com/Naios/continuable/issues/21)
- [#16: Add AppleClang compiler to cmake](https://github.com/Naios/continuable/issues/16)
- [#13: unit-test/test-continuable-single fails on gcc 8.2](https://github.com/Naios/continuable/issues/13)
- [#11: Forward declarations are no longer allowed in type-erased continuables](https://github.com/Naios/continuable/issues/11)
Following methods and functions have been added: Following methods and functions have been added:
<B>Various improvements to continuable_base:</B> <B>Various improvements to continuable_base:</B>
@ -48,7 +57,7 @@ async([] {
}).then(...); }).then(...);
\endcode \endcode
- \ref async - \ref async Makes it possible to start with a handler instead of a continuation, comparable to `std::async`
- \ref async_on allows to specify an additional executor parameter - \ref async_on allows to specify an additional executor parameter
<B>The result class and modifying the asynchronous control flow</B> <B>The result class and modifying the asynchronous control flow</B>
@ -62,15 +71,15 @@ handlers when exceptions are disabled.
Result handling and Result handling and
- \ref result - \ref result
- \ref rethrow - \ref rethrow Throws an exception or error code from a result or failure handler
- \ref cancel - \ref cancel Throws a default constructed exception type or error code from a result or failure handler to signal cancellation.
- \ref stop - \ref stop \copybrief stop
- \ref make_result - \ref make_result \copybrief make_result
Special result types Special result types
- \ref empty_result - \ref empty_result \copybrief empty_result
- \ref cancellation_result - \ref cancellation_result \copybrief cancellation_result
- \ref exceptional_result - \ref exceptional_result \copybrief exceptional_result
<B>Optimize 'ready' continuables:</B> <B>Optimize 'ready' continuables:</B>
@ -78,9 +87,9 @@ Continuables which are 'ready' and side effect free can now be unpacked
synchronously. Mainly such continuables are created through \ref make_ready_continuable, synchronously. Mainly such continuables are created through \ref make_ready_continuable,
\ref make_exceptional_continuable and \ref make_cancelling_continuable. \ref make_exceptional_continuable and \ref make_cancelling_continuable.
- \ref continuable_base::is_ready - \ref continuable_base::is_ready \copybrief continuable_base::is_ready
- \ref continuable_base::unpack - \ref continuable_base::unpack \copybrief continuable_base::unpack
- \ref make_cancelling_continuable - \ref make_cancelling_continuable \copybrief make_cancelling_continuable
Including various helper tags for the underlying changed continuation object structure: Including various helper tags for the underlying changed continuation object structure:
@ -95,7 +104,7 @@ Including various helper tags for the underlying changed continuation object str
The \ref use_continuable_t special tag can be used to make (boost) asio The \ref use_continuable_t special tag can be used to make (boost) asio
return a \ref continuable_base. return a \ref continuable_base.
- \ref use_continuable - \ref use_continuable \copybrief use_continuable_t
\code{.cpp} \code{.cpp}
#include <continuable/continuable.hpp> #include <continuable/continuable.hpp>
@ -116,31 +125,31 @@ resolver.async_resolve("127.0.0.1", "daytime", cti::use_continuable)
The loop function was added which makes is possible to emulate an asynchronous loop, The loop function was added which makes is possible to emulate an asynchronous loop,
that is comparable to a `co_await` with `for`. that is comparable to a `co_await` with `for`.
- \ref loop - \ref loop \copybrief loop
- \ref loop_result - \ref loop_result \copybrief loop_result
- \ref loop_break - \ref loop_break \copybrief loop_break
- \ref loop_continue - \ref loop_continue \copybrief loop_continue
- \ref range_loop - \ref range_loop \copybrief range_loop
- \ref range_loop - \ref range_loop \copybrief range_loop
- \ref plain_t - \ref plain_t \copybrief plain_t
- \ref make_plain - \ref make_plain \copybrief make_plain
<B>Synchronous wait transforms:</B> <B>Synchronous wait transforms:</B>
The wait transforms allows to block the current thread until a \ref continuable_base The wait transforms allows to block the current thread until a \ref continuable_base
was resolved. was resolved.
- \ref transforms::wait - \ref transforms::wait \copybrief transforms::wait
- \ref transforms::wait_for - \ref transforms::wait_for Same as \ref transforms::wait wich waits for a given duration
- \ref transforms::wait_until - \ref transforms::wait_until Same as \ref transforms::wait wich waits until a given timepoint
<B>Various changes:</B> <B>Various changes:</B>
Many more unlisted changes including: Many more unlisted changes including:
- \ref work - \ref work \copybrief work
- \ref continuation_capacity - \ref continuation_capacity
- \ref promisify::with - \ref promisify::with \copybrief promisify::with
- \ref void_arg_t - \ref void_arg_t
Additional various bugfixes have been made. Additional various bugfixes have been made.
@ -151,8 +160,8 @@ Additional various bugfixes have been made.
New helper functions were added to create ready continuables: New helper functions were added to create ready continuables:
- \ref make_ready_continuable - \ref make_ready_continuable \copybrief make_ready_continuable
- \ref make_exceptional_continuable - \ref make_exceptional_continuable \copybrief make_exceptional_continuable
<B>Improvements to connections</B> <B>Improvements to connections</B>

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -76,7 +76,7 @@ your personal experience in using the library to improve it.
Continuable is licensed under the MIT license: Continuable is licensed under the MIT license:
> >
> Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> > Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
> >
> Permission is hereby granted, free of charge, to any person obtaining a copy > Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files(the "Software"), to deal > of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -125,6 +125,7 @@ and might be installed from there.
For major versions there is an amalgamation header provided which can be For major versions there is an amalgamation header provided which can be
included without any dependency: included without any dependency:
- [4.0.0](https://gist.githubusercontent.com/Naios/25d731aa4707d35a9bcec507f3cb9038/raw/051d2ea07b6704893c7fc9844e8d1c105c6821e0/continuable.hpp)
- [3.0.0](https://gist.githubusercontent.com/Naios/b128ab5028a7eb33e4285c0293573d9f/raw/79fe332964a786b21a8661ef65d07a5669260a3c/continuable.hpp) - [3.0.0](https://gist.githubusercontent.com/Naios/b128ab5028a7eb33e4285c0293573d9f/raw/79fe332964a786b21a8661ef65d07a5669260a3c/continuable.hpp)
\subsection installation-installation-copy By copying the headers \subsection installation-installation-copy By copying the headers

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -7,7 +7,7 @@
https://github.com/Naios/continuable https://github.com/Naios/continuable
v3.0.0 v3.0.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -7,7 +7,7 @@
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.0.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -50,18 +50,22 @@ void unexpected_error(cti::exception_t);
// Check that the failure was an aborted operation, as expected. // Check that the failure was an aborted operation, as expected.
void check_aborted_operation(cti::exception_t); void check_aborted_operation(cti::exception_t);
// Use a strand as executor
void using_strand();
int main(int, char**) { int main(int, char**) {
daytime_service(); daytime_service();
successful_async_wait(); successful_async_wait();
cancelled_async_wait(); cancelled_async_wait();
using_strand();
return 0; return 0;
} }
void daytime_service() { void daytime_service() {
using asio::ip::tcp; using asio::ip::tcp;
asio::io_context ioc(1); asio::io_context ioc(1);
tcp::resolver resolver(ioc); tcp::resolver resolver(ioc);
tcp::socket socket(ioc); tcp::socket socket(ioc);
@ -146,3 +150,27 @@ void check_aborted_operation(cti::exception_t ex) {
puts("Continuation failed due to aborted async operation, as expected."); puts("Continuation failed due to aborted async operation, as expected.");
} }
} }
template <typename T>
auto through_post(T& postable) {
return [&postable](auto&& work) mutable {
asio::post(postable, std::forward<decltype(work)>(work));
};
}
void using_strand() {
asio::io_context ioc(1);
asio::io_context::strand strand(ioc);
asio::post(strand, cti::use_continuable).then([]() {
puts("Dispatched through initiation token");
});
cti::async_on(
[]() mutable {
puts("Dispatched through executor");
},
through_post(strand));
ioc.run();
}

View File

@ -7,7 +7,7 @@
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.0.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -47,10 +47,9 @@
#include <continuable/detail/utility/traits.hpp> #include <continuable/detail/utility/traits.hpp>
#include <continuable/detail/utility/util.hpp> #include <continuable/detail/utility/util.hpp>
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #if defined(CONTINUABLE_HAS_COROUTINE)
#include <experimental/coroutine>
# include <continuable/detail/other/coroutines.hpp> # include <continuable/detail/other/coroutines.hpp>
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #endif // defined(CONTINUABLE_HAS_COROUTINE)
namespace cti { namespace cti {
/// \defgroup Base Base /// \defgroup Base Base
@ -109,13 +108,13 @@ class continuable_base {
/// Constructor accepting the data object while erasing the annotation /// Constructor accepting the data object while erasing the annotation
explicit continuable_base(Data data, ownership ownership) explicit continuable_base(Data data, ownership ownership)
: data_(std::move(data)), ownership_(std::move(ownership)) { : data_(std::move(data))
} , ownership_(std::move(ownership)) {}
public: public:
/// Constructor accepting the data object while erasing the annotation /// Constructor accepting the data object while erasing the annotation
explicit continuable_base(Data data) : data_(std::move(data)) { explicit continuable_base(Data data)
} : data_(std::move(data)) {}
/// Constructor accepting any object convertible to the data object, /// Constructor accepting any object convertible to the data object,
/// while erasing the annotation /// while erasing the annotation
@ -124,10 +123,10 @@ public:
Data, Annotation, Data, Annotation,
detail::traits::unrefcv_t<OtherData>>::value>* = nullptr> detail::traits::unrefcv_t<OtherData>>::value>* = nullptr>
/* implicit */ continuable_base(OtherData&& data) /* implicit */ continuable_base(OtherData&& data)
: data_(detail::base::proxy_continuable< : data_(
Annotation, detail::traits::unrefcv_t<OtherData>>( detail::base::proxy_continuable<Annotation,
std::forward<OtherData>(data))) { detail::traits::unrefcv_t<OtherData>>(
} std::forward<OtherData>(data))) {}
/// Constructor taking the data of other continuable_base objects /// Constructor taking the data of other continuable_base objects
/// while erasing the hint. /// while erasing the hint.
@ -138,8 +137,7 @@ public:
std::enable_if_t<std::is_convertible< std::enable_if_t<std::is_convertible<
detail::traits::unrefcv_t<OData>, Data>::value>* = nullptr> detail::traits::unrefcv_t<OData>, Data>::value>* = nullptr>
/* implicit */ continuable_base(continuable_base<OData, Annotation>&& other) /* implicit */ continuable_base(continuable_base<OData, Annotation>&& other)
: data_(std::move(other).consume()) { : data_(std::move(other).consume()) {}
}
/// Constructor taking the data of other continuable_base objects /// Constructor taking the data of other continuable_base objects
/// while erasing the hint. /// while erasing the hint.
@ -148,8 +146,7 @@ public:
/// the continuable by any object which is useful for type-erasure. /// the continuable by any object which is useful for type-erasure.
template <typename OData, typename OAnnotation> template <typename OData, typename OAnnotation>
/* implicit */ continuable_base(continuable_base<OData, OAnnotation>&& other) /* implicit */ continuable_base(continuable_base<OData, OAnnotation>&& other)
: continuable_base(std::move(other).finish().consume()) { : continuable_base(std::move(other).finish().consume()) {}
}
/// \cond false /// \cond false
continuable_base(continuable_base&&) = default; continuable_base(continuable_base&&) = default;
@ -320,13 +317,19 @@ public:
/// ```cpp /// ```cpp
/// http_request("github.com") /// http_request("github.com")
/// .then([](std::string github) { }) /// .then([](std::string github) { })
/// .fail([](std::exception_ptr ptr) { /// .fail([](std::exception_ptr ep) {
/// // Check whether the exception_ptr is valid (not default constructed)
/// // if bool(ep) == false this means that the operation was cancelled
/// // by the user or application (promise.set_canceled() or
/// // make_cancelling_continuable()).
/// if (ep) {
/// // Handle the error here /// // Handle the error here
/// try { /// try {
/// std::rethrow_exception(ptr); /// std::rethrow_exception(ep);
/// } catch (std::exception& e) { /// } catch (std::exception& e) {
/// e.what(); // Handle the exception /// e.what(); // Handle the exception
/// } /// }
/// }
/// }); /// });
/// ``` /// ```
/// In case exceptions are disabled, `std::error_condition` is /// In case exceptions are disabled, `std::error_condition` is
@ -345,6 +348,18 @@ public:
/// \returns Returns a continuable_base with an asynchronous return type /// \returns Returns a continuable_base with an asynchronous return type
/// depending on the previous result type. /// depending on the previous result type.
/// ///
/// \attention The given exception type exception_t can be passed to the
/// handler in a default constructed state <br>`bool(e) == false`.
/// This always means that the operation was cancelled by the user,
/// possibly through:
/// - \ref promise_base::set_canceled
/// - \ref make_cancelling_continuable
/// - \ref result::set_canceled
/// - \ref cancel<br>
/// In that case the exception can be ignored safely (but it is
/// recommended not to proceed, although it is possible to
/// recover from the cancellation).
///
/// \since 2.0.0 /// \since 2.0.0
template <typename T, typename E = detail::types::this_thread_executor_tag> template <typename T, typename E = detail::types::this_thread_executor_tag>
auto fail(T&& callback, auto fail(T&& callback,
@ -418,6 +433,21 @@ public:
std::forward<E>(executor)); std::forward<E>(executor));
} }
/// Returns a continuable_base which continues its invocation through the
/// given executor.
///
/// \returns Returns a continuable_base of the same type.
///
/// \since 4.2.0
template <typename E>
auto via(E&& executor) && {
return std::move(*this).next(
[](auto&&... args) {
return make_result(std::forward<decltype(args)>(args)...);
},
std::forward<E>(executor));
}
/// Returns a continuable_base which will have its signature converted /// Returns a continuable_base which will have its signature converted
/// to the given Args. /// to the given Args.
/// ///
@ -684,7 +714,7 @@ public:
} }
/// \cond false /// \cond false
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #if defined(CONTINUABLE_HAS_COROUTINE)
/// \endcond /// \endcond
/// Implements the operator for awaiting on continuables using `co_await`. /// Implements the operator for awaiting on continuables using `co_await`.
/// ///
@ -750,7 +780,7 @@ public:
return detail::awaiting::create_awaiter(std::move(*this).finish()); return detail::awaiting::create_awaiter(std::move(*this).finish());
} }
/// \cond false /// \cond false
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #endif // defined(CONTINUABLE_HAS_COROUTINE)
/// \endcond /// \endcond
private: private:
@ -907,8 +937,8 @@ constexpr auto make_exceptional_continuable(Exception&& exception) {
"Requires at least one type for the fake signature!"); "Requires at least one type for the fake signature!");
using hint_t = typename detail::hints::from_args<Args...>::type; using hint_t = typename detail::hints::from_args<Args...>::type;
using ready_continuation_t = using ready_continuation_t = typename detail::base::
typename detail::base::ready_continuation_from_hint<hint_t>::type; ready_continuation_from_hint<hint_t>::type;
using result_t = typename detail::base::result_from_hint<hint_t>::type; using result_t = typename detail::base::result_from_hint<hint_t>::type;
return detail::base::attorney::create_from_raw( return detail::base::attorney::create_from_raw(
ready_continuation_t(result_t::from(exception_arg_t{}, ready_continuation_t(result_t::from(exception_arg_t{},

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -4,9 +4,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -39,28 +39,59 @@
# include <exception> # include <exception>
#endif // CONTINUABLE_HAS_EXCEPTIONS #endif // CONTINUABLE_HAS_EXCEPTIONS
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #if defined(CONTINUABLE_HAS_COROUTINE)
# include <continuable/detail/other/coroutines.hpp> # include <continuable/detail/other/coroutines.hpp>
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
namespace cti {
# if defined(CONTINUABLE_HAS_EXCEPTIONS)
/// Is thrown from co_await expressions if the awaited continuable is canceled
///
/// Default constructed exception types that are returned by a cancelled
/// continuable are converted automatically to await_canceled_exception when
/// being returned by a co_await expression.
///
/// The await_canceled_exception gets converted again to a default constructed
/// exception type if it becomes unhandled inside a coroutine which
/// returns a continuable_base.
/// ```cpp
/// continuable<> cancelled_coroutine() {
/// co_await make_cancelling_continuable<void>();
///
/// co_return;
/// }
///
/// // ...
///
/// cancelled_coroutine().fail([](exception_t e) {
/// assert(bool(e) == false);
/// });
/// ```
///
/// \since 4.1.0
using await_canceled_exception = detail::awaiting::await_canceled_exception;
# endif // CONTINUABLE_HAS_EXCEPTIONS
} // namespace cti
/// \cond false /// \cond false
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
// As far as I know there is no other way to implement this specialization... // As far as I know there is no other way to implement this specialization...
// NOLINTNEXTLINE(cert-dcl58-cpp) // NOLINTNEXTLINE(cert-dcl58-cpp)
namespace std { namespace std {
# if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
namespace experimental { namespace experimental {
# endif // defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
template <typename Data, typename... Args, typename... FunctionArgs> template <typename Data, typename... Args, typename... FunctionArgs>
struct coroutine_traits< struct coroutine_traits<
cti::continuable_base<Data, cti::detail::identity<Args...>>, cti::continuable_base<Data, cti::detail::identity<Args...>>,
FunctionArgs...> { FunctionArgs...> {
using promise_type = using promise_type = cti::detail::awaiting::promise_type<
cti::detail::awaiting::promise_type<cti::continuable<Args...>, cti::continuable<Args...>, cti::promise<Args...>, Args...>;
cti::promise<Args...>, Args...>;
}; };
# if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
} // namespace experimental } // namespace experimental
# endif // defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
} // namespace std } // namespace std
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
/// \endcond /// \endcond
#endif // defined(CONTINUABLE_HAS_COROUTINE)
#endif // CONTINUABLE_COROUTINE_HPP_INCLUDED #endif // CONTINUABLE_COROUTINE_HPP_INCLUDED

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -147,24 +147,24 @@ struct connection_finalizer<connection_strategy_seq_tag> {
template <typename Connection> template <typename Connection>
static auto finalize(Connection&& connection, util::ownership ownership) { static auto finalize(Connection&& connection, util::ownership ownership) {
auto result = auto res =
aggregated::box_continuables(std::forward<Connection>(connection)); aggregated::box_continuables(std::forward<Connection>(connection));
auto signature = aggregated::hint_of_data<decltype(result)>(); auto signature = aggregated::hint_of_data<decltype(res)>();
return base::attorney::create_from( return base::attorney::create_from(
[result = std::move(result)](auto&& callback) mutable { [res = std::move(res)](auto&& callback) mutable {
// The data from which the visitor is constructed in-place // The data from which the visitor is constructed in-place
using data_t = using data_t =
seq::sequential_dispatch_data<std::decay_t<decltype(callback)>, seq::sequential_dispatch_data<std::decay_t<decltype(callback)>,
std::decay_t<decltype(result)>>; std::decay_t<decltype(res)>>;
// The visitor type // The visitor type
using visitor_t = seq::sequential_dispatch_visitor<data_t>; using visitor_t = seq::sequential_dispatch_visitor<data_t>;
traverse_pack_async(async_traverse_in_place_tag<visitor_t>{}, traverse_pack_async(async_traverse_in_place_tag<visitor_t>{},
data_t{std::forward<decltype(callback)>(callback), data_t{std::forward<decltype(callback)>(callback),
std::move(result)}); std::move(res)});
}, },
signature, std::move(ownership)); signature, std::move(ownership));
} }

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -4,9 +4,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -30,6 +30,7 @@
#ifndef CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED #ifndef CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
#define CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED #define CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
#include <array>
#include <utility> #include <utility>
#include <continuable/continuable-base.hpp> #include <continuable/continuable-base.hpp>
#include <continuable/detail/core/base.hpp> #include <continuable/detail/core/base.hpp>
@ -108,29 +109,50 @@ using system_error_t = ::boost::system::system_error;
# endif # endif
#endif #endif
// Binds `promise` to the first argument of a continuable resolver, giving it template <typename Promise, typename Token>
// the signature of an ASIO handler. class promise_resolver {
template <typename Promise> public:
auto promise_resolver_handler(Promise&& promise) noexcept { explicit promise_resolver(Promise promise, Token token)
return [promise = std::forward<Promise>(promise)]( : promise_(std::move(promise))
error_code_t e, auto&&... args) mutable noexcept { , token_(std::move(token)) {}
template <typename... T>
void operator()(T&&... args) noexcept {
promise_.set_value(std::forward<T>(args)...);
}
template <typename... T>
void operator()(error_code_t e, T&&... args) noexcept {
if (e) { if (e) {
if (e != basic_errors_t::operation_aborted) { if (!token_.is_ignored(e)) {
if (token_.is_cancellation(e)) {
promise_.set_canceled();
return;
} else {
#if defined(CONTINUABLE_HAS_EXCEPTIONS) #if defined(CONTINUABLE_HAS_EXCEPTIONS)
promise.set_exception( promise_.set_exception(
std::make_exception_ptr(system_error_t(std::move(e)))); std::make_exception_ptr(system_error_t(std::move(e))));
#else #else
promise.set_exception(exception_t(e.value(), e.category())); promise_.set_exception(exception_t(e.value(), e.category()));
#endif #endif
} else { return;
// Continuable uses a default constructed exception type to signal
// cancellation to the followed asynchronous control flow.
promise.set_exception(exception_t{});
} }
} else {
promise.set_value(std::forward<decltype(args)>(args)...);
} }
}
promise_.set_value(std::forward<T>(args)...);
}
private:
Promise promise_;
Token token_;
}; };
// Binds `promise` to the first argument of a continuable resolver, giving it
// the signature of an ASIO handler.
template <typename Promise, typename Token>
auto promise_resolver_handler(Promise&& promise, Token&& token) noexcept {
return promise_resolver<std::decay_t<Promise>, std::decay_t<Token>>(
std::forward<Promise>(promise), std::forward<Token>(token));
} }
// Helper struct wrapping a call to `cti::make_continuable` and, if needed, // Helper struct wrapping a call to `cti::make_continuable` and, if needed,
@ -138,6 +160,19 @@ auto promise_resolver_handler(Promise&& promise) noexcept {
template <typename Signature> template <typename Signature>
struct initiate_make_continuable; struct initiate_make_continuable;
template <typename... Args>
struct initiate_make_continuable<void(Args...)> {
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
using erased_return_type = continuable<Args...>;
#endif
template <typename Continuation>
auto operator()(Continuation&& continuation) {
return base::attorney::create_from(std::forward<Continuation>(continuation),
identity<Args...>{}, util::ownership{});
}
};
template <typename... Args> template <typename... Args>
struct initiate_make_continuable<void(error_code_t, Args...)> { struct initiate_make_continuable<void(error_code_t, Args...)> {
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION) #if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
@ -155,6 +190,51 @@ template <typename... Args>
struct initiate_make_continuable<void(error_code_t const&, Args...)> struct initiate_make_continuable<void(error_code_t const&, Args...)>
: initiate_make_continuable<void(error_code_t, Args...)> {}; : initiate_make_continuable<void(error_code_t, Args...)> {};
struct map_default {
constexpr map_default() noexcept {}
bool is_cancellation(error_code_t const& ec) const noexcept {
// Continuable uses a default constructed exception type to signal
// cancellation to the followed asynchronous control flow.
return ec == basic_errors_t::operation_aborted;
}
bool is_ignored(error_code_t const& /*ec*/) const noexcept {
return false;
}
};
struct map_none {
constexpr map_none() noexcept {}
bool is_cancellation(error_code_t const& /*ec*/) const noexcept {
return false;
}
bool is_ignored(error_code_t const& /*ec*/) const noexcept {
return false;
}
};
template <std::size_t Size>
class map_ignore {
public:
map_ignore(std::array<basic_errors_t, Size> ignored) noexcept
: ignored_(ignored) {}
bool is_cancellation(error_code_t const& ec) const noexcept {
return ec == basic_errors_t::operation_aborted;
}
bool is_ignored(error_code_t const& ec) const noexcept {
for (basic_errors_t ignored : ignored_) {
if (ec == ignored) {
return true;
}
}
return false;
}
private:
std::array<basic_errors_t, Size> ignored_;
};
} // namespace asio } // namespace asio
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -86,24 +86,42 @@
#endif #endif
#endif #endif
/// Usually this is enabled by the CMake project // Automatically detects support for coroutines.
#if !defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE) // Parts of this detection mechanism were adapted from boost::asio,
// with support added for experimental coroutines.
#if !defined(CONTINUABLE_HAS_DISABLED_COROUTINE) \
&& !defined(CONTINUABLE_HAS_COROUTINE)
/// Define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE when /// Define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE when
/// CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE is defined. /// CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE is defined.
#if defined(CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE) #if defined(CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE)
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #define CONTINUABLE_HAS_COROUTINE 1
#elif defined(_MSC_VER) #elif defined(CONTINUABLE_WITH_COROUTINE)
#if _MSC_FULL_VER >= 190023506 #define CONTINUABLE_HAS_COROUTINE 1
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE 1
#elif defined(_MSC_VER) // Visual Studio
#if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)
#define CONTINUABLE_HAS_COROUTINE 1
#elif _MSC_FULL_VER >= 190023506
#if defined(_RESUMABLE_FUNCTIONS_SUPPORTED) #if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #define CONTINUABLE_HAS_COROUTINE 1
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE 1
#endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED) #endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
#endif // _MSC_FULL_VER >= 190023506 #endif // _MSC_FULL_VER >= 190023506
#elif defined(__clang__) #elif defined(__clang__) // Clang
#if defined(__cpp_coroutines) && (__cpp_coroutines >= 201707) #if defined(__cpp_coroutines) && (__cpp_coroutines >= 201703L)
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #define CONTINUABLE_HAS_COROUTINE 1
#endif // defined(__cpp_coroutines) && (__cpp_coroutines >= 201707) #if defined(_LIBCPP_EXPERIMENTAL_COROUTINE)
#endif // defined(__clang__) #define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE 1
#endif // !defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE) #endif
#endif // defined(__cpp_coroutines) && (__cpp_coroutines >= 201703L)
#elif defined(__GNUC__) // GCC
#if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)
#if __has_include(<coroutine>)
#define CONTINUABLE_HAS_COROUTINE 1
#endif // __has_include(<coroutine>)
#endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)
#endif
#endif
/// Define CONTINUABLE_HAS_EXCEPTIONS when exceptions are used /// Define CONTINUABLE_HAS_EXCEPTIONS when exceptions are used
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \ #if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -34,7 +34,6 @@
#include <cassert> #include <cassert>
#include <type_traits> #include <type_traits>
#include <experimental/coroutine>
#include <continuable/continuable-primitives.hpp> #include <continuable/continuable-primitives.hpp>
#include <continuable/continuable-result.hpp> #include <continuable/continuable-result.hpp>
#include <continuable/detail/core/annotation.hpp> #include <continuable/detail/core/annotation.hpp>
@ -48,11 +47,35 @@
# include <exception> # include <exception>
#endif // CONTINUABLE_HAS_EXCEPTIONS #endif // CONTINUABLE_HAS_EXCEPTIONS
#if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
# include <experimental/coroutine>
#elif defined(CONTINUABLE_HAS_COROUTINE)
# include <coroutine>
#endif
#if defined(CONTINUABLE_HAS_COROUTINE)
namespace cti { namespace cti {
namespace detail { namespace detail {
namespace awaiting { namespace awaiting {
/// We import the coroutine handle in our namespace /// We import the coroutine handle in our namespace
# if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
using std::experimental::coroutine_handle; using std::experimental::coroutine_handle;
using std::experimental::suspend_never;
# else
using std::coroutine_handle;
using std::suspend_never;
# endif
# if defined(CONTINUABLE_HAS_EXCEPTIONS)
class await_canceled_exception : public std::exception {
public:
await_canceled_exception() noexcept = default;
char const* what() const noexcept override {
return "co_await canceled due to cancellation of the continuation";
}
};
# endif // CONTINUABLE_HAS_EXCEPTIONS
template <typename T> template <typename T>
struct result_from_identity; struct result_from_identity;
@ -73,6 +96,16 @@ class awaitable {
/// A cache which is used to pass the result of the continuation /// A cache which is used to pass the result of the continuation
/// to the coroutine. /// to the coroutine.
result_t result_; result_t result_;
/// Enumeration that represents the suspension state of the awaitable.
enum class state : std::uint8_t {
suspended,
pending,
resolved,
};
/// An atomic that specifies whether the awaitable has suspended or not.
/// Allows to perform symmetric transfer on continuables that are
/// immediately resolved.
std::atomic<state> state_{state::pending};
public: public:
explicit constexpr awaitable(Continuable&& continuable) explicit constexpr awaitable(Continuable&& continuable)
@ -94,29 +127,46 @@ public:
/// Suspend the current context /// Suspend the current context
// TODO Convert this to an r-value function once possible // TODO Convert this to an r-value function once possible
void await_suspend(coroutine_handle<> h) { bool await_suspend(coroutine_handle<> h) {
assert(result_.is_empty()); assert(result_.is_empty());
// Forward every result to the current awaitable // Forward every result to the current awaitable
std::move(continuable_) std::move(continuable_)
.next([h, this](auto&&... args) mutable { .next([h, this](auto&&... args) mutable {
assert(result_.is_empty()); assert(result_.is_empty());
result_ = result_t::from(std::forward<decltype(args)>(args)...); result_ = result_t::from(std::forward<decltype(args)>(args)...);
h.resume();
// If true, it means that the promise was suspended (i.e., the
// awaitable await_suspend method has already returned). That
// means we must call the resume coroutine from the continuation
// chain.
if (state_.exchange(state::resolved, std::memory_order_acq_rel) ==
state::suspended) {
return h.resume();
}
}) })
.done(); .done();
return state_.exchange(state::suspended, std::memory_order_acq_rel) !=
state::resolved;
} }
/// Resume the coroutine represented by the handle /// Resume the coroutine represented by the handle
typename result_t::value_t await_resume() noexcept(false) { typename result_t::value_t await_resume() noexcept(false) {
if (result_) { if (result_.is_value()) {
// When the result was resolved return it // When the result was resolved return it
return std::move(result_).get_value(); return std::move(result_).get_value();
} }
assert(result_.is_exception());
# if defined(CONTINUABLE_HAS_EXCEPTIONS) # if defined(CONTINUABLE_HAS_EXCEPTIONS)
std::rethrow_exception(result_.get_exception()); if (exception_t e = result_.get_exception()) {
std::rethrow_exception(std::move(e));
} else {
throw await_canceled_exception();
}
# else // CONTINUABLE_HAS_EXCEPTIONS # else // CONTINUABLE_HAS_EXCEPTIONS
// Returning error types in await isn't supported as of now // Returning error types from co_await isn't supported!
CTI_DETAIL_TRAP(); CTI_DETAIL_TRAP();
# endif // CONTINUABLE_HAS_EXCEPTIONS # endif // CONTINUABLE_HAS_EXCEPTIONS
} }
@ -141,8 +191,7 @@ struct handle_takeover {
handle_ = handle; handle_ = handle;
} }
void await_resume() noexcept { void await_resume() noexcept {}
}
}; };
/// The type which is passed to the compiler that describes the properties /// The type which is passed to the compiler that describes the properties
@ -197,15 +246,21 @@ struct promise_type
return {handle_}; return {handle_};
} }
std::experimental::suspend_never final_suspend() { suspend_never final_suspend() noexcept {
return {}; return {};
} }
void unhandled_exception() noexcept { void unhandled_exception() noexcept {
# if defined(CONTINUABLE_HAS_EXCEPTIONS) # if defined(CONTINUABLE_HAS_EXCEPTIONS)
try {
std::rethrow_exception(std::current_exception());
} catch (await_canceled_exception const&) {
promise_.set_canceled();
} catch (...) {
promise_.set_exception(std::current_exception()); promise_.set_exception(std::current_exception());
}
# else // CONTINUABLE_HAS_EXCEPTIONS # else // CONTINUABLE_HAS_EXCEPTIONS
// Returning error types from coroutines isn't supported // Returning exception types from a coroutine isn't supported
CTI_DETAIL_TRAP(); CTI_DETAIL_TRAP();
# endif // CONTINUABLE_HAS_EXCEPTIONS # endif // CONTINUABLE_HAS_EXCEPTIONS
} }
@ -213,5 +268,6 @@ struct promise_type
} // namespace awaiting } // namespace awaiting
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti
#endif // defined(CONTINUABLE_HAS_COROUTINE)
#endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED #endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -50,6 +50,18 @@
namespace cti { namespace cti {
namespace detail { namespace detail {
namespace transforms { namespace transforms {
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
class wait_transform_canceled_exception : public std::exception {
public:
wait_transform_canceled_exception() noexcept = default;
char const* what() const noexcept override {
return "cti::transforms::wait canceled due to cancellation of the "
"continuation";
}
};
#endif // CONTINUABLE_HAS_EXCEPTIONS
template <typename Hint> template <typename Hint>
struct sync_trait; struct sync_trait;
template <typename... Args> template <typename... Args>
@ -60,6 +72,52 @@ struct sync_trait<identity<Args...>> {
using lock_t = std::unique_lock<std::mutex>; using lock_t = std::unique_lock<std::mutex>;
using condition_variable_t = std::condition_variable; using condition_variable_t = std::condition_variable;
template <typename Result>
struct unsafe_unlocker {
explicit unsafe_unlocker(std::atomic_bool* ready, condition_variable_t* cv,
std::mutex* mutex, Result* result)
: ready_(ready)
, cv_(cv)
, mutex_(mutex)
, result_(result) {}
unsafe_unlocker(unsafe_unlocker const&) = delete;
unsafe_unlocker(unsafe_unlocker&&) = default;
unsafe_unlocker& operator=(unsafe_unlocker const&) = delete;
unsafe_unlocker& operator=(unsafe_unlocker&&) = default;
~unsafe_unlocker() {
unlock(Result::empty());
}
template <typename... Args>
void operator()(Args&&... args) {
unlock(Result::from(std::forward<Args>(args)...));
}
void unlock(Result&& result) {
if (!ownership_.is_acquired()) {
return;
}
ownership_.release();
lock_t lock(*mutex_);
*result_ = std::move(result);
assert(!ready_->load(std::memory_order_acquire));
ready_->store(true, std::memory_order_release);
cv_->notify_all();
}
std::atomic_bool* ready_;
condition_variable_t* cv_;
std::mutex* mutex_;
Result* result_;
util::ownership ownership_;
};
template <typename Data, typename Annotation, template <typename Data, typename Annotation,
typename Result = typename sync_trait<Annotation>::result_t> typename Result = typename sync_trait<Annotation>::result_t>
Result wait_relaxed(continuable_base<Data, Annotation>&& continuable) { Result wait_relaxed(continuable_base<Data, Annotation>&& continuable) {
@ -69,22 +127,23 @@ Result wait_relaxed(continuable_base<Data, Annotation>&& continuable) {
return std::move(continuable).unpack(); return std::move(continuable).unpack();
} }
std::mutex cv_mutex;
condition_variable_t cv; condition_variable_t cv;
std::mutex cv_mutex;
std::atomic_bool ready{false}; std::atomic_bool ready{false};
Result sync_result; Result sync_result;
std::move(continuable) std::move(continuable)
.next([&](auto&&... args) { .next(unsafe_unlocker<Result>{
sync_result = Result::from(std::forward<decltype(args)>(args)...); &ready,
&cv,
ready.store(true, std::memory_order_release); &cv_mutex,
cv.notify_all(); &sync_result,
}) })
.done(); .done();
if (!ready.load(std::memory_order_acquire)) {
lock_t lock(cv_mutex); lock_t lock(cv_mutex);
if (!ready.load(std::memory_order_acquire)) {
cv.wait(lock, [&] { cv.wait(lock, [&] {
return ready.load(std::memory_order_acquire); return ready.load(std::memory_order_acquire);
}); });
@ -103,10 +162,15 @@ auto wait_and_unpack(continuable_base<Data, Annotation>&& continuable) {
#if defined(CONTINUABLE_HAS_EXCEPTIONS) #if defined(CONTINUABLE_HAS_EXCEPTIONS)
if (sync_result.is_value()) { if (sync_result.is_value()) {
return std::move(sync_result).get_value(); return std::move(sync_result).get_value();
} else { } else if (sync_result.is_exception()) {
assert(sync_result.is_exception()); if (sync_result.is_exception()) {
std::rethrow_exception(sync_result.get_exception()); if (exception_t e = sync_result.get_exception()) {
std::rethrow_exception(e);
} }
}
}
throw wait_transform_canceled_exception();
#else #else
return sync_result; return sync_result;
#endif // CONTINUABLE_HAS_EXCEPTIONS #endif // CONTINUABLE_HAS_EXCEPTIONS
@ -121,6 +185,47 @@ struct wait_frame {
Result sync_result; Result sync_result;
}; };
template <typename Result>
struct unlocker {
unlocker(unlocker const&) = delete;
unlocker(unlocker&&) = default;
unlocker& operator=(unlocker const&) = delete;
unlocker& operator=(unlocker&&) = default;
explicit unlocker(std::weak_ptr<wait_frame<Result>> frame)
: frame_(std::move(frame)) {}
~unlocker() {
unlock(Result::empty());
}
template <typename... Args>
void operator()(Args&&... args) {
unlock(Result::from(std::forward<decltype(args)>(args)...));
}
void unlock(Result&& result) {
if (!ownership_.is_acquired()) {
return;
}
ownership_.release();
if (auto locked = frame_.lock()) {
{
std::lock_guard<std::mutex> rw_lock(locked->rw_mutex);
assert(!locked->ready.load(std::memory_order_acquire));
locked->sync_result = std::move(result);
}
locked->ready.store(true, std::memory_order_release);
locked->cv.notify_all();
}
}
std::weak_ptr<wait_frame<Result>> frame_;
util::ownership ownership_;
};
template <typename Data, typename Annotation, typename Waiter, template <typename Data, typename Annotation, typename Waiter,
typename Result = typename sync_trait<Annotation>::result_t> typename Result = typename sync_trait<Annotation>::result_t>
Result wait_unsafe(continuable_base<Data, Annotation>&& continuable, Result wait_unsafe(continuable_base<Data, Annotation>&& continuable,
@ -136,18 +241,7 @@ Result wait_unsafe(continuable_base<Data, Annotation>&& continuable,
auto frame = std::make_shared<frame_t>(); auto frame = std::make_shared<frame_t>();
std::move(continuable) std::move(continuable)
.next([frame = std::weak_ptr<frame_t>(frame)](auto&&... args) { .next(unlocker<Result>{std::weak_ptr<frame_t>(frame)})
if (auto locked = frame.lock()) {
{
std::lock_guard<std::mutex> rw_lock(locked->rw_mutex);
locked->sync_result = Result::from(
std::forward<decltype(args)>(args)...);
}
locked->ready.store(true, std::memory_order_release);
locked->cv.notify_all();
}
})
.done(); .done();
if (!frame->ready.load(std::memory_order_acquire)) { if (!frame->ready.load(std::memory_order_acquire)) {

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -4,9 +4,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -35,6 +35,23 @@
#include <continuable/detail/utility/traits.hpp> #include <continuable/detail/utility/traits.hpp>
namespace cti { namespace cti {
/// The error code type used by your asio distribution
///
/// \since 4.1.0
using asio_error_code_t = detail::asio::error_code_t;
/// The basic error code enum used by your asio distribution
///
/// \since 4.1.0
using asio_basic_errors_t = detail::asio::basic_errors_t;
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
/// The system error type used by your asio distribution
///
/// \since 4.1.0
using asio_system_error_t = detail::asio::system_error_t;
#endif // CONTINUABLE_HAS_EXCEPTIONS
/// Type used as an ASIO completion token to specify an asynchronous operation /// Type used as an ASIO completion token to specify an asynchronous operation
/// that should return a continuable_base. /// that should return a continuable_base.
/// ///
@ -60,19 +77,77 @@ namespace cti {
/// }); /// });
/// ``` /// ```
/// ///
/// \tparam Mapper The token can be instantiated with a custom mapper
/// for asio error codes which makes it possible to ignore
/// errors or treat them as cancellation types.
/// The mapper has the following form:
/// ```
/// struct my_mapper {
/// constexpr my_mapper() noexcept {}
///
/// /// Returns true when the error_code_t is a type which represents
/// /// cancellation and
/// bool is_cancellation(error_code_t const& /*ec*/) const noexcept {
/// return false;
/// }
/// bool is_ignored(error_code_t const& /*ec*/) const noexcept {
/// return false;
/// }
/// };
/// ```
///
/// \attention `asio::error::basic_errors::operation_aborted` errors returned
/// by asio are automatically transformed into a default constructed
/// exception type which represents "operation canceled" by the
/// user or program. If you intend to retrieve the full
/// asio::error_code without remapping use the use_continuable_raw_t
/// completion token instead!
///
/// \since 4.0.0 /// \since 4.0.0
struct use_continuable_t {}; template <typename Mapper = detail::asio::map_default>
struct use_continuable_t : public Mapper {
using Mapper::Mapper;
};
/// Special value for instance of `asio_token_t` /// \copydoc use_continuable_t
///
/// The raw async completion handler token does not remap the asio error
/// `asio::error::basic_errors::operation_aborted` to a default constructed
/// exception type.
///
/// \since 4.1.0
using use_continuable_raw_t = use_continuable_t<detail::asio::map_none>;
/// Special value for instance of use_continuable_t which performs remapping
/// of asio error codes to align the cancellation behaviour with the library.
/// ///
/// \copydetails use_continuable_t /// \copydetails use_continuable_t
constexpr use_continuable_t use_continuable{}; constexpr use_continuable_t<> use_continuable{};
/// Special value for instance of use_continuable_raw_t which doesn't perform
/// remapping of asio error codes and rethrows the raw error code.
///
/// \copydetails use_continuable_raw_t
constexpr use_continuable_raw_t use_continuable_raw{};
/// Represents a special asio completion token which treats the given
/// asio basic error codes as success instead of failure.
///
/// `asio::error::basic_errors::operation_aborted` is mapped
/// as cancellation token.
///
/// \since 4.1.0
template <typename... Args>
auto use_continuable_ignoring(Args&&... args) noexcept {
return use_continuable_t<detail::asio::map_ignore<sizeof...(Args)>>{
{asio_basic_errors_t(std::forward<Args>(args))...}};
}
} // namespace cti } // namespace cti
CTI_DETAIL_ASIO_NAMESPACE_BEGIN CTI_DETAIL_ASIO_NAMESPACE_BEGIN
template <typename Signature> template <typename Signature, typename Matcher>
class async_result<cti::use_continuable_t, Signature> { class async_result<cti::use_continuable_t<Matcher>, Signature> {
public: public:
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION) #if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
using return_type = typename cti::detail::asio::initiate_make_continuable< using return_type = typename cti::detail::asio::initiate_make_continuable<
@ -80,16 +155,16 @@ public:
#endif #endif
template <typename Initiation, typename... Args> template <typename Initiation, typename... Args>
static auto initiate(Initiation initiation, cti::use_continuable_t, static auto initiate(Initiation initiation,
Args... args) { cti::use_continuable_t<Matcher> token, Args... args) {
return cti::detail::asio::initiate_make_continuable<Signature>{}( return cti::detail::asio::initiate_make_continuable<Signature>{}(
[initiation = std::move(initiation), [initiation = std::move(initiation), token = std::move(token),
init_args = std::make_tuple(std::move(args)...)]( init_args = std::make_tuple(std::move(args)...)](
auto&& promise) mutable { auto&& promise) mutable {
cti::detail::traits::unpack( cti::detail::traits::unpack(
[initiation = std::move(initiation), [initiation = std::move(initiation),
handler = cti::detail::asio::promise_resolver_handler( handler = cti::detail::asio::promise_resolver_handler(
std::forward<decltype(promise)>(promise))]( std::forward<decltype(promise)>(promise), std::move(token))](
auto&&... args) mutable { auto&&... args) mutable {
std::move(initiation)(std::move(handler), std::move(initiation)(std::move(handler),
std::forward<decltype(args)>(args)...); std::forward<decltype(args)>(args)...);

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_ \_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable https://github.com/Naios/continuable
v4.0.0 v4.2.0
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -34,6 +34,7 @@
#include <chrono> #include <chrono>
#include <condition_variable> #include <condition_variable>
#include <utility> #include <utility>
#include <continuable/detail/features.hpp>
#include <continuable/detail/transforms/wait.hpp> #include <continuable/detail/transforms/wait.hpp>
namespace cti { namespace cti {
@ -41,6 +42,15 @@ namespace cti {
/// \{ /// \{
namespace transforms { namespace transforms {
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
/// Is thrown from wait if the awaited continuable_base was cancelled,
/// which was signaled through resolving with a default
/// constructed exception type.
///
/// \since 4.1.0
using wait_transform_canceled_exception = detail::transforms::wait_transform_canceled_exception;
#endif // CONTINUABLE_HAS_EXCEPTIONS
/// Returns a transform that if applied to a continuable, /// Returns a transform that if applied to a continuable,
/// it will start the continuation chain and returns the result synchronously. /// it will start the continuation chain and returns the result synchronously.
/// The current thread is blocked until the continuation chain is finished. /// The current thread is blocked until the continuation chain is finished.
@ -53,6 +63,10 @@ namespace transforms {
/// | `continuable_base with <Arg>` | `Arg` | /// | `continuable_base with <Arg>` | `Arg` |
/// | `continuable_base with <Args...>` | `std::tuple<Args...>` | /// | `continuable_base with <Args...>` | `std::tuple<Args...>` |
/// ///
/// \throws wait_transform_canceled_exception if the awaited continuable_base
/// is cancelled, and thus was resolved with a default
/// constructed exception type.
///
/// \attention If exceptions are used, exceptions that are thrown, are rethrown /// \attention If exceptions are used, exceptions that are thrown, are rethrown
/// synchronously. /// synchronously.
/// ///

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -44,9 +44,7 @@ public:
}) {} }) {}
~async_test_helper() { ~async_test_helper() {
assert(work_); cancel();
timer_.cancel();
work_.reset();
thread_.join(); thread_.join();
} }
@ -55,6 +53,11 @@ public:
return timer_.async_wait(use_continuable); return timer_.async_wait(use_continuable);
} }
void cancel() {
timer_.cancel();
work_.reset();
}
private: private:
asio::io_context context_; asio::io_context context_;
asio::steady_timer timer_; asio::steady_timer timer_;
@ -111,6 +114,51 @@ TYPED_TEST(single_dimension_tests, wait_test_exception) {
.apply(cti::transforms::wait()), .apply(cti::transforms::wait()),
test_exception); test_exception);
} }
TYPED_TEST(single_dimension_tests, wait_test_unlocked) {
make_continuable<void>([&](promise<> p) {
p.set_value();
}).apply(transforms::wait());
ASSERT_TRUE(true);
}
TYPED_TEST(single_dimension_tests, wait_test_cancellation) {
ASSERT_THROW(make_cancelling_continuable<void>().apply(
cti::transforms::wait()),
transforms::wait_transform_canceled_exception);
}
TYPED_TEST(single_dimension_tests,
wait_test_exception_unlocked_void_failure_handle) {
ASSERT_THROW(make_exceptional_continuable<void>(supply_test_exception())
.fail([](exception_t) {})
.apply(transforms::wait()),
transforms::wait_transform_canceled_exception);
}
TYPED_TEST(single_dimension_tests, wait_test_unlocked_empty_result) {
ASSERT_THROW(async([]() -> result<> {
return empty_result();
}).apply(transforms::wait()),
transforms::wait_transform_canceled_exception);
}
TYPED_TEST(single_dimension_tests,
wait_for_test_exception_unlocked_void_failure_handle) {
ASSERT_TRUE(make_exceptional_continuable<void>(supply_test_exception())
.fail([](exception_t) {})
.apply(transforms::wait_for(24h))
.is_empty());
}
TYPED_TEST(single_dimension_tests, wait_for_test_unlocked_empty_result) {
ASSERT_TRUE(async([]() -> result<> {
return empty_result();
})
.apply(transforms::wait_for(24h))
.is_empty());
}
#endif // CONTINUABLE_HAS_EXCEPTIONS #endif // CONTINUABLE_HAS_EXCEPTIONS
TYPED_TEST(single_dimension_tests, wait_for_test_sync) { TYPED_TEST(single_dimension_tests, wait_for_test_sync) {
@ -135,3 +183,53 @@ TYPED_TEST(single_dimension_tests, wait_for_test_async) {
result<> res = helper.wait_for(500ms).apply(cti::transforms::wait_for(50ms)); result<> res = helper.wait_for(500ms).apply(cti::transforms::wait_for(50ms));
ASSERT_FALSE(res.is_exception()); ASSERT_FALSE(res.is_exception());
} }
TYPED_TEST(single_dimension_tests, token_remap_canceled) {
asio::io_context io(1);
asio::steady_timer timer(io, 50ms);
result<> value;
timer.async_wait(use_continuable).next([&](auto&&... args) {
value = result<>::from(std::forward<decltype(args)>(args)...);
});
timer.cancel();
io.run();
ASSERT_TRUE(value.is_exception());
ASSERT_FALSE(bool(value.get_exception()));
}
TYPED_TEST(single_dimension_tests, token_remap_none_raw) {
asio::io_context io(1);
asio::steady_timer timer(io, 50ms);
result<> value;
timer.async_wait(use_continuable_raw).next([&](auto&&... args) {
value = result<>::from(std::forward<decltype(args)>(args)...);
});
timer.cancel();
io.run();
ASSERT_TRUE(value.is_exception());
ASSERT_TRUE(bool(value.get_exception()));
}
TYPED_TEST(single_dimension_tests, token_remap_ignore) {
asio::io_context io(1);
asio::steady_timer timer(io, 50ms);
result<> value;
timer
.async_wait(
use_continuable_ignoring(asio_basic_errors_t::operation_aborted))
.next([&](auto&&... args) {
value = result<>::from(std::forward<decltype(args)>(args)...);
});
timer.cancel();
io.run();
ASSERT_TRUE(value.is_value());
}

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -24,7 +24,8 @@
#include <test-continuable.hpp> #include <test-continuable.hpp>
#include <continuable/detail/features.hpp> #include <continuable/detail/features.hpp>
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
#ifdef CONTINUABLE_HAS_COROUTINE
# ifndef CONTINUABLE_WITH_NO_EXCEPTIONS # ifndef CONTINUABLE_WITH_NO_EXCEPTIONS
# include <exception> # include <exception>
@ -105,7 +106,9 @@ cti::continuable<> resolve_async_exceptional(S&& supplier) {
// GTest ASSERT_THROW isn't co_await friendly yet: // GTest ASSERT_THROW isn't co_await friendly yet:
// clang: 'return statement not allowed in coroutine; did you mean // clang: 'return statement not allowed in coroutine; did you mean
// 'co_return'?' // 'co_return'?'
EXPECT_THROW(co_await supplier().then([] { throw await_exception{}; }), EXPECT_THROW(co_await supplier().then([] {
throw await_exception{};
}),
await_exception); await_exception);
co_return; co_return;
@ -141,6 +144,103 @@ TYPED_TEST(single_dimension_tests, are_awaitable_with_exceptions_from_coro) {
await_exception{}) await_exception{})
} }
template <typename S>
cti::continuable<> resolve_coro_canceled(S&& supplier) {
// Pseudo wait
co_await supplier();
try {
co_await cti::make_cancelling_continuable<void>();
} catch (cti::await_canceled_exception const& e) {
std::rethrow_exception(std::make_exception_ptr(e));
} catch (...) {
EXPECT_TRUE(false);
}
co_return;
}
TYPED_TEST(single_dimension_tests, are_awaitable_with_cancellation_from_coro) {
auto const& supply = [&](auto&&... args) {
// Supplies the current tested continuable
return this->supply(std::forward<decltype(args)>(args)...);
};
ASSERT_ASYNC_CANCELLATION(resolve_coro_canceled(supply))
}
template <typename S>
cti::continuable<> test_symmetric_transfer(S&& supplier) {
// If symmetric transfer is not working properly, large
// loops will quickly cause stack overflows.
for (size_t index = 0; index < 10000; index++) {
co_await supplier();
}
co_return;
}
TYPED_TEST(single_dimension_tests, are_symmetric_transferable) {
auto const& supply = [&]() {
return cti::make_continuable<int>([](auto&& promise) {
promise.set_value(0);
});
};
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
}
TYPED_TEST(single_dimension_tests, are_symmetric_transferable_type_erased) {
auto const& supply = [&]() -> cti::continuable<int> {
return cti::make_continuable<int>([](auto&& promise) {
promise.set_value(0);
});
};
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
}
TYPED_TEST(single_dimension_tests,
are_symmetric_transferable_using_make_ready) {
auto const& supply = [&]() {
return cti::make_ready_continuable<int>(0);
};
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
}
TYPED_TEST(single_dimension_tests,
are_symmetric_transferable_using_type_erased_make_ready) {
auto const& supply = [&]() -> cti::continuable<int> {
return cti::make_ready_continuable<int>(0);
};
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
}
TYPED_TEST(single_dimension_tests, are_symmetric_transferable_using_type_erased_from_thread) {
auto const& supply = [&]() -> cti::continuable<int> {
return cti::make_continuable<int>([](auto&& promise) {
std::async(std::launch::async, std::forward<decltype(promise)>(promise), 0);
});
};
ASSERT_ASYNC_COMPLETION(test_symmetric_transfer(supply));
}
TYPED_TEST(single_dimension_tests, are_symmetric_transferable_except) {
size_t count = 0;
auto const& supply = [&]() -> cti::continuable<int> {
// NOTE: The symmetric transfer loop does 10000 iterations.
if(++count == 5000) {
return cti::make_exceptional_continuable<int>(
std::make_exception_ptr(std::runtime_error("Failed")));
}
return cti::make_ready_continuable<int>(0);
};
ASSERT_ASYNC_EXCEPTION_COMPLETION(test_symmetric_transfer(supply));
}
# endif // CONTINUABLE_WITH_NO_EXCEPTIONS # endif // CONTINUABLE_WITH_NO_EXCEPTIONS
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE #endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal
@ -47,6 +47,26 @@ TYPED_TEST(single_dimension_tests, are_executor_dispatchable) {
ASSERT_ASYNC_COMPLETION(std::move(chain)); ASSERT_ASYNC_COMPLETION(std::move(chain));
} }
TYPED_TEST(single_dimension_tests, are_executor_dispatchable_via) {
bool invoked = false;
auto executor = [&](auto&& work) {
// We can move the worker object
auto local = std::forward<decltype(work)>(work);
ASSERT_FALSE(invoked);
// We can invoke the worker object
std::move(local)();
};
auto chain = this->supply().via(executor).then([&] {
ASSERT_FALSE(invoked);
invoked = true;
});
ASSERT_ASYNC_COMPLETION(std::move(chain));
ASSERT_TRUE(invoked);
}
TYPED_TEST(single_dimension_tests, are_executor_exception_resolveable) { TYPED_TEST(single_dimension_tests, are_executor_exception_resolveable) {
auto executor = [&](auto&& work) { auto executor = [&](auto&& work) {
std::forward<decltype(work)>(work).set_exception(supply_test_exception()); std::forward<decltype(work)>(work).set_exception(supply_test_exception());

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/* /*
Copyright(c) 2015 - 2020 Denis Blank <denis.blank at outlook dot com> Copyright(c) 2015 - 2022 Denis Blank <denis.blank at outlook dot com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal of this software and associated documentation files(the "Software"), to deal

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