Skip to content

Instantly share code, notes, and snippets.

@RedBeard0531
Created August 23, 2018 02:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RedBeard0531/08350c784f979d98c7d05f52e9d69835 to your computer and use it in GitHub Desktop.
Save RedBeard0531/08350c784f979d98c7d05f52e9d69835 to your computer and use it in GitHub Desktop.
#include <utility>
#include <exception>
// This is probably customizable
using Error = std::exception_ptr;
template <typename R, typename T>
concept ValueReciever = requires (T a, R r) {
std::move(r).value(std::move(a));
};
template <typename R, typename T>
concept Reciever = ValueReciever<R,T> && requires (R r) {
std::move(r).error(Error());
};
template <typename R, typename T>
concept DoneReciever = Reciever<R,T> && requires (R r) {
std::move(r).done();
};
struct value_reciever {
void value(int);
};
static_assert(ValueReciever<value_reciever, int>);
static_assert(!Reciever<value_reciever, int>);
static_assert(!DoneReciever<value_reciever, int>);
struct reciever {
void value(int);
void error(Error);
};
static_assert(ValueReciever<reciever, int>);
static_assert(Reciever<reciever, int>);
static_assert(!DoneReciever<reciever, int>);
struct done_reciever {
void value(int);
void error(Error);
void done();
};
static_assert(ValueReciever<done_reciever, int>);
static_assert(Reciever<done_reciever, int>);
static_assert(DoneReciever<done_reciever, int>);
template <typename T, typename S, typename R = done_reciever>
concept DoneSender = DoneReciever<R, T> && requires (S s, R r) {
std::move(s).submit(std::move(r));
};
// Subsumes DoneSender<T,S,R> if DoneReciever<R, T>
template <typename T, typename S, typename R = reciever>
concept Sender = Reciever<R, T> && requires (S s, R r) {
std::move(s).submit(std::move(r));
};
// Subsumes Sender<T,S,R> if Reciever<R, T>
template <typename T, typename S, typename R = value_reciever>
concept ValueSender = ValueReciever<R, T> && requires (S s, R r) {
std::move(s).submit(std::move(r));
};
struct value_sender {
template <ValueReciever<int> R>
void submit(R&&);
};
static_assert(ValueSender<int, value_sender>);
static_assert(Sender<int, value_sender>);
static_assert(DoneSender<int, value_sender>);
struct sender {
template <Reciever<int> R>
void submit(R&&);
};
static_assert(!ValueSender<int, sender>);
static_assert(Sender<int, sender>);
static_assert(DoneSender<int, sender>);
struct done_sender {
template <DoneReciever<int> R>
void submit(R&&);
};
static_assert(!ValueSender<int, done_sender>);
static_assert(!Sender<int, done_sender>);
static_assert(DoneSender<int, done_sender>);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment