mirror of
https://github.com/Naios/continuable.git
synced 2025-12-08 01:36:46 +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 <continuable/continuable-api.hpp>
|
||||
#include <continuable/detail/expected.hpp>
|
||||
#include <continuable/detail/features.hpp>
|
||||
|
||||
namespace cti {
|
||||
namespace detail {
|
||||
namespace awaiting {
|
||||
/// We import the coroutine handle in our namespace
|
||||
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
|
||||
/// the C++ coroutine TS.
|
||||
template <typename T>
|
||||
auto create_awaiter(T&& continuable) {
|
||||
struct Awaiter {
|
||||
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();
|
||||
return awaitable<std::decay_t<T>>{std::forward<T>(continuable)};
|
||||
}
|
||||
} // namespace awaiting
|
||||
} // 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/base.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/features.hpp
|
||||
${CMAKE_SOURCE_DIR}/include/continuable/detail/traits.hpp
|
||||
|
||||
@ -5,6 +5,7 @@ foreach(STEP RANGE 4)
|
||||
add_executable(${PROJECT_NAME}
|
||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable.hpp
|
||||
${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-destruct.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