mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 21:44:55 +01:00
Introduce bit_cast() backport (#2991)
This commit is contained in:
parent
26dd1f8532
commit
e5775cf812
2 changed files with 32 additions and 13 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue