mirror of
https://github.com/Naios/continuable.git
synced 2026-02-15 14:50:17 +08:00
Make continuables usable in await expressions
This commit is contained in:
parent
d8591d1f13
commit
6001e99723
@ -37,34 +37,63 @@
|
|||||||
#include <experimental/coroutine>
|
#include <experimental/coroutine>
|
||||||
|
|
||||||
#include <continuable/continuable-api.hpp>
|
#include <continuable/continuable-api.hpp>
|
||||||
|
#include <continuable/detail/expected.hpp>
|
||||||
#include <continuable/detail/features.hpp>
|
#include <continuable/detail/features.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace awaiting {
|
namespace awaiting {
|
||||||
|
/// We import the coroutine handle in our namespace
|
||||||
using std::experimental::coroutine_handle;
|
using std::experimental::coroutine_handle;
|
||||||
|
|
||||||
|
/// An object which provides the internal buffer and helper methods
|
||||||
|
/// for waiting on a continuable in a stackless coroutine.
|
||||||
|
template <typename Continuable>
|
||||||
|
struct awaitable {
|
||||||
|
Continuable continuable_;
|
||||||
|
|
||||||
|
/// A cache which is used to
|
||||||
|
// expected::expected<int> cache_;
|
||||||
|
|
||||||
|
/// Since continuables are evaluated lazily we are not
|
||||||
|
/// capable to say whether the resumption will be instantly.
|
||||||
|
bool await_ready() const noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Suspend the current context
|
||||||
|
// TODO Convert this to an r-value function once possible
|
||||||
|
void await_suspend(coroutine_handle<> h) {
|
||||||
|
// Forward every result to the current awaitable
|
||||||
|
std::move(continuable_).flow([h, this](auto&&... args) {
|
||||||
|
resolve();
|
||||||
|
h.resume();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void await_resume() {
|
||||||
|
// if ec throw
|
||||||
|
// return n;
|
||||||
|
// return
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolve the continuation through the result
|
||||||
|
template <typename... Args>
|
||||||
|
void resolve(Args&&... args) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolve the continuation through an error
|
||||||
|
void resolve(types::dispatch_error_tag, types::error_type error) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Converts a continuable into an awaitable object as described by
|
/// Converts a continuable into an awaitable object as described by
|
||||||
/// the C++ coroutine TS.
|
/// the C++ coroutine TS.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto create_awaiter(T&& continuable) {
|
auto create_awaiter(T&& continuable) {
|
||||||
struct Awaiter {
|
return awaitable<std::decay_t<T>>{std::forward<T>(continuable)};
|
||||||
bool is_ready() const noexcept {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void await_suspend(coroutine_handle<> h) && {
|
|
||||||
|
|
||||||
h.resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto await_resume() {
|
|
||||||
// if ec throw
|
|
||||||
// return n;
|
|
||||||
// return
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return Awaiter();
|
|
||||||
}
|
}
|
||||||
} // namespace awaiting
|
} // namespace awaiting
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|||||||
65
include/continuable/detail/expected.hpp
Normal file
65
include/continuable/detail/expected.hpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v2.0.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2017 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_EXPECTED_HPP_INCLUDED__
|
||||||
|
#define CONTINUABLE_DETAIL_EXPECTED_HPP_INCLUDED__
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <continuable/continuable-api.hpp>
|
||||||
|
#include <continuable/detail/types.hpp>
|
||||||
|
|
||||||
|
namespace cti {
|
||||||
|
namespace detail {
|
||||||
|
namespace expected {
|
||||||
|
/// A class similar to the one in the expected proposal,
|
||||||
|
/// however it is capable of carrying an exception_ptr if
|
||||||
|
/// exceptions are used.
|
||||||
|
template <typename T, typename Storage = std::aligned_storage_t<std::max(
|
||||||
|
sizeof(types::error_type), sizeof(T))>>
|
||||||
|
class expected {
|
||||||
|
enum class slot_t { empty, type, error };
|
||||||
|
|
||||||
|
Storage storage_;
|
||||||
|
slot_t slot_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit expected() : slot_(slot_t::empty) {
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit expected(T value) : slot_(slot_t::error) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace expected
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace cti
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_DETAIL_EXPECTED_HPP_INCLUDED__
|
||||||
@ -10,6 +10,7 @@ set(LIB_SOURCES_DETAIL
|
|||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/awaiting.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/awaiting.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/base.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/base.hpp
|
||||||
${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/hints.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/hints.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/features.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/features.hpp
|
||||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/traits.hpp
|
${CMAKE_SOURCE_DIR}/include/continuable/detail/traits.hpp
|
||||||
|
|||||||
@ -5,6 +5,7 @@ foreach(STEP RANGE 4)
|
|||||||
add_executable(${PROJECT_NAME}
|
add_executable(${PROJECT_NAME}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable.hpp
|
${CMAKE_CURRENT_LIST_DIR}/test-continuable.hpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable.cpp
|
${CMAKE_CURRENT_LIST_DIR}/test-continuable.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/test-continuable-await.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-base-chaining.cpp
|
${CMAKE_CURRENT_LIST_DIR}/test-continuable-base-chaining.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-base-destruct.cpp
|
${CMAKE_CURRENT_LIST_DIR}/test-continuable-base-destruct.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-base-errors.cpp
|
${CMAKE_CURRENT_LIST_DIR}/test-continuable-base-errors.cpp
|
||||||
|
|||||||
72
test/unit-test/test-continuable-await.cpp
Normal file
72
test/unit-test/test-continuable-await.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
Copyright(c) 2015 - 2017 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||||
|
|
||||||
|
#include "test-continuable.hpp"
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
namespace experimental {
|
||||||
|
template <class... T>
|
||||||
|
struct coroutine_traits<void, T...> {
|
||||||
|
struct promise_type {
|
||||||
|
void get_return_object() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_exception(exception_ptr const&) noexcept {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initial_suspend() noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool final_suspend() noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void return_void() noexcept {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace experimental
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
TYPED_TEST(single_dimension_tests, is_awaitable) {
|
||||||
|
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mk() {
|
||||||
|
return cti::make_continuable<void>([](auto&& promise) {
|
||||||
|
// ...
|
||||||
|
promise.set_value();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void teststhh() {
|
||||||
|
auto c = mk();
|
||||||
|
|
||||||
|
co_await std::move(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||||
Loading…
x
Reference in New Issue
Block a user