diff options
Diffstat (limited to '')
-rw-r--r-- | src/util/Cast.hxx | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/src/util/Cast.hxx b/src/util/Cast.hxx index 8eb3479b8..680f81704 100644 --- a/src/util/Cast.hxx +++ b/src/util/Cast.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Max Kellermann <max@duempel.org> + * Copyright (C) 2013-2014 Max Kellermann <max@duempel.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -64,11 +64,31 @@ OffsetCast(const U *p, ptrdiff_t offset) return reinterpret_cast<const T *>(OffsetPointer(p, offset)); } +template<class C, class A> +static constexpr inline ptrdiff_t +ContainerAttributeOffset(const C *null_c, const A C::*p) +{ + return ptrdiff_t((const char *)null_c - (const char *)&(null_c->*p)); +} + +template<class C, class A> +static constexpr inline 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. */ -#define ContainerCast(p, container, attribute) \ - OffsetCast<container, decltype(((container*)nullptr)->attribute)> \ - ((p), -ptrdiff_t(offsetof(container, attribute))) +template<class C, class A> +#if defined(__clang__) || GCC_CHECK_VERSION(4,7) +constexpr +#endif +static inline C & +ContainerCast(A &a, A C::*member) +{ + return *OffsetCast<C, A>(&a, ContainerAttributeOffset<C, A>(member)); +} #endif |