2016-07-31 05:56:36 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <string.h>
|
2019-06-28 16:21:05 +00:00
|
|
|
#include <type_traits>
|
2016-07-31 05:56:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
inline T unalignedLoad(const void * address)
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
T res {};
|
|
|
|
memcpy(&res, address, sizeof(res));
|
|
|
|
return res;
|
2016-07-31 05:56:36 +00:00
|
|
|
}
|
2016-08-19 01:54:23 +00:00
|
|
|
|
2019-06-28 16:21:05 +00:00
|
|
|
/// 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.
|
2016-08-19 01:54:23 +00:00
|
|
|
template <typename T>
|
2019-06-28 16:21:05 +00:00
|
|
|
inline void unalignedStore(void * address,
|
|
|
|
const typename std::enable_if<true, T>::type & src)
|
2016-08-19 01:54:23 +00:00
|
|
|
{
|
2019-06-28 16:21:05 +00:00
|
|
|
static_assert(std::is_trivially_copyable_v<T>);
|
2017-04-01 07:20:54 +00:00
|
|
|
memcpy(address, &src, sizeof(src));
|
2016-08-19 01:54:23 +00:00
|
|
|
}
|