From 7a1f3177c92556c4ca224d28fc881686845c5052 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Jul 2014 16:24:07 +0200 Subject: util/Cast: reimplement as template without macro --- src/util/Cast.hxx | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'src/util/Cast.hxx') 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 + * Copyright (C) 2013-2014 Max Kellermann * * 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(OffsetPointer(p, offset)); } +template +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 +static constexpr inline ptrdiff_t +ContainerAttributeOffset(const A C::*p) +{ + return ContainerAttributeOffset(nullptr, p); +} + /** * Cast the given pointer to a struct member to its parent structure. */ -#define ContainerCast(p, container, attribute) \ - OffsetCastattribute)> \ - ((p), -ptrdiff_t(offsetof(container, attribute))) +template +#if defined(__clang__) || GCC_CHECK_VERSION(4,7) +constexpr +#endif +static inline C & +ContainerCast(A &a, A C::*member) +{ + return *OffsetCast(&a, ContainerAttributeOffset(member)); +} #endif -- cgit v1.2.3