Compare commits

..

No commits in common. "master" and "4.0.0" have entirely different histories.

114 changed files with 553 additions and 1253 deletions

View File

@ -1,109 +0,0 @@
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

80
.travis.yml Normal file
View File

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

View File

@ -7,6 +7,7 @@
<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://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>
<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>

View File

@ -1,5 +1,5 @@
# 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
# of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# 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
# of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# 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
# of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# 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
# of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# 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
# of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# 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
# of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
# 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
# of this software and associated documentation files(the "Software"), to deal

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

View File

@ -7,7 +7,7 @@
https://github.com/Naios/continuable
v4.0.0
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
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
# control system is used.
PROJECT_NUMBER = 4.1.0
PROJECT_NUMBER = 4.0.0
# 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

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal
@ -30,15 +30,6 @@ Following versions were released:
\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:
<B>Various improvements to continuable_base:</B>
@ -57,7 +48,7 @@ async([] {
}).then(...);
\endcode
- \ref async Makes it possible to start with a handler instead of a continuation, comparable to `std::async`
- \ref async
- \ref async_on allows to specify an additional executor parameter
<B>The result class and modifying the asynchronous control flow</B>
@ -71,15 +62,15 @@ handlers when exceptions are disabled.
Result handling and
- \ref result
- \ref rethrow Throws an exception or error code from a result or failure handler
- \ref cancel Throws a default constructed exception type or error code from a result or failure handler to signal cancellation.
- \ref stop \copybrief stop
- \ref make_result \copybrief make_result
- \ref rethrow
- \ref cancel
- \ref stop
- \ref make_result
Special result types
- \ref empty_result \copybrief empty_result
- \ref cancellation_result \copybrief cancellation_result
- \ref exceptional_result \copybrief exceptional_result
- \ref empty_result
- \ref cancellation_result
- \ref exceptional_result
<B>Optimize 'ready' continuables:</B>
@ -87,9 +78,9 @@ Continuables which are 'ready' and side effect free can now be unpacked
synchronously. Mainly such continuables are created through \ref make_ready_continuable,
\ref make_exceptional_continuable and \ref make_cancelling_continuable.
- \ref continuable_base::is_ready \copybrief continuable_base::is_ready
- \ref continuable_base::unpack \copybrief continuable_base::unpack
- \ref make_cancelling_continuable \copybrief make_cancelling_continuable
- \ref continuable_base::is_ready
- \ref continuable_base::unpack
- \ref make_cancelling_continuable
Including various helper tags for the underlying changed continuation object structure:
@ -104,7 +95,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
return a \ref continuable_base.
- \ref use_continuable \copybrief use_continuable_t
- \ref use_continuable
\code{.cpp}
#include <continuable/continuable.hpp>
@ -125,31 +116,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,
that is comparable to a `co_await` with `for`.
- \ref loop \copybrief loop
- \ref loop_result \copybrief loop_result
- \ref loop_break \copybrief loop_break
- \ref loop_continue \copybrief loop_continue
- \ref range_loop \copybrief range_loop
- \ref range_loop \copybrief range_loop
- \ref plain_t \copybrief plain_t
- \ref make_plain \copybrief make_plain
- \ref loop
- \ref loop_result
- \ref loop_break
- \ref loop_continue
- \ref range_loop
- \ref range_loop
- \ref plain_t
- \ref make_plain
<B>Synchronous wait transforms:</B>
The wait transforms allows to block the current thread until a \ref continuable_base
was resolved.
- \ref transforms::wait \copybrief transforms::wait
- \ref transforms::wait_for Same as \ref transforms::wait wich waits for a given duration
- \ref transforms::wait_until Same as \ref transforms::wait wich waits until a given timepoint
- \ref transforms::wait
- \ref transforms::wait_for
- \ref transforms::wait_until
<B>Various changes:</B>
Many more unlisted changes including:
- \ref work \copybrief work
- \ref work
- \ref continuation_capacity
- \ref promisify::with \copybrief promisify::with
- \ref promisify::with
- \ref void_arg_t
Additional various bugfixes have been made.
@ -160,8 +151,8 @@ Additional various bugfixes have been made.
New helper functions were added to create ready continuables:
- \ref make_ready_continuable \copybrief make_ready_continuable
- \ref make_exceptional_continuable \copybrief make_exceptional_continuable
- \ref make_ready_continuable
- \ref make_exceptional_continuable
<B>Improvements to connections</B>

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
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:
>
> 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
> of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal
@ -125,7 +125,6 @@ and might be installed from there.
For major versions there is an amalgamation header provided which can be
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)
\subsection installation-installation-copy By copying the headers

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -7,7 +7,7 @@
https://github.com/Naios/continuable
v3.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -7,7 +7,7 @@
https://github.com/Naios/continuable
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -50,22 +50,18 @@ void unexpected_error(cti::exception_t);
// Check that the failure was an aborted operation, as expected.
void check_aborted_operation(cti::exception_t);
// Use a strand as executor
void using_strand();
int main(int, char**) {
daytime_service();
successful_async_wait();
cancelled_async_wait();
using_strand();
return 0;
}
void daytime_service() {
using asio::ip::tcp;
asio::io_context ioc(1);
tcp::resolver resolver(ioc);
tcp::socket socket(ioc);
@ -150,27 +146,3 @@ void check_aborted_operation(cti::exception_t ex) {
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
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -47,9 +47,10 @@
#include <continuable/detail/utility/traits.hpp>
#include <continuable/detail/utility/util.hpp>
#if defined(CONTINUABLE_HAS_COROUTINE)
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
#include <experimental/coroutine>
#include <continuable/detail/other/coroutines.hpp>
#endif // defined(CONTINUABLE_HAS_COROUTINE)
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
namespace cti {
/// \defgroup Base Base
@ -108,13 +109,13 @@ class continuable_base {
/// Constructor accepting the data object while erasing the annotation
explicit continuable_base(Data data, ownership ownership)
: data_(std::move(data))
, ownership_(std::move(ownership)) {}
: data_(std::move(data)), ownership_(std::move(ownership)) {
}
public:
/// 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,
/// while erasing the annotation
@ -123,10 +124,10 @@ public:
Data, Annotation,
detail::traits::unrefcv_t<OtherData>>::value>* = nullptr>
/* implicit */ continuable_base(OtherData&& data)
: data_(
detail::base::proxy_continuable<Annotation,
detail::traits::unrefcv_t<OtherData>>(
std::forward<OtherData>(data))) {}
: data_(detail::base::proxy_continuable<
Annotation, detail::traits::unrefcv_t<OtherData>>(
std::forward<OtherData>(data))) {
}
/// Constructor taking the data of other continuable_base objects
/// while erasing the hint.
@ -137,7 +138,8 @@ public:
std::enable_if_t<std::is_convertible<
detail::traits::unrefcv_t<OData>, Data>::value>* = nullptr>
/* 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
/// while erasing the hint.
@ -146,7 +148,8 @@ public:
/// the continuable by any object which is useful for type-erasure.
template <typename OData, typename OAnnotation>
/* implicit */ continuable_base(continuable_base<OData, OAnnotation>&& other)
: continuable_base(std::move(other).finish().consume()) {}
: continuable_base(std::move(other).finish().consume()) {
}
/// \cond false
continuable_base(continuable_base&&) = default;
@ -317,19 +320,13 @@ public:
/// ```cpp
/// http_request("github.com")
/// .then([](std::string github) { })
/// .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) {
/// .fail([](std::exception_ptr ptr) {
/// // Handle the error here
/// try {
/// std::rethrow_exception(ep);
/// std::rethrow_exception(ptr);
/// } catch (std::exception& e) {
/// e.what(); // Handle the exception
/// }
/// }
/// });
/// ```
/// In case exceptions are disabled, `std::error_condition` is
@ -348,18 +345,6 @@ public:
/// \returns Returns a continuable_base with an asynchronous return 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
template <typename T, typename E = detail::types::this_thread_executor_tag>
auto fail(T&& callback,
@ -433,21 +418,6 @@ public:
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
/// to the given Args.
///
@ -714,7 +684,7 @@ public:
}
/// \cond false
#if defined(CONTINUABLE_HAS_COROUTINE)
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
/// \endcond
/// Implements the operator for awaiting on continuables using `co_await`.
///
@ -780,7 +750,7 @@ public:
return detail::awaiting::create_awaiter(std::move(*this).finish());
}
/// \cond false
#endif // defined(CONTINUABLE_HAS_COROUTINE)
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
/// \endcond
private:
@ -937,8 +907,8 @@ constexpr auto make_exceptional_continuable(Exception&& exception) {
"Requires at least one type for the fake signature!");
using hint_t = typename detail::hints::from_args<Args...>::type;
using ready_continuation_t = typename detail::base::
ready_continuation_from_hint<hint_t>::type;
using ready_continuation_t =
typename detail::base::ready_continuation_from_hint<hint_t>::type;
using result_t = typename detail::base::result_from_hint<hint_t>::type;
return detail::base::attorney::create_from_raw(
ready_continuation_t(result_t::from(exception_arg_t{},

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -4,9 +4,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -39,59 +39,28 @@
#include <exception>
#endif // CONTINUABLE_HAS_EXCEPTIONS
#if defined(CONTINUABLE_HAS_COROUTINE)
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
#include <continuable/detail/other/coroutines.hpp>
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
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
/// \cond false
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
// As far as I know there is no other way to implement this specialization...
// NOLINTNEXTLINE(cert-dcl58-cpp)
namespace std {
# if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
namespace experimental {
# endif // defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
template <typename Data, typename... Args, typename... FunctionArgs>
struct coroutine_traits<
cti::continuable_base<Data, cti::detail::identity<Args...>>,
FunctionArgs...> {
using promise_type = cti::detail::awaiting::promise_type<
cti::continuable<Args...>, cti::promise<Args...>, Args...>;
using promise_type =
cti::detail::awaiting::promise_type<cti::continuable<Args...>,
cti::promise<Args...>, Args...>;
};
# if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
} // namespace experimental
# endif // defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
} // namespace std
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
/// \endcond
#endif // defined(CONTINUABLE_HAS_COROUTINE)
#endif // CONTINUABLE_COROUTINE_HPP_INCLUDED

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
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>
static auto finalize(Connection&& connection, util::ownership ownership) {
auto res =
auto result =
aggregated::box_continuables(std::forward<Connection>(connection));
auto signature = aggregated::hint_of_data<decltype(res)>();
auto signature = aggregated::hint_of_data<decltype(result)>();
return base::attorney::create_from(
[res = std::move(res)](auto&& callback) mutable {
[result = std::move(result)](auto&& callback) mutable {
// The data from which the visitor is constructed in-place
using data_t =
seq::sequential_dispatch_data<std::decay_t<decltype(callback)>,
std::decay_t<decltype(res)>>;
std::decay_t<decltype(result)>>;
// The visitor type
using visitor_t = seq::sequential_dispatch_visitor<data_t>;
traverse_pack_async(async_traverse_in_place_tag<visitor_t>{},
data_t{std::forward<decltype(callback)>(callback),
std::move(res)});
std::move(result)});
},
signature, std::move(ownership));
}

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -4,9 +4,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -30,7 +30,6 @@
#ifndef CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
#define CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
#include <array>
#include <utility>
#include <continuable/continuable-base.hpp>
#include <continuable/detail/core/base.hpp>
@ -109,50 +108,29 @@ using system_error_t = ::boost::system::system_error;
#endif
#endif
template <typename Promise, typename Token>
class promise_resolver {
public:
explicit promise_resolver(Promise promise, Token token)
: promise_(std::move(promise))
, 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 (!token_.is_ignored(e)) {
if (token_.is_cancellation(e)) {
promise_.set_canceled();
return;
} else {
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
promise_.set_exception(
std::make_exception_ptr(system_error_t(std::move(e))));
#else
promise_.set_exception(exception_t(e.value(), e.category()));
#endif
return;
}
}
}
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));
template <typename Promise>
auto promise_resolver_handler(Promise&& promise) noexcept {
return [promise = std::forward<Promise>(promise)](
error_code_t e, auto&&... args) mutable noexcept {
if (e) {
if (e != basic_errors_t::operation_aborted) {
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
promise.set_exception(
std::make_exception_ptr(system_error_t(std::move(e))));
#else
promise.set_exception(exception_t(e.value(), e.category()));
#endif
} else {
// 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)...);
}
};
}
// Helper struct wrapping a call to `cti::make_continuable` and, if needed,
@ -160,19 +138,6 @@ auto promise_resolver_handler(Promise&& promise, Token&& token) noexcept {
template <typename Signature>
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>
struct initiate_make_continuable<void(error_code_t, Args...)> {
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
@ -190,51 +155,6 @@ template <typename... Args>
struct initiate_make_continuable<void(error_code_t const&, 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 detail
} // namespace cti

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -86,42 +86,24 @@
#endif
#endif
// Automatically detects support for coroutines.
// 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)
/// Usually this is enabled by the CMake project
#if !defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
/// Define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE when
/// CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE is defined.
#if defined(CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE)
#define CONTINUABLE_HAS_COROUTINE 1
#elif defined(CONTINUABLE_WITH_COROUTINE)
#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
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
#elif defined(_MSC_VER)
#if _MSC_FULL_VER >= 190023506
#if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
#define CONTINUABLE_HAS_COROUTINE 1
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE 1
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
#endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
#endif // _MSC_FULL_VER >= 190023506
#elif defined(__clang__) // Clang
#if defined(__cpp_coroutines) && (__cpp_coroutines >= 201703L)
#define CONTINUABLE_HAS_COROUTINE 1
#if defined(_LIBCPP_EXPERIMENTAL_COROUTINE)
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE 1
#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
#elif defined(__clang__)
#if defined(__cpp_coroutines) && (__cpp_coroutines >= 201707)
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
#endif // defined(__cpp_coroutines) && (__cpp_coroutines >= 201707)
#endif // defined(__clang__)
#endif // !defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
/// Define CONTINUABLE_HAS_EXCEPTIONS when exceptions are used
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -34,6 +34,7 @@
#include <cassert>
#include <type_traits>
#include <experimental/coroutine>
#include <continuable/continuable-primitives.hpp>
#include <continuable/continuable-result.hpp>
#include <continuable/detail/core/annotation.hpp>
@ -47,35 +48,11 @@
#include <exception>
#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 detail {
namespace awaiting {
/// We import the coroutine handle in our namespace
# if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
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>
struct result_from_identity;
@ -96,16 +73,6 @@ class awaitable {
/// A cache which is used to pass the result of the continuation
/// to the coroutine.
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:
explicit constexpr awaitable(Continuable&& continuable)
@ -127,46 +94,29 @@ public:
/// Suspend the current context
// TODO Convert this to an r-value function once possible
bool await_suspend(coroutine_handle<> h) {
void await_suspend(coroutine_handle<> h) {
assert(result_.is_empty());
// Forward every result to the current awaitable
std::move(continuable_)
.next([h, this](auto&&... args) mutable {
assert(result_.is_empty());
result_ = result_t::from(std::forward<decltype(args)>(args)...);
// 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();
}
h.resume();
})
.done();
return state_.exchange(state::suspended, std::memory_order_acq_rel) !=
state::resolved;
}
/// Resume the coroutine represented by the handle
typename result_t::value_t await_resume() noexcept(false) {
if (result_.is_value()) {
if (result_) {
// When the result was resolved return it
return std::move(result_).get_value();
}
assert(result_.is_exception());
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
if (exception_t e = result_.get_exception()) {
std::rethrow_exception(std::move(e));
} else {
throw await_canceled_exception();
}
std::rethrow_exception(result_.get_exception());
#else // CONTINUABLE_HAS_EXCEPTIONS
// Returning error types from co_await isn't supported!
// Returning error types in await isn't supported as of now
CTI_DETAIL_TRAP();
#endif // CONTINUABLE_HAS_EXCEPTIONS
}
@ -191,7 +141,8 @@ struct handle_takeover {
handle_ = handle;
}
void await_resume() noexcept {}
void await_resume() noexcept {
}
};
/// The type which is passed to the compiler that describes the properties
@ -246,21 +197,15 @@ struct promise_type
return {handle_};
}
suspend_never final_suspend() noexcept {
std::experimental::suspend_never final_suspend() {
return {};
}
void unhandled_exception() noexcept {
#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());
}
#else // CONTINUABLE_HAS_EXCEPTIONS
// Returning exception types from a coroutine isn't supported
// Returning error types from coroutines isn't supported
CTI_DETAIL_TRAP();
#endif // CONTINUABLE_HAS_EXCEPTIONS
}
@ -268,6 +213,5 @@ struct promise_type
} // namespace awaiting
} // namespace detail
} // namespace cti
#endif // defined(CONTINUABLE_HAS_COROUTINE)
#endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -50,18 +50,6 @@
namespace cti {
namespace detail {
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>
struct sync_trait;
template <typename... Args>
@ -72,52 +60,6 @@ struct sync_trait<identity<Args...>> {
using lock_t = std::unique_lock<std::mutex>;
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,
typename Result = typename sync_trait<Annotation>::result_t>
Result wait_relaxed(continuable_base<Data, Annotation>&& continuable) {
@ -127,23 +69,22 @@ Result wait_relaxed(continuable_base<Data, Annotation>&& continuable) {
return std::move(continuable).unpack();
}
condition_variable_t cv;
std::mutex cv_mutex;
condition_variable_t cv;
std::atomic_bool ready{false};
Result sync_result;
std::move(continuable)
.next(unsafe_unlocker<Result>{
&ready,
&cv,
&cv_mutex,
&sync_result,
.next([&](auto&&... args) {
sync_result = Result::from(std::forward<decltype(args)>(args)...);
ready.store(true, std::memory_order_release);
cv.notify_all();
})
.done();
lock_t lock(cv_mutex);
if (!ready.load(std::memory_order_acquire)) {
lock_t lock(cv_mutex);
cv.wait(lock, [&] {
return ready.load(std::memory_order_acquire);
});
@ -162,15 +103,10 @@ auto wait_and_unpack(continuable_base<Data, Annotation>&& continuable) {
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
if (sync_result.is_value()) {
return std::move(sync_result).get_value();
} else if (sync_result.is_exception()) {
if (sync_result.is_exception()) {
if (exception_t e = sync_result.get_exception()) {
std::rethrow_exception(e);
} else {
assert(sync_result.is_exception());
std::rethrow_exception(sync_result.get_exception());
}
}
}
throw wait_transform_canceled_exception();
#else
return sync_result;
#endif // CONTINUABLE_HAS_EXCEPTIONS
@ -185,47 +121,6 @@ struct wait_frame {
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,
typename Result = typename sync_trait<Annotation>::result_t>
Result wait_unsafe(continuable_base<Data, Annotation>&& continuable,
@ -241,7 +136,18 @@ Result wait_unsafe(continuable_base<Data, Annotation>&& continuable,
auto frame = std::make_shared<frame_t>();
std::move(continuable)
.next(unlocker<Result>{std::weak_ptr<frame_t>(frame)})
.next([frame = std::weak_ptr<frame_t>(frame)](auto&&... args) {
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();
if (!frame->ready.load(std::memory_order_acquire)) {

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -4,9 +4,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -35,23 +35,6 @@
#include <continuable/detail/utility/traits.hpp>
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
/// that should return a continuable_base.
///
@ -77,77 +60,19 @@ using asio_system_error_t = detail::asio::system_error_t;
/// });
/// ```
///
/// \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
template <typename Mapper = detail::asio::map_default>
struct use_continuable_t : public Mapper {
using Mapper::Mapper;
};
struct use_continuable_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.
/// Special value for instance of `asio_token_t`
///
/// \copydetails use_continuable_t
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))...}};
}
constexpr use_continuable_t use_continuable{};
} // namespace cti
CTI_DETAIL_ASIO_NAMESPACE_BEGIN
template <typename Signature, typename Matcher>
class async_result<cti::use_continuable_t<Matcher>, Signature> {
template <typename Signature>
class async_result<cti::use_continuable_t, Signature> {
public:
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
using return_type = typename cti::detail::asio::initiate_make_continuable<
@ -155,16 +80,16 @@ public:
#endif
template <typename Initiation, typename... Args>
static auto initiate(Initiation initiation,
cti::use_continuable_t<Matcher> token, Args... args) {
static auto initiate(Initiation initiation, cti::use_continuable_t,
Args... args) {
return cti::detail::asio::initiate_make_continuable<Signature>{}(
[initiation = std::move(initiation), token = std::move(token),
[initiation = std::move(initiation),
init_args = std::make_tuple(std::move(args)...)](
auto&& promise) mutable {
cti::detail::traits::unpack(
[initiation = std::move(initiation),
handler = cti::detail::asio::promise_resolver_handler(
std::forward<decltype(promise)>(promise), std::move(token))](
std::forward<decltype(promise)>(promise))](
auto&&... args) mutable {
std::move(initiation)(std::move(handler),
std::forward<decltype(args)>(args)...);

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -5,9 +5,9 @@
\_,(_)| | | || ||_|(_||_)|(/_
https://github.com/Naios/continuable
v4.2.0
v4.0.0
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
of this software and associated documentation files(the "Software"), to deal
@ -34,7 +34,6 @@
#include <chrono>
#include <condition_variable>
#include <utility>
#include <continuable/detail/features.hpp>
#include <continuable/detail/transforms/wait.hpp>
namespace cti {
@ -42,15 +41,6 @@ namespace cti {
/// \{
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,
/// it will start the continuation chain and returns the result synchronously.
/// The current thread is blocked until the continuation chain is finished.
@ -63,10 +53,6 @@ using wait_transform_canceled_exception = detail::transforms::wait_transform_can
/// | `continuable_base with <Arg>` | `Arg` |
/// | `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
/// synchronously.
///

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,5 +1,5 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal
@ -44,7 +44,9 @@ public:
}) {}
~async_test_helper() {
cancel();
assert(work_);
timer_.cancel();
work_.reset();
thread_.join();
}
@ -53,11 +55,6 @@ public:
return timer_.async_wait(use_continuable);
}
void cancel() {
timer_.cancel();
work_.reset();
}
private:
asio::io_context context_;
asio::steady_timer timer_;
@ -114,51 +111,6 @@ TYPED_TEST(single_dimension_tests, wait_test_exception) {
.apply(cti::transforms::wait()),
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
TYPED_TEST(single_dimension_tests, wait_for_test_sync) {
@ -183,53 +135,3 @@ TYPED_TEST(single_dimension_tests, wait_for_test_async) {
result<> res = helper.wait_for(500ms).apply(cti::transforms::wait_for(50ms));
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 - 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
of this software and associated documentation files(the "Software"), to deal
@ -24,8 +24,7 @@
#include <test-continuable.hpp>
#include <continuable/detail/features.hpp>
#ifdef CONTINUABLE_HAS_COROUTINE
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
#ifndef CONTINUABLE_WITH_NO_EXCEPTIONS
#include <exception>
@ -106,9 +105,7 @@ cti::continuable<> resolve_async_exceptional(S&& supplier) {
// GTest ASSERT_THROW isn't co_await friendly yet:
// clang: 'return statement not allowed in coroutine; did you mean
// 'co_return'?'
EXPECT_THROW(co_await supplier().then([] {
throw await_exception{};
}),
EXPECT_THROW(co_await supplier().then([] { throw await_exception{}; }),
await_exception);
co_return;
@ -144,103 +141,6 @@ TYPED_TEST(single_dimension_tests, are_awaitable_with_exceptions_from_coro) {
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_HAS_EXPERIMENTAL_COROUTINE

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal
@ -47,26 +47,6 @@ TYPED_TEST(single_dimension_tests, are_executor_dispatchable) {
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) {
auto executor = [&](auto&& work) {
std::forward<decltype(work)>(work).set_exception(supply_test_exception());

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
of this software and associated documentation files(the "Software"), to deal

View File

@ -1,6 +1,6 @@
/*
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
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