mpd/src/util/Cast.hxx
2024-03-11 15:32:24 +01:00

57 lines
1.3 KiB
C++

// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <max.kellermann@gmail.com>
#pragma once
#include "OffsetPointer.hxx"
#include <cstddef>
template<typename T, typename U>
constexpr T *
OffsetCast(U *p, std::ptrdiff_t offset)
{
return reinterpret_cast<T *>(OffsetPointer(p, offset));
}
template<typename T, typename U>
constexpr T *
OffsetCast(const U *p, std::ptrdiff_t offset)
{
return reinterpret_cast<const T *>(OffsetPointer(p, offset));
}
template<class C, class A>
constexpr std::ptrdiff_t
ContainerAttributeOffset(const C *null_c, const A C::*p)
{
return std::ptrdiff_t((const char *)&(null_c->*p) - (const char *)null_c);
}
template<class C, class A>
constexpr std::ptrdiff_t
ContainerAttributeOffset(const A C::*p)
{
return ContainerAttributeOffset<C, A>(nullptr, p);
}
/**
* Cast the given pointer to a struct member to its parent structure.
*/
template<class C, class A>
constexpr C &
ContainerCast(A &a, const A C::*member)
{
return *OffsetCast<C, A>(&a, -ContainerAttributeOffset<C, A>(member));
}
/**
* Cast the given pointer to a struct member to its parent structure.
*/
template<class C, class A>
constexpr const C &
ContainerCast(const A &a, const A C::*member)
{
return *OffsetCast<const C, const A>(&a, -ContainerAttributeOffset<C, A>(member));
}