Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added noop utility #178

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/boost/cobalt/detail/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <boost/cobalt/detail/this_thread.hpp>
#include <boost/cobalt/unique_handle.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/noop.hpp>

#include <boost/asio/bind_allocator.hpp>
#include <boost/core/exchange.hpp>
Expand Down Expand Up @@ -92,6 +93,8 @@ struct generator_receiver : generator_receiver_base<Yield, Push>

bool ready() { return exception || result || done; }

generator_receiver(noop<Yield> n) : result(std::move(n.value)), done(true) {}

generator_receiver() = default;
generator_receiver(generator_receiver && lhs)
: generator_receiver_base<Yield, Push>{std::move(lhs.pushed_value)},
Expand Down
7 changes: 7 additions & 0 deletions include/boost/cobalt/detail/promise.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/detail/this_thread.hpp>
#include <boost/cobalt/noop.hpp>
#include <boost/cobalt/unique_handle.hpp>

#include <boost/asio/cancellation_signal.hpp>
Expand Down Expand Up @@ -65,6 +66,8 @@ struct promise_value_holder
result.emplace(ret);
static_cast<promise_receiver<T>*>(this)->set_done();
}
constexpr promise_value_holder() = default;
constexpr promise_value_holder(noop<T> value) noexcept(std::is_nothrow_move_constructible_v<T>) : result(std::move(value.value)) {}

};

Expand All @@ -79,6 +82,9 @@ struct promise_value_holder<void>
}

inline void return_void();

constexpr promise_value_holder() = default;
constexpr promise_value_holder(noop<void>) {}
};


Expand Down Expand Up @@ -113,6 +119,7 @@ struct promise_receiver : promise_value_holder<T>
}

promise_receiver() = default;
promise_receiver(noop<T> value) : promise_value_holder<T>(std::move(value)), done(true) {}
promise_receiver(promise_receiver && lhs) noexcept
: promise_value_holder<T>(std::move(lhs)),
exception(std::move(lhs.exception)), done(lhs.done), awaited_from(std::move(lhs.awaited_from)),
Expand Down
8 changes: 8 additions & 0 deletions include/boost/cobalt/detail/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <boost/cobalt/detail/forward_cancellation.hpp>
#include <boost/cobalt/detail/wrapper.hpp>
#include <boost/cobalt/detail/this_thread.hpp>
#include <boost/cobalt/noop.hpp>

#include <boost/asio/bind_allocator.hpp>
#include <boost/asio/cancellation_signal.hpp>
Expand Down Expand Up @@ -59,6 +60,9 @@ struct task_value_holder
result.emplace(ret);
static_cast<task_receiver<T>*>(this)->set_done();
}

constexpr task_value_holder() noexcept = default;
constexpr task_value_holder(noop<T> n) noexcept(std::is_nothrow_move_constructible_v<T>) : result(std::move(n.value)) {}
};

template<>
Expand All @@ -72,6 +76,9 @@ struct task_value_holder<void>
}

inline void return_void();

constexpr task_value_holder() noexcept = default;
constexpr task_value_holder(noop<void> n) noexcept {}
};


Expand Down Expand Up @@ -114,6 +121,7 @@ struct task_receiver : task_value_holder<T>
promise->signal.emit(ct);
}

task_receiver(noop<T> n) : task_value_holder<T>(std::move(n)), done(true) {}
task_receiver() = default;
task_receiver(task_receiver && lhs)
: task_value_holder<T>(std::move(lhs)),
Expand Down
1 change: 1 addition & 0 deletions include/boost/cobalt/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct [[nodiscard]] generator
generator(const generator &) = delete;
generator& operator=(const generator &) = delete;

constexpr generator(noop<Yield> n) : receiver_(std::move(n)){}

private:
template<typename, typename>
Expand Down
55 changes: 55 additions & 0 deletions include/boost/cobalt/noop.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright (c) 2024 Klemens Morgenstern ([email protected])
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_COBALT_NOOP_HPP
#define BOOST_COBALT_NOOP_HPP

#include <type_traits>
#include <utility>

namespace boost::cobalt
{


// tag::outline[]
// This is a tag type allowing the creation of promises or generators without creating a coroutine.
template<typename T = void>
struct noop
{
template<typename ... Args>
constexpr noop(Args && ... args) noexcept(std::is_nothrow_constructible_v<T, Args&&...>)
: value(std::forward<Args>(args)...)
{
}
// end::outline[]
T value;

constexpr static bool await_ready() {return true;}
template<typename P>
constexpr static void await_suspend(std::coroutine_handle<P>) {}
constexpr T await_resume() {return std::move(value);}

// tag::outline[]
};
// end::outline[]

template<> struct noop<void>
{
constexpr static bool await_ready() {return true;}
template<typename P>
constexpr static void await_suspend(std::coroutine_handle<P>) {}
constexpr static void await_resume() {}
};


template<typename T> noop( T &&) -> noop<T>;
template<typename T> noop(const T & ) -> noop<T>;
noop() -> noop<void>;

}

#endif //BOOST_COBALT_NOOP_HPP
6 changes: 6 additions & 0 deletions include/boost/cobalt/promise.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ struct [[nodiscard]] promise
// end::outline[]

/* tag::outline[]
// Create an already completed promimse

static promise

// Get the return value. If !ready() this function has undefined behaviour.
Return get();
end::outline[] */
Expand All @@ -60,6 +64,8 @@ struct [[nodiscard]] promise
if (attached_)
cancel();
}

constexpr promise(noop<Return> n) : receiver_(std::move(n)), attached_(false) {}
private:
template<typename>
friend struct detail::cobalt_promise;
Expand Down
2 changes: 2 additions & 0 deletions include/boost/cobalt/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ struct [[nodiscard]] task

using promise_type = detail::task_promise<Return>;

constexpr task(noop<Return> n) : receiver_(std::move(n)){}

private:
template<typename>
friend struct detail::task_promise;
Expand Down
3 changes: 3 additions & 0 deletions test/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,14 @@ cobalt::generator<int, int> detached_push()
co_return i;
}

cobalt::generator<int> np() {return cobalt::noop(42);}

CO_TEST_CASE(detached_push_)
{
auto g = detached_push();

co_await g(1);
co_await np();
}

BOOST_AUTO_TEST_SUITE_END();
2 changes: 1 addition & 1 deletion test/promise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(unwind)

cobalt::promise<int> return_(std::size_t ms)
{
co_return 1234u;
return cobalt::noop(1234);
}

cobalt::promise<int> return_(std::size_t ms, asio::executor_arg_t,
Expand Down
3 changes: 2 additions & 1 deletion test/task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ namespace

cobalt::task<void> test0()
{
co_return;
return cobalt::noop<void>();
}

cobalt::task<double> test2(int i)
{
co_await cobalt::noop();
co_await test0();
co_return i;
}
Expand Down
Loading