Created
April 3, 2020 22:58
-
-
Save qookei/79db4dc57aa823159c37ea0c3d01d9f7 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <iostream> | |
#include <tuple> | |
#include <array> | |
struct RecvBuffer{}; | |
struct SendBuffer{}; | |
struct ImbueCredentials{}; | |
struct ExtractCredentials{}; | |
struct RecvInline{}; | |
struct Offer{}; | |
struct Accept{}; | |
struct PushDescriptor{}; | |
struct PullDescriptor{}; | |
struct Result { virtual ~Result() {} virtual void parse(void *&element) = 0; }; | |
struct RecvBufferResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 1; } private: int _error; }; | |
struct SendBufferResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 2; } private: int _error; }; | |
struct ImbueCredentialsResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 3; } private: int _error; }; | |
struct ExtractCredentialsResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 4; } private: int _error; }; | |
struct RecvInlineResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 5; } private: int _error; }; | |
struct OfferResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 6; } private: int _error; }; | |
struct AcceptResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 7; } private: int _error; }; | |
struct PushDescriptorResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 8; } private: int _error; }; | |
struct PullDescriptorResult : public Result { int error() { return _error; } void parse(void *&element) override { _error = 9; } private: int _error; }; | |
struct HelAction { int i; }; | |
HelAction createActionFrom(const RecvBuffer &) { return HelAction{1}; } | |
HelAction createActionFrom(const SendBuffer &) { return HelAction{2}; } | |
HelAction createActionFrom(const ImbueCredentials &) { return HelAction{3}; } | |
HelAction createActionFrom(const ExtractCredentials &) { return HelAction{4}; } | |
HelAction createActionFrom(const RecvInline &) { return HelAction{5}; } | |
HelAction createActionFrom(const Offer &) { return HelAction{6}; } | |
HelAction createActionFrom(const Accept &) { return HelAction{7}; } | |
HelAction createActionFrom(const PushDescriptor &) { return HelAction{8}; } | |
HelAction createActionFrom(const PullDescriptor &) { return HelAction{9}; } | |
struct TransmissionError { int i; }; | |
template <typename T> | |
struct ResultTypeTransformation { using type = void; }; | |
#define AddTypeResultTransform(t)\ | |
template <> \ | |
struct ResultTypeTransformation<t> { using type = t##Result; } | |
AddTypeResultTransform(RecvBuffer); | |
AddTypeResultTransform(SendBuffer); | |
AddTypeResultTransform(ImbueCredentials); | |
AddTypeResultTransform(ExtractCredentials); | |
AddTypeResultTransform(RecvInline); | |
AddTypeResultTransform(Offer); | |
AddTypeResultTransform(Accept); | |
AddTypeResultTransform(PushDescriptor); | |
AddTypeResultTransform(PullDescriptor); | |
template <typename T> | |
using ResultTypeFor = typename ResultTypeTransformation<T>::type; | |
template <typename ...Args> | |
struct Transmission { | |
Transmission(std::tuple<Args...> actions) | |
:_results{ResultTypeFor<Args>{}...} { | |
[&]<std::size_t ...p>(std::index_sequence<p...>) { | |
((_actions[p] = createActionFrom(std::get<p>(actions))), ...); | |
} (std::make_index_sequence<sizeof...(Args)>{}); | |
// submit _actions | |
// ... | |
complete(nullptr); | |
} | |
// replace with co_await stuff to return the values | |
auto operator *() { | |
return std::tuple_cat(std::make_tuple(TransmissionError{0}), _results); | |
} | |
private: | |
void complete(void *ptr) { | |
[&]<size_t ...p>(std::index_sequence<p...>) { | |
(std::get<p>(_results).parse(ptr), ...); | |
} (std::make_index_sequence<sizeof...(Args)>{}); | |
} | |
std::array<HelAction, sizeof...(Args)> _actions; | |
std::tuple<ResultTypeFor<Args>...> _results; | |
}; | |
template <typename ...Args> | |
auto asyncSubmit(Args &&...args) { | |
return Transmission{std::make_tuple(args...)}; | |
} | |
void test1() { | |
auto [error, offer, send_buffer, recv_buffer, cred] = *asyncSubmit(Offer{}, SendBuffer{}, RecvBuffer{}, ImbueCredentials{}); | |
std::cout << offer.error() << " " << send_buffer.error() << " " << recv_buffer.error() << " " << cred.error() << "\n"; | |
} | |
void test2() { | |
auto [error, accept, recv_buffer, send_buffer, cred] = *asyncSubmit(Accept{}, RecvBuffer{}, SendBuffer{}, ExtractCredentials{}); | |
std::cout << accept.error() << " " << recv_buffer.error() << " " << send_buffer.error() << " " << cred.error() << "\n"; | |
} | |
void test3() { | |
auto [error, offer, send_req, recv_resp] = *asyncSubmit(Offer{}, SendBuffer{}, RecvBuffer{}); | |
std::cout << offer.error() << " " << send_req.error() << " " << recv_resp.error() << "\n"; | |
} | |
int main() { | |
test1(); | |
test2(); | |
test3(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment