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/sdf_config.h"
40 #include "sdf/system_util.hh"
41 #include "sdf/Types.hh"
42 
43 #ifdef _WIN32
44 // Disable warning C4251 which is triggered by
45 // std::unique_ptr
46 #pragma warning(push)
47 #pragma warning(disable: 4251)
48 #endif
49 
50 namespace sdf
51 {
52  // Inline bracket to help doxygen filtering.
53  inline namespace SDF_VERSION_NAMESPACE {
54  //
55 
57 
60  typedef std::shared_ptr<Param> ParamPtr;
61 
64  typedef std::vector<ParamPtr> Param_V;
65 
67  class ParamPrivate;
68 
69  template<class T>
71  {
72  const T &val;
73  };
74 
75  template<class T> ParamStreamer(T) -> ParamStreamer<T>;
76 
77  template<class T>
78  std::ostream& operator<<(std::ostream &os, ParamStreamer<T> s)
79  {
80  os << s.val;
81  return os;
82  }
83 
84  template<>
85  inline std::ostream& operator<<(std::ostream &os, ParamStreamer<double> s)
86  {
87  os << std::setprecision(std::numeric_limits<double>::max_digits10) << s.val;
88  return os;
89  }
90 
91  template<>
92  inline std::ostream& operator<<(std::ostream &os, ParamStreamer<float> s)
93  {
94  os << std::setprecision(std::numeric_limits<float>::max_digits10) << s.val;
95  return os;
96  }
97 
98  template<class... Ts>
99  std::ostream& operator<<(std::ostream& os,
100  ParamStreamer<std::variant<Ts...>> sv)
101  {
102  std::visit([&os](auto const &v)
103  {
104  os << ParamStreamer{v};
105  }, sv.val);
106  return os;
107  }
108 
112  {
121  public: Param(const std::string &_key, const std::string &_typeName,
122  const std::string &_default, bool _required,
123  const std::string &_description = "");
124 
135  public: Param(const std::string &_key, const std::string &_typeName,
136  const std::string &_default, bool _required,
137  const std::string &_minValue, const std::string &_maxValue,
138  const std::string &_description = "");
139 
143  public: Param(const Param &_param);
144 
147  public: Param(Param &&_param) noexcept = default;
148 
153  public: Param &operator=(const Param &_param);
154 
158  public: Param &operator=(Param &&_param) noexcept = default;
159 
161  public: virtual ~Param();
162 
165  public: std::string GetAsString() const;
166 
169  public: std::string GetDefaultAsString() const;
170 
175  public: std::optional<std::string> GetMinValueAsString() const;
176 
181  public: std::optional<std::string> GetMaxValueAsString() const;
182 
185  public: bool SetFromString(const std::string &_value);
186 
188  public: void Reset();
189 
192  public: const std::string &GetKey() const;
193 
197  public: template<typename Type>
198  bool IsType() const;
199 
202  public: const std::string &GetTypeName() const;
203 
206  public: bool GetRequired() const;
207 
210  public: bool GetSet() const;
211 
214  public: ParamPtr Clone() const;
215 
219  public: template<typename T>
220  void SetUpdateFunc(T _updateFunc);
221 
224  public: void Update();
225 
231  public: template<typename T>
232  bool Set(const T &_value);
233 
237  public: bool GetAny(std::any &_anyVal) const;
238 
243  public: template<typename T>
244  bool Get(T &_value) const;
245 
250  public: template<typename T>
251  bool GetDefault(T &_value) const;
252 
255  public: void SetDescription(const std::string &_desc);
256 
259  public: std::string GetDescription() const;
260 
263  public: bool ValidateValue() const;
264 
269  public: friend std::ostream &operator<<(std::ostream &_out,
270  const Param &_p)
271  {
272  _out << _p.GetAsString();
273  return _out;
274  }
275 
279  private: bool ValueFromString(const std::string &_value);
280 
282  private: std::unique_ptr<ParamPrivate> dataPtr;
283  };
284 
288  {
290  public: std::string key;
291 
293  public: bool required;
294 
296  public: bool set;
297 
299  public: std::string typeName;
300 
302  public: std::string description;
303 
305  public: std::function<std::any ()> updateFunc;
306 
311  public: typedef std::variant<bool, char, std::string, int, std::uint64_t,
312  unsigned int, double, float, sdf::Time,
313  ignition::math::Angle,
314  ignition::math::Color,
315  ignition::math::Vector2i,
316  ignition::math::Vector2d,
317  ignition::math::Vector3d,
318  ignition::math::Quaterniond,
319  ignition::math::Pose3d> ParamVariant;
320 
322  public: ParamVariant value;
323 
325  public: ParamVariant defaultValue;
326 
328  public: std::optional<ParamVariant> minValue;
329 
331  public: std::optional<ParamVariant> maxValue;
332 
338  public: bool SDFORMAT_VISIBLE ValueFromStringImpl(
339  const std::string &_typeName,
340  const std::string &_valueStr,
341  ParamVariant &_valueToSet) const;
342 
345  public: template<typename T>
346  std::string TypeToString() const;
347  };
348 
350  template<typename T>
351  std::string ParamPrivate::TypeToString() const
352  {
353  // cppcheck-suppress syntaxError
354  if constexpr (std::is_same_v<T, bool>)
355  return "bool";
356  else if constexpr (std::is_same_v<T, char>)
357  return "char";
358  else if constexpr (std::is_same_v<T, std::string>)
359  return "string";
360  else if constexpr (std::is_same_v<T, int>)
361  return "int";
362  else if constexpr (std::is_same_v<T, std::uint64_t>)
363  return "uint64_t";
364  else if constexpr (std::is_same_v<T, unsigned int>)
365  return "unsigned int";
366  else if constexpr (std::is_same_v<T, double>)
367  return "double";
368  else if constexpr (std::is_same_v<T, float>)
369  return "float";
370  else if constexpr (std::is_same_v<T, sdf::Time>)
371  return "time";
372  else if constexpr (std::is_same_v<T, ignition::math::Angle>)
373  return "angle";
374  else if constexpr (std::is_same_v<T, ignition::math::Color>)
375  return "color";
376  else if constexpr (std::is_same_v<T, ignition::math::Vector2i>)
377  return "vector2i";
378  else if constexpr (std::is_same_v<T, ignition::math::Vector2d>)
379  return "vector2d";
380  else if constexpr (std::is_same_v<T, ignition::math::Vector3d>)
381  return "vector3";
382  else if constexpr (std::is_same_v<T, ignition::math::Quaterniond>)
383  return "quaternion";
384  else if constexpr (std::is_same_v<T, ignition::math::Pose3d>)
385  return "pose";
386  else
387  return "";
388  }
389 
391  template<typename T>
392  void Param::SetUpdateFunc(T _updateFunc)
393  {
394  this->dataPtr->updateFunc = _updateFunc;
395  }
396 
398  template<typename T>
399  bool Param::Set(const T &_value)
400  {
401  try
402  {
403  std::stringstream ss;
404  ss << _value;
405  return this->SetFromString(ss.str());
406  }
407  catch(...)
408  {
409  sdferr << "Unable to set parameter["
410  << this->dataPtr->key << "]."
411  << "Type used must have a stream input and output operator,"
412  << "which allows proper functioning of Param.\n";
413  return false;
414  }
415  }
416 
418  template<typename T>
419  bool Param::Get(T &_value) const
420  {
421  T *value = std::get_if<T>(&this->dataPtr->value);
422  if (value)
423  {
424  _value = *value;
425  }
426  else
427  {
428  std::string typeStr = this->dataPtr->TypeToString<T>();
429  if (typeStr.empty())
430  {
431  sdferr << "Unknown parameter type[" << typeid(T).name() << "]\n";
432  return false;
433  }
434 
435  std::string valueStr = this->GetAsString();
437  bool success = this->dataPtr->ValueFromStringImpl(typeStr, valueStr, pv);
438 
439  if (success)
440  {
441  _value = std::get<T>(pv);
442  }
443  else if (typeStr == "bool" && this->dataPtr->typeName == "string")
444  {
445  // this section for handling bool types is to keep backward behavior
446  // TODO(anyone) remove for Fortress. For more details:
447  // https://github.com/ignitionrobotics/sdformat/pull/638
448  valueStr = lowercase(valueStr);
449 
450  std::stringstream tmp;
451  if (valueStr == "true" || valueStr == "1")
452  tmp << "1";
453  else
454  tmp << "0";
455 
456  tmp >> _value;
457  return true;
458  }
459 
460  return success;
461  }
462 
463  return true;
464  }
465 
467  template<typename T>
468  bool Param::GetDefault(T &_value) const
469  {
470  std::stringstream ss;
471 
472  try
473  {
474  ss << ParamStreamer{this->dataPtr->defaultValue};
475  ss >> _value;
476  }
477  catch(...)
478  {
479  sdferr << "Unable to convert parameter["
480  << this->dataPtr->key << "] "
481  << "whose type is["
482  << this->dataPtr->typeName << "], to "
483  << "type[" << typeid(T).name() << "]\n";
484  return false;
485  }
486 
487  return true;
488  }
489 
491  template<typename Type>
492  bool Param::IsType() const
493  {
494  return std::holds_alternative<Type>(this->dataPtr->value);
495  }
496  }
497 }
498 
499 #ifdef _WIN32
500 #pragma warning(pop)
501 #endif
502 
503 #endif
class SDFORMAT_VISIBLE Param
Definition: Param.hh:56
ParamVariant defaultValue
This parameter&#39;s default value.
Definition: Param.hh:325
std::string key
Key value.
Definition: Param.hh:290
std::string SDFORMAT_VISIBLE lowercase(const std::string &_in)
Transforms a string to its lowercase equivalent.
ParamStreamer(T) -> ParamStreamer< T >
std::string GetAsString() const
Get the value as a string.
const T & val
Definition: Param.hh:72
ParamVariant value
This parameter&#39;s value.
Definition: Param.hh:322
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:319
std::string description
Description of the parameter.
Definition: Param.hh:302
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:305
#define SDFORMAT_VISIBLE
Use to represent "symbol visible" if supported.
Definition: system_util.hh:41
#define sdferr
Output an error message.
Definition: Console.hh:57
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:269
namespace for Simulation Description Format parser
Definition: Actor.hh:33
Definition: Param.hh:287
std::ostream & operator<<(std::ostream &os, ParamStreamer< std::variant< Ts... >> sv)
Definition: Param.hh:99
Definition: Param.hh:70
bool required
True if the parameter is required.
Definition: Param.hh:293
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:60
std::vector< ParamPtr > Param_V
Definition: Param.hh:64
std::optional< ParamVariant > maxValue
This parameter&#39;s maximum allowed value.
Definition: Param.hh:331
std::optional< ParamVariant > minValue
This parameter&#39;s minimum allowed value.
Definition: Param.hh:328
std::string typeName
Definition: Param.hh:299
A parameter class.
Definition: Param.hh:111