Mercury Currency Engine
chan.hpp
Go to the documentation of this file.
1 //SPDX-License-Identifier: Apache-2.0
2 //Author: Blayne Dennis
7 #ifndef __MERCURY_COROUTINE_ENGINE_CHAN__
8 #define __MERCURY_COROUTINE_ENGINE_CHAN__
9 
10 // c++
11 #include <type_traits>
12 #include <typeinfo>
13 #include <memory>
14 
15 // local
16 #include "base_channel.hpp"
17 #include "unbuffered_channel.hpp"
18 
19 // test, only uncomment for development of this library
20 //#include "dev_print.hpp"
21 
22 //-----------------------------------------------------------------------------
23 namespace mce {
24 
25 //-----------------------------------------------------------------------------
30 template <typename T>
31 struct chan : public base_channel<T>,
32  public channel_operators<T,chan<T>>
33 {
34  inline chan() :
35  base_channel<T>(this),
37  { }
38 
39  inline chan(const chan<T>& rhs) :
40  base_channel<T>(this),
42  ctx(rhs.ctx)
43  { }
44 
45  inline chan(chan<T>&& rhs) :
46  base_channel<T>(this),
48  ctx(std::move(rhs.ctx))
49  { }
50 
51  // operations
54  template <typename CHANNEL>
55  inline void construct(CHANNEL&& ch) const
56  {
57  ctx = std::unique_ptr<base_channel<T>>(
58  allocate_context(std::forward<CHANNEL>(ch)));
59  }
60 
62  inline void construct() const
63  {
65  ch.construct();
66  construct(std::move(ch));
67  }
68 
70  inline void* context() const { return ctx ? ctx->context() : NULL; }
71 
73  inline const std::type_info& type_info() const { return typeid(*this); }
74 
80  inline const std::type_info& context_type_info() const
81  {
82  return ctx->type_info();
83  }
84 
92  template <typename CHANNEL>
93  inline CHANNEL cast() const
94  {
95  if(context() && ctx->type_info() == typeid(CHANNEL))
96  {
97  return *(dynamic_cast<CHANNEL*>(ctx.get()));
98  }
99  else
100  {
101  return CHANNEL();
102  }
103  }
104 
106  inline void close() const { ctx->close(); }
107 
109  inline bool closed() const { return ctx->closed(); }
110 
112  inline bool send(const T& s) const { return ctx->send(s); }
113 
115  inline bool send(T&& s) const { return ctx->send(std::move(s)); }
116 
118  inline bool recv(T& r) const { return ctx->recv(r); }
119 
121  inline result try_send(const T& s) const { return ctx->try_send(s); }
122 
124  inline result try_send(T&& s) const { return ctx->try_send(std::move(s)); }
125 
127  inline result try_recv(T& s) const { return ctx->try_recv(s); }
128 
130  inline void assign(const chan<T>& rhs) const { this->ctx = rhs.ctx; }
131 
133  inline void assign(chan<T>&& rhs) const { this->ctx = std::move(rhs.ctx); }
134 
135  // operators
137  inline const chan<T>& operator=(const chan<T>& rhs) const
138  {
139  assign(rhs);
140  return *this;
141  }
142 
144  inline const chan<T>& operator=(chan<T>&& rhs) const
145  {
146  assign(std::move(rhs));
147  return *this;
148  }
149 
150 private:
151  mutable std::shared_ptr<base_channel<T>> ctx;
152 
153  template <typename CHANNEL>
154  base_channel<T>* allocate_context(CHANNEL&& ch) const
155  {
156  typedef typename std::decay<CHANNEL>::type DECAY_CH;
157  return dynamic_cast<base_channel<T>*>(
158  new DECAY_CH(std::forward<CHANNEL>(ch))
159  );
160  }
161 };
162 
163 }
164 
165 #endif
result
enum for channel operation results
Definition: base_channel.hpp:23
Definition: base_channel.hpp:49
Definition: chan.hpp:33
result try_send(const T &s) const
attempt to send a copy of data through channel
Definition: chan.hpp:121
void assign(const chan< T > &rhs) const
copy internal context of argument channel
Definition: chan.hpp:130
result try_recv(T &s) const
attempt to retrieve data from channel
Definition: chan.hpp:127
void * context() const
retrieve internal context pointer
Definition: chan.hpp:70
bool send(const T &s) const
send a copy of data through channel
Definition: chan.hpp:112
const chan< T > & operator=(chan< T > &&rhs) const
rvalue assign channel context
Definition: chan.hpp:144
void construct(CHANNEL &&ch) const
Definition: chan.hpp:55
bool recv(T &r) const
retrieve data from channel
Definition: chan.hpp:118
void construct() const
construct unbuffered channel context
Definition: chan.hpp:62
const chan< T > & operator=(const chan< T > &rhs) const
lvalue assign channel context
Definition: chan.hpp:137
bool closed() const
report if channel is closed
Definition: chan.hpp:109
void close() const
close channel
Definition: chan.hpp:106
void assign(chan< T > &&rhs) const
move internal context of argument channel
Definition: chan.hpp:133
result try_send(T &&s) const
attempt to move data through channel
Definition: chan.hpp:124
const std::type_info & type_info() const
retrieve type_info
Definition: chan.hpp:73
CHANNEL cast() const
Definition: chan.hpp:93
bool send(T &&s) const
move data through channel
Definition: chan.hpp:115
const std::type_info & context_type_info() const
Definition: chan.hpp:80
Definition: base_channel.hpp:229
Definition: unbuffered_channel.hpp:39
void construct() const
construct channel context
Definition: unbuffered_channel.hpp:59