diff options
author | Max Kellermann <max@duempel.org> | 2014-07-14 16:24:07 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-07-14 16:24:07 +0200 |
commit | 7a1f3177c92556c4ca224d28fc881686845c5052 (patch) | |
tree | 158b962f07f6877ad33ebd6e590475fb6c0d6833 | |
parent | f8da8b02615bc5b8a358407da147c97debc40e06 (diff) | |
download | mpd-7a1f3177c92556c4ca224d28fc881686845c5052.tar.gz mpd-7a1f3177c92556c4ca224d28fc881686845c5052.tar.xz mpd-7a1f3177c92556c4ca224d28fc881686845c5052.zip |
util/Cast: reimplement as template without macro
-rw-r--r-- | src/output/plugins/httpd/HttpdInternal.hxx | 14 | ||||
-rw-r--r-- | src/tag/TagPool.cxx | 7 | ||||
-rw-r--r-- | src/util/Cast.hxx | 28 |
3 files changed, 33 insertions, 16 deletions
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 <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 |