Param.hh
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #ifndef SDFORMAT_PARAM_HH_
19 #define SDFORMAT_PARAM_HH_
20 
21 #include <any>
22 #include <algorithm>
23 #include <cctype>
24 #include <cstdint>
25 #include <functional>
26 #include <iomanip>
27 #include <limits>
28 #include <memory>
29 #include <optional>
30 #include <sstream>
31 #include <string>
32 #include <typeinfo>
33 #include <variant>
34 #include <vector>
35 
36 #include <ignition/math.hh>
37 
38 #include "sdf/Console.hh"
39 #include "sdf/PrintConfig.hh"
40 #include "sdf/sdf_config.h"
41 #include "sdf/system_util.hh"
42 #include "sdf/Types.hh"
43 
44 #ifdef _WIN32
45 // Disable warning C4251 which is triggered by
46 // std::unique_ptr
47 #pragma warning(push)
48 #pragma warning(disable: 4251)
49 #endif
50 
51 namespace sdf
52 {
53  // Inline bracket to help doxygen filtering.
54  inline namespace SDF_VERSION_NAMESPACE {
55  //
56 
58  using ElementPtr = std::shared_ptr<Element>;
59  using ElementWeakPtr = std::weak_ptr<Element>;
60 
61  class SDFORMAT_VISIBLE Param;
62 
65  typedef std::shared_ptr<Param> ParamPtr;
66 
69  typedef std::vector<ParamPtr> Param_V;
70 
72  class ParamPrivate;
73 
74  template<class T>
76  {
77  const T &val;
78  };
79 
80  template<class T> ParamStreamer(T) -> ParamStreamer<T>;
81 
82  template<class T>
83  std::ostream& operator<<(std::ostream &os, ParamStreamer<T> s)
84  {
85  os << s.val;
86  return os;
87  }
88 
89  template<>
90  inline std::ostream& operator<<(std::ostream &os, ParamStreamer<double> s)
91  {
92  os << std::setprecision(std::numeric_limits<double>::max_digits10) << s.val;
93  return os;
94  }
95 
96  template<>
97  inline std::ostream& operator<<(std::ostream &os, ParamStreamer<float> s)
98  {
99  os << std::setprecision(std::numeric_limits<float>::max_digits10) << s.val;
100  return os;
101  }
102 
103  template<class... Ts>
104  std::ostream& operator<<(std::ostream& os,
105  ParamStreamer<std::variant<Ts...>> sv)
106  {
107  std::visit([&os](auto const &v)
108  {
109  os << ParamStreamer{v};
110  }, sv.val);
111  return os;
112  }
113 
117  {
126  public: Param(const std::string &_key, const std::string &_typeName,
127  const std::string &_default, bool _required,
128  const std::string &_description = "");
129 
140  public: Param(const std::string &_key, const std::string &_typeName,
141  const std::string &_default, bool _required,
142  const std::string &_minValue, const std::string &_maxValue,
143  const std::string &_description = "");
144 
148  public: Param(const Param &_param);
149 
152  public: Param(Param &&_param) noexcept = default;
153 
158  public: Param &operator=(const Param &_param);
159 
163  public: Param &operator=(Param &&_param) noexcept = default;
164 
166  public: virtual ~Param();
167 
171  public: std::string GetAsString(
172  const PrintConfig &_config = PrintConfig()) const;
173 
177  public: std::string GetDefaultAsString(
178  const PrintConfig &_config = PrintConfig()) const;
179 
185  public: std::optional<std::string> GetMinValueAsString(
186  const PrintConfig &_config = PrintConfig()) const;
187 
193  public: std::optional<std::string> GetMaxValueAsString(
194  const PrintConfig &_config = PrintConfig()) const;
195 
201  public: bool SetFromString(const std::string &_value,
202  bool _ignoreParentAttributes);
203 
206  public: bool SetFromString(const std::string &_value);
207 
211  public: ElementPtr GetParentElement() const;
212 
218  public: bool SetParentElement(ElementPtr _parentElement);
219 
221  public: void Reset();
222 
234  public: bool Reparse();
235 
238  public: const std::string &GetKey() const;
239 
243  public: template<typename Type>
244  bool IsType() const;
245 
248  public: const std::string &GetTypeName() const;
249 
252  public: bool GetRequired() const;
253 
256  public: bool GetSet() const;
257 
262  public: bool IgnoresParentElementAttribute() const;
263 
266  public: ParamPtr Clone() const;
267 
271  public: template<typename T>
272  void SetUpdateFunc(T _updateFunc);
273 
276  public: void Update();
277 
283  public: template<typename T>
284  bool Set(const T &_value);
285 
289  public: bool GetAny(std::any &_anyVal) const;
290 
295  public: template<typename T>
296  bool Get(T &_value) const;
297 
302  public: template<typename T>
303  bool GetDefault(T &_value) const;
304 
307  public: void SetDescription(const std::string &_desc);
308 
311  public: std::string GetDescription() const;
312 
315  public: bool ValidateValue() const;
316 
321  public: friend std::ostream &operator<<(std::ostream &_out,
322  const Param &_p)
323  {
324  _out << _p.GetAsString();
325  return _out;
326  }
327 
329  private: std::unique_ptr<ParamPrivate> dataPtr;
330  };
331 
335  {
337  public: std::string key;
338 
340  public: bool required;
341 
343  public: bool set;
344 
346  public: std::string typeName;
347 
349  public: std::string description;
350 
353 
355  public: std::function<std::any ()> updateFunc;
356 
361  public: typedef std::variant<bool, char, std::string, int, std::uint64_t,
362  unsigned int, double, float, sdf::Time,
363  ignition::math::Angle,
364  ignition::math::Color,
365  ignition::math::Vector2i,
366  ignition::math::Vector2d,
367  ignition::math::Vector3d,
368  ignition::math::Quaterniond,
369  ignition::math::Pose3d> ParamVariant;
370 
373 
378 
380  public: std::optional<std::string> strValue;
381 
383  public: std::string defaultStrValue;
384 
387 
389  public: std::optional<ParamVariant> minValue;
390 
392  public: std::optional<ParamVariant> maxValue;
393 
400  const std::string &_typeName,
401  const std::string &_valueStr,
402  ParamVariant &_valueToSet) const;
403 
411  public: bool StringFromValueImpl(
412  const PrintConfig &_config,
413  const std::string &_typeName,
414  const ParamVariant &_value,
415  std::string &_valueStr) const;
416 
426  public: bool StringFromValueImpl(
427  const PrintConfig &_config,
428  const std::string &_typeName,
429  const ParamVariant &_value,
430  const std::optional<std::string> &_originalStr,
431  std::string &_valueStr) const;
432 
435  public: template<typename T>
436  std::string TypeToString() const;
437  };
438 
440  template<typename T>
441  std::string ParamPrivate::TypeToString() const
442  {
443  // cppcheck-suppress syntaxError
444  if constexpr (std::is_same_v<T, bool>)
445  return "bool";
446  else if constexpr (std::is_same_v<T, char>)
447  return "char";
448  else if constexpr (std::is_same_v<T, std::string>)
449  return "string";
450  else if constexpr (std::is_same_v<T, int>)
451  return "int";
452  else if constexpr (std::is_same_v<T, std::uint64_t>)
453  return "uint64_t";
454  else if constexpr (std::is_same_v<T, unsigned int>)
455  return "unsigned int";
456  else if constexpr (std::is_same_v<T, double>)
457  return "double";
458  else if constexpr (std::is_same_v<T, float>)
459  return "float";
460  else if constexpr (std::is_same_v<T, sdf::Time>)
461  return "time";
462  else if constexpr (std::is_same_v<T, ignition::math::Angle>)
463  return "angle";
464  else if constexpr (std::is_same_v<T, ignition::math::Color>)
465  return "color";
466  else if constexpr (std::is_same_v<T, ignition::math::Vector2i>)
467  return "vector2i";
468  else if constexpr (std::is_same_v<T, ignition::math::Vector2d>)
469  return "vector2d";
470  else if constexpr (std::is_same_v<T, ignition::math::Vector3d>)
471  return "vector3";
472  else if constexpr (std::is_same_v<T, ignition::math::Quaterniond>)
473  return "quaternion";
474  else if constexpr (std::is_same_v<T, ignition::math::Pose3d>)
475  return "pose";
476  else
477  return "";
478  }
479 
481  template<typename T>
482  void Param::SetUpdateFunc(T _updateFunc)
483  {
484  this->dataPtr->updateFunc = _updateFunc;
485  }
486 
488  template<typename T>
489  bool Param::Set(const T &_value)
490  {
491  try
492  {
493  std::stringstream ss;
494  ss << _value;
495  return this->SetFromString(ss.str(), true);
496  }
497  catch(...)
498  {
499  sdferr << "Unable to set parameter["
500  << this->dataPtr->key << "]."
501  << "Type used must have a stream input and output operator,"
502  << "which allows proper functioning of Param.\n";
503  return false;
504  }
505  }
506 
508  template<typename T>
509  bool Param::Get(T &_value) const
510  {
511  T *value = std::get_if<T>(&this->dataPtr->value);
512  if (value)
513  {
514  _value = *value;
515  }
516  else
517  {
518  std::string typeStr = this->dataPtr->TypeToString<T>();
519  if (typeStr.empty())
520  {
521  sdferr << "Unknown parameter type[" << typeid(T).name() << "]\n";
522  return false;
523  }
524 
525  std::string valueStr = this->GetAsString();
527  bool success = this->dataPtr->ValueFromStringImpl(typeStr, valueStr, pv);
528 
529  if (success)
530  {
531  _value = std::get<T>(pv);
532  }
533  else if (typeStr == "bool" && this->dataPtr->typeName == "string")
534  {
535  // this section for handling bool types is to keep backward behavior
536  // TODO(anyone) remove for Fortress. For more details:
537  // https://github.com/ignitionrobotics/sdformat/pull/638
538  valueStr = lowercase(valueStr);
539 
540  std::stringstream tmp;
541  if (valueStr == "true" || valueStr == "1")
542  tmp << "1";
543  else
544  tmp << "0";
545 
546  tmp >> _value;
547  return true;
548  }
549 
550  return success;
551  }
552 
553  return true;
554  }
555 
557  template<typename T>
558  bool Param::GetDefault(T &_value) const
559  {
560  std::stringstream ss;
561 
562  try
563  {
564  ss << ParamStreamer{this->dataPtr->defaultValue};
565  ss >> _value;
566  }
567  catch(...)
568  {
569  sdferr << "Unable to convert parameter["
570  << this->dataPtr->key << "] "
571  << "whose type is["
572  << this->dataPtr->typeName << "], to "
573  << "type[" << typeid(T).name() << "]\n";
574  return false;
575  }
576 
577  return true;
578  }
579 
581  template<typename Type>
582  bool Param::IsType() const
583  {
584  return std::holds_alternative<Type>(this->dataPtr->value);
585  }
586  }
587 }
588 
589 #ifdef _WIN32
590 #pragma warning(pop)
591 #endif
592 
593 #endif
SDF Element class.
Definition: Element.hh:75
Definition: Param.hh:335
bool set
True if the parameter is set.
Definition: Param.hh:343
bool required
True if the parameter is required.
Definition: Param.hh:340
std::variant< bool, char, std::string, int, std::uint64_t, unsigned int, double, float, sdf::Time, ignition::math::Angle, ignition::math::Color, ignition::math::Vector2i, ignition::math::Vector2d, ignition::math::Vector3d, ignition::math::Quaterniond, ignition::math::Pose3d > ParamVariant
Definition: Param.hh:369
bool StringFromValueImpl(const PrintConfig &_config, const std::string &_typeName, const ParamVariant &_value, std::string &_valueStr) const
Method used to get the string representation from a ParamVariant, or the string that was used to set ...
ParamVariant defaultValue
This parameter's default value.
Definition: Param.hh:386
std::string TypeToString() const
Data type to string mapping.
Definition: Param.hh:441
ElementWeakPtr parentElement
Parent element.
Definition: Param.hh:352
bool IGNITION_SDFORMAT_VISIBLE ValueFromStringImpl(const std::string &_typeName, const std::string &_valueStr, ParamVariant &_valueToSet) const
Method used to set the Param from a passed-in string.
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:355
std::string defaultStrValue
This parameter's default value that was provided as a string.
Definition: Param.hh:383
std::string typeName
Definition: Param.hh:346
bool ignoreParentAttributes
True if the value has been parsed while ignoring its parent element's attributes, and will continue t...
Definition: Param.hh:377
ParamVariant value
This parameter's value.
Definition: Param.hh:372
std::string key
Key value.
Definition: Param.hh:337
std::optional< ParamVariant > maxValue
This parameter's maximum allowed value.
Definition: Param.hh:392
std::optional< ParamVariant > minValue
This parameter's minimum allowed value.
Definition: Param.hh:389
std::optional< std::string > strValue
This parameter's value that was provided as a string.
Definition: Param.hh:380
std::string description
Description of the parameter.
Definition: Param.hh:349
bool StringFromValueImpl(const PrintConfig &_config, const std::string &_typeName, const ParamVariant &_value, const std::optional< std::string > &_originalStr, std::string &_valueStr) const
Method used to get the string representation from a ParamVariant, or the string that was used to set ...
A parameter class.
Definition: Param.hh:117
Param(Param &&_param) noexcept=default
Move constructor.
bool SetFromString(const std::string &_value, bool _ignoreParentAttributes)
Set the parameter value from a string.
ElementPtr GetParentElement() const
Get the parent Element of this Param.
std::optional< std::string > GetMaxValueAsString(const PrintConfig &_config=PrintConfig()) const
Get the maximum allowed value as a string.
const std::string & GetTypeName() const
Get the type name value.
const std::string & GetKey() const
Get the key value.
Param & operator=(Param &&_param) noexcept=default
Move assignment operator.
std::string GetAsString(const PrintConfig &_config=PrintConfig()) const
Get the value as a string.
void SetDescription(const std::string &_desc)
Set the description of the parameter.
Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_minValue, const std::string &_maxValue, const std::string &_description="")
Constructor with min and max values.
void Update()
Set the parameter's value using the updateFunc.
bool Set(const T &_value)
Set the parameter's value.
Definition: Param.hh:489
void SetUpdateFunc(T _updateFunc)
Set the update function.
Definition: Param.hh:482
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:321
std::string GetDefaultAsString(const PrintConfig &_config=PrintConfig()) const
Get the default value as a string.
Param & operator=(const Param &_param)
Copy assignment operator Note that the updateFunc member will not get copied.
ParamPtr Clone() const
Clone the parameter.
Param(const Param &_param)
Copy constructor Note that the updateFunc member does not get copied.
Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_description="")
Constructor.
std::string GetDescription() const
Get the description of the parameter.
bool GetSet() const
Return true if the parameter has been set.
bool SetParentElement(ElementPtr _parentElement)
Set the parent Element of this Param.
bool ValidateValue() const
Validate the value against minimum and maximum allowed values.
bool Get(T &_value) const
Get the value of the parameter.
Definition: Param.hh:509
bool Reparse()
Reparse the parameter value.
bool IsType() const
Return true if the param is a particular type.
Definition: Param.hh:582
bool GetAny(std::any &_anyVal) const
Get the value of the parameter as a std::any.
bool IgnoresParentElementAttribute() const
Return true if the parameter ignores the parent element's attributes, or if the parameter has no pare...
void Reset()
Reset the parameter to the default value.
bool GetDefault(T &_value) const
Get the default value of the parameter.
Definition: Param.hh:558
bool GetRequired() const
Return whether the parameter is required.
std::optional< std::string > GetMinValueAsString(const PrintConfig &_config=PrintConfig()) const
Get the minimum allowed value as a string.
bool SetFromString(const std::string &_value)
Set the parameter value from a string.
This class contains configuration options for printing elements.
Definition: PrintConfig.hh:32
A Time class, can be used to hold wall- or sim-time.
Definition: Types.hh:118
#define sdferr
Output an error message.
Definition: Console.hh:57
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:65
std::vector< ParamPtr > Param_V
Definition: Param.hh:69
std::string IGNITION_SDFORMAT_VISIBLE lowercase(const std::string &_in)
Transforms a string to its lowercase equivalent.
std::ostream & operator<<(std::ostream &os, ParamStreamer< T > s)
Definition: Param.hh:83
std::weak_ptr< Element > ElementWeakPtr
Definition: Element.hh:62
std::shared_ptr< Element > ElementPtr
Definition: Element.hh:54
ParamStreamer(T) -> ParamStreamer< T >
namespace for Simulation Description Format parser
Definition: Actor.hh:35
Definition: Param.hh:76
const T & val
Definition: Param.hh:77
#define SDFORMAT_VISIBLE
Use to represent "symbol visible" if supported.
Definition: system_util.hh:25