diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 27df14d95d..2e6a978012 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -255,7 +255,7 @@ uint32_t fnv1_hash(const std::string &str); /// @name STL backports ///@{ -// std::to_string() from C++11, available from libstdc++/g++ 8+ +// std::to_string() from C++11, available from libstdc++/g++ 8 // See https://github.com/espressif/esp-idf/issues/1445 #if _GLIBCXX_RELEASE >= 8 using std::to_string; @@ -271,6 +271,32 @@ inline std::string to_string(double value) { return str_snprintf("%f", 32, value inline std::string to_string(long double value) { return str_snprintf("%Lf", 32, value); } #endif +// std::is_trivially_copyable from C++11, implemented in libstdc++/g++ 5.1 (but minor releases can't be detected) +#if _GLIBCXX_RELEASE >= 6 +using std::is_trivially_copyable; +#else +// Implementing this is impossible without compiler intrinsics, so don't bother. Invalid usage will be detected on +// other variants that use a newer compiler anyway. +// NOLINTNEXTLINE(readability-identifier-naming) +template struct is_trivially_copyable : public std::integral_constant {}; +#endif + +// std::bit_cast from C++20 +#if __cpp_lib_bit_cast >= 201806 +using std::bit_cast; +#else +/// Convert data between types, without aliasing issues or undefined behaviour. +template< + typename To, typename From, + enable_if_t::value && is_trivially_copyable::value, + int> = 0> +To bit_cast(const From &src) { + To dst; + memcpy(&dst, &src, sizeof(To)); + return dst; +} +#endif + // std::byteswap is from C++23 and technically should be a template, but this will do for now. constexpr uint8_t byteswap(uint8_t n) { return n; } constexpr uint16_t byteswap(uint16_t n) { return __builtin_bswap16(n); } diff --git a/esphome/core/preferences.h b/esphome/core/preferences.h index ad45cd9684..2b13061a59 100644 --- a/esphome/core/preferences.h +++ b/esphome/core/preferences.h @@ -2,7 +2,8 @@ #include #include -#include + +#include "esphome/core/helpers.h" namespace esphome { @@ -45,20 +46,12 @@ class ESPPreferences { */ virtual bool sync() = 0; -#ifndef USE_ESP8266 - template::value, bool>::type = true> -#else - // esp8266 toolchain doesn't have is_trivially_copyable - template -#endif + template::value, bool> = true> ESPPreferenceObject make_preference(uint32_t type, bool in_flash) { return this->make_preference(sizeof(T), type, in_flash); } -#ifndef USE_ESP8266 - template::value, bool>::type = true> -#else - template -#endif + + template::value, bool> = true> ESPPreferenceObject make_preference(uint32_t type) { return this->make_preference(sizeof(T), type); }