11#pragma once
22
3+ #include < chrono>
34#include < iostream>
4- #include < vector>
5- #include < unordered_map>
6- #include < typeinfo>
75#include < functional>
8- #include < chrono>
96#include < string_view>
7+ #include < typeinfo>
8+ #include < unordered_map>
109#include < utility>
1110#include < variant>
1211#include < vector>
@@ -156,11 +155,17 @@ inline StringConverter GetAnyFromStringFunctor<void>()
156155
157156// ------------------------------------------------------------------
158157
158+ template <typename T>
159+ constexpr bool IsConvertibleToString ()
160+ {
161+ return std::is_convertible_v<T, std::string> ||
162+ std::is_convertible_v<T, std::string_view>;
163+ }
164+
159165template <typename T> [[nodiscard]]
160166std::string toStr (const T& value)
161167{
162- if constexpr (std::is_convertible_v<T, std::string> ||
163- std::is_convertible_v<T, std::string_view>)
168+ if constexpr (IsConvertibleToString<T>())
164169 {
165170 return value;
166171 }
@@ -169,8 +174,9 @@ std::string toStr(const T& value)
169174 throw LogicError (
170175 StrCat (" Function BT::toStr<T>() not specialized for type [" ,
171176 BT::demangle (typeid (T)), " ]" )
172- );
173- } else {
177+ );
178+ }
179+ else {
174180 return std::to_string (value);
175181 }
176182}
@@ -383,45 +389,165 @@ std::pair<std::string, PortInfo> CreatePort(PortDirection direction,
383389}
384390
385391// ----------
392+ /* * Syntactic sugar to invoke CreatePort<T>(PortDirection::INPUT, ...)
393+ *
394+ * @param name the name of the port
395+ * @param description optional human-readable description
396+ */
386397template <typename T = AnyTypeAllowed> [[nodiscard]]
387398inline std::pair<std::string, PortInfo> InputPort (StringView name,
388399 StringView description = {})
389400{
390401 return CreatePort<T>(PortDirection::INPUT, name, description);
391402}
392403
404+ /* * Syntactic sugar to invoke CreatePort<T>(PortDirection::OUTPUT,...)
405+ *
406+ * @param name the name of the port
407+ * @param description optional human-readable description
408+ */
393409template <typename T = AnyTypeAllowed> [[nodiscard]]
394410inline std::pair<std::string, PortInfo> OutputPort (StringView name,
395411 StringView description = {})
396412{
397413 return CreatePort<T>(PortDirection::OUTPUT, name, description);
398414}
399415
416+ /* * Syntactic sugar to invoke CreatePort<T>(PortDirection::INOUT,...)
417+ *
418+ * @param name the name of the port
419+ * @param description optional human-readable description
420+ */
400421template <typename T = AnyTypeAllowed> [[nodiscard]]
401422inline std::pair<std::string, PortInfo> BidirectionalPort (StringView name,
402423 StringView description = {})
403424{
404425 return CreatePort<T>(PortDirection::INOUT, name, description);
405426}
406427// ----------
407- template <typename T = AnyTypeAllowed> [[nodiscard]]
408- inline std::pair<std::string, PortInfo> InputPort (StringView name, const T& default_value,
428+ /* * Syntactic sugar to invoke CreatePort<T>(PortDirection::INPUT,...)
429+ * It also sets the PortInfo::defaultValue()
430+ *
431+ * @param name the name of the port
432+ * @param default_value default value of the port, either type T of BlackboardKey
433+ * @param description optional human-readable description
434+ */
435+ template <typename T = AnyTypeAllowed, typename DefaultT = T> [[nodiscard]]
436+ inline std::pair<std::string, PortInfo> InputPort (StringView name,
437+ const DefaultT& default_value,
409438 StringView description)
410439{
440+ static_assert (std::is_same_v<T, DefaultT> ||
441+ IsConvertibleToString<DefaultT>() ||
442+ std::is_convertible_v<DefaultT, T>,
443+ " The default value must be either the same of the port or BlackboardKey" );
444+
411445 auto out = CreatePort<T>(PortDirection::INPUT, name, description);
412446 out.second .setDefaultValue (default_value);
413447 return out;
414448}
415449
416- template <typename T = AnyTypeAllowed> [[nodiscard]]
450+ /* * Syntactic sugar to invoke CreatePort<T>(PortDirection::INOUT,...)
451+ * It also sets the PortInfo::defaultValue()
452+ *
453+ * @param name the name of the port
454+ * @param default_value default value of the port, either type T of BlackboardKey
455+ * @param description optional human-readable description
456+ */
457+ template <typename T = AnyTypeAllowed, typename DefaultT = T> [[nodiscard]]
417458inline std::pair<std::string, PortInfo> BidirectionalPort (StringView name,
418- const T & default_value,
459+ const DefaultT & default_value,
419460 StringView description)
420461{
462+ static_assert (std::is_same_v<T, DefaultT> ||
463+ IsConvertibleToString<DefaultT>() ||
464+ std::is_convertible_v<DefaultT, T>,
465+ " The default value must be either the same of the port or BlackboardKey" );
466+
421467 auto out = CreatePort<T>(PortDirection::INOUT, name, description);
422468 out.second .setDefaultValue (default_value);
423469 return out;
424470}
471+
472+ /* * Syntactic sugar to invoke CreatePort<T>(PortDirection::OUTPUT,...)
473+ * It also sets the PortInfo::defaultValue()
474+ *
475+ * @param name the name of the port
476+ * @param default_value default blackboard entry where the output is written
477+ * @param description optional human-readable description
478+ */
479+ template <typename T = AnyTypeAllowed> [[nodiscard]]
480+ inline std::pair<std::string, PortInfo> OutputPort (StringView name,
481+ StringView default_value,
482+ StringView description)
483+ {
484+ if (default_value.empty () || default_value.front () != ' {' || default_value.back () != ' }' )
485+ {
486+ throw LogicError (" Output port can only refer to blackboard entries, i.e. use the syntax '{port_name}'" );
487+ }
488+ auto out = CreatePort<T>(PortDirection::OUTPUT, name, description);
489+ out.second .setDefaultValue (default_value);
490+ return out;
491+ }
492+
493+ // ----------
494+
495+ // /** Syntactic sugar to invoke CreatePort<T>(PortDirection::INPUT,...)
496+ // * It also sets the default value to the blackboard entry specified
497+ // * in "default_key"
498+ // *
499+ // * @param name the name of the port
500+ // * @param default_key the key of an entry in the blackbard
501+ // * @param description optional human-readable description
502+ // */
503+ // template <typename T> [[nodiscard]]
504+ // inline std::pair<std::string, PortInfo> InputPort(
505+ // StringView name,
506+ // BlackboardKey default_key,
507+ // StringView description)
508+ // {
509+ // auto out = CreatePort<T>(PortDirection::INPUT, name, description);
510+ // out.second.setDefaultValue(default_key);
511+ // return out;
512+ // }
513+
514+ // /** Syntactic sugar to invoke CreatePort<T>(PortDirection::INOUT,...)
515+ // * It also sets the default value to the blackboard entry specified
516+ // * in "default_key"
517+ // *
518+ // * @param name the name of the port
519+ // * @param default_key the key of an entry in the blackbard
520+ // * @param description optional human-readable description
521+ // */
522+ // template <typename T> [[nodiscard]]
523+ // inline std::pair<std::string, PortInfo> BidirectionalPort(
524+ // StringView name,
525+ // BlackboardKey default_key,
526+ // StringView description)
527+ // {
528+ // auto out = CreatePort<T>(PortDirection::INOUT, name, description);
529+ // out.second.setDefaultValue(default_key);
530+ // return out;
531+ // }
532+
533+ // /** Syntactic sugar to invoke CreatePort<T>(PortDirection::OUTPUT,...)
534+ // * It also sets the default value to the blackboard entry specified
535+ // * in "default_key"
536+ // *
537+ // * @param name the name of the port
538+ // * @param default_key the key of an entry in the blackbard
539+ // * @param description optional human-readable description
540+ // */
541+ // template <typename T> [[nodiscard]]
542+ // inline std::pair<std::string, PortInfo> OutputPort(
543+ // StringView name,
544+ // BlackboardKey default_key,
545+ // StringView description)
546+ // {
547+ // auto out = CreatePort<T>(PortDirection::OUTPUT, name, description);
548+ // out.second.setDefaultValue(default_key);
549+ // return out;
550+ // }
425551// ----------
426552
427553using PortsList = std::unordered_map<std::string, PortInfo>;
0 commit comments