Created
August 23, 2018 02:06
-
-
Save RedBeard0531/08350c784f979d98c7d05f52e9d69835 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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