mirror of
https://github.com/Naios/continuable.git
synced 2025-12-07 01:06: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(std::string host, std::string service) {
|
||||||
auto async_resolve(Protocol&& protocol, std::string host,
|
return cti::promisify<asio::ip::udp::resolver::iterator>::from_asio(
|
||||||
std::string service) {
|
[&](auto&&... args) {
|
||||||
using asio::ip::udp;
|
resolver_.async_resolve(std::forward<decltype(args)>(args)...);
|
||||||
|
},
|
||||||
return cti::make_continuable<udp::resolver::iterator>([
|
std::move(host), std::move(service));
|
||||||
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));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,7 +73,7 @@ int main(int, char**) {
|
|||||||
|
|
||||||
functional_io_service service;
|
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) {
|
.then([](udp::resolver::iterator iterator) {
|
||||||
// ...
|
// ...
|
||||||
return *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-base.hpp>
|
||||||
#include <continuable/continuable-compositions.hpp>
|
#include <continuable/continuable-compositions.hpp>
|
||||||
#include <continuable/continuable-promise-base.hpp>
|
#include <continuable/continuable-promise-base.hpp>
|
||||||
|
#include <continuable/continuable-promisify.hpp>
|
||||||
#include <continuable/continuable-trait.hpp>
|
#include <continuable/continuable-trait.hpp>
|
||||||
#include <continuable/continuable-transforms.hpp>
|
#include <continuable/continuable-transforms.hpp>
|
||||||
#include <continuable/continuable-traverse-async.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-compositions.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-trait.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/continuable-trait.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-promise-base.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-transforms.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-traverse.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/continuable-traverse.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/continuable-traverse-async.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/composition.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/expected.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/expected.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/hints.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/container-category.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse-async.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/traverse-async.hpp
|
||||||
|
|||||||
@ -253,34 +253,7 @@ struct future_result {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|
||||||
using namespace cti::detail;
|
using namespace cti::detail::remapping;
|
||||||
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*/){
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user