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 <memory>
27 #include <optional>
28 #include <sstream>
29 #include <string>
30 #include <typeinfo>
31 #include <variant>
32 #include <vector>
33 
34 #include <ignition/math.hh>
35 
36 #include "sdf/Console.hh"
37 #include "sdf/sdf_config.h"
38 #include "sdf/system_util.hh"
39 #include "sdf/Types.hh"
40 
41 #ifdef _WIN32
42 // Disable warning C4251 which is triggered by
43 // std::unique_ptr
44 #pragma warning(push)
45 #pragma warning(disable: 4251)
46 #endif
47 
48 namespace sdf
49 {
50  // Inline bracket to help doxygen filtering.
51  inline namespace SDF_VERSION_NAMESPACE {
52  //
53 
55 
58  typedef std::shared_ptr<Param> ParamPtr;
59 
62  typedef std::vector<ParamPtr> Param_V;
63 
65  class ParamPrivate;
66 
67  template<class T>
69  {
70  const T &val;
71  };
72 
73  template<class T> ParamStreamer(T) -> ParamStreamer<T>;
74 
75  template<class T>
76  std::ostream& operator<<(std::ostream &os, ParamStreamer<T> s)
77  {
78  os << s.val;
79  return os;
80  }
81 
82  template<class... Ts>
83  std::ostream& operator<<(std::ostream& os,
84  ParamStreamer<std::variant<Ts...>> sv)
85  {
86  std::visit([&os](auto const &v)
87  {
88  os << ParamStreamer{v};
89  }, sv.val);
90  return os;
91  }
92 
96  {
105  public: Param(const std::string &_key, const std::string &_typeName,
106  const std::string &_default, bool _required,
107  const std::string &_description = "");
108 
119  public: Param(const std::string &_key, const std::string &_typeName,
120  const std::string &_default, bool _required,
121  const std::string &_minValue, const std::string &_maxValue,
122  const std::string &_description = "");
123 
127  public: Param(const Param &_param);
128 
131  public: Param(Param &&_param) noexcept = default;
132 
137  public: Param &operator=(const Param &_param);
138 
142  public: Param &operator=(Param &&_param) noexcept = default;
143 
145  public: virtual ~Param();
146 
149  public: std::string GetAsString() const;
150 
153  public: std::string GetDefaultAsString() const;
154 
159  public: std::optional<std::string> GetMinValueAsString() const;
160 
165  public: std::optional<std::string> GetMaxValueAsString() const;
166 
169  public: bool SetFromString(const std::string &_value);
170 
172  public: void Reset();
173 
176  public: const std::string &GetKey() const;
177 
181  public: template<typename Type>
182  bool IsType() const;
183 
186  public: const std::string &GetTypeName() const;
187 
190  public: bool GetRequired() const;
191 
194  public: bool GetSet() const;
195 
198  public: ParamPtr Clone() const;
199 
203  public: template<typename T>
204  void SetUpdateFunc(T _updateFunc);
205 
208  public: void Update();
209 
215  public: template<typename T>
216  bool Set(const T &_value);
217 
221  public: bool GetAny(std::any &_anyVal) const;
222 
227  public: template<typename T>
228  bool Get(T &_value) const;
229 
234  public: template<typename T>
235  bool GetDefault(T &_value) const;
236 
239  public: void SetDescription(const std::string &_desc);
240 
243  public: std::string GetDescription() const;
244 
247  public: bool ValidateValue() const;
248 
253  public: friend std::ostream &operator<<(std::ostream &_out,
254  const Param &_p)
255  {
256  _out << _p.GetAsString();
257  return _out;
258  }
259 
263  private: bool ValueFromString(const std::string &_value);
264 
266  private: std::unique_ptr<ParamPrivate> dataPtr;
267  };
268 
272  {
274  public: std::string key;
275 
277  public: bool required;
278 
280  public: bool set;
281 
283  public: std::string typeName;
284 
286  public: std::string description;
287 
289  public: std::function<std::any ()> updateFunc;
290 
295  public: typedef std::variant<bool, char, std::string, int, std::uint64_t,
296  unsigned int, double, float, sdf::Time,
297  ignition::math::Angle,
298  ignition::math::Color,
299  ignition::math::Vector2i,
300  ignition::math::Vector2d,
301  ignition::math::Vector3d,
302  ignition::math::Quaterniond,
303  ignition::math::Pose3d> ParamVariant;
304 
306  public: ParamVariant value;
307 
309  public: ParamVariant defaultValue;
310 
312  public: std::optional<ParamVariant> minValue;
313 
315  public: std::optional<ParamVariant> maxValue;
316 
322  public: bool SDFORMAT_VISIBLE ValueFromStringImpl(
323  const std::string &_typeName,
324  const std::string &_valueStr,
325  ParamVariant &_valueToSet) const;
326 
329  public: template<typename T>
330  std::string TypeToString() const;
331  };
332 
334  template<typename T>
335  std::string ParamPrivate::TypeToString() const
336  {
337  // cppcheck-suppress syntaxError
338  if constexpr (std::is_same_v<T, bool>)
339  return "bool";
340  else if constexpr (std::is_same_v<T, char>)
341  return "char";
342  else if constexpr (std::is_same_v<T, std::string>)
343  return "string";
344  else if constexpr (std::is_same_v<T, int>)
345  return "int";
346  else if constexpr (std::is_same_v<T, std::uint64_t>)
347  return "uint64_t";
348  else if constexpr (std::is_same_v<T, unsigned int>)
349  return "unsigned int";
350  else if constexpr (std::is_same_v<T, double>)
351  return "double";
352  else if constexpr (std::is_same_v<T, float>)
353  return "float";
354  else if constexpr (std::is_same_v<T, sdf::Time>)
355  return "time";
356  else if constexpr (std::is_same_v<T, ignition::math::Angle>)
357  return "angle";
358  else if constexpr (std::is_same_v<T, ignition::math::Color>)
359  return "color";
360  else if constexpr (std::is_same_v<T, ignition::math::Vector2i>)
361  return "vector2i";
362  else if constexpr (std::is_same_v<T, ignition::math::Vector2d>)
363  return "vector2d";
364  else if constexpr (std::is_same_v<T, ignition::math::Vector3d>)
365  return "vector3";
366  else if constexpr (std::is_same_v<T, ignition::math::Quaterniond>)
367  return "quaternion";
368  else if constexpr (std::is_same_v<T, ignition::math::Pose3d>)
369  return "pose";
370  else
371  return "";
372  }
373 
375  template<typename T>
376  void Param::SetUpdateFunc(T _updateFunc)
377  {
378  this->dataPtr->updateFunc = _updateFunc;
379  }
380 
382  template<typename T>
383  bool Param::Set(const T &_value)
384  {
385  try
386  {
387  std::stringstream ss;
388  ss << _value;
389  return this->SetFromString(ss.str());
390  }
391  catch(...)
392  {
393  sdferr << "Unable to set parameter["
394  << this->dataPtr->key << "]."
395  << "Type used must have a stream input and output operator,"
396  << "which allows proper functioning of Param.\n";
397  return false;
398  }
399  }
400 
402  template<typename T>
403  bool Param::Get(T &_value) const
404  {
405  T *value = std::get_if<T>(&this->dataPtr->value);
406  if (value)
407  {
408  _value = *value;
409  }
410  else
411  {
412  std::string typeStr = this->dataPtr->TypeToString<T>();
413  if (typeStr.empty())
414  {
415  sdferr << "Unknown parameter type[" << typeid(T).name() << "]\n";
416  return false;
417  }
418 
419  std::string valueStr = this->GetAsString();
421  bool success = this->dataPtr->ValueFromStringImpl(typeStr, valueStr, pv);
422 
423  if (success)
424  {
425  _value = std::get<T>(pv);
426  }
427  else if (typeStr == "bool" && this->dataPtr->typeName == "string")
428  {
429  // this section for handling bool types is to keep backward behavior
430  // TODO(anyone) remove for Fortress. For more details:
431  // https://github.com/ignitionrobotics/sdformat/pull/638
432  valueStr = lowercase(valueStr);
433 
434  std::stringstream tmp;
435  if (valueStr == "true" || valueStr == "1")
436  tmp << "1";
437  else
438  tmp << "0";
439 
440  tmp >> _value;
441  return true;
442  }
443 
444  return success;
445  }
446 
447  return true;
448  }
449 
451  template<typename T>
452  bool Param::GetDefault(T &_value) const
453  {
454  std::stringstream ss;
455 
456  try
457  {
458  ss << ParamStreamer{this->dataPtr->defaultValue};
459  ss >> _value;
460  }
461  catch(...)
462  {
463  sdferr << "Unable to convert parameter["
464  << this->dataPtr->key << "] "
465  << "whose type is["
466  << this->dataPtr->typeName << "], to "
467  << "type[" << typeid(T).name() << "]\n";
468  return false;
469  }
470 
471  return true;
472  }
473 
475  template<typename Type>
476  bool Param::IsType() const
477  {
478  return std::holds_alternative<Type>(this->dataPtr->value);
479  }
480  }
481 }
482 
483 #ifdef _WIN32
484 #pragma warning(pop)
485 #endif
486 
487 #endif
void SetUpdateFunc(T _updateFunc)
Set the update function.
Definition: Param.hh:376
std::ostream & operator<<(std::ostream &os, ParamStreamer< T > s)
Definition: Param.hh:76
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:58
ParamVariant value
This parameter&#39;s value.
Definition: Param.hh:306
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:253
std::string SDFORMAT_VISIBLE lowercase(const std::string &_in)
Transforms a string to its lowercase equivalent.
std::vector< ParamPtr > Param_V
Definition: Param.hh:62
bool required
True if the parameter is required.
Definition: Param.hh:277
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:289
std::string TypeToString() const
Data type to string mapping.
Definition: Param.hh:335
std::optional< ParamVariant > maxValue
This parameter&#39;s maximum allowed value.
Definition: Param.hh:315
class SDFORMAT_VISIBLE Param
Definition: Param.hh:54
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:303
std::optional< ParamVariant > minValue
This parameter&#39;s minimum allowed value.
Definition: Param.hh:312
bool GetDefault(T &_value) const
Get the default value of the parameter.
Definition: Param.hh:452
std::string key
Key value.
Definition: Param.hh:274
#define SDFORMAT_VISIBLE
Use to represent "symbol visible" if supported.
Definition: system_util.hh:25
#define sdferr
Output an error message.
Definition: Console.hh:57
const T & val
Definition: Param.hh:70
std::string GetAsString() const
Get the value as a string.
ParamVariant defaultValue
This parameter&#39;s default value.
Definition: Param.hh:309
std::string typeName
Definition: Param.hh:283
bool IsType() const
Return true if the param is a particular type.
Definition: Param.hh:476
ParamStreamer(T) -> ParamStreamer< T >
namespace for Simulation Description Format parser
Definition: Actor.hh:32
bool Get(T &_value) const
Get the value of the parameter.
Definition: Param.hh:403
std::string description
Description of the parameter.
Definition: Param.hh:286
bool Set(const T &_value)
Set the parameter&#39;s value.
Definition: Param.hh:383
A parameter class.
Definition: Param.hh:95