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 
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 
399  public: bool SDFORMAT_VISIBLE ValueFromStringImpl(
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::v12::ParamPrivate::maxValue
std::optional< ParamVariant > maxValue
This parameter's maximum allowed value.
Definition: Param.hh:392
sdf::v12::ParamPrivate::ignoreParentAttributes
bool ignoreParentAttributes
True if the value has been parsed while ignoring its parent element's attributes, and will continue t...
Definition: Param.hh:377
sdf::v12::ParamPtr
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:65
sdf::v12::ParamPrivate::description
std::string description
Description of the parameter.
Definition: Param.hh:349
sdf::v12::Param::operator<<
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:321
sdf::v12::ParamPrivate::set
bool set
True if the parameter is set.
Definition: Param.hh:343
sdf::v12::ParamPrivate::value
ParamVariant value
This parameter's value.
Definition: Param.hh:372
sdf
namespace for Simulation Description Format parser
Definition: Actor.hh:34
sdf::v12::ParamPrivate::defaultValue
ParamVariant defaultValue
This parameter's default value.
Definition: Param.hh:386
sdf::v12::ParamPrivate::typeName
std::string typeName
Definition: Param.hh:346
sdf::v12::lowercase
std::string IGNITION_SDFORMAT_VISIBLE lowercase(const std::string &_in)
Transforms a string to its lowercase equivalent.
PrintConfig.hh
Console.hh
sdf::v12::Param_V
std::vector< ParamPtr > Param_V
Definition: Param.hh:69
sdf::v12::ParamPrivate::key
std::string key
Key value.
Definition: Param.hh:337
sdf::v12::Param::GetAsString
std::string GetAsString(const PrintConfig &_config=PrintConfig()) const
Get the value as a string.
sdf::v12::ParamStreamer
Definition: Param.hh:75
sdf::v12::Param
A parameter class.
Definition: Param.hh:116
Types.hh
sdf_config.h
sdf::v12::ParamPrivate::updateFunc
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:355
SDFORMAT_VISIBLE
#define SDFORMAT_VISIBLE
Definition: system_util.hh:25
sdf::v12::ParamPrivate::minValue
std::optional< ParamVariant > minValue
This parameter's minimum allowed value.
Definition: Param.hh:389
sdf::v12::Element
class IGNITION_SDFORMAT_VISIBLE Element
Definition: Element.hh:50
sdf::v12::ParamPrivate::strValue
std::optional< std::string > strValue
This parameter's value that was provided as a string.
Definition: Param.hh:380
sdf::v12::PrintConfig
This class contains configuration options for printing elements.
Definition: PrintConfig.hh:31
sdf::v12::ParamPrivate::ParamVariant
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
sdf::v12::Param
class IGNITION_SDFORMAT_VISIBLE Param
Definition: Param.hh:61
sdf::v12::Time
A Time class, can be used to hold wall- or sim-time.
Definition: Types.hh:117
sdf::v12::ParamStreamer::val
const T & val
Definition: Param.hh:77
sdf::v12::ElementWeakPtr
std::weak_ptr< Element > ElementWeakPtr
Definition: Element.hh:62
sdf::v12::ParamPrivate::defaultStrValue
std::string defaultStrValue
This parameter's default value that was provided as a string.
Definition: Param.hh:383
sdf::v12::ParamPrivate::parentElement
ElementWeakPtr parentElement
Parent element.
Definition: Param.hh:352
sdf::v12::ParamStreamer
ParamStreamer(T) -> ParamStreamer< T >
system_util.hh
sdf::v12::ParamPrivate
Definition: Param.hh:334
sdf::v12::ParamPrivate::required
bool required
True if the parameter is required.
Definition: Param.hh:340
sdf::v12::ElementPtr
std::shared_ptr< Element > ElementPtr
Definition: Element.hh:54
sdferr
#define sdferr
Output an error message.
Definition: Console.hh:57
sdf::v12::operator<<
std::ostream & operator<<(std::ostream &os, ParamStreamer< T > s)
Definition: Param.hh:83