mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Base implementation of an ASIO completion token integration
* Bump the asio version to 1.41 * Move headers that require an external dependency to include/continuable/support * Ref #28 * Ref #27
This commit is contained in:
parent
0b1b284e3a
commit
1a1c7b68c6
@ -1 +1 @@
|
|||||||
Subproject commit 0a52abce85ab83b920cc7257d8a2703fe69bc79c
|
Subproject commit 8087252a0c3c2f0baad96ddbd6554db17a846376
|
||||||
@ -49,7 +49,7 @@ Continuable is a header-only library with one required header-only dependency:
|
|||||||
erasure wrapper to convert a \ref continuable_base into a \ref continuable.
|
erasure wrapper to convert a \ref continuable_base into a \ref continuable.
|
||||||
|
|
||||||
Additionally GTest is required as optional dependency for the asynchronous
|
Additionally GTest is required as optional dependency for the asynchronous
|
||||||
unit testing macros defined in `continuable/continuable-testing.hpp`
|
unit testing macros defined in `continuable/support/gtest.hpp`
|
||||||
if those are used:
|
if those are used:
|
||||||
|
|
||||||
- [google/googletest](https://github.com/google/googletest) is used as
|
- [google/googletest](https://github.com/google/googletest) is used as
|
||||||
|
|||||||
@ -1,15 +1,28 @@
|
|||||||
|
add_library(asio-example-deps INTERFACE)
|
||||||
|
|
||||||
|
target_include_directories(asio-example-deps
|
||||||
|
INTERFACE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
target_link_libraries(asio-example-deps
|
||||||
|
INTERFACE
|
||||||
|
asio
|
||||||
|
continuable)
|
||||||
|
|
||||||
add_executable(example-asio
|
add_executable(example-asio
|
||||||
${CMAKE_CURRENT_LIST_DIR}/example-asio.cpp)
|
${CMAKE_CURRENT_LIST_DIR}/example-asio.cpp)
|
||||||
|
|
||||||
target_include_directories(example-asio
|
|
||||||
PRIVATE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR})
|
|
||||||
|
|
||||||
target_link_libraries(example-asio
|
target_link_libraries(example-asio
|
||||||
PRIVATE
|
PRIVATE
|
||||||
asio
|
asio-example-deps)
|
||||||
continuable)
|
|
||||||
|
|
||||||
target_compile_definitions(example-asio
|
target_compile_definitions(example-asio
|
||||||
PUBLIC
|
PUBLIC
|
||||||
-DCONTINUABLE_WITH_NO_EXCEPTIONS)
|
-DCONTINUABLE_WITH_NO_EXCEPTIONS)
|
||||||
|
|
||||||
|
add_executable(example-asio-integration
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/example-asio-integration.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(example-asio-integration
|
||||||
|
PRIVATE
|
||||||
|
asio-example-deps)
|
||||||
|
|||||||
129
examples/example-asio/example-asio-integration.cpp
Normal file
129
examples/example-asio/example-asio-integration.cpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v4.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2019 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
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <asio.hpp>
|
||||||
|
|
||||||
|
#include <continuable/continuable.hpp>
|
||||||
|
#include <continuable/support/asio.hpp>
|
||||||
|
|
||||||
|
// Queries the NIST daytime service and prints the current date and time
|
||||||
|
void daytime_service();
|
||||||
|
|
||||||
|
// Checks that a cancelled timer async_wait fails with
|
||||||
|
// `asio::error::operation_aborted`
|
||||||
|
void cancelled_async_wait();
|
||||||
|
|
||||||
|
// Indicates fatal error due to an unexpected failure in the continuation chain.
|
||||||
|
void unexpected_error(cti::exception_t);
|
||||||
|
|
||||||
|
// Check that the failure was an aborted operation, as expected.
|
||||||
|
void check_aborted_operation(cti::exception_t);
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
daytime_service();
|
||||||
|
cancelled_async_wait();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void daytime_service() {
|
||||||
|
using asio::ip::tcp;
|
||||||
|
|
||||||
|
asio::io_context ioc(1);
|
||||||
|
tcp::resolver resolver(ioc);
|
||||||
|
tcp::socket socket(ioc);
|
||||||
|
std::string buf;
|
||||||
|
|
||||||
|
resolver.async_resolve("time.nist.gov", "daytime", cti::asio_token)
|
||||||
|
.then([&socket](tcp::resolver::results_type endpoints) {
|
||||||
|
return asio::async_connect(socket, endpoints, cti::asio_token);
|
||||||
|
})
|
||||||
|
.then([&socket, &buf] {
|
||||||
|
return asio::async_read_until(socket, asio::dynamic_buffer(buf), '\n',
|
||||||
|
cti::asio_token);
|
||||||
|
})
|
||||||
|
.then([&buf](std::size_t) { puts(buf.data()); })
|
||||||
|
.fail(&unexpected_error);
|
||||||
|
|
||||||
|
ioc.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancelled_async_wait() {
|
||||||
|
asio::io_context ioc(1);
|
||||||
|
asio::steady_timer t(ioc);
|
||||||
|
|
||||||
|
t.expires_after(std::chrono::seconds(999));
|
||||||
|
|
||||||
|
t.async_wait(cti::asio_token)
|
||||||
|
.then([] {
|
||||||
|
puts("This should never be called");
|
||||||
|
std::terminate();
|
||||||
|
})
|
||||||
|
.fail(&check_aborted_operation);
|
||||||
|
|
||||||
|
t.cancel_one();
|
||||||
|
ioc.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void unexpected_error(cti::exception_t e) {
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
std::rethrow_exception(e);
|
||||||
|
#else
|
||||||
|
puts("Continuation failed with unexpected error");
|
||||||
|
puts(e.message().data());
|
||||||
|
std::terminate();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_aborted_operation(cti::exception_t ex) {
|
||||||
|
auto is_expected_error = [](auto err_val) {
|
||||||
|
if (err_val == asio::error_code(asio::error::operation_aborted)) {
|
||||||
|
puts("Continuation failed due to aborted async operation, as expected.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(ex);
|
||||||
|
} catch (asio::system_error const& err) {
|
||||||
|
if (is_expected_error(err.code())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (is_expected_error(ex)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unexpected_error(ex);
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@
|
|||||||
\_,(_)| | | || ||_|(_||_)|(/_
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
https://github.com/Naios/continuable
|
https://github.com/Naios/continuable
|
||||||
v3.0.0
|
v4.0.0
|
||||||
|
|
||||||
Copyright(c) 2015 - 2019 Denis Blank <denis.blank at outlook dot com>
|
Copyright(c) 2015 - 2019 Denis Blank <denis.blank at outlook dot com>
|
||||||
|
|
||||||
|
|||||||
154
include/continuable/detail/support/asio.hpp
Normal file
154
include/continuable/detail/support/asio.hpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v4.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2019 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
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
|
||||||
|
#define CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <continuable/detail/features.hpp>
|
||||||
|
|
||||||
|
#if defined(ASIO_STANDALONE)
|
||||||
|
#include <asio/async_result.hpp>
|
||||||
|
#include <asio/error_code.hpp>
|
||||||
|
#include <asio/version.hpp>
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
#include <asio/system_error.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (ASIO_VERSION / 100 % 1000) <= 12
|
||||||
|
#define CTI_DETAIL_ASIO_HAS_NO_INTEGRATION
|
||||||
|
#elif (ASIO_VERSION / 100 % 1000) <= 14
|
||||||
|
#define CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CTI_DETAIL_ASIO_NAMESPACE_BEGIN namespace asio {
|
||||||
|
#define CTI_DETAIL_ASIO_NAMESPACE_END }
|
||||||
|
#else
|
||||||
|
#include <boost/asio/async_result.hpp>
|
||||||
|
#include <boost/system/error_code.hpp>
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
#include <boost/system/system_error.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (BOOST_VERSION / 100 % 1000) <= 69
|
||||||
|
#define CTI_DETAIL_ASIO_HAS_NO_INTEGRATION
|
||||||
|
#elif (BOOST_VERSION / 100 % 1000) <= 71
|
||||||
|
#define CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CTI_DETAIL_ASIO_NAMESPACE_BEGIN \
|
||||||
|
namespace boost { \
|
||||||
|
namespace asio {
|
||||||
|
#define CTI_DETAIL_ASIO_NAMESPACE_END \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CTI_DETAIL_ASIO_HAS_NO_INTEGRATION)
|
||||||
|
#error "First-class ASIO support for continuable requires the form of "\
|
||||||
|
"`async_result` with an `initiate` static member function, which was added " \
|
||||||
|
"in standalone ASIO 1.13.0 and Boost ASIO 1.70. Older versions can be " \
|
||||||
|
"integrated manually with `cti::promisify`."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <continuable/detail/core/base.hpp>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
#include <exception>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
namespace detail {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
#if defined(ASIO_STANDALONE)
|
||||||
|
using error_code_t = ::asio::error_code;
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
using system_error_t = ::asio::system_error;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
using error_code_t = ::boost::system::error_code;
|
||||||
|
|
||||||
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
using system_error_t = ::boost::system::system_error;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Binds `promise` to the first argument of a continuable resolver, giving it
|
||||||
|
// the signature of an ASIO handler.
|
||||||
|
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 defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
|
promise.set_exception(
|
||||||
|
std::make_exception_ptr(system_error_t(std::move(e))));
|
||||||
|
#else
|
||||||
|
promise.set_exception(cti::exception_t(e.value(), e.category()));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
promise.set_value(std::forward<decltype(args)>(args)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper struct wrapping a call to `cti::make_continuable` and, if needed,
|
||||||
|
// providing an erased, explicit `return_type` for `async_result`.
|
||||||
|
template <typename Signature>
|
||||||
|
struct initiate_make_continuable;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
struct initiate_make_continuable<void(error_code_t, Args...)> {
|
||||||
|
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
|
||||||
|
using erased_return_type = cti::continuable<Args...>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Continuation>
|
||||||
|
auto operator()(Continuation&& continuation) {
|
||||||
|
return detail::base::attorney::create_from(
|
||||||
|
std::forward<Continuation>(continuation), detail::identity<Args...>{},
|
||||||
|
detail::util::ownership{});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
struct initiate_make_continuable<void(error_code_t const&, Args...)>
|
||||||
|
: initiate_make_continuable<void(error_code_t, Args...)> {};
|
||||||
|
|
||||||
|
} // namespace asio
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
|
||||||
83
include/continuable/support/asio.hpp
Normal file
83
include/continuable/support/asio.hpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v4.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2019 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
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef CONTINUABLE_SUPPORT_ASIO_HPP_INCLUDED
|
||||||
|
#define CONTINUABLE_SUPPORT_ASIO_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <continuable/continuable-base.hpp>
|
||||||
|
#include <continuable/detail/support/asio.hpp>
|
||||||
|
#include <continuable/detail/utility/traits.hpp>
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
|
||||||
|
// Type used as an ASIO completion token to specify an asynchronous operation
|
||||||
|
// should return a continuable.
|
||||||
|
struct asio_token_t {};
|
||||||
|
|
||||||
|
// Special value for instance of `asio_token_t`.
|
||||||
|
constexpr asio_token_t asio_token{};
|
||||||
|
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
CTI_DETAIL_ASIO_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
template <typename Signature>
|
||||||
|
class async_result<cti::asio_token_t, Signature> {
|
||||||
|
public:
|
||||||
|
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
|
||||||
|
using return_type = typename cti::detail::asio::initiate_make_continuable<
|
||||||
|
Signature>::erased_return_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Initiation, typename... Args>
|
||||||
|
static auto initiate(Initiation initiation, cti::asio_token_t, Args... args) {
|
||||||
|
return cti::detail::asio::initiate_make_continuable<Signature>{}(
|
||||||
|
[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))](
|
||||||
|
auto&&... args) mutable {
|
||||||
|
std::move(initiation)(std::move(handler),
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
},
|
||||||
|
std::move(init_args));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CTI_DETAIL_ASIO_NAMESPACE_END
|
||||||
|
|
||||||
|
#undef CTI_DETAIL_ASIO_NAMESPACE_BEGIN
|
||||||
|
#undef CTI_DETAIL_ASIO_NAMESPACE_END
|
||||||
|
#undef CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_SUPPORT_ASIO_HPP_INCLUDED
|
||||||
@ -28,8 +28,8 @@
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef CONTINUABLE_TESTING_HPP_INCLUDED
|
#ifndef CONTINUABLE_SUPPORT_GTEST_HPP_INCLUDED
|
||||||
#define CONTINUABLE_TESTING_HPP_INCLUDED
|
#define CONTINUABLE_SUPPORT_GTEST_HPP_INCLUDED
|
||||||
|
|
||||||
#include <continuable/detail/other/testing.hpp>
|
#include <continuable/detail/other/testing.hpp>
|
||||||
#include <continuable/detail/utility/traits.hpp>
|
#include <continuable/detail/utility/traits.hpp>
|
||||||
@ -169,4 +169,4 @@
|
|||||||
|
|
||||||
/// \}
|
/// \}
|
||||||
|
|
||||||
#endif // CONTINUABLE_TESTING_HPP_INCLUDED
|
#endif // CONTINUABLE_SUPPORT_GTEST_HPP_INCLUDED
|
||||||
@ -31,8 +31,8 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <continuable/continuable-base.hpp>
|
#include <continuable/continuable-base.hpp>
|
||||||
#include <continuable/continuable-testing.hpp>
|
|
||||||
#include <continuable/continuable.hpp>
|
#include <continuable/continuable.hpp>
|
||||||
|
#include <continuable/support/gtest.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using cti::detail::identity;
|
using cti::detail::identity;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user