mirror of
https://github.com/esphome/esphome.git
synced 2026-09-17 18:18:43 +00:00
Replace custom esphome::optional with std::optional
The custom optional implementation (from optional-bare, 2017) predates C++17. All ESPHome platforms now compile with gnu++20, making std::optional available everywhere. The custom implementation had several issues: - No emplace() support - Always default-constructs value_ (wasteful for non-trivial types) - reset() only flips a bool without destroying the value - No move semantics - Requires T to be default constructible Replace with using aliases (using std::optional, using std::nullopt, etc.) so all existing code using esphome::optional continues to work. Also fix ~30 unsafe .value() calls across climate IR components that relied on the custom optional's behavior of returning a default-constructed value when empty. With std::optional, accessing an empty optional is UB. These are replaced with value_or() using appropriate defaults (CLIMATE_FAN_AUTO, CLIMATE_PRESET_NONE).
This commit is contained in:
@@ -47,7 +47,7 @@ void BalluClimate::transmit_state() {
|
||||
remote_state[11] = 0x1e;
|
||||
|
||||
// Fan speed
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_HIGH:
|
||||
remote_state[4] |= BALLU_FAN_HIGH;
|
||||
break;
|
||||
|
||||
@@ -79,7 +79,7 @@ void LgIrClimate::transmit_state() {
|
||||
if (this->mode == climate::CLIMATE_MODE_OFF) {
|
||||
remote_state |= FAN_AUTO;
|
||||
} else {
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_HIGH:
|
||||
remote_state |= FAN_MAX;
|
||||
break;
|
||||
|
||||
@@ -83,7 +83,7 @@ void CoolixClimate::transmit_state() {
|
||||
this->fan_mode = climate::CLIMATE_FAN_AUTO;
|
||||
remote_state |= COOLIX_FAN_MODE_AUTO_DRY;
|
||||
} else {
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_HIGH:
|
||||
remote_state |= COOLIX_FAN_MAX;
|
||||
break;
|
||||
|
||||
@@ -94,7 +94,7 @@ uint8_t DaikinClimate::operation_mode_() const {
|
||||
|
||||
uint16_t DaikinClimate::fan_speed_() const {
|
||||
uint16_t fan_speed;
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_QUIET:
|
||||
fan_speed = DAIKIN_FAN_SILENT << 8;
|
||||
break;
|
||||
|
||||
@@ -176,7 +176,7 @@ uint8_t DaikinArcClimate::operation_mode_() {
|
||||
|
||||
uint16_t DaikinArcClimate::fan_speed_() {
|
||||
uint16_t fan_speed;
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
fan_speed = DAIKIN_FAN_1 << 8;
|
||||
break;
|
||||
|
||||
@@ -111,7 +111,7 @@ uint8_t DaikinBrcClimate::operation_mode_() {
|
||||
|
||||
uint8_t DaikinBrcClimate::fan_speed_swing_() {
|
||||
uint16_t fan_speed;
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
fan_speed = DAIKIN_BRC_FAN_1;
|
||||
break;
|
||||
|
||||
@@ -64,7 +64,7 @@ uint8_t DelonghiClimate::operation_mode_() {
|
||||
|
||||
uint16_t DelonghiClimate::fan_speed_() {
|
||||
uint16_t fan_speed;
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
fan_speed = DELONGHI_FAN_LOW;
|
||||
break;
|
||||
|
||||
@@ -28,7 +28,7 @@ uint8_t EmmetiClimate::set_mode_() {
|
||||
}
|
||||
|
||||
uint8_t EmmetiClimate::set_fan_speed_() {
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
return EMMETI_FAN_1;
|
||||
case climate::CLIMATE_FAN_MEDIUM:
|
||||
|
||||
@@ -141,7 +141,7 @@ void FujitsuGeneralClimate::transmit_state() {
|
||||
}
|
||||
|
||||
// Set fan
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_HIGH:
|
||||
SET_NIBBLE(remote_state, FUJITSU_GENERAL_FAN_NIBBLE, FUJITSU_GENERAL_FAN_HIGH);
|
||||
break;
|
||||
|
||||
@@ -180,7 +180,7 @@ uint8_t GreeClimate::operation_mode_() {
|
||||
uint8_t GreeClimate::fan_speed_() {
|
||||
// YX1FF has 4 fan speeds -- we treat low as quiet and turbo as high
|
||||
if (this->model_ == GREE_YX1FF) {
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_QUIET:
|
||||
return GREE_FAN_1;
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
@@ -195,7 +195,7 @@ uint8_t GreeClimate::fan_speed_() {
|
||||
}
|
||||
}
|
||||
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
return GREE_FAN_1;
|
||||
case climate::CLIMATE_FAN_MEDIUM:
|
||||
@@ -235,7 +235,7 @@ uint8_t GreeClimate::temperature_() {
|
||||
uint8_t GreeClimate::preset_() {
|
||||
// YX1FF has sleep preset
|
||||
if (this->model_ == GREE_YX1FF) {
|
||||
switch (this->preset.value()) {
|
||||
switch (this->preset.value_or(climate::CLIMATE_PRESET_NONE)) {
|
||||
case climate::CLIMATE_PRESET_NONE:
|
||||
return GREE_PRESET_NONE;
|
||||
case climate::CLIMATE_PRESET_SLEEP:
|
||||
|
||||
@@ -893,7 +893,8 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
|
||||
} else {
|
||||
this->preset = CLIMATE_PRESET_NONE;
|
||||
}
|
||||
should_publish = should_publish || (!old_preset.has_value()) || (old_preset.value() != this->preset.value());
|
||||
should_publish = should_publish || (!old_preset.has_value()) ||
|
||||
(old_preset.value_or(CLIMATE_PRESET_NONE) != this->preset.value_or(CLIMATE_PRESET_NONE));
|
||||
}
|
||||
{
|
||||
// Target temperature
|
||||
@@ -936,7 +937,8 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
|
||||
this->fan_mode = CLIMATE_FAN_HIGH;
|
||||
break;
|
||||
}
|
||||
should_publish = should_publish || (!old_fan_mode.has_value()) || (old_fan_mode.value() != fan_mode.value());
|
||||
should_publish = should_publish || (!old_fan_mode.has_value()) ||
|
||||
(old_fan_mode.value_or(CLIMATE_FAN_AUTO) != fan_mode.value_or(CLIMATE_FAN_AUTO));
|
||||
}
|
||||
// Display status
|
||||
// should be before "Climate mode" because it is changing this->mode
|
||||
|
||||
@@ -402,7 +402,8 @@ haier_protocol::HandlerError Smartair2Climate::process_status_message_(const uin
|
||||
} else {
|
||||
this->preset = CLIMATE_PRESET_NONE;
|
||||
}
|
||||
should_publish = should_publish || (!old_preset.has_value()) || (old_preset.value() != this->preset.value());
|
||||
should_publish = should_publish || (!old_preset.has_value()) ||
|
||||
(old_preset.value_or(CLIMATE_PRESET_NONE) != this->preset.value_or(CLIMATE_PRESET_NONE));
|
||||
}
|
||||
{
|
||||
// Target temperature
|
||||
@@ -446,7 +447,8 @@ haier_protocol::HandlerError Smartair2Climate::process_status_message_(const uin
|
||||
this->fan_mode = CLIMATE_FAN_HIGH;
|
||||
break;
|
||||
}
|
||||
should_publish = should_publish || (!old_fan_mode.has_value()) || (old_fan_mode.value() != fan_mode.value());
|
||||
should_publish = should_publish || (!old_fan_mode.has_value()) ||
|
||||
(old_fan_mode.value_or(CLIMATE_FAN_AUTO) != fan_mode.value_or(CLIMATE_FAN_AUTO));
|
||||
}
|
||||
// Display status
|
||||
// should be before "Climate mode" because it is changing this->mode
|
||||
|
||||
@@ -175,7 +175,7 @@ void HitachiClimate::transmit_state() {
|
||||
|
||||
set_temp_(static_cast<uint8_t>(this->target_temperature));
|
||||
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
set_fan_(HITACHI_AC344_FAN_LOW);
|
||||
break;
|
||||
|
||||
@@ -176,7 +176,7 @@ void HitachiClimate::transmit_state() {
|
||||
|
||||
set_temp_(static_cast<uint8_t>(this->target_temperature));
|
||||
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
set_fan_(HITACHI_AC424_FAN_LOW);
|
||||
break;
|
||||
|
||||
@@ -180,7 +180,7 @@ void MitsubishiClimate::transmit_state() {
|
||||
// For 5Level: Low = 1, Middle = 2, Medium = 3, High = 4
|
||||
// For 4Level + Quiet: Low = 1, Middle = 2, Medium = 3, High = 4, Quiet = 5
|
||||
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
remote_state[9] = 1;
|
||||
break;
|
||||
@@ -209,7 +209,8 @@ void MitsubishiClimate::transmit_state() {
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "fan: %02x state: %02x", this->fan_mode.value(), remote_state[9]);
|
||||
ESP_LOGD(TAG, "fan: %02x state: %02x", static_cast<uint8_t>(this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)),
|
||||
remote_state[9]);
|
||||
|
||||
// Vertical Vane
|
||||
switch (this->swing_mode) {
|
||||
@@ -227,7 +228,7 @@ void MitsubishiClimate::transmit_state() {
|
||||
ESP_LOGD(TAG, "default_vertical_direction_: %02X", this->default_vertical_direction_);
|
||||
|
||||
// Special modes
|
||||
switch (this->preset.value()) {
|
||||
switch (this->preset.value_or(climate::CLIMATE_PRESET_NONE)) {
|
||||
case climate::CLIMATE_PRESET_ECO:
|
||||
remote_state[6] = MITSUBISHI_MODE_COOL | MITSUBISHI_OTHERWISE;
|
||||
remote_state[8] = (remote_state[8] & ~7) | MITSUBISHI_MODE_A_COOL;
|
||||
|
||||
@@ -71,7 +71,7 @@ void NoblexClimate::transmit_state() {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_LOW << 2);
|
||||
break;
|
||||
|
||||
@@ -89,7 +89,7 @@ void Tcl112Climate::transmit_state() {
|
||||
|
||||
// Set fan
|
||||
uint8_t selected_fan;
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_HIGH:
|
||||
selected_fan = TCL112_FAN_HIGH;
|
||||
break;
|
||||
|
||||
@@ -84,7 +84,7 @@ void ThermostatClimate::refresh() {
|
||||
this->switch_to_mode_(this->mode, false);
|
||||
this->switch_to_action_(this->compute_action_(), false);
|
||||
this->switch_to_supplemental_action_(this->compute_supplemental_action_());
|
||||
this->switch_to_fan_mode_(this->fan_mode.value(), false);
|
||||
this->switch_to_fan_mode_(this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO), false);
|
||||
this->switch_to_swing_mode_(this->swing_mode, false);
|
||||
this->switch_to_humidity_control_action_(this->compute_humidity_control_action_());
|
||||
this->check_humidity_change_trigger_();
|
||||
|
||||
@@ -502,7 +502,7 @@ void ToshibaClimate::transmit_generic_() {
|
||||
}
|
||||
|
||||
uint8_t fan;
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_QUIET:
|
||||
fan = TOSHIBA_FAN_SPEED_QUIET;
|
||||
break;
|
||||
@@ -567,7 +567,7 @@ void ToshibaClimate::transmit_rac_pt1411hwru_() {
|
||||
message[2] = RAC_PT1411HWRU_NO_FAN.code1;
|
||||
message[7] = RAC_PT1411HWRU_NO_FAN.code2;
|
||||
} else {
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
message[2] = RAC_PT1411HWRU_FAN_LOW.code1;
|
||||
message[7] = RAC_PT1411HWRU_FAN_LOW.code2;
|
||||
@@ -811,12 +811,12 @@ void ToshibaClimate::transmit_ras_2819t_() {
|
||||
uint8_t temp_code = get_ras_2819t_temp_code(temperature);
|
||||
|
||||
// Get fan speed encoding for rc_code_1
|
||||
climate::ClimateFanMode effective_fan_mode = this->fan_mode.value();
|
||||
climate::ClimateFanMode effective_fan_mode = this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO);
|
||||
|
||||
// Dry mode only supports AUTO fan speed
|
||||
if (this->mode == climate::CLIMATE_MODE_DRY) {
|
||||
effective_fan_mode = climate::CLIMATE_FAN_AUTO;
|
||||
if (this->fan_mode.value() != climate::CLIMATE_FAN_AUTO) {
|
||||
if (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO) != climate::CLIMATE_FAN_AUTO) {
|
||||
ESP_LOGW(TAG, "Dry mode only supports AUTO fan speed, forcing AUTO");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ void WhirlpoolClimate::transmit_state() {
|
||||
remote_state[3] |= (uint8_t) (temp - this->temperature_min_()) << 4;
|
||||
|
||||
// Fan speed
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_HIGH:
|
||||
remote_state[2] |= WHIRLPOOL_FAN_HIGH;
|
||||
break;
|
||||
|
||||
@@ -69,7 +69,7 @@ void Whynter::transmit_state() {
|
||||
}
|
||||
mode_before_ = this->mode;
|
||||
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
remote_state |= FAN_LOW;
|
||||
break;
|
||||
|
||||
@@ -13,7 +13,7 @@ void ZHLT01Climate::transmit_state() {
|
||||
ir_message[1] = 0x00; // Timer off
|
||||
|
||||
// Byte 3 : Turbo mode
|
||||
if (this->preset.value() == climate::CLIMATE_PRESET_BOOST) {
|
||||
if (this->preset.value_or(climate::CLIMATE_PRESET_NONE) == climate::CLIMATE_PRESET_BOOST) {
|
||||
ir_message[3] = AC1_FAN_TURBO;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ void ZHLT01Climate::transmit_state() {
|
||||
}
|
||||
|
||||
// -- Fan
|
||||
switch (this->preset.value()) {
|
||||
switch (this->preset.value_or(climate::CLIMATE_PRESET_NONE)) {
|
||||
case climate::CLIMATE_PRESET_BOOST:
|
||||
ir_message[7] |= AC1_FAN3;
|
||||
break;
|
||||
@@ -55,7 +55,7 @@ void ZHLT01Climate::transmit_state() {
|
||||
ir_message[7] |= AC1_FAN_SILENT;
|
||||
break;
|
||||
default:
|
||||
switch (this->fan_mode.value()) {
|
||||
switch (this->fan_mode.value_or(climate::CLIMATE_FAN_AUTO)) {
|
||||
case climate::CLIMATE_FAN_LOW:
|
||||
ir_message[7] |= AC1_FAN1;
|
||||
break;
|
||||
|
||||
+5
-213
@@ -1,220 +1,12 @@
|
||||
#pragma once
|
||||
//
|
||||
// Copyright (c) 2017 Martin Moene
|
||||
//
|
||||
// https://github.com/martinmoene/optional-bare
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// Modified by Otto Winter on 18.05.18
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
// type for nullopt
|
||||
|
||||
struct nullopt_t { // NOLINT
|
||||
struct init {}; // NOLINT
|
||||
nullopt_t(init /*unused*/) {}
|
||||
};
|
||||
|
||||
// extra parenthesis to prevent the most vexing parse:
|
||||
|
||||
const nullopt_t nullopt((nullopt_t::init())); // NOLINT
|
||||
|
||||
// Simplistic optional: requires T to be default constructible, copyable.
|
||||
|
||||
template<typename T> class optional { // NOLINT
|
||||
private:
|
||||
using safe_bool = void (optional::*)() const;
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
optional() {}
|
||||
|
||||
optional(nullopt_t /*unused*/) {}
|
||||
|
||||
optional(T const &arg) : has_value_(true), value_(arg) {} // NOLINT
|
||||
|
||||
template<class U> optional(optional<U> const &other) : has_value_(other.has_value()), value_(other.value()) {}
|
||||
|
||||
optional &operator=(nullopt_t /*unused*/) {
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
bool operator==(optional<T> const &rhs) const {
|
||||
if (has_value() && rhs.has_value())
|
||||
return value() == rhs.value();
|
||||
return !has_value() && !rhs.has_value();
|
||||
}
|
||||
|
||||
template<class U> optional &operator=(optional<U> const &other) {
|
||||
has_value_ = other.has_value();
|
||||
value_ = other.value();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(optional &rhs) noexcept {
|
||||
using std::swap;
|
||||
if (has_value() && rhs.has_value()) {
|
||||
swap(**this, *rhs);
|
||||
} else if (!has_value() && rhs.has_value()) {
|
||||
initialize(*rhs);
|
||||
rhs.reset();
|
||||
} else if (has_value() && !rhs.has_value()) {
|
||||
rhs.initialize(**this);
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
// observers
|
||||
|
||||
value_type const *operator->() const { return &value_; }
|
||||
|
||||
value_type *operator->() { return &value_; }
|
||||
|
||||
value_type const &operator*() const { return value_; }
|
||||
|
||||
value_type &operator*() { return value_; }
|
||||
|
||||
operator safe_bool() const { return has_value() ? &optional::this_type_does_not_support_comparisons : nullptr; }
|
||||
|
||||
bool has_value() const { return has_value_; }
|
||||
|
||||
value_type const &value() const { return value_; }
|
||||
|
||||
value_type &value() { return value_; }
|
||||
|
||||
template<class U> value_type value_or(U const &v) const { return has_value() ? value() : static_cast<value_type>(v); }
|
||||
|
||||
// modifiers
|
||||
|
||||
void reset() { has_value_ = false; }
|
||||
|
||||
private:
|
||||
void this_type_does_not_support_comparisons() const {} // NOLINT
|
||||
|
||||
template<typename V> void initialize(V const &value) { // NOLINT
|
||||
value_ = value;
|
||||
has_value_ = true;
|
||||
}
|
||||
|
||||
bool has_value_{false}; // NOLINT
|
||||
value_type value_; // NOLINT
|
||||
};
|
||||
|
||||
// Relational operators
|
||||
|
||||
template<typename T, typename U> inline bool operator==(optional<T> const &x, optional<U> const &y) {
|
||||
return bool(x) != bool(y) ? false : !bool(x) ? true : *x == *y;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator!=(optional<T> const &x, optional<U> const &y) {
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator<(optional<T> const &x, optional<U> const &y) {
|
||||
return (!y) ? false : (!x) ? true : *x < *y;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator>(optional<T> const &x, optional<U> const &y) { return (y < x); }
|
||||
|
||||
template<typename T, typename U> inline bool operator<=(optional<T> const &x, optional<U> const &y) { return !(y < x); }
|
||||
|
||||
template<typename T, typename U> inline bool operator>=(optional<T> const &x, optional<U> const &y) { return !(x < y); }
|
||||
|
||||
// Comparison with nullopt
|
||||
|
||||
template<typename T> inline bool operator==(optional<T> const &x, nullopt_t /*unused*/) { return (!x); }
|
||||
|
||||
template<typename T> inline bool operator==(nullopt_t /*unused*/, optional<T> const &x) { return (!x); }
|
||||
|
||||
template<typename T> inline bool operator!=(optional<T> const &x, nullopt_t /*unused*/) { return bool(x); }
|
||||
|
||||
template<typename T> inline bool operator!=(nullopt_t /*unused*/, optional<T> const &x) { return bool(x); }
|
||||
|
||||
template<typename T> inline bool operator<(optional<T> const & /*unused*/, nullopt_t /*unused*/) { return false; }
|
||||
|
||||
template<typename T> inline bool operator<(nullopt_t /*unused*/, optional<T> const &x) { return bool(x); }
|
||||
|
||||
template<typename T> inline bool operator<=(optional<T> const &x, nullopt_t /*unused*/) { return (!x); }
|
||||
|
||||
template<typename T> inline bool operator<=(nullopt_t /*unused*/, optional<T> const & /*unused*/) { return true; }
|
||||
|
||||
template<typename T> inline bool operator>(optional<T> const &x, nullopt_t /*unused*/) { return bool(x); }
|
||||
|
||||
template<typename T> inline bool operator>(nullopt_t /*unused*/, optional<T> const & /*unused*/) { return false; }
|
||||
|
||||
template<typename T> inline bool operator>=(optional<T> const & /*unused*/, nullopt_t /*unused*/) { return true; }
|
||||
|
||||
template<typename T> inline bool operator>=(nullopt_t /*unused*/, optional<T> const &x) { return (!x); }
|
||||
|
||||
// Comparison with T
|
||||
|
||||
template<typename T, typename U> inline bool operator==(optional<T> const &x, U const &v) {
|
||||
return bool(x) ? *x == v : false;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator==(U const &v, optional<T> const &x) {
|
||||
return bool(x) ? v == *x : false;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator!=(optional<T> const &x, U const &v) {
|
||||
return bool(x) ? *x != v : true;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator!=(U const &v, optional<T> const &x) {
|
||||
return bool(x) ? v != *x : true;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator<(optional<T> const &x, U const &v) {
|
||||
return bool(x) ? *x < v : true;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator<(U const &v, optional<T> const &x) {
|
||||
return bool(x) ? v < *x : false;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator<=(optional<T> const &x, U const &v) {
|
||||
return bool(x) ? *x <= v : true;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator<=(U const &v, optional<T> const &x) {
|
||||
return bool(x) ? v <= *x : false;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator>(optional<T> const &x, U const &v) {
|
||||
return bool(x) ? *x > v : false;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator>(U const &v, optional<T> const &x) {
|
||||
return bool(x) ? v > *x : true;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator>=(optional<T> const &x, U const &v) {
|
||||
return bool(x) ? *x >= v : false;
|
||||
}
|
||||
|
||||
template<typename T, typename U> inline bool operator>=(U const &v, optional<T> const &x) {
|
||||
return bool(x) ? v >= *x : true;
|
||||
}
|
||||
|
||||
// Specialized algorithms
|
||||
|
||||
template<typename T> void swap(optional<T> &x, optional<T> &y) noexcept { x.swap(y); }
|
||||
|
||||
// Convenience function to create an optional.
|
||||
|
||||
template<typename T> inline optional<T> make_optional(T const &v) { return optional<T>(v); }
|
||||
using std::make_optional;
|
||||
using std::nullopt;
|
||||
using std::nullopt_t;
|
||||
using std::optional;
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
@@ -31,9 +31,7 @@ Component = esphome_ns.class_("Component")
|
||||
ComponentPtr = Component.operator("ptr")
|
||||
PollingComponent = esphome_ns.class_("PollingComponent", Component)
|
||||
Application = esphome_ns.class_("Application")
|
||||
# Create optional with explicit namespace to avoid ambiguity with std::optional
|
||||
# The generated code will use esphome::optional instead of just optional
|
||||
optional = global_ns.namespace("esphome").class_("optional")
|
||||
optional = global_ns.namespace("std").class_("optional")
|
||||
arduino_json_ns = global_ns.namespace("ArduinoJson")
|
||||
JsonObject = arduino_json_ns.class_("JsonObject")
|
||||
JsonObjectConst = arduino_json_ns.class_("JsonObjectConst")
|
||||
|
||||
Reference in New Issue
Block a user