diff --git a/components/ratgdo/common.h b/components/ratgdo/common.h index 4b6a076..c010a29 100644 --- a/components/ratgdo/common.h +++ b/components/ratgdo/common.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include "macros.h" #include "observable.h" #define ESP_LOG1 ESP_LOGD @@ -25,86 +26,25 @@ struct ClearPairedDevices { PairedDevice kind; }; // a poor man's sum-type, because C++ -class Args { -public: - union { - SetRollingCodeCounter set_rolling_code_counter; - GetRollingCodeCounter get_rolling_code_counter; - SetClientID set_client_id; - QueryStatus query_status; - QueryOpenings query_openings; - ActivateLearn activate_learn; - InactivateLearn inactivate_learn; - QueryPairedDevices query_paired_devices; - QueryPairedDevicesAll query_paired_devices_all; - ClearPairedDevices clear_paired_devices; - } value; - - enum class Tag { - set_rolling_code_counter, - get_rolling_code_counter, - set_client_id, - query_status, - query_openings, - activate_learn, - inactivate_learn, - query_paired_devices, - query_paired_devices_all, - clear_paired_devices, - } tag; - - Args(GetRollingCodeCounter&& arg): tag(Tag::get_rolling_code_counter) { - value.get_rolling_code_counter = std::move(arg); - } - Args(SetRollingCodeCounter&& arg): tag(Tag::set_rolling_code_counter) { - value.set_rolling_code_counter = std::move(arg); - } - Args(SetClientID&& arg): tag(Tag::set_client_id) { - value.set_client_id = std::move(arg); - } - Args(QueryStatus&& arg): tag(Tag::query_status) { - value.query_status = std::move(arg); - } - Args(QueryOpenings&& arg): tag(Tag::query_openings) { - value.query_openings = std::move(arg); - } - Args(ActivateLearn&& arg): tag(Tag::activate_learn) { - value.activate_learn = std::move(arg); - } - Args(InactivateLearn&& arg): tag(Tag::inactivate_learn) { - value.inactivate_learn = std::move(arg); - } - Args(QueryPairedDevices&& arg): tag(Tag::query_paired_devices) { - value.query_paired_devices = std::move(arg); - } - Args(QueryPairedDevicesAll&& arg): tag(Tag::query_paired_devices_all) { - value.query_paired_devices_all = std::move(arg); - } - Args(ClearPairedDevices&& arg): tag(Tag::clear_paired_devices) { - value.clear_paired_devices = std::move(arg); - } -}; +SUM_TYPE(Args, + (SetRollingCodeCounter, set_rolling_code_counter), + (GetRollingCodeCounter, get_rolling_code_counter), + (SetClientID, set_client_id), + (QueryStatus, query_status), + (QueryOpenings, query_openings), + (ActivateLearn, activate_learn), + (InactivateLearn, inactivate_learn), + (QueryPairedDevices, query_paired_devices), + (QueryPairedDevicesAll, query_paired_devices_all), + (ClearPairedDevices, clear_paired_devices), +) struct RollingCodeCounter { observable* value; }; -class Result { -public: - union { - RollingCodeCounter rolling_code_counter; - } value; - - enum class Tag { - rolling_code_counter, - void_, - } tag; - - Result(): tag(Tag::void_) { - } - Result(RollingCodeCounter&& arg): tag(Tag::rolling_code_counter) { - value.rolling_code_counter = std::move(arg); - } -}; +SUM_TYPE(Result, + (RollingCodeCounter, rolling_code_counter), +) } // namespace protocol } // namespace ratgdo diff --git a/components/ratgdo/enum.h b/components/ratgdo/macros.h similarity index 59% rename from components/ratgdo/enum.h rename to components/ratgdo/macros.h index db090af..81e2e45 100644 --- a/components/ratgdo/enum.h +++ b/components/ratgdo/macros.h @@ -55,3 +55,35 @@ return _unknown; \ } \ } + +#define SUM_TYPE_UNION_MEMBER0(type, var) type var; +#define SUM_TYPE_UNION_MEMBER(name, tuple) SUM_TYPE_UNION_MEMBER0 tuple + +#define SUM_TYPE_ENUM_MEMBER0(type, var) var, +#define SUM_TYPE_ENUM_MEMBER(name, tuple) SUM_TYPE_ENUM_MEMBER0 tuple + +#define SUM_TYPE_CONSTRUCTOR0(name, type, val) \ + name(type&& arg) \ + : tag(Tag::val) \ + { \ + value.val = std::move(arg); \ + } +#define SUM_TYPE_CONSTRUCTOR(name, tuple) SUM_TYPE_CONSTRUCTOR0 LPAREN name, TUPLE tuple) + +#define SUM_TYPE(name, ...) \ + class name { \ + public: \ + union { \ + FOR_EACH(SUM_TYPE_UNION_MEMBER, name, __VA_ARGS__) \ + } value; \ + enum class Tag { \ + void_, \ + FOR_EACH(SUM_TYPE_ENUM_MEMBER, name, __VA_ARGS__) \ + } tag; \ + \ + name() \ + : tag(Tag::void_) \ + { \ + } \ + FOR_EACH(SUM_TYPE_CONSTRUCTOR, name, __VA_ARGS__) \ + }; diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index 896fbaf..7afb818 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -19,7 +19,7 @@ #include "observable.h" #include "callbacks.h" -#include "enum.h" +#include "macros.h" #include "ratgdo_state.h" #include "protocol.h" diff --git a/components/ratgdo/ratgdo_state.h b/components/ratgdo/ratgdo_state.h index 6fac999..51b9109 100644 --- a/components/ratgdo/ratgdo_state.h +++ b/components/ratgdo/ratgdo_state.h @@ -12,7 +12,7 @@ ************************************/ #pragma once -#include "enum.h" +#include "macros.h" #include namespace esphome {