emlabcpp
modern opinionated embedded C++ library
request_reply.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./memory_promise.h"
28 
29 #include <coroutine>
30 #include <optional>
31 
32 namespace emlabcpp::coro
33 {
34 
35 template < typename RequestType, typename ReplyType >
37 {
38 public:
39  using request_type = RequestType;
40  using reply_type = ReplyType;
41 
42  struct promise_type;
43 
44  struct awaiter
45  {
47 
48  bool await_ready()
49  {
50  return false;
51  }
52 
53  void await_suspend( std::coroutine_handle<> )
54  {
55  }
56 
57  ReplyType const& await_resume()
58  {
59  // NOLINTNEXTLINE
60  return *prom_->reply;
61  }
62  };
63 
64  struct promise_type : memory_promise< promise_type >
65  {
66  std::optional< RequestType > request;
67  std::optional< ReplyType > reply;
68 
70  {
71  return {};
72  }
73 
75  {
76  return { handle::from_promise( *this ) };
77  }
78 
79  std::suspend_never initial_suspend()
80  {
81  return {};
82  }
83 
84  std::suspend_always final_suspend() noexcept
85  {
86  return {};
87  }
88 
90  {
91  }
92 
93  void return_void()
94  {
95  }
96 
97  awaiter yield_value( RequestType out )
98  {
99  request = out;
100  return { this };
101  }
102  };
103 
104  using handle = std::coroutine_handle< promise_type >;
106 
107  request_reply() = default;
108 
109  request_reply( handle const cor )
110  : h_( cor )
111  {
112  }
113 
114  request_reply( request_reply const& ) = delete;
115  request_reply& operator=( request_reply const& ) = delete;
116 
117  request_reply( request_reply&& ) noexcept = default;
118  request_reply& operator=( request_reply&& ) noexcept = default;
119 
120  RequestType const* get_request()
121  {
122  if ( !h_ )
123  return nullptr;
124  std::optional< RequestType >& opt_val = h_.promise().request;
125  if ( !opt_val.has_value() )
126  return nullptr;
127  return &*opt_val;
128  }
129 
130  bool has_reply()
131  {
132  if ( h_ )
133  return h_.promise().reply.has_value();
134  else
135  return false;
136  }
137 
138  void store_reply( ReplyType const& inpt )
139  {
140  if ( h_ )
141  h_.promise().reply = inpt;
142  }
143 
144  [[nodiscard]] operator bool() const
145  {
146  return h_.done();
147  }
148 
149  [[nodiscard]] bool done() const
150  {
151  return h_.done();
152  }
153 
154  [[nodiscard]] bool tick()
155  {
156  if ( !h_.promise().reply )
157  return false;
158  if ( !h_ )
159  return false;
160  if ( h_.done() )
161  return false;
162  h_.promise().request.reset();
163  h_();
164  h_.promise().reply.reset();
165  return true;
166  }
167 
168  [[nodiscard]] void* address() const
169  {
170  return h_.address();
171  }
172 
173 private:
174  owning_handle h_;
175 };
176 
177 } // namespace emlabcpp::coro
constexpr bool done() const
Definition: owning_coroutine_handle.h:70
constexpr void * address() const
Definition: owning_coroutine_handle.h:75
constexpr promise_type & promise()
Definition: owning_coroutine_handle.h:80
Definition: request_reply.h:37
request_reply(request_reply &&) noexcept=default
request_reply(handle const cor)
Definition: request_reply.h:109
void * address() const
Definition: request_reply.h:168
std::coroutine_handle< promise_type > handle
Definition: request_reply.h:104
RequestType const * get_request()
Definition: request_reply.h:120
RequestType request_type
Definition: request_reply.h:39
bool has_reply()
Definition: request_reply.h:130
ReplyType reply_type
Definition: request_reply.h:40
request_reply(request_reply const &)=delete
bool done() const
Definition: request_reply.h:149
owning_coroutine_handle< promise_type > owning_handle
Definition: request_reply.h:105
bool tick()
Definition: request_reply.h:154
void store_reply(ReplyType const &inpt)
Definition: request_reply.h:138
request_reply & operator=(request_reply const &)=delete
MIT License.
Definition: data_promise.h:27
Definition: memory_promise.h:34
Definition: request_reply.h:45
promise_type * prom_
Definition: request_reply.h:46
ReplyType const & await_resume()
Definition: request_reply.h:57
void await_suspend(std::coroutine_handle<>)
Definition: request_reply.h:53
bool await_ready()
Definition: request_reply.h:48
Definition: request_reply.h:65
void unhandled_exception()
Definition: request_reply.h:89
std::suspend_always final_suspend() noexcept
Definition: request_reply.h:84
request_reply get_return_object()
Definition: request_reply.h:74
void return_void()
Definition: request_reply.h:93
std::suspend_never initial_suspend()
Definition: request_reply.h:79
static request_reply get_return_object_on_allocation_failure()
Definition: request_reply.h:69
std::optional< ReplyType > reply
Definition: request_reply.h:67
std::optional< RequestType > request
Definition: request_reply.h:66
awaiter yield_value(RequestType out)
Definition: request_reply.h:97