Core/Algorithm: Add AccessByOffset functions

This commit is contained in:
Jérôme Leclercq 2020-10-30 23:04:22 +01:00
parent 3b2e375382
commit 0d779077c1
2 changed files with 40 additions and 0 deletions

View File

@ -21,6 +21,8 @@ namespace Nz
{
class ByteArray;
template<typename T> decltype(auto) AccessByOffset(void* basePtr, std::size_t offset);
template<typename T> decltype(auto) AccessByOffset(const void* basePtr, std::size_t offset);
template<typename T> constexpr T Align(T offset, T alignment);
template<typename T> constexpr T AlignPow2(T offset, T alignment);
template<typename F, typename Tuple> decltype(auto) Apply(F&& fn, Tuple&& t);

View File

@ -36,6 +36,44 @@ namespace Nz
NAZARA_CORE_API extern const UInt8 BitReverseTable256[256];
}
/*!
* \ingroup core
* \brief Access a non-typed struct field by offset
* \return A pointer to the field of the asked type
*
* \param basePtr Pointer to the start of the struct
* \param offset Offset to the field (as generated by offsetof or similar)
*/
template<typename T>
decltype(auto) AccessByOffset(void* basePtr, std::size_t offset)
{
static_assert((std::is_reference_v<T> && !std::is_rvalue_reference_v<T>) || std::is_pointer_v<T>);
if constexpr (std::is_reference_v<T>)
return *reinterpret_cast<std::remove_reference_t<T>*>(static_cast<Nz::UInt8*>(basePtr) + offset);
else
return reinterpret_cast<T>(static_cast<Nz::UInt8*>(basePtr) + offset);
}
/*!
* \ingroup core
* \brief Access a non-typed struct field by offset
* \return A pointer to the field of the asked type
*
* \param basePtr Pointer to the start of the struct
* \param offset Offset to the field (as generated by offsetof or similar)
*/
template<typename T>
decltype(auto) AccessByOffset(const void* basePtr, std::size_t offset)
{
static_assert((std::is_reference_v<T> && !std::is_rvalue_reference_v<T>) || std::is_pointer_v<T>);
if constexpr (std::is_reference_v<T>)
return *reinterpret_cast<std::remove_reference_t<T>*>(static_cast<const Nz::UInt8*>(basePtr) + offset);
else
return reinterpret_cast<T>(static_cast<const Nz::UInt8*>(basePtr) + offset);
}
/*!
* \ingroup core
* \brief Align an offset