mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 08:46:44 +08:00
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.
This commit is contained in:
parent
2fcc2bf281
commit
01f9dbd1f4
121
CMakeLists.txt
121
CMakeLists.txt
@ -1,4 +1,3 @@
|
||||
|
||||
# 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
|
||||
@ -8,8 +7,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,
|
||||
@ -21,7 +20,10 @@
|
||||
|
||||
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)
|
||||
@ -30,47 +32,47 @@ else()
|
||||
CTI_CONTINUABLE_IS_TOP_LEVEL_PROJECT)
|
||||
endif()
|
||||
|
||||
option(CTI_CONTINUABLE_WITH_INSTALL
|
||||
"Add the continuable install targets"
|
||||
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"
|
||||
${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)
|
||||
"Enable unhandled asynchronous exceptions" OFF)
|
||||
|
||||
option(CTI_CONTINUABLE_WITH_COROUTINE "Enable C++20 coroutines" OFF)
|
||||
|
||||
option(CTI_CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE
|
||||
"Enable co_await support"
|
||||
OFF)
|
||||
"Enable experimental coroutines" 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()
|
||||
@ -98,18 +100,16 @@ 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,26 +124,29 @@ target_compile_features(continuable-base
|
||||
cxx_return_type_deduction)
|
||||
|
||||
if(CTI_CONTINUABLE_WITH_CPP_LATEST)
|
||||
target_compile_features(continuable-base
|
||||
INTERFACE
|
||||
cxx_std_17)
|
||||
target_compile_features(continuable-base INTERFACE cxx_std_20)
|
||||
endif()
|
||||
|
||||
if (CTI_CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE)
|
||||
target_compile_options(continuable-base
|
||||
INTERFACE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/await>
|
||||
$<$<CXX_COMPILER_ID:Clang>:-fcoroutines-ts>)
|
||||
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_definitions(continuable-base
|
||||
INTERFACE
|
||||
CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE)
|
||||
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>
|
||||
$<$<CXX_COMPILER_ID:Clang>:-fcoroutines-ts>)
|
||||
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)
|
||||
@ -154,9 +157,7 @@ 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)
|
||||
@ -164,8 +165,7 @@ 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,7 +180,8 @@ 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
|
||||
@ -189,13 +190,17 @@ 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
|
||||
install(
|
||||
TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-base
|
||||
EXPORT "${PROJECT_NAME}Targets"
|
||||
INCLUDES
|
||||
DESTINATION "include")
|
||||
install(
|
||||
EXPORT "${PROJECT_NAME}Targets"
|
||||
INCLUDES DESTINATION "include")
|
||||
install(EXPORT "${PROJECT_NAME}Targets"
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
|
||||
|
||||
|
||||
@ -47,10 +47,9 @@
|
||||
#include <continuable/detail/utility/traits.hpp>
|
||||
#include <continuable/detail/utility/util.hpp>
|
||||
|
||||
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
# include <experimental/coroutine>
|
||||
#if defined(CONTINUABLE_HAS_COROUTINE)
|
||||
# include <continuable/detail/other/coroutines.hpp>
|
||||
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
#endif // defined(CONTINUABLE_HAS_COROUTINE)
|
||||
|
||||
namespace cti {
|
||||
/// \defgroup Base Base
|
||||
@ -715,7 +714,7 @@ public:
|
||||
}
|
||||
|
||||
/// \cond false
|
||||
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
#if defined(CONTINUABLE_HAS_COROUTINE)
|
||||
/// \endcond
|
||||
/// Implements the operator for awaiting on continuables using `co_await`.
|
||||
///
|
||||
@ -781,7 +780,7 @@ public:
|
||||
return detail::awaiting::create_awaiter(std::move(*this).finish());
|
||||
}
|
||||
/// \cond false
|
||||
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
#endif // defined(CONTINUABLE_HAS_COROUTINE)
|
||||
/// \endcond
|
||||
|
||||
private:
|
||||
|
||||
@ -39,11 +39,9 @@
|
||||
# include <exception>
|
||||
#endif // CONTINUABLE_HAS_EXCEPTIONS
|
||||
|
||||
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
#if defined(CONTINUABLE_HAS_COROUTINE)
|
||||
# include <continuable/detail/other/coroutines.hpp>
|
||||
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
|
||||
#if defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
|
||||
namespace cti {
|
||||
# if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||
/// Is thrown from co_await expressions if the awaited continuable is canceled
|
||||
@ -78,7 +76,9 @@ using await_canceled_exception = detail::awaiting::await_canceled_exception;
|
||||
// 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...>>,
|
||||
@ -87,9 +87,11 @@ struct coroutine_traits<
|
||||
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
|
||||
/// \endcond
|
||||
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
#endif // defined(CONTINUABLE_HAS_COROUTINE)
|
||||
|
||||
#endif // CONTINUABLE_COROUTINE_HPP_INCLUDED
|
||||
|
||||
@ -86,24 +86,40 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// Usually this is enabled by the CMake project
|
||||
#if !defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
|
||||
// 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)
|
||||
/// Define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE when
|
||||
/// CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE is defined.
|
||||
#if defined(CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE)
|
||||
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
#elif defined(_MSC_VER)
|
||||
#if _MSC_FULL_VER >= 190023506
|
||||
#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
|
||||
#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 // _MSC_FULL_VER >= 190023506
|
||||
#elif defined(__clang__)
|
||||
#elif defined(__clang__) // Clang
|
||||
#if defined(__cpp_coroutines) && (__cpp_coroutines >= 201707)
|
||||
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
#define CONTINUABLE_HAS_COROUTINE 1
|
||||
#define CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE 1
|
||||
#endif // defined(__cpp_coroutines) && (__cpp_coroutines >= 201707)
|
||||
#endif // defined(__clang__)
|
||||
#endif // !defined(CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE)
|
||||
#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
|
||||
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include <experimental/coroutine>
|
||||
#include <continuable/continuable-primitives.hpp>
|
||||
#include <continuable/continuable-result.hpp>
|
||||
#include <continuable/detail/core/annotation.hpp>
|
||||
@ -48,11 +47,24 @@
|
||||
# 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 {
|
||||
@ -213,7 +225,7 @@ struct promise_type
|
||||
return {handle_};
|
||||
}
|
||||
|
||||
std::experimental::suspend_never final_suspend() {
|
||||
suspend_never final_suspend() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -235,5 +247,6 @@ struct promise_type
|
||||
} // namespace awaiting
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
#endif // defined(CONTINUABLE_HAS_COROUTINE)
|
||||
|
||||
#endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED
|
||||
|
||||
@ -24,7 +24,8 @@
|
||||
#include <test-continuable.hpp>
|
||||
|
||||
#include <continuable/detail/features.hpp>
|
||||
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
|
||||
#ifdef CONTINUABLE_HAS_COROUTINE
|
||||
|
||||
# ifndef CONTINUABLE_WITH_NO_EXCEPTIONS
|
||||
# include <exception>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user