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 
57  class SDFORMAT_VISIBLE Element;
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(const PrintConfig &_config,
412  const std::string &_typeName,
413  const ParamVariant &_value,
414  std::string &_valueStr) const;
415 
418  public: template<typename T>
419  std::string TypeToString() const;
420  };
421 
423  template<typename T>
424  std::string ParamPrivate::TypeToString() const
425  {
426  // cppcheck-suppress syntaxError
427  if constexpr (std::is_same_v<T, bool>)
428  return "bool";
429  else if constexpr (std::is_same_v<T, char>)
430  return "char";
431  else if constexpr (std::is_same_v<T, std::string>)
432  return "string";
433  else if constexpr (std::is_same_v<T, int>)
434  return "int";
435  else if constexpr (std::is_same_v<T, std::uint64_t>)
436  return "uint64_t";
437  else if constexpr (std::is_same_v<T, unsigned int>)
438  return "unsigned int";
439  else if constexpr (std::is_same_v<T, double>)
440  return "double";
441  else if constexpr (std::is_same_v<T, float>)
442  return "float";
443  else if constexpr (std::is_same_v<T, sdf::Time>)
444  return "time";
445  else if constexpr (std::is_same_v<T, ignition::math::Angle>)
446  return "angle";
447  else if constexpr (std::is_same_v<T, ignition::math::Color>)
448  return "color";
449  else if constexpr (std::is_same_v<T, ignition::math::Vector2i>)
450  return "vector2i";
451  else if constexpr (std::is_same_v<T, ignition::math::Vector2d>)
452  return "vector2d";
453  else if constexpr (std::is_same_v<T, ignition::math::Vector3d>)
454  return "vector3";
455  else if constexpr (std::is_same_v<T, ignition::math::Quaterniond>)
456  return "quaternion";
457  else if constexpr (std::is_same_v<T, ignition::math::Pose3d>)
458  return "pose";
459  else
460  return "";
461  }
462 
464  template<typename T>
465  void Param::SetUpdateFunc(T _updateFunc)
466  {
467  this->dataPtr->updateFunc = _updateFunc;
468  }
469 
471  template<typename T>
472  bool Param::Set(const T &_value)
473  {
474  try
475  {
476  std::stringstream ss;
477  ss << _value;
478  return this->SetFromString(ss.str(), true);
479  }
480  catch(...)
481  {
482  sdferr << "Unable to set parameter["
483  << this->dataPtr->key << "]."
484  << "Type used must have a stream input and output operator,"
485  << "which allows proper functioning of Param.\n";
486  return false;
487  }
488  }
489 
491  template<typename T>
492  bool Param::Get(T &_value) const
493  {
494  T *value = std::get_if<T>(&this->dataPtr->value);
495  if (value)
496  {
497  _value = *value;
498  }
499  else
500  {
501  std::string typeStr = this->dataPtr->TypeToString<T>();
502  if (typeStr.empty())
503  {
504  sdferr << "Unknown parameter type[" << typeid(T).name() << "]\n";
505  return false;
506  }
507 
508  std::string valueStr = this->GetAsString();
510  bool success = this->dataPtr->ValueFromStringImpl(typeStr, valueStr, pv);
511 
512  if (success)
513  {
514  _value = std::get<T>(pv);
515  }
516  else if (typeStr == "bool" && this->dataPtr->typeName == "string")
517  {
518  // this section for handling bool types is to keep backward behavior
519  // TODO(anyone) remove for Fortress. For more details:
520  // https://github.com/ignitionrobotics/sdformat/pull/638
521  valueStr = lowercase(valueStr);
522 
523  std::stringstream tmp;
524  if (valueStr == "true" || valueStr == "1")
525  tmp << "1";
526  else
527  tmp << "0";
528 
529  tmp >> _value;
530  return true;
531  }
532 
533  return success;
534  }
535 
536  return true;
537  }
538 
540  template<typename T>
541  bool Param::GetDefault(T &_value) const
542  {
543  std::stringstream ss;
544 
545  try
546  {
547  ss << ParamStreamer{this->dataPtr->defaultValue};
548  ss >> _value;
549  }
550  catch(...)
551  {
552  sdferr << "Unable to convert parameter["
553  << this->dataPtr->key << "] "
554  << "whose type is["
555  << this->dataPtr->typeName << "], to "
556  << "type[" << typeid(T).name() << "]\n";
557  return false;
558  }
559 
560  return true;
561  }
562 
564  template<typename Type>
565  bool Param::IsType() const
566  {
567  return std::holds_alternative<Type>(this->dataPtr->value);
568  }
569  }
570 }
571 
572 #ifdef _WIN32
573 #pragma warning(pop)
574 #endif
575 
576 #endif
Definition: Param.hh:335
bool set
True if the parameter is set.
Definition: Param.hh:343
ParamVariant value
This parameter's value.
Definition: Param.hh:372
ParamVariant defaultValue
This parameter's default value.
Definition: Param.hh:386
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.
std::optional< std::string > strValue
This parameter's value that was provided as a string.
Definition: Param.hh:380
std::optional< ParamVariant > maxValue
This parameter's maximum allowed value.
Definition: Param.hh:392
std::string description
Description of the parameter.
Definition: Param.hh:349
bool ValueFromStringImpl(const std::string &_typeName, const std::string &_valueStr, ParamVariant &_valueToSet) const
Method used to set the Param from a passed-in string.
std::string typeName
Definition: Param.hh:346
bool required
True if the parameter is required.
Definition: Param.hh:340
std::string defaultStrValue
This parameter's default value that was provided as a string.
Definition: Param.hh:383
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
ElementWeakPtr parentElement
Parent element.
Definition: Param.hh:352
std::string key
Key value.
Definition: Param.hh:337
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:355
std::optional< ParamVariant > minValue
This parameter's minimum allowed value.
Definition: Param.hh:389
bool ignoreParentAttributes
True if the value has been parsed while ignoring its parent element's attributes, and will continue t...
Definition: Param.hh:377
A parameter class.
Definition: Param.hh:117
virtual ~Param()
Destructor.
const std::string & GetTypeName() const
Get the type name value.
Param & operator=(const Param &_param)
Copy assignment operator Note that the updateFunc member will not get copied.
bool IgnoresParentElementAttribute() const
Return true if the parameter ignores the parent element's attributes, or if the parameter has no pare...
void Update()
Set the parameter's value using the updateFunc.
std::optional< std::string > GetMinValueAsString(const PrintConfig &_config=PrintConfig()) const
Get the minimum allowed value as a string.
bool GetRequired() const
Return whether the parameter is required.
Param(Param &&_param) noexcept=default
Move constructor.
ElementPtr GetParentElement() const
Get the parent Element of this Param.
bool SetParentElement(ElementPtr _parentElement)
Set the parent Element of this Param.
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.
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:321
bool ValidateValue() const
Validate the value against minimum and maximum allowed values.
const std::string & GetKey() const
Get the key value.
bool GetAny(std::any &_anyVal) const
Get the value of the parameter as a std::any.
bool Reparse()
Reparse the parameter value.
Param & operator=(Param &&_param) noexcept=default
Move assignment operator.
Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_description="")
Constructor.
void SetDescription(const std::string &_desc)
Set the description of the parameter.
void Reset()
Reset the parameter to the default value.
std::string GetDescription() const
Get the description of the parameter.
bool SetFromString(const std::string &_value)
Set the parameter value from a string.
Param(const Param &_param)
Copy constructor Note that the updateFunc member does not get copied.
std::string GetAsString(const PrintConfig &_config=PrintConfig()) const
Get the value as a string.
bool SetFromString(const std::string &_value, bool _ignoreParentAttributes)
Set the parameter value from a string.
ParamPtr Clone() const
Clone the parameter.
std::optional< std::string > GetMaxValueAsString(const PrintConfig &_config=PrintConfig()) const
Get the maximum allowed value as a string.
std::string GetDefaultAsString(const PrintConfig &_config=PrintConfig()) const
Get the default value as a string.
bool GetSet() const
Return true if the parameter has been set.
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::weak_ptr< Element > ElementWeakPtr
Definition: Element.hh:62
ParamStreamer(T) -> ParamStreamer< T >
std::shared_ptr< Element > ElementPtr
Definition: Element.hh:54
std::string 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::vector< ParamPtr > Param_V
Definition: Param.hh:69
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:65
namespace for Simulation Description Format parser
Definition: Actor.hh:34
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:41