2023-03-06 14:42:04 +01:00
|
|
|
// SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
// author: Max Kellermann <max.kellermann@gmail.com>
|
2013-12-26 11:42:34 +01:00
|
|
|
|
|
|
|
#ifndef CAST_HXX
|
|
|
|
#define CAST_HXX
|
|
|
|
|
2018-08-20 13:46:18 +02:00
|
|
|
#include "OffsetPointer.hxx"
|
2014-07-14 17:08:16 +02:00
|
|
|
|
2020-03-13 00:46:28 +01:00
|
|
|
#include <cstddef>
|
2013-12-26 11:42:34 +01:00
|
|
|
|
|
|
|
template<typename T, typename U>
|
2019-01-21 21:17:58 +01:00
|
|
|
constexpr T *
|
2020-09-28 13:12:53 +02:00
|
|
|
OffsetCast(U *p, std::ptrdiff_t offset)
|
2013-12-26 11:42:34 +01:00
|
|
|
{
|
2014-07-14 15:57:48 +02:00
|
|
|
return reinterpret_cast<T *>(OffsetPointer(p, offset));
|
2013-12-26 11:42:34 +01:00
|
|
|
}
|
|
|
|
|
2014-07-14 16:02:02 +02:00
|
|
|
template<typename T, typename U>
|
2019-01-21 21:17:58 +01:00
|
|
|
constexpr T *
|
2020-09-28 13:12:53 +02:00
|
|
|
OffsetCast(const U *p, std::ptrdiff_t offset)
|
2014-07-14 16:02:02 +02:00
|
|
|
{
|
|
|
|
return reinterpret_cast<const T *>(OffsetPointer(p, offset));
|
|
|
|
}
|
|
|
|
|
2014-07-14 16:24:07 +02:00
|
|
|
template<class C, class A>
|
2020-09-28 13:12:53 +02:00
|
|
|
constexpr std::ptrdiff_t
|
2014-07-14 16:24:07 +02:00
|
|
|
ContainerAttributeOffset(const C *null_c, const A C::*p)
|
|
|
|
{
|
2020-09-28 13:12:53 +02:00
|
|
|
return std::ptrdiff_t((const char *)&(null_c->*p) - (const char *)null_c);
|
2014-07-14 16:24:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class C, class A>
|
2020-09-28 13:12:53 +02:00
|
|
|
constexpr std::ptrdiff_t
|
2014-07-14 16:24:07 +02:00
|
|
|
ContainerAttributeOffset(const A C::*p)
|
|
|
|
{
|
2014-07-14 16:44:43 +02:00
|
|
|
return ContainerAttributeOffset<C, A>(nullptr, p);
|
2014-07-14 16:24:07 +02:00
|
|
|
}
|
|
|
|
|
2013-12-26 11:42:34 +01:00
|
|
|
/**
|
|
|
|
* Cast the given pointer to a struct member to its parent structure.
|
|
|
|
*/
|
2014-07-14 16:24:07 +02:00
|
|
|
template<class C, class A>
|
2019-01-21 21:17:58 +01:00
|
|
|
constexpr C &
|
2017-09-13 10:32:55 +02:00
|
|
|
ContainerCast(A &a, const A C::*member)
|
2014-07-14 16:24:07 +02:00
|
|
|
{
|
2018-08-20 14:23:02 +02:00
|
|
|
return *OffsetCast<C, A>(&a, -ContainerAttributeOffset<C, A>(member));
|
2014-07-14 16:24:07 +02:00
|
|
|
}
|
2013-12-26 11:42:34 +01:00
|
|
|
|
2014-07-14 16:44:17 +02:00
|
|
|
/**
|
|
|
|
* Cast the given pointer to a struct member to its parent structure.
|
|
|
|
*/
|
|
|
|
template<class C, class A>
|
2019-01-21 21:17:58 +01:00
|
|
|
constexpr const C &
|
2017-09-13 10:32:55 +02:00
|
|
|
ContainerCast(const A &a, const A C::*member)
|
2014-07-14 16:44:17 +02:00
|
|
|
{
|
2018-08-20 14:23:02 +02:00
|
|
|
return *OffsetCast<const C, const A>(&a, -ContainerAttributeOffset<C, A>(member));
|
2014-07-14 16:44:17 +02:00
|
|
|
}
|
|
|
|
|
2013-12-26 11:42:34 +01:00
|
|
|
#endif
|