11#pragma once
22
3- #include < variant>
4-
53#include " ../SinricProRequest.h"
64#include " ../SinricProStrings.h"
75#include " ../EventLimiter.h"
@@ -14,9 +12,77 @@ FSTR(SETTING, id); // "id"
1412FSTR (SETTING , value); // "value"
1513
1614/* *
17- * @brief Variant type for setting values that can hold int, float, bool, or String
15+ * @brief C++11-compatible variant type for setting values that can hold int, float, bool, or String
16+ *
17+ * This is a lightweight alternative to std::variant (C++17) for Arduino boards.
1818 */
19- using SettingValue = std::variant<int , float , bool , String>;
19+ class SettingValue {
20+ public:
21+ enum class Type { INT , FLOAT , BOOL , STRING , NONE };
22+
23+ SettingValue () : type_(Type::NONE ), int_val(0 ) {}
24+ SettingValue (int val) : type_(Type::INT ), int_val(val) {}
25+ SettingValue (float val) : type_(Type::FLOAT ), float_val(val) {}
26+ SettingValue (bool val) : type_(Type::BOOL ), bool_val(val) {}
27+ SettingValue (const String& val) : type_(Type::STRING ), string_val(val) {}
28+ SettingValue (const char * val) : type_(Type::STRING ), string_val(val) {}
29+
30+ SettingValue (const SettingValue& other) : type_(other.type_) {
31+ switch (type_) {
32+ case Type::INT : int_val = other.int_val ; break ;
33+ case Type::FLOAT : float_val = other.float_val ; break ;
34+ case Type::BOOL : bool_val = other.bool_val ; break ;
35+ case Type::STRING : string_val = other.string_val ; break ;
36+ case Type::NONE : break ;
37+ }
38+ }
39+
40+ SettingValue& operator =(int val) { type_ = Type::INT ; int_val = val; return *this ; }
41+ SettingValue& operator =(float val) { type_ = Type::FLOAT ; float_val = val; return *this ; }
42+ SettingValue& operator =(bool val) { type_ = Type::BOOL ; bool_val = val; return *this ; }
43+ SettingValue& operator =(const String& val) { type_ = Type::STRING ; string_val = val; return *this ; }
44+ SettingValue& operator =(const char * val) { type_ = Type::STRING ; string_val = val; return *this ; }
45+
46+ SettingValue& operator =(const SettingValue& other) {
47+ if (this != &other) {
48+ type_ = other.type_ ;
49+ switch (type_) {
50+ case Type::INT : int_val = other.int_val ; break ;
51+ case Type::FLOAT : float_val = other.float_val ; break ;
52+ case Type::BOOL : bool_val = other.bool_val ; break ;
53+ case Type::STRING : string_val = other.string_val ; break ;
54+ case Type::NONE : break ;
55+ }
56+ }
57+ return *this ;
58+ }
59+
60+ template <typename T> bool holds () const ;
61+ template <typename T> T get () const ;
62+
63+ Type type () const { return type_; }
64+
65+ private:
66+ Type type_;
67+ union {
68+ int int_val;
69+ float float_val;
70+ bool bool_val;
71+ };
72+ String string_val; // Can't be in union
73+ };
74+
75+ // Template specializations for holds()
76+ template <> inline bool SettingValue::holds<int >() const { return type_ == Type::INT ; }
77+ template <> inline bool SettingValue::holds<float >() const { return type_ == Type::FLOAT ; }
78+ template <> inline bool SettingValue::holds<bool >() const { return type_ == Type::BOOL ; }
79+ template <> inline bool SettingValue::holds<String>() const { return type_ == Type::STRING ; }
80+
81+ // Template specializations for get()
82+ template <> inline int SettingValue::get<int >() const { return int_val; }
83+ template <> inline float SettingValue::get<float >() const { return float_val; }
84+ template <> inline bool SettingValue::get<bool >() const { return bool_val; }
85+ template <> inline String SettingValue::get<String>() const { return string_val; }
2086
2187using SetSettingCallback = std::function<bool (const String&, const String&, SettingValue&)>;
2288
@@ -67,14 +133,14 @@ bool SettingController<T>::sendSettingEvent(String settingId, SettingValue setti
67133 eventMessage[FSTR_SINRICPRO_scope] = FSTR_SINRICPRO_device;
68134 event_value[FSTR_SETTING_id] = settingId;
69135
70- if (std::holds_alternative <int >(settingValue )) {
71- event_value[FSTR_SETTING_value] = std:: get<int >(settingValue );
72- } else if (std::holds_alternative <float >(settingValue )) {
73- event_value[FSTR_SETTING_value] = std:: get<float >(settingValue );
74- } else if (std::holds_alternative <bool >(settingValue )) {
75- event_value[FSTR_SETTING_value] = std:: get<bool >(settingValue );
76- } else if (std::holds_alternative <String>(settingValue )) {
77- event_value[FSTR_SETTING_value] = std:: get<String>(settingValue );
136+ if (settingValue. holds <int >()) {
137+ event_value[FSTR_SETTING_value] = settingValue. get <int >();
138+ } else if (settingValue. holds <float >()) {
139+ event_value[FSTR_SETTING_value] = settingValue. get <float >();
140+ } else if (settingValue. holds <bool >()) {
141+ event_value[FSTR_SETTING_value] = settingValue. get <bool >();
142+ } else if (settingValue. holds <String>()) {
143+ event_value[FSTR_SETTING_value] = settingValue. get <String>();
78144 }
79145
80146 return device->sendEvent (eventMessage);
@@ -112,14 +178,14 @@ bool SettingController<T>::handleSettingController(SinricProRequest &request) {
112178
113179 if (valueVariant.is <JsonObject>()) {
114180 request.response_value [FSTR_SETTING_value] = valueVariant;
115- } else if (std::holds_alternative <int >(settingValue )) {
116- request.response_value [FSTR_SETTING_value] = std:: get<int >(settingValue );
117- } else if (std::holds_alternative <float >(settingValue )) {
118- request.response_value [FSTR_SETTING_value] = std:: get<float >(settingValue );
119- } else if (std::holds_alternative <bool >(settingValue )) {
120- request.response_value [FSTR_SETTING_value] = std:: get<bool >(settingValue );
121- } else if (std::holds_alternative <String>(settingValue )) {
122- request.response_value [FSTR_SETTING_value] = std:: get<String>(settingValue );
181+ } else if (settingValue. holds <int >()) {
182+ request.response_value [FSTR_SETTING_value] = settingValue. get <int >();
183+ } else if (settingValue. holds <float >()) {
184+ request.response_value [FSTR_SETTING_value] = settingValue. get <float >();
185+ } else if (settingValue. holds <bool >()) {
186+ request.response_value [FSTR_SETTING_value] = settingValue. get <bool >();
187+ } else if (settingValue. holds <String>()) {
188+ request.response_value [FSTR_SETTING_value] = settingValue. get <String>();
123189 }
124190
125191 return success;
0 commit comments