mirror of https://github.com/ByConity/ByConity
49 lines
1.4 KiB
C++
49 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include <string.h>
|
|
#include <type_traits>
|
|
#include <bit>
|
|
|
|
|
|
template <typename T>
|
|
inline T unalignedLoad(const void * address)
|
|
{
|
|
T res {};
|
|
memcpy(&res, address, sizeof(res));
|
|
return res;
|
|
}
|
|
|
|
/// We've had troubles before with wrong store size due to integral promotions
|
|
/// (e.g., unalignedStore(dest, uint16_t + uint16_t) stores an uint32_t).
|
|
/// To prevent this, make the caller specify the stored type explicitly.
|
|
/// To disable deduction of T, wrap the argument type with std::enable_if.
|
|
template <typename T>
|
|
inline void unalignedStore(void * address,
|
|
const typename std::enable_if<true, T>::type & src)
|
|
{
|
|
static_assert(std::is_trivially_copyable_v<T>);
|
|
memcpy(address, &src, sizeof(src));
|
|
}
|
|
|
|
template <typename T>
|
|
inline T unalignedLoadLE(const void * address)
|
|
{
|
|
T res {};
|
|
if constexpr (std::endian::native == std::endian::little)
|
|
memcpy(&res, address, sizeof(res));
|
|
else
|
|
reverseMemcpy(&res, address, sizeof(res));
|
|
return res;
|
|
}
|
|
|
|
template <typename T>
|
|
inline void unalignedStoreLE(void * address,
|
|
const typename std::enable_if<true, T>::type & src)
|
|
{
|
|
static_assert(std::is_trivially_copyable_v<T>);
|
|
if constexpr (std::endian::native == std::endian::little)
|
|
memcpy(address, &src, sizeof(src));
|
|
else
|
|
reverseMemcpy(address, &src, sizeof(src));
|
|
}
|