mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Introduce bit_cast() backport (#2991)
This commit is contained in:
		| @@ -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<typename T> struct is_trivially_copyable : public std::integral_constant<bool, true> {}; | ||||
| #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<sizeof(To) == sizeof(From) && is_trivially_copyable<From>::value && is_trivially_copyable<To>::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); } | ||||
|   | ||||
| @@ -2,7 +2,8 @@ | ||||
|  | ||||
| #include <cstring> | ||||
| #include <cstdint> | ||||
| #include <type_traits> | ||||
|  | ||||
| #include "esphome/core/helpers.h" | ||||
|  | ||||
| namespace esphome { | ||||
|  | ||||
| @@ -45,20 +46,12 @@ class ESPPreferences { | ||||
|    */ | ||||
|   virtual bool sync() = 0; | ||||
|  | ||||
| #ifndef USE_ESP8266 | ||||
|   template<typename T, typename std::enable_if<std::is_trivially_copyable<T>::value, bool>::type = true> | ||||
| #else | ||||
|   // esp8266 toolchain doesn't have is_trivially_copyable | ||||
|   template<typename T> | ||||
| #endif | ||||
|   template<typename T, enable_if_t<is_trivially_copyable<T>::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<typename T, typename std::enable_if<std::is_trivially_copyable<T>::value, bool>::type = true> | ||||
| #else | ||||
|   template<typename T> | ||||
| #endif | ||||
|  | ||||
|   template<typename T, enable_if_t<is_trivially_copyable<T>::value, bool> = true> | ||||
|   ESPPreferenceObject make_preference(uint32_t type) { | ||||
|     return this->make_preference(sizeof(T), type); | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user