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 <gz/math/Angle.hh>
37#include <gz/math/Color.hh>
38#include <gz/math/Pose3.hh>
39#include <gz/math/Quaternion.hh>
40#include <gz/math/Vector2.hh>
41#include <gz/math/Vector3.hh>
42
43#include "sdf/Console.hh"
44#include "sdf/PrintConfig.hh"
45#include "sdf/sdf_config.h"
46#include "sdf/system_util.hh"
47#include "sdf/Types.hh"
48
49#ifdef _WIN32
50// Disable warning C4251 which is triggered by
51// std::unique_ptr
52#pragma warning(push)
53#pragma warning(disable: 4251)
54#endif
55
56namespace sdf
57{
58 // Inline bracket to help doxygen filtering.
59 inline namespace SDF_VERSION_NAMESPACE {
60 //
61
63 using ElementPtr = std::shared_ptr<Element>;
64 using ElementWeakPtr = std::weak_ptr<Element>;
65
67
70 typedef std::shared_ptr<Param> ParamPtr;
71
74 typedef std::vector<ParamPtr> Param_V;
75
77 class ParamPrivate;
78
79 template<class T>
81 {
82 const T &val;
83 const int precision; // Used to set std::ostream's std::setprecision
84 explicit ParamStreamer(const T &_val, int _precision = 0)
85 : val(_val), precision(_precision) {}
86 };
87
88 template<class T>
89 std::ostream& operator<<(std::ostream &os, ParamStreamer<T> s)
90 {
91 if (s.precision == std::numeric_limits<int>::max())
92 {
93 if constexpr (std::is_same_v<T, double>
94 || std::is_same_v<T, gz::math::Angle>
95 || std::is_same_v<T, gz::math::Vector2d>
96 || std::is_same_v<T, gz::math::Vector3d>
97 || std::is_same_v<T, gz::math::Quaterniond>
98 || std::is_same_v<T, gz::math::Pose3d>)
99 {
100 os << std::setprecision(std::numeric_limits<double>::max_digits10);
101 }
102 else if constexpr (std::is_same_v<T, float>
103 || std::is_same_v<T, gz::math::Color>)
104 {
105 os << std::setprecision(std::numeric_limits<float>::max_digits10);
106 }
107 }
108 else
109 {
110 os << std::setprecision(s.precision);
111 }
112
113 os << s.val;
114 return os;
115 }
116
117 template<class... Ts>
118 std::ostream& operator<<(std::ostream& os,
119 ParamStreamer<std::variant<Ts...>> sv)
120 {
121 std::visit([&os, &sv](auto const &v)
122 {
123 os << ParamStreamer{v, sv.precision};
124 }, sv.val);
125 return os;
126 }
127
131 {
140 public: Param(const std::string &_key, const std::string &_typeName,
141 const std::string &_default, bool _required,
142 const std::string &_description = "");
143
152 public: Param(const std::string &_key, const std::string &_typeName,
153 const std::string &_default, bool _required,
154 sdf::Errors &_errors,
155 const std::string &_description = "");
156
167 public: Param(const std::string &_key, const std::string &_typeName,
168 const std::string &_default, bool _required,
169 const std::string &_minValue, const std::string &_maxValue,
170 const std::string &_description = "");
171
182 public: Param(const std::string &_key, const std::string &_typeName,
183 const std::string &_default, bool _required,
184 const std::string &_minValue, const std::string &_maxValue,
185 sdf::Errors &_errors,
186 const std::string &_description = "");
187
191 public: Param(const Param &_param);
192
195 public: Param(Param &&_param) noexcept = default;
196
201 public: Param &operator=(const Param &_param);
202
206 public: Param &operator=(Param &&_param) noexcept = default;
207
209 public: virtual ~Param();
210
214 public: std::string GetAsString(
215 const PrintConfig &_config = PrintConfig()) const;
216
221 public: std::string GetAsString(
222 sdf::Errors &_errors,
223 const PrintConfig &_config = PrintConfig()) const;
224
228 public: std::string GetDefaultAsString(
229 const PrintConfig &_config = PrintConfig()) const;
230
235 public: std::string GetDefaultAsString(
236 sdf::Errors &_errors,
237 const PrintConfig &_config = PrintConfig()) const;
238
244 public: std::optional<std::string> GetMinValueAsString(
245 const PrintConfig &_config = PrintConfig()) const;
246
253 public: std::optional<std::string> GetMinValueAsString(
254 sdf::Errors &_errors,
255 const PrintConfig &_config = PrintConfig()) const;
256
262 public: std::optional<std::string> GetMaxValueAsString(
263 const PrintConfig &_config = PrintConfig()) const;
264
271 public: std::optional<std::string> GetMaxValueAsString(
272 sdf::Errors &_errors,
273 const PrintConfig &_config = PrintConfig()) const;
274
280 public: bool SetFromString(const std::string &_value,
281 bool _ignoreParentAttributes);
282
289 public: bool SetFromString(const std::string &_value,
290 bool _ignoreParentAttributes,
291 sdf::Errors &_errors);
292
295 public: bool SetFromString(const std::string &_value);
296
300 public: bool SetFromString(const std::string &_value,
301 sdf::Errors &_errors);
302
307
313 public: bool SetParentElement(ElementPtr _parentElement);
314
321 public: bool SetParentElement(ElementPtr _parentElement,
322 sdf::Errors &_errors);
323
325 public: void Reset();
326
338 public: bool Reparse();
339
352 public: bool Reparse(sdf::Errors &_errors);
353
356 public: const std::string &GetKey() const;
357
361 public: template<typename Type>
362 bool IsType() const;
363
366 public: const std::string &GetTypeName() const;
367
370 public: bool GetRequired() const;
371
374 public: bool GetSet() const;
375
380 public: bool IgnoresParentElementAttribute() const;
381
384 public: ParamPtr Clone() const;
385
389 public: template<typename T>
390 void SetUpdateFunc(T _updateFunc);
391
394 public: void Update();
395
399 public: void Update(sdf::Errors &_errors);
400
406 public: template<typename T>
407 bool Set(const T &_value);
408
415 public: template<typename T>
416 bool Set(const T &_value,
417 sdf::Errors &_errors);
418
422 public: bool GetAny(std::any &_anyVal) const;
423
428 public: bool GetAny(std::any &_anyVal, sdf::Errors &_errors) const;
429
434 public: template<typename T>
435 bool Get(T &_value) const;
436
442 public: template<typename T>
443 bool Get(T &_value,
444 sdf::Errors &_errors) const;
445
450 public: template<typename T>
451 bool GetDefault(T &_value) const;
452
458 public: template<typename T>
459 bool GetDefault(T &_value,
460 sdf::Errors &_errors) const;
461
464 public: void SetDescription(const std::string &_desc);
465
468 public: std::string GetDescription() const;
469
472 public: bool ValidateValue() const;
473
477 public: bool ValidateValue(sdf::Errors &_errors) const;
478
483 public: friend std::ostream &operator<<(std::ostream &_out,
484 const Param &_p)
485 {
486 _out << _p.GetAsString();
487 return _out;
488 }
489
491 private: std::unique_ptr<ParamPrivate> dataPtr;
492 };
493
497 {
499 public: std::string key;
500
502 public: bool required;
503
505 public: bool set;
506
508 public: std::string typeName;
509
511 public: std::string description;
512
515
517 public: std::function<std::any ()> updateFunc;
518
524 public: typedef std::variant<bool, char, std::string, int, std::uint64_t,
525 unsigned int, double, float, sdf::Time,
526 gz::math::Angle,
527 gz::math::Color,
528 gz::math::Vector2i,
529 gz::math::Vector2d,
530 gz::math::Vector3d,
531 gz::math::Quaterniond,
532 gz::math::Pose3d> ParamVariant;
533
536
541
543 public: std::optional<std::string> strValue;
544
546 public: std::string defaultStrValue;
547
550
552 public: std::optional<ParamVariant> minValue;
553
555 public: std::optional<ParamVariant> maxValue;
556
565 public: void Init(const std::string &_key, const std::string &_typeName,
566 const std::string &_default, bool _required,
567 sdf::Errors &_errors,
568 const std::string &_description);
569
580 public: void Init(const std::string &_key, const std::string &_typeName,
581 const std::string &_default, bool _required,
582 const std::string &_minValue, const std::string &_maxValue,
583 sdf::Errors &_errors,
584 const std::string &_description);
585
593 const std::string &_typeName,
594 const std::string &_valueStr,
595 ParamVariant &_valueToSet,
596 sdf::Errors &_errors) const;
597
607 const PrintConfig &_config,
608 const std::string &_typeName,
609 const ParamVariant &_value,
610 std::string &_valueStr,
611 sdf::Errors &_errors) const;
612
615 public: template<typename T>
616 static std::string TypeToString();
617 };
618
620 template<typename T>
622 {
623 // cppcheck-suppress syntaxError
624 if constexpr (std::is_same_v<T, bool>)
625 return "bool";
626 else if constexpr (std::is_same_v<T, char>)
627 return "char";
628 else if constexpr (std::is_same_v<T, std::string>)
629 return "string";
630 else if constexpr (std::is_same_v<T, int>)
631 return "int";
632 else if constexpr (std::is_same_v<T, std::uint64_t>)
633 return "uint64_t";
634 else if constexpr (std::is_same_v<T, unsigned int>)
635 return "unsigned int";
636 else if constexpr (std::is_same_v<T, double>)
637 return "double";
638 else if constexpr (std::is_same_v<T, float>)
639 return "float";
640 else if constexpr (std::is_same_v<T, sdf::Time>)
641 return "time";
642 else if constexpr (std::is_same_v<T, gz::math::Angle>)
643 return "angle";
644 else if constexpr (std::is_same_v<T, gz::math::Color>)
645 return "color";
646 else if constexpr (std::is_same_v<T, gz::math::Vector2i>)
647 return "vector2i";
648 else if constexpr (std::is_same_v<T, gz::math::Vector2d>)
649 return "vector2d";
650 else if constexpr (std::is_same_v<T, gz::math::Vector3d>)
651 return "vector3";
652 else if constexpr (std::is_same_v<T, gz::math::Quaterniond>)
653 return "quaternion";
654 else if constexpr (std::is_same_v<T, gz::math::Pose3d>)
655 return "pose";
656 else
657 return "";
658 }
659
661 template<typename T>
662 void Param::SetUpdateFunc(T _updateFunc)
663 {
664 this->dataPtr->updateFunc = _updateFunc;
665 }
666
668 template<typename T>
669 bool Param::Set(const T &_value)
670 {
671 sdf::Errors errors;
672 bool result = this->Set<T>(_value, errors);
673 if (!errors.empty())
674 sdferr << errors;
675 return result;
676 }
677
679 template<typename T>
680 bool Param::Set(const T &_value, sdf::Errors &_errors)
681 {
682 try
683 {
684 std::stringstream ss;
685 ss << ParamStreamer<T>{_value, std::numeric_limits<int>::max()};
686 return this->SetFromString(ss.str(), true, _errors);
687 }
688 catch(...)
689 {
690 _errors.push_back({ErrorCode::PARAMETER_ERROR,
691 "Unable to set parameter["
692 + this->dataPtr->key + "]."
693 + "Type used must have a stream input and output operator,"
694 + "which allows proper functioning of Param."});
695 return false;
696 }
697 }
698
700 template<typename T>
701 bool Param::Get(T &_value) const
702 {
703 sdf::Errors errors;
704 bool result = this->Get<T>(_value, errors);
705 if (!errors.empty())
706 sdferr << errors;
707 return result;
708 }
709
711 template<typename T>
712 bool Param::Get(T &_value, sdf::Errors &_errors) const
713 {
714 T *value = std::get_if<T>(&this->dataPtr->value);
715 if (value)
716 {
717 _value = *value;
718 }
719 else
720 {
721 std::string typeStr = this->dataPtr->TypeToString<T>();
722 if (typeStr.empty())
723 {
724 _errors.push_back({ErrorCode::UNKNOWN_PARAMETER_TYPE,
725 "Unknown parameter type[" + std::string(typeid(T).name()) + "]"});
726 return false;
727 }
728
729 std::string valueStr = this->GetAsString(_errors);
731 bool success = this->dataPtr->ValueFromStringImpl(
732 typeStr, valueStr, pv, _errors);
733
734 if (success)
735 {
736 _value = std::get<T>(pv);
737 }
738 else if (typeStr == "bool" && this->dataPtr->typeName == "string")
739 {
740 // this section for handling bool types is to keep backward behavior
741 // TODO(anyone) remove for Fortress. For more details:
742 // https://github.com/gazebosim/sdformat/pull/638
743 valueStr = lowercase(valueStr);
744
745 std::stringstream tmp;
746 if (valueStr == "true" || valueStr == "1")
747 tmp << "1";
748 else
749 tmp << "0";
750
751 tmp >> _value;
752 return true;
753 }
754
755 return success;
756 }
757
758 return true;
759 }
760
762 template<typename T>
763 bool Param::GetDefault(T &_value) const
764 {
765 sdf::Errors errors;
766 bool result = this>GetDefault<T>(_value, errors);
767 if (!errors.empty())
768 sdferr << errors;
769 return result;
770 }
771
773 template<typename T>
774 bool Param::GetDefault(T &_value, sdf::Errors &_errors) const
775 {
776 std::stringstream ss;
777
778 try
779 {
780 ss << ParamStreamer{this->dataPtr->defaultValue,
781 std::numeric_limits<int>::max()};
782 ss >> _value;
783 }
784 catch(...)
785 {
786 _errors.push_back({ErrorCode::PARAMETER_ERROR,
787 "Unable to convert parameter["
788 + this->dataPtr->key + "] "
789 + "whose type is["
790 + this->dataPtr->typeName + "], to "
791 + "type[" + typeid(T).name() + "]"});
792 return false;
793 }
794
795 return true;
796 }
797
799 template<typename Type>
800 bool Param::IsType() const
801 {
802 return std::holds_alternative<Type>(this->dataPtr->value);
803 }
804 }
805}
806
807#ifdef _WIN32
808#pragma warning(pop)
809#endif
810
811#endif
Definition: Param.hh:497
std::variant< bool, char, std::string, int, std::uint64_t, unsigned int, double, float, sdf::Time, gz::math::Angle, gz::math::Color, gz::math::Vector2i, gz::math::Vector2d, gz::math::Vector3d, gz::math::Quaterniond, gz::math::Pose3d > ParamVariant
Definition: Param.hh:532
void Init(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, sdf::Errors &_errors, const std::string &_description)
Initializer function to help Param constructors.
static std::string TypeToString()
Data type to string mapping.
Definition: Param.hh:621
bool set
True if the parameter is set.
Definition: Param.hh:505
bool required
True if the parameter is required.
Definition: Param.hh:502
bool GZ_SDFORMAT_VISIBLE ValueFromStringImpl(const std::string &_typeName, const std::string &_valueStr, ParamVariant &_valueToSet, sdf::Errors &_errors) const
Method used to set the Param from a passed-in string.
ParamVariant defaultValue
This parameter's default value.
Definition: Param.hh:549
ElementWeakPtr parentElement
Parent element.
Definition: Param.hh:514
std::function< std::any()> updateFunc
Update function pointer.
Definition: Param.hh:517
std::string defaultStrValue
This parameter's default value that was provided as a string.
Definition: Param.hh:546
std::string typeName
Definition: Param.hh:508
void Init(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_minValue, const std::string &_maxValue, sdf::Errors &_errors, const std::string &_description)
Initializer function to help Param constructors.
bool StringFromValueImpl(const PrintConfig &_config, const std::string &_typeName, const ParamVariant &_value, std::string &_valueStr, sdf::Errors &_errors) const
Method used to get the string representation from a ParamVariant, or the string that was used to set ...
bool ignoreParentAttributes
True if the value has been parsed while ignoring its parent element's attributes, and will continue t...
Definition: Param.hh:540
ParamVariant value
This parameter's value.
Definition: Param.hh:535
std::string key
Key value.
Definition: Param.hh:499
std::optional< ParamVariant > maxValue
This parameter's maximum allowed value.
Definition: Param.hh:555
std::optional< ParamVariant > minValue
This parameter's minimum allowed value.
Definition: Param.hh:552
std::optional< std::string > strValue
This parameter's value that was provided as a string.
Definition: Param.hh:543
std::string description
Description of the parameter.
Definition: Param.hh:511
A parameter class.
Definition: Param.hh:131
Param(Param &&_param) noexcept=default
Move constructor.
bool SetFromString(const std::string &_value, bool _ignoreParentAttributes)
Set the parameter value from a string.
ElementPtr GetParentElement() const
Get the parent Element of this Param.
Param & operator=(Param &&_param) noexcept=default
Move assignment operator.
std::string GetAsString(const PrintConfig &_config=PrintConfig()) const
Get the value as a string.
void SetDescription(const std::string &_desc)
Set the description of the parameter.
std::optional< std::string > GetMaxValueAsString(sdf::Errors &_errors, const PrintConfig &_config=PrintConfig()) const
Get the maximum allowed value as a string.
Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_minValue, const std::string &_maxValue, const std::string &_description="")
Constructor with min and max values.
void Update()
Set the parameter's value using the updateFunc.
Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_minValue, const std::string &_maxValue, sdf::Errors &_errors, const std::string &_description="")
Constructor with min and max values.
std::string GetAsString(sdf::Errors &_errors, const PrintConfig &_config=PrintConfig()) const
Get the value as a string.
bool Set(const T &_value)
Set the parameter's value.
Definition: Param.hh:669
bool Reparse(sdf::Errors &_errors)
Reparse the parameter value.
void SetUpdateFunc(T _updateFunc)
Set the update function.
Definition: Param.hh:662
std::string GetDefaultAsString(const PrintConfig &_config=PrintConfig()) const
Get the default value as a string.
bool SetFromString(const std::string &_value, bool _ignoreParentAttributes, sdf::Errors &_errors)
Set the parameter value from a string.
bool SetParentElement(ElementPtr _parentElement, sdf::Errors &_errors)
Set the parent Element of this Param.
ParamPtr Clone() const
Clone the parameter.
Param(const Param &_param)
Copy constructor Note that the updateFunc member does not get copied.
Param & operator=(const Param &_param)
Copy assignment operator Note that the updateFunc member will not get copied.
friend std::ostream & operator<<(std::ostream &_out, const Param &_p)
Ostream operator.
Definition: Param.hh:483
const std::string & GetTypeName() const
Get the type name value.
bool SetFromString(const std::string &_value, sdf::Errors &_errors)
Set the parameter value from a string.
bool GetAny(std::any &_anyVal, sdf::Errors &_errors) const
Get the value of the parameter as a std::any.
Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, const std::string &_description="")
Constructor.
std::optional< std::string > GetMinValueAsString(sdf::Errors &_errors, const PrintConfig &_config=PrintConfig()) const
Get the minimum allowed value as a string.
std::string GetDescription() const
Get the description of the parameter.
std::string GetDefaultAsString(sdf::Errors &_errors, const PrintConfig &_config=PrintConfig()) const
Get the default value as a string.
bool GetSet() const
Return true if the parameter has been set.
bool SetParentElement(ElementPtr _parentElement)
Set the parent Element of this Param.
Param(const std::string &_key, const std::string &_typeName, const std::string &_default, bool _required, sdf::Errors &_errors, const std::string &_description="")
Constructor.
void Update(sdf::Errors &_errors)
Set the parameter's value using the updateFunc.
std::optional< std::string > GetMinValueAsString(const PrintConfig &_config=PrintConfig()) const
Get the minimum allowed value as a string.
const std::string & GetKey() const
Get the key value.
bool ValidateValue() const
Validate the value against minimum and maximum allowed values.
bool Get(T &_value) const
Get the value of the parameter.
Definition: Param.hh:701
bool Reparse()
Reparse the parameter value.
bool IsType() const
Return true if the param is a particular type.
Definition: Param.hh:800
bool GetAny(std::any &_anyVal) const
Get the value of the parameter as a std::any.
bool IgnoresParentElementAttribute() const
Return true if the parameter ignores the parent element's attributes, or if the parameter has no pare...
void Reset()
Reset the parameter to the default value.
bool GetDefault(T &_value) const
Get the default value of the parameter.
Definition: Param.hh:763
std::optional< std::string > GetMaxValueAsString(const PrintConfig &_config=PrintConfig()) const
Get the maximum allowed value as a string.
bool GetRequired() const
Return whether the parameter is required.
bool SetFromString(const std::string &_value)
Set the parameter value from a string.
bool ValidateValue(sdf::Errors &_errors) const
Validate the value against minimum and maximum allowed values.
This class contains configuration options for printing elements.
Definition: PrintConfig.hh:33
A Time class, can be used to hold wall- or sim-time.
Definition: Types.hh:107
#define sdferr
Output an error message.
Definition: Console.hh:57
class GZ_SDFORMAT_VISIBLE Element
Definition: Element.hh:51
std::shared_ptr< Param > ParamPtr
Definition: Param.hh:70
std::vector< ParamPtr > Param_V
Definition: Param.hh:74
std::ostream & operator<<(std::ostream &os, ParamStreamer< T > s)
Definition: Param.hh:89
std::string GZ_SDFORMAT_VISIBLE lowercase(const std::string &_in)
Transforms a string to its lowercase equivalent.
@ PARAMETER_ERROR
Generic error type for parameters (values of SDFormat elements or attributes).
@ UNKNOWN_PARAMETER_TYPE
The specified parameter (values of SDFormat elements or attributes) type is unknown.
std::vector< Error > Errors
A vector of Error.
Definition: Types.hh:95
std::weak_ptr< Element > ElementWeakPtr
Definition: Element.hh:63
std::shared_ptr< Element > ElementPtr
Definition: Element.hh:55
namespace for Simulation Description Format parser
Definition: Actor.hh:35
Definition: Param.hh:81
const int precision
Definition: Param.hh:83
const T & val
Definition: Param.hh:82
ParamStreamer(const T &_val, int _precision=0)
Definition: Param.hh:84
#define SDFORMAT_VISIBLE
Use to represent "symbol visible" if supported.
Definition: system_util.hh:25