@@ -158,13 +158,16 @@ inline StringConverter GetAnyFromStringFunctor<void>()
158158template <typename T> [[nodiscard]]
159159std::string toStr (const T& value)
160160{
161- if constexpr (!std::is_arithmetic_v<T>)
161+ if constexpr (std::is_convertible_v<T, std::string> ||
162+ std::is_convertible_v<T, std::string_view>)
163+ {
164+ return value;
165+ }
166+ else if constexpr (!std::is_arithmetic_v<T>)
162167 {
163168 throw LogicError (
164169 StrCat (" Function BT::toStr<T>() not specialized for type [" ,
165- BT::demangle (typeid (T)), " ]," ,
166- " Implement it consistently with BT::convertFromString<T>(), "
167- " or provide at dummy version that returns an empty string." )
170+ BT::demangle (typeid (T)), " ]" )
168171 );
169172 } else {
170173 return std::to_string (value);
@@ -255,25 +258,27 @@ using Result = Expected<std::monostate>;
255258[[nodiscard]]
256259bool IsAllowedPortName (StringView str);
257260
258- class PortInfo
261+ struct AnyTypeAllowed
262+ {};
263+
264+ class TypeInfo
259265{
260266public:
261- struct AnyTypeAllowed
262- {
263- };
264267
265- PortInfo (PortDirection direction = PortDirection::INOUT) :
266- type_ (direction), type_info_(typeid (AnyTypeAllowed)),
268+ template <typename T>
269+ static TypeInfo Create () {
270+ return TypeInfo{typeid (T), GetAnyFromStringFunctor<T>()};
271+ }
272+
273+ TypeInfo (): type_info_(typeid (AnyTypeAllowed)),
267274 type_str_ (" AnyTypeAllowed" )
268275 {}
269276
270- PortInfo (PortDirection direction, std::type_index type_info, StringConverter conv) :
271- type_ (direction), type_info_(type_info), converter_(conv),
277+ TypeInfo ( std::type_index type_info, StringConverter conv) :
278+ type_info_(type_info), converter_(conv),
272279 type_str_(BT::demangle(type_info))
273280 {}
274281
275- [[nodiscard]] PortDirection direction () const ;
276-
277282 [[nodiscard]] const std::type_index& type () const ;
278283
279284 [[nodiscard]] const std::string& typeName () const ;
@@ -289,6 +294,38 @@ class PortInfo
289294 return {};
290295 }
291296
297+ [[nodiscard]] bool isStronglyTyped () const
298+ {
299+ return type_info_ != typeid (AnyTypeAllowed);
300+ }
301+
302+ [[nodiscard]] const StringConverter& converter () const
303+ {
304+ return converter_;
305+ }
306+
307+ private:
308+
309+ std::type_index type_info_;
310+ StringConverter converter_;
311+ std::string type_str_;
312+ };
313+
314+
315+ class PortInfo : public TypeInfo
316+ {
317+ public:
318+
319+ PortInfo (PortDirection direction = PortDirection::INOUT) :
320+ TypeInfo (), direction_(direction)
321+ {}
322+
323+ PortInfo (PortDirection direction, std::type_index type_info, StringConverter conv) :
324+ TypeInfo (type_info, conv), direction_(direction)
325+ {}
326+
327+ [[nodiscard]] PortDirection direction () const ;
328+
292329 void setDescription (StringView description);
293330
294331 template <typename T>
@@ -306,27 +343,14 @@ class PortInfo
306343
307344 [[nodiscard]] const std::string& defaultValueString () const ;
308345
309- [[nodiscard]] bool isStronglyTyped () const
310- {
311- return type_info_ != typeid (AnyTypeAllowed);
312- }
313-
314- [[nodiscard]] const StringConverter& converter () const
315- {
316- return converter_;
317- }
318-
319346private:
320- PortDirection type_;
321- std::type_index type_info_;
322- StringConverter converter_;
347+ PortDirection direction_;
323348 std::string description_;
324349 Any default_value_;
325350 std::string default_value_str_;
326- std::string type_str_;
327351};
328352
329- template <typename T = PortInfo:: AnyTypeAllowed> [[nodiscard]]
353+ template <typename T = AnyTypeAllowed> [[nodiscard]]
330354std::pair<std::string, PortInfo> CreatePort (PortDirection direction,
331355 StringView name,
332356 StringView description = {})
@@ -357,28 +381,28 @@ std::pair<std::string, PortInfo> CreatePort(PortDirection direction,
357381}
358382
359383// ----------
360- template <typename T = PortInfo:: AnyTypeAllowed> [[nodiscard]]
384+ template <typename T = AnyTypeAllowed> [[nodiscard]]
361385inline std::pair<std::string, PortInfo> InputPort (StringView name,
362386 StringView description = {})
363387{
364388 return CreatePort<T>(PortDirection::INPUT, name, description);
365389}
366390
367- template <typename T = PortInfo:: AnyTypeAllowed> [[nodiscard]]
391+ template <typename T = AnyTypeAllowed> [[nodiscard]]
368392inline std::pair<std::string, PortInfo> OutputPort (StringView name,
369393 StringView description = {})
370394{
371395 return CreatePort<T>(PortDirection::OUTPUT, name, description);
372396}
373397
374- template <typename T = PortInfo:: AnyTypeAllowed> [[nodiscard]]
398+ template <typename T = AnyTypeAllowed> [[nodiscard]]
375399inline std::pair<std::string, PortInfo> BidirectionalPort (StringView name,
376400 StringView description = {})
377401{
378402 return CreatePort<T>(PortDirection::INOUT, name, description);
379403}
380404// ----------
381- template <typename T = PortInfo:: AnyTypeAllowed> [[nodiscard]]
405+ template <typename T = AnyTypeAllowed> [[nodiscard]]
382406inline std::pair<std::string, PortInfo> InputPort (StringView name, const T& default_value,
383407 StringView description)
384408{
@@ -387,7 +411,7 @@ inline std::pair<std::string, PortInfo> InputPort(StringView name, const T& defa
387411 return out;
388412}
389413
390- template <typename T = PortInfo:: AnyTypeAllowed> [[nodiscard]]
414+ template <typename T = AnyTypeAllowed> [[nodiscard]]
391415inline std::pair<std::string, PortInfo> BidirectionalPort (StringView name,
392416 const T& default_value,
393417 StringView description)
0 commit comments