mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 08:46:44 +08:00
Add cti::promisify with an initial boost asio helper
This commit is contained in:
parent
9c66b53f23
commit
786792f4f0
@ -59,29 +59,12 @@ struct functional_io_service : asio::io_service {
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Protocol>
|
||||
auto async_resolve(Protocol&& protocol, std::string host,
|
||||
std::string service) {
|
||||
using asio::ip::udp;
|
||||
|
||||
return cti::make_continuable<udp::resolver::iterator>([
|
||||
this, protocol = std::forward<Protocol>(protocol), host = std::move(host),
|
||||
service = std::move(service)
|
||||
](auto&& promise) mutable {
|
||||
resolver_.async_resolve(
|
||||
host, service,
|
||||
[promise = std::forward<decltype(promise)>(promise)](
|
||||
std::error_code const& error,
|
||||
udp::resolver::iterator iterator) mutable {
|
||||
|
||||
if (error) {
|
||||
promise.set_exception(
|
||||
std::error_condition(error.value(), error.category()));
|
||||
} else {
|
||||
promise.set_value(std::move(iterator));
|
||||
}
|
||||
});
|
||||
});
|
||||
auto async_resolve(std::string host, std::string service) {
|
||||
return cti::promisify<asio::ip::udp::resolver::iterator>::from_asio(
|
||||
[&](auto&&... args) {
|
||||
resolver_.async_resolve(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
std::move(host), std::move(service));
|
||||
}
|
||||
};
|
||||
|
||||
@ -90,7 +73,7 @@ int main(int, char**) {
|
||||
|
||||
functional_io_service service;
|
||||
|
||||
service.async_resolve(udp::v4(), "127.0.0.1", "daytime")
|
||||
service.async_resolve("127.0.0.1", "daytime")
|
||||
.then([](udp::resolver::iterator iterator) {
|
||||
// ...
|
||||
return *iterator;
|
||||
|
||||
83
include/continuable/continuable-promisify.hpp
Normal file
83
include/continuable/continuable-promisify.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
/*
|
||||
|
||||
/~` _ _ _|_. _ _ |_ | _
|
||||
\_,(_)| | | || ||_|(_||_)|(/_
|
||||
|
||||
https://github.com/Naios/continuable
|
||||
v3.0.0
|
||||
|
||||
Copyright(c) 2015 - 2018 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_PROMISIFY_HPP_INCLUDED
|
||||
#define CONTINUABLE_PROMISIFY_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <continuable/detail/promisify.hpp>
|
||||
|
||||
namespace cti {
|
||||
/// Helper class for converting callback taking callable types into a
|
||||
/// a continuable. Various styles are supported.
|
||||
/// - `from_asio`: Converts callback taking callable types into continuables
|
||||
/// which pass an error code as first parameter and the rest of
|
||||
/// the result afterwards.
|
||||
///
|
||||
/// \tparam Result The result of the converted continuable, this should align
|
||||
/// with the arguments that are passed to the callback.
|
||||
template <typename... Result>
|
||||
class promisify {
|
||||
using helper = detail::convert::promisify_helper<Result...>;
|
||||
|
||||
public:
|
||||
/// Converts callback taking callable types into a continuable.
|
||||
/// This applies to calls which pass an error code as first parameter
|
||||
/// and the rest of the asynchronous result afterwards.
|
||||
///
|
||||
/// See an example of how to promisify boost asio's async_resolve below:
|
||||
/// ```cpp
|
||||
/// auto async_resolve(std::string host, std::string service) {
|
||||
/// return cti::promisify<asio::ip::udp::resolver::iterator>::from_asio(
|
||||
/// [&](auto&&... args) {
|
||||
/// resolver_.async_resolve(std::forward<decltype(args)>(args)...);
|
||||
/// },
|
||||
/// std::move(host), std::move(service));
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If the error code which is passed as first parameter is set there are
|
||||
/// two behaviours depending whether exceptions are enabled:
|
||||
/// - If exceptions are enabled the error type is passed via
|
||||
/// an exception_ptr to the failure handler.
|
||||
/// - If exceptions are disabled the error type is copnverted to an
|
||||
/// `std::error_conditon` and passed down to the error handler.
|
||||
///
|
||||
template <typename Callable, typename... Args>
|
||||
static auto from_asio(Callable&& callable, Args&&... args) {
|
||||
return helper::template from<detail::convert::promisify_asio>(
|
||||
std::forward<Callable>(callable), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
} // namespace cti
|
||||
|
||||
#endif // CONTINUABLE_PROMISIFY_HPP_INCLUDED
|
||||
@ -48,6 +48,7 @@ namespace cti {}
|
||||
#include <continuable/continuable-base.hpp>
|
||||
#include <continuable/continuable-compositions.hpp>
|
||||
#include <continuable/continuable-promise-base.hpp>
|
||||
#include <continuable/continuable-promisify.hpp>
|
||||
#include <continuable/continuable-trait.hpp>
|
||||
#include <continuable/continuable-transforms.hpp>
|
||||
#include <continuable/continuable-traverse-async.hpp>
|
||||
|
||||
95
include/continuable/detail/promisify.hpp
Normal file
95
include/continuable/detail/promisify.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
/*
|
||||
|
||||
/~` _ _ _|_. _ _ |_ | _
|
||||
\_,(_)| | | || ||_|(_||_)|(/_
|
||||
|
||||
https://github.com/Naios/continuable
|
||||
v3.0.0
|
||||
|
||||
Copyright(c) 2015 - 2018 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_PROMISIFY_HPP_INCLUDED
|
||||
#define CONTINUABLE_DETAIL_PROMISIFY_HPP_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||
#include <exception>
|
||||
#endif // CONTINUABLE_HAS_EXCEPTIONS
|
||||
|
||||
#include <continuable/continuable-base.hpp>
|
||||
#include <continuable/detail/traits.hpp>
|
||||
#include <continuable/detail/util.hpp>
|
||||
|
||||
namespace cti {
|
||||
namespace detail {
|
||||
namespace convert {
|
||||
/// A helper class for promisifying asio style callback taking functions
|
||||
/// into a continuable.
|
||||
template <typename P>
|
||||
struct promisify_asio {
|
||||
P promise;
|
||||
|
||||
template <typename E, typename... T>
|
||||
void operator()(E&& error, T&&... result) {
|
||||
if (error) {
|
||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||
promise.set_exception(std::make_exception_ptr(std::forward<E>(error)));
|
||||
#else
|
||||
promise.set_exception(
|
||||
std::error_condition(error.value(), error.category()));
|
||||
#endif // CONTINUABLE_HAS_EXCEPTIONS
|
||||
|
||||
} else {
|
||||
promise.set_value(std::forward<T>(result)...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Result>
|
||||
struct promisify_helper {
|
||||
template <template <class T> class Evaluator, typename Callable,
|
||||
typename... Args>
|
||||
static auto from(Callable&& callable, Args&&... args) {
|
||||
return make_continuable<Result...>([args = std::make_tuple(
|
||||
std::forward<Callable>(callable),
|
||||
std::forward<Args>(args)...)](
|
||||
auto&& promise) mutable {
|
||||
|
||||
traits::unpack(
|
||||
std::move(args), [promise = std::forward<decltype(promise)>(promise)](
|
||||
auto&&... args) mutable {
|
||||
Evaluator<std::decay_t<decltype(promise)>> evaluator{
|
||||
std::move(promise)};
|
||||
|
||||
util::invoke(std::forward<decltype(args)>(args)...,
|
||||
std::move(evaluator));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
} // namespace convert
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
|
||||
#endif // CONTINUABLE_DETAIL_PROMISIFY_HPP_INCLUDED
|
||||
@ -5,6 +5,7 @@ set(LIB_SOURCES
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-compositions.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-trait.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-promise-base.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-promisify.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-transforms.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-traverse.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-traverse-async.hpp
|
||||
@ -15,6 +16,7 @@ set(LIB_SOURCES_DETAIL
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/composition.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/expected.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/hints.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/promisify.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/container-category.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse-async.hpp
|
||||
|
||||
@ -253,34 +253,7 @@ struct future_result {
|
||||
} // namespace detail
|
||||
} // namespace cti
|
||||
|
||||
using namespace cti::detail;
|
||||
using namespace remapping;
|
||||
|
||||
template <typename... Result>
|
||||
struct promisify {
|
||||
template <typename Callable, typename... Args>
|
||||
static auto from(Callable&& callable, Args&&... args) {
|
||||
return cti::make_continuable<Result...>([args = std::make_tuple(
|
||||
std::forward<Callable>(
|
||||
callable),
|
||||
std::forward<Args>(args)...)](
|
||||
auto&& promise) mutable {
|
||||
|
||||
traits::unpack(std::move(args), [promise =
|
||||
std::forward<decltype(promise)>(
|
||||
promise)](
|
||||
auto&&... args) mutable {
|
||||
util::invoke(
|
||||
std::forward<decltype(args)>(args)..., [promise =
|
||||
std::move(promise)](
|
||||
auto&&... /*result*/){
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
using namespace cti::detail::remapping;
|
||||
|
||||
int main(int, char**) {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user