Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // http://govnokod.ru/23568
- #include <experimental/coroutine>
- #include <iostream>
- #include <optional>
- #include <utility>
- template<typename T>
- class Maybe
- {
- std::shared_ptr<std::optional<T>> m_maybe = std::make_shared<std::optional<T>>();
- public:
- Maybe() = default;
- Maybe(const T& t)
- : m_maybe { std::make_shared<std::optional<T>>(t) }
- {
- }
- explicit operator bool() const { return static_cast<bool>(*m_maybe); }
- T& operator* () { return **m_maybe; }
- const T& operator*() const { return **m_maybe; }
- void reset() { m_maybe->reset(); }
- template<typename U>
- void emplace(U&& u) { m_maybe->emplace(std::forward<U>(u)); }
- };
- template<typename T>
- void printMaybe(const Maybe<T>& opt)
- {
- if (opt)
- std::cout << *opt << std::endl;
- else
- std::cout << "<empty>" << std::endl;
- }
- template<typename T, typename... Args>
- struct std::experimental::coroutine_traits<Maybe<T>, Args...>
- {
- struct promise_type
- {
- Maybe<T> m_maybe;
- auto get_return_object() { return m_maybe; }
- std::experimental::suspend_never initial_suspend() { return {}; }
- std::experimental::suspend_never final_suspend() { return {}; }
- void unhandled_exception() { m_maybe.reset(); }
- template<typename U>
- void return_value(U&& u) { m_maybe.emplace(std::forward<U>(u)); }
- };
- };
- template<typename T>
- auto operator co_await(const Maybe<T>& maybe)
- {
- struct Awaiter
- {
- const Maybe<T>& input;
- bool await_ready() { return static_cast<bool>(input); }
- auto await_resume() { return *input; }
- void await_suspend(std::experimental::coroutine_handle<> coro) { coro.destroy(); }
- };
- return Awaiter { maybe };
- }
- Maybe<int> maybeAdd(const Maybe<int>& maybeA, const Maybe<int>& maybeB)
- {
- auto a = co_await maybeA;
- auto b = co_await maybeB;
- co_return a + b;
- }
- int main()
- {
- /*
- printMaybe(maybeAdd({ 1 }, { 2 }));
- printMaybe(maybeAdd({}, { 2 }));
- printMaybe(maybeAdd({ 1 }, {}));
- */
- const auto res = maybeAdd({ 1 }, { 2 });
- return res ? *res : 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement