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 <sstream>
28 #include <string>
29 #include <typeinfo>
30 #include <variant>
31 #include <vector>
32 
33 #include <ignition/math.hh>
34 
35 #include "sdf/Console.hh"
36 #include "sdf/sdf_config.h"
37 #include "sdf/system_util.hh"
38 #include "sdf/Types.hh"
39 
40 #ifdef _WIN32
41 // Disable warning C4251 which is triggered by
42 // std::unique_ptr
43 #pragma warning(push)
44 #pragma warning(disable: 4251)
45 #endif
46 
47 namespace sdf
48 {
49  // Inline bracket to help doxygen filtering.
50  inline namespace SDF_VERSION_NAMESPACE {
51  //
52 
53  class SDFORMAT_VISIBLE Param;
54 
57  typedef std::shared_ptr<Param> ParamPtr;
58 
61  typedef std::vector<ParamPtr> Param_V;
62 
64  class ParamPrivate;
65 
66  template<class T>
68  {
69  const T &val;
70  };
71 
72  template<class T> ParamStreamer(T) -> ParamStreamer<T>;
73 
74  template<class T>
75  std::ostream& operator<<(std::ostream &os, ParamStreamer<T> s)
76  {
77  os << s.val;
78  return os;
79  }
80 
81  template<class... Ts>
82  std::ostream& operator<<(std::ostream& os,
83  ParamStreamer<std::variant<Ts...>> sv)
84  {
85  std::visit([&os](auto const &v)
86  {
87  os << ParamStreamer{v};
88  }, sv.val);
89  return os;
90  }
91 
95  {
104  public: Param(const std::string &_key, const std::string &_typeName,
105  const std::string &_default, bool _required,
106  const std::string &_description = "");
107 
109  public: virtual ~Param();
110 
113  public: std::string GetAsString() const;
114 
117  public: std::string GetDefaultAsString() const;
118 
121  public: bool SetFromString(const std::string &_value);
122 
124  public: void Reset();
125 
128  public: const std::string &GetKey() const;
129 
133  public: template<typename Type>
134  bool IsType() const;
135 
138  public: const std::string &GetTypeName() const;
139 
142  public: bool GetRequired() const;
143 
146  public: bool GetSet() const;
147 
150  public: ParamPtr Clone() const;
151 
155  public: template<typename T>
156  void SetUpdateFunc(T _updateFunc);
157 
160  public: void Update();
161 
167  public: template<typename T>
168  bool Set(const T &_value);
169 
173  public: bool GetAny(std::any &_anyVal) const;
174 
179  public: template<typename T>
180  bool Get(T &_value) const;
181 
186  public: template<typename T>
187  bool GetDefault(T &_value) const;
188 
193  public: Param &operator=(const Param &_param);
194 
197  public: void SetDescription(const std::string &_desc);
198 
201  public: std::string GetDescription() const;
202 
207  public: friend std::ostream &operator<<(std::ostream &_out,
208  const Param &_p)
209  {
210  _out << _p.GetAsString();
211  return _out;
212  }
213 
217  private: bool ValueFromString(const std::string &_value);
218 
220  private: std::unique_ptr<ParamPrivate> dataPtr;
221  };
222 
226  {
228  public: std::string key;
229 
231  public: bool required;
232 
234  public: bool set;
235 
237  public: std::string typeName;
238 
240  public: std::string description;
241 
243  public: std::function<std::any ()> updateFunc;
244 
249  public: typedef std::variant<bool, char, std::string, int, std::uint64_t,
250  unsigned int, double, float, sdf::Time,
251  ignition::math::Angle,
252  ignition::math::Color,
253  ignition::math::Vector2i,
254  ignition::math::Vector2d,
255  ignition::math::Vector3d,
256  ignition::math::Quaterniond,
257  ignition::math::Pose3d> ParamVariant;
258 
261 
264 
271  const std::string &_typeName,
272  const std::string &_valueStr,
273  ParamVariant &_valueToSet) const;
274 
277  public: template<typename T>
278  std::string TypeToString() const;
279  };
280 
282  template<typename T>
283  std::string ParamPrivate::TypeToString() const
284  {
285  // cppcheck-suppress syntaxError
286  if constexpr (std::is_same_v<T, bool>)
287  return "bool";
288  else if constexpr (std::is_same_v<T, char>)
289  return "char";
290  else if constexpr (std::is_same_v<T, std::string>)
291  return "string";
292  else if constexpr (std::is_same_v<T, int>)
293  return "int";
294  else if constexpr (std::is_same_v<T, std::uint64_t>)
295  return "uint64_t";
296  else if constexpr (std::is_same_v<T, unsigned int>)
297  return "unsigned int";
298  else if constexpr (std::is_same_v<T, double>)
299  return "double";
300  else if constexpr (std::is_same_v<T, float>)
301  return "float";
302  else if constexpr (std::is_same_v<T, sdf::Time>)
303  return "time";
304  else if constexpr (std::is_same_v<T, ignition::math::Angle>)
305  return "angle";
306  else if constexpr (std::is_same_v<T, ignition::math::Color>)
307  return "color";
308  else if constexpr (std::is_same_v<T, ignition::math::Vector2i>)
309  return "vector2i";
310  else if constexpr (std::is_same_v<T, ignition::math::Vector2d>)
311  return "vector2d";
312  else if constexpr (std::is_same_v<T, ignition::math::Vector3d>)
313  return "vector3";
314  else if constexpr (std::is_same_v<T, ignition::math::Quaterniond>)
315  return "quaternion";
316  else if constexpr (std::is_same_v<T, ignition::math::Pose3d>)
317  return "pose";
318  else
319  return "";
320  }
321 
323  template<typename T>
324  void Param::SetUpdateFunc(T _updateFunc)
325  {
326  this->dataPtr->updateFunc = _updateFunc;
327  }
328 
330  template<typename T>
331  bool Param::Set(const T &_value)
332  {
333  try
334  {
335  std::stringstream ss;
336  ss << _value;
337  return this->SetFromString(ss.str());
338  }
339  catch(...)
340  {
341  sdferr << "Unable to set parameter["
342  << this->dataPtr->key << "]."
343  << "Type used must have a stream input and output operator,"
344  << "which allows proper functioning of Param.\n";
345  return false;
346  }
347  }
348 
350  template<typename T>
351  bool Param::Get(T &_value) const
352  {
353  T *value = std::get_if<T>(&this->dataPtr->value);
354  if (value)
355  {
356  _value = *value;
357  }
358  else
359  {
360  std::string typeStr = this->dataPtr->TypeToString<T>();
361  if (typeStr.empty())
362  {
363  sdferr << "Unknown parameter type[" << typeid(T).name() << "]\n";
364  return false;
365  }
366 
367  std::string valueStr = this->GetAsString();
369  bool success = this->dataPtr->ValueFromStringImpl(typeStr, valueStr, pv);
370 
371  if (success)
372  {
373  _value = std::get<T>(pv);
374  }
375  else if (typeStr == "bool" && this->dataPtr->typeName == "string")
376  {
377  // this section for handling bool types is to keep backward behavior
378  // TODO(anyone) remove for Fortress. For more details:
379  // https://github.com/ignitionrobotics/sdformat/pull/638
380  valueStr = lowercase(valueStr);
381 
382  std::stringstream tmp;
383  if (valueStr == "true" || valueStr == "1")
384  tmp << "1";
385  else
386  tmp << "0";
387 
388  tmp >> _value;
389  return true;
390  }
391 
392  return success;
393  }
394 
395  return true;
396  }
397 
399  template<typename T>
400  bool Param::GetDefault(T &_value) const
401  {
402  std::stringstream ss;
403 
404  try
405  {
406  ss << ParamStreamer{this->dataPtr->defaultValue};
407  ss >> _value;
408  }
409  catch(...)
410  {
411  sdferr << "Unable to convert parameter["
412  << this->dataPtr->key << "] "
413  << "whose type is["
414  << this->dataPtr->typeName << "], to "
415  << "type[" << typeid(T).name() << "]\n";
416  return false;
417  }
418 
419  return true;
420  }
421 
423  template<typename Type>
424  bool Param::IsType() const
425  {
426  return std::holds_alternative<Type>(this->dataPtr->value);
427  }
428  }
429 }
430 
431 #ifdef _WIN32
432 #pragma warning(pop)
433 #endif
434 
435 #endif
Definition: Param.hh:226
ParamVariant defaultValue
This parameter's default value.
Definition: Param.hh:263
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:243
bool set
True if the parameter is set.
Definition: Param.hh:234
bool required
True if the parameter is required.
Definition: Param.hh:231
std::string description
Description of the parameter.
Definition: Param.hh:240
std::string typeName
Definition: Param.hh:237
ParamVariant value
This parameter's value.
Definition: Param.hh:260
std::string key
Key value.
Definition: Param.hh:228
bool 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::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:257
A parameter class.
Definition: Param.hh:95
std::string GetAsString() const
Get the value as a string.
const std::string & GetTypeName() const
Get the type name value.
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 SetFromString(const std::string &_value)
Set the parameter value from a string.
ParamPtr Clone() const
Clone the parameter.
void Update()
Set the parameter's value using the updateFunc.
bool GetRequired() const
Return whether the parameter is required.
bool GetSet() const
Return true if the parameter has been set.
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:207
bool GetAny(std::any &_anyVal) const
Get the value of the parameter as a std::any.
void SetDescription(const std::string &_desc)
Set the description of the parameter.
virtual ~Param()
Destructor.
const std::string & GetKey() const
Get the key value.
Param & operator=(const Param &_param)
Equal operator.
std::string GetDefaultAsString() const
Get the default value as a string.
void Reset()
Reset the parameter to the default value.
A Time class, can be used to hold wall- or sim-time.
Definition: Types.hh:154
#define sdferr
Output an error message.
Definition: Console.hh:57
std::ostream & operator<<(std::ostream &os, ParamStreamer< T > s)
Definition: Param.hh:75
ParamStreamer(T) -> ParamStreamer< T >
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:57
std::vector< ParamPtr > Param_V
Definition: Param.hh:61
std::string SDFORMAT_VISIBLE lowercase(const std::string &_in)
Transforms a string to its lowercase equivalent.
namespace for Simulation Description Format parser
Definition: Actor.hh:33
Definition: Param.hh:68
const T & val
Definition: Param.hh:69
#define SDFORMAT_VISIBLE
Use to represent "symbol visible" if supported.
Definition: system_util.hh:48