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 
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 
270  public: bool SDFORMAT_VISIBLE ValueFromStringImpl(
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  if constexpr (std::is_same_v<T, bool>)
286  return "bool";
287  else if constexpr (std::is_same_v<T, char>)
288  return "char";
289  else if constexpr (std::is_same_v<T, std::string>)
290  return "string";
291  else if constexpr (std::is_same_v<T, int>)
292  return "int";
293  else if constexpr (std::is_same_v<T, std::uint64_t>)
294  return "uint64_t";
295  else if constexpr (std::is_same_v<T, unsigned int>)
296  return "unsigned int";
297  else if constexpr (std::is_same_v<T, double>)
298  return "double";
299  else if constexpr (std::is_same_v<T, float>)
300  return "float";
301  else if constexpr (std::is_same_v<T, sdf::Time>)
302  return "time";
303  else if constexpr (std::is_same_v<T, ignition::math::Angle>)
304  return "angle";
305  else if constexpr (std::is_same_v<T, ignition::math::Color>)
306  return "color";
307  else if constexpr (std::is_same_v<T, ignition::math::Vector2i>)
308  return "vector2i";
309  else if constexpr (std::is_same_v<T, ignition::math::Vector2d>)
310  return "vector2d";
311  else if constexpr (std::is_same_v<T, ignition::math::Vector3d>)
312  return "vector3";
313  else if constexpr (std::is_same_v<T, ignition::math::Quaterniond>)
314  return "quaternion";
315  else if constexpr (std::is_same_v<T, ignition::math::Pose3d>)
316  return "pose";
317  else
318  return "";
319  }
320 
322  template<typename T>
323  void Param::SetUpdateFunc(T _updateFunc)
324  {
325  this->dataPtr->updateFunc = _updateFunc;
326  }
327 
329  template<typename T>
330  bool Param::Set(const T &_value)
331  {
332  try
333  {
334  std::stringstream ss;
335  ss << _value;
336  return this->SetFromString(ss.str());
337  }
338  catch(...)
339  {
340  sdferr << "Unable to set parameter["
341  << this->dataPtr->key << "]."
342  << "Type used must have a stream input and output operator,"
343  << "which allows proper functioning of Param.\n";
344  return false;
345  }
346  }
347 
349  template<typename T>
350  bool Param::Get(T &_value) const
351  {
352  T *value = std::get_if<T>(&this->dataPtr->value);
353  if (value)
354  {
355  _value = *value;
356  }
357  else
358  {
359  std::string typeStr = this->dataPtr->TypeToString<T>();
360  if (typeStr.empty())
361  {
362  sdferr << "Unknown parameter type[" << typeid(T).name() << "]\n";
363  return false;
364  }
365 
366  std::string valueStr = this->GetAsString();
368  bool success = this->dataPtr->ValueFromStringImpl(typeStr, valueStr, pv);
369 
370  if (success)
371  {
372  _value = std::get<T>(pv);
373  }
374  else if (typeStr == "bool" && this->dataPtr->typeName == "string")
375  {
376  // this section for handling bool types is to keep backward behavior
377  // TODO(anyone) remove for Fortress. For more details:
378  // https://github.com/ignitionrobotics/sdformat/pull/638
379  valueStr = lowercase(valueStr);
380 
381  std::stringstream tmp;
382  if (valueStr == "true" || valueStr == "1")
383  tmp << "1";
384  else
385  tmp << "0";
386 
387  tmp >> _value;
388  return true;
389  }
390 
391  return success;
392  }
393 
394  return true;
395  }
396 
398  template<typename T>
399  bool Param::GetDefault(T &_value) const
400  {
401  std::stringstream ss;
402 
403  try
404  {
405  ss << ParamStreamer{this->dataPtr->defaultValue};
406  ss >> _value;
407  }
408  catch(...)
409  {
410  sdferr << "Unable to convert parameter["
411  << this->dataPtr->key << "] "
412  << "whose type is["
413  << this->dataPtr->typeName << "], to "
414  << "type[" << typeid(T).name() << "]\n";
415  return false;
416  }
417 
418  return true;
419  }
420 
422  template<typename Type>
423  bool Param::IsType() const
424  {
425  return std::holds_alternative<Type>(this->dataPtr->value);
426  }
427  }
428 }
429 
430 #ifdef _WIN32
431 #pragma warning(pop)
432 #endif
433 
434 #endif
sdf::v9::Param::GetAsString
std::string GetAsString() const
Get the value as a string.
sdf::v9::ParamStreamer::val
const T & val
Definition: Param.hh:69
sdf::v9::ParamStreamer
ParamStreamer(T) -> ParamStreamer< T >
sdf
namespace for Simulation Description Format parser
Definition: Actor.hh:32
sdf::v9::operator<<
std::ostream & operator<<(std::ostream &os, ParamStreamer< T > s)
Definition: Param.hh:75
sdf::v9::lowercase
std::string SDFORMAT_VISIBLE lowercase(const std::string &_in)
Transforms a string to its lowercase equivalent.
Console.hh
sdf::v9::ParamPrivate::defaultValue
ParamVariant defaultValue
This parameter's default value.
Definition: Param.hh:263
sdf::v9::Param
A parameter class.
Definition: Param.hh:94
sdf::v9::ParamPrivate
Definition: Param.hh:225
sdf::v9::ParamPrivate::required
bool required
True if the parameter is required.
Definition: Param.hh:231
Types.hh
sdf::v9::ParamStreamer
Definition: Param.hh:67
sdf::v9::ParamPtr
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:57
sdf::v9::ParamPrivate::typeName
std::string typeName
Definition: Param.hh:237
SDFORMAT_VISIBLE
#define SDFORMAT_VISIBLE
Definition: system_util.hh:48
sdf::v9::ParamPrivate::description
std::string description
Description of the parameter.
Definition: Param.hh:240
sdf::v9::Param_V
std::vector< ParamPtr > Param_V
Definition: Param.hh:61
sdf::v9::ParamPrivate::set
bool set
True if the parameter is set.
Definition: Param.hh:234
sdf::v9::ParamPrivate::updateFunc
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:243
sdf::v9::Param
class SDFORMAT_VISIBLE Param
Definition: Param.hh:53
system_util.hh
sdf::v9::Time
A Time class, can be used to hold wall- or sim-time.
Definition: Types.hh:153
sdf::v9::ParamPrivate::key
std::string key
Key value.
Definition: Param.hh:228
sdferr
#define sdferr
Output an error message.
Definition: Console.hh:57
sdf::v9::ParamPrivate::value
ParamVariant value
This parameter's value.
Definition: Param.hh:260
sdf::v9::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:257
sdf::v9::Param::operator<<
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:207