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/output/plugins/httpd/HttpdInternal.hxx | 14 ++++---------- src/tag/TagPool.cxx | 7 +++++-- src/util/Cast.hxx | 28 ++++++++++++++++++++++++---- 3 files changed, 33 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/output/plugins/httpd/HttpdInternal.hxx b/src/output/plugins/httpd/HttpdInternal.hxx index a16c60bc3..5c113520d 100644 --- a/src/output/plugins/httpd/HttpdInternal.hxx +++ b/src/output/plugins/httpd/HttpdInternal.hxx @@ -152,19 +152,13 @@ public: HttpdOutput(EventLoop &_loop); ~HttpdOutput(); -#if GCC_CHECK_VERSION(4,6) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winvalid-offsetof" +#if defined(__clang__) || GCC_CHECK_VERSION(4,7) + constexpr #endif - - static constexpr HttpdOutput *Cast(AudioOutput *ao) { - return ContainerCast(ao, HttpdOutput, base); + static HttpdOutput *Cast(AudioOutput *ao) { + return &ContainerCast(*ao, &HttpdOutput::base); } -#if GCC_CHECK_VERSION(4,6) || defined(__clang__) -#pragma GCC diagnostic pop -#endif - using DeferredMonitor::GetEventLoop; bool Init(const config_param ¶m, Error &error); diff --git a/src/tag/TagPool.cxx b/src/tag/TagPool.cxx index 0b6bc956c..29f605337 100644 --- a/src/tag/TagPool.cxx +++ b/src/tag/TagPool.cxx @@ -87,10 +87,13 @@ calc_hash(TagType type, const char *p) return hash ^ type; } -static inline constexpr TagPoolSlot * +#if defined(__clang__) || GCC_CHECK_VERSION(4,7) + constexpr +#endif +static inline TagPoolSlot * tag_item_to_slot(TagItem *item) { - return ContainerCast(item, TagPoolSlot, item); + return &ContainerCast(*item, &TagPoolSlot::item); } static inline TagPoolSlot ** 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