SyDEVS  v0.6.5
Multiscale Simulation and Systems Modeling Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
port.h
Go to the documentation of this file.
1 #pragma once
2 #ifndef SYDEVS_SYSTEMS_PORT_H_
3 #define SYDEVS_SYSTEMS_PORT_H_
4 
6 
7 namespace sydevs {
8 namespace systems {
9 
10 
17 template<data_mode dmode, data_goal dgoal, typename T>
18 class port_base
19 {
20 public:
21  port_base(const port_base&) = delete;
22  port_base& operator=(const port_base&) = delete;
23  port_base(port_base&&) = default;
24  port_base& operator=(port_base&&) = default;
25  virtual ~port_base() = default;
26 
27  const std::string& port_name() const;
28 
29  int64 port_index() const;
30  int64 node_index() const;
31 
32  const node_interface& external_interface() const;
33 
34 protected:
35  port_base(const std::string& port_name, int64 port_index, node_interface& external_interface);
36 
37 private:
38  const std::string port_name_;
39  const int64 port_index_;
40  node_interface& external_interface_;
41 };
42 
43 
52 template<data_mode dmode, data_goal dgoal, typename T>
53 class port : public port_base<dmode, dgoal, T>
54 {
55 };
56 
57 
67 template<typename T>
68 class port<flow, input, T> : public port_base<flow, input, T>
69 {
70 public:
84  port(const std::string& port_name, const node_interface& external_interface);
85 
86  port(port&&) = default;
87  port& operator=(port&&) = default;
88  ~port() = default;
89 
90  const T& value() const;
91 
92  void print_on_use(bool flag = true) const;
93 };
94 
95 
105 template<typename T>
106 class port<message, input, T> : public port_base<message, input, T>
107 {
108 public:
122  port(const std::string& port_name, const node_interface& external_interface);
123 
124  port(port&&) = default;
125  port& operator=(port&&) = default;
126  ~port() = default;
127 
128  bool received() const;
129  const T& value() const;
130 
131  void print_on_use(bool flag = true) const;
132 };
133 
134 
144 template<typename T>
145 class port<message, output, T> : public port_base<message, output, T>
146 {
147 public:
161  port(const std::string& port_name, const node_interface& external_interface);
162 
163  port(port&&) = default;
164  port& operator=(port&&) = default;
165  ~port() = default;
166 
167  void send(const T& val);
168 
169  void print_on_use(bool flag = true) const;
170 };
171 
172 
182 template<typename T>
183 class port<flow, output, T> : public port_base<flow, output, T>
184 {
185 public:
199  port(const std::string& port_name, const node_interface& external_interface);
200 
201  port(port&&) = default;
202  port& operator=(port&&) = default;
203  ~port() = default;
204 
205  void assign(const T& val);
206 
207  void print_on_use(bool flag = true) const;
208 };
209 
210 
211 template<data_mode dmode, data_goal dgoal, typename T>
212 const std::string& port_base<dmode, dgoal, T>::port_name() const
213 {
214  return port_name_;
215 }
216 
217 
218 template<data_mode dmode, data_goal dgoal, typename T>
220 {
221  return port_index_;
222 }
223 
224 
225 template<data_mode dmode, data_goal dgoal, typename T>
227 {
228  return external_interface_.node_index();
229 }
230 
231 
232 template<data_mode dmode, data_goal dgoal, typename T>
234 {
235  return external_interface_;
236 }
237 
238 
239 template<data_mode dmode, data_goal dgoal, typename T>
240 port_base<dmode, dgoal, T>::port_base(const std::string& port_name, int64 port_index, node_interface& external_interface)
241  : port_name_(port_name)
242  , port_index_(port_index)
243  , external_interface_(external_interface)
244 {
246  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
247  throw std::logic_error("Invalid data type for port (" + this->port_name() + ") " +
248  "of node (" + full_node_name + ")");
249  }
250 }
251 
252 
253 template<typename T>
254 port<flow, input, T>::port(const std::string& port_name, const node_interface& external_interface)
255  : port_base<flow, input, T>(
256  port_name,
257  const_cast<node_interface&>(external_interface).add_flow_input_port(port_name),
258  const_cast<node_interface&>(external_interface))
259 {
260 }
261 
262 
263 template<typename T>
265 {
266  if (!this->external_interface().active()) {
267  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
268  throw std::logic_error("Attempt to get value on flow input port (" + this->port_name() + ") " +
269  "of inactive node (" + full_node_name + ")");
270  }
271  const auto& val = const_cast<node_interface&>(this->external_interface()).flow_input_port_value(this->port_index());
272  return const_cast<const T&>(val.template dereference<T>());
273 }
274 
275 
276 template<typename T>
278 {
279  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
280  const_cast<node_interface&>(this->external_interface()).set_flow_input_printable(this->port_index(), tostring_func);
281 }
282 
283 
284 template<typename T>
285 port<message, input, T>::port(const std::string& port_name, const node_interface& external_interface)
286  : port_base<message, input, T>(
287  port_name,
288  const_cast<node_interface&>(external_interface).add_message_input_port(port_name),
289  const_cast<node_interface&>(external_interface))
290 {
291 }
292 
293 
294 template<typename T>
296 {
297  if (!this->external_interface().active()) {
298  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
299  throw std::logic_error("Attempt to check message input port (" + this->port_name() + ") " +
300  "of inactive node (" + full_node_name + ")");
301  }
302  if (this->external_interface().dmode() != message || this->external_interface().dgoal() != input) {
303  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
304  throw std::logic_error("Attempt to check message input port (" + this->port_name() + ") " +
305  "of node (" + full_node_name + ") outside of unplanned event");
306  }
307  return const_cast<node_interface&>(this->external_interface()).message_input_port_index() == this->port_index();
308 }
309 
310 
311 template<typename T>
313 {
314  if (!this->external_interface().active()) {
315  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
316  throw std::logic_error("Attempt to get value on message input port (" + this->port_name() + ") " +
317  "of inactive node (" + full_node_name + ")");
318  }
319  if (this->external_interface().dmode() != message || this->external_interface().dgoal() != input) {
320  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
321  throw std::logic_error("Attempt to get value on message input port (" + this->port_name() + ") " +
322  "of node (" + full_node_name + ") outside of unplanned event");
323  }
324  const auto& val = const_cast<node_interface&>(this->external_interface()).message_input_port_value(this->port_index());
325  return const_cast<const T&>(val.template dereference<T>());
326 }
327 
328 
329 template<typename T>
331 {
332  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
333  const_cast<node_interface&>(this->external_interface()).set_message_input_printable(this->port_index(), tostring_func);
334 }
335 
336 
337 template<typename T>
338 port<message, output, T>::port(const std::string& port_name, const node_interface& external_interface)
339  : port_base<message, output, T>(
340  port_name,
341  const_cast<node_interface&>(external_interface).add_message_output_port(port_name),
342  const_cast<node_interface&>(external_interface))
343 {
344 }
345 
346 
347 template<typename T>
349 {
350  if (!this->external_interface().active()) {
351  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
352  throw std::logic_error("Attempt to send value on message output port (" + this->port_name() + ") " +
353  "of inactive node (" + full_node_name + ")");
354  }
355  if (this->external_interface().dmode() != message || this->external_interface().dgoal() != output) {
356  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
357  throw std::logic_error("Attempt to send value on message output port (" + this->port_name() + ") " +
358  "of node (" + full_node_name + ") outside of planned event");
359  }
360  const_cast<node_interface&>(this->external_interface()).append_message_output(this->port_index(), qualified_type<T>::copy(val));
361 }
362 
363 
364 template<typename T>
366 {
367  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
368  const_cast<node_interface&>(this->external_interface()).set_message_output_printable(this->port_index(), tostring_func);
369 }
370 
371 
372 template<typename T>
373 port<flow, output, T>::port(const std::string& port_name, const node_interface& external_interface)
374  : port_base<flow, output, T>(
375  port_name,
376  const_cast<node_interface&>(external_interface).add_flow_output_port(port_name),
377  const_cast<node_interface&>(external_interface))
378 {
379 }
380 
381 
382 template<typename T>
384 {
385  if (!this->external_interface().active()) {
386  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
387  throw std::logic_error("Attempt to assign value on flow output port (" + this->port_name() + ") " +
388  "of inactive node (" + full_node_name + ")");
389  }
390  if (this->external_interface().dmode() != flow) {
391  const auto& full_node_name = const_cast<node_interface&>(this->external_interface()).full_name();
392  throw std::logic_error("Attempt to assign value on flow output port (" + this->port_name() + ") " +
393  "of node (" + full_node_name + ") outside of initialization or finalization event");
394  }
395  const_cast<node_interface&>(this->external_interface()).assign_flow_output(this->port_index(), qualified_type<T>::copy(val));
396 }
397 
398 
399 template<typename T>
401 {
402  auto tostring_func = flag ? tostring_converter<T>() : nullptr;
403  const_cast<node_interface&>(this->external_interface()).set_flow_output_printable(this->port_index(), tostring_func);
404 }
405 
406 
407 } // namespace
408 } // namespace
409 
410 #endif
const auto output
Equivalent to data_goal::output.
Definition: data_goal.h:22
A base class template for all port classes.
Definition: port.h:18
const auto input
Equivalent to data_goal::input.
Definition: data_goal.h:21
Indicates output data.
A generic port class template declaration.
Definition: port.h:53
Definition: qualified_type.h:24
port_base(const port_base &)=delete
No copy constructor.
const std::string & port_name() const
Returns the name of the port.
Definition: port.h:212
Indicates input data.
port_base & operator=(const port_base &)=delete
No copy assignment.
static pointer copy(const T &X)
If T is a qualified type, returns a deep copy of X.
Definition: qualified_type.h:174
Definition: node_interface.h:16
const auto flow
Equivalent to data_mode::flow.
Definition: data_mode.h:22
Indicates message-passing.
const auto message
Equivalent to data_mode::message.
Definition: data_mode.h:23
int64 node_index() const
Returns the index of the node within the encompassing node_structure object.
Definition: port.h:226
int64 port_index() const
Returns the index of the port within the encompassing node_interface object.
Definition: port.h:219
virtual ~port_base()=default
Destructor.
const node_interface & external_interface() const
Returns the encomassing node_interface object.
Definition: port.h:233