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 | /// @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 | // See https://github.com/espressif/esp-idf/issues/1445 | ||||||
| #if _GLIBCXX_RELEASE >= 8 | #if _GLIBCXX_RELEASE >= 8 | ||||||
| using std::to_string; | 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); } | inline std::string to_string(long double value) { return str_snprintf("%Lf", 32, value); } | ||||||
| #endif | #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. | // 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 uint8_t byteswap(uint8_t n) { return n; } | ||||||
| constexpr uint16_t byteswap(uint16_t n) { return __builtin_bswap16(n); } | constexpr uint16_t byteswap(uint16_t n) { return __builtin_bswap16(n); } | ||||||
|   | |||||||
| @@ -2,7 +2,8 @@ | |||||||
|  |  | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <type_traits> |  | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
|  |  | ||||||
| @@ -45,20 +46,12 @@ class ESPPreferences { | |||||||
|    */ |    */ | ||||||
|   virtual bool sync() = 0; |   virtual bool sync() = 0; | ||||||
|  |  | ||||||
| #ifndef USE_ESP8266 |   template<typename T, enable_if_t<is_trivially_copyable<T>::value, bool> = true> | ||||||
|   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 |  | ||||||
|   ESPPreferenceObject make_preference(uint32_t type, bool in_flash) { |   ESPPreferenceObject make_preference(uint32_t type, bool in_flash) { | ||||||
|     return this->make_preference(sizeof(T), type, 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> |   template<typename T, enable_if_t<is_trivially_copyable<T>::value, bool> = true> | ||||||
| #else |  | ||||||
|   template<typename T> |  | ||||||
| #endif |  | ||||||
|   ESPPreferenceObject make_preference(uint32_t type) { |   ESPPreferenceObject make_preference(uint32_t type) { | ||||||
|     return this->make_preference(sizeof(T), type); |     return this->make_preference(sizeof(T), type); | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user