MPD  0.20.6
Cast.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013-2014 Max Kellermann <max.kellermann@gmail.com>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27  * OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef CAST_HXX
31 #define CAST_HXX
32 
33 #include "Compiler.h"
34 
35 #include <stddef.h>
36 
40 static inline constexpr void *
41 OffsetPointer(void *p, ptrdiff_t offset)
42 {
43  return (char *)p + offset;
44 }
45 
49 static inline constexpr const void *
50 OffsetPointer(const void *p, ptrdiff_t offset)
51 {
52  return (const char *)p + offset;
53 }
54 
55 template<typename T, typename U>
56 static inline constexpr T *
57 OffsetCast(U *p, ptrdiff_t offset)
58 {
59  return reinterpret_cast<T *>(OffsetPointer(p, offset));
60 }
61 
62 template<typename T, typename U>
63 static inline constexpr T *
64 OffsetCast(const U *p, ptrdiff_t offset)
65 {
66  return reinterpret_cast<const T *>(OffsetPointer(p, offset));
67 }
68 
69 template<class C, class A>
70 static constexpr inline ptrdiff_t
71 ContainerAttributeOffset(const C *null_c, const A C::*p)
72 {
73  return ptrdiff_t((const char *)null_c - (const char *)&(null_c->*p));
74 }
75 
76 template<class C, class A>
77 static constexpr inline ptrdiff_t
79 {
80  return ContainerAttributeOffset<C, A>(nullptr, p);
81 }
82 
86 template<class C, class A>
87 #if CLANG_OR_GCC_VERSION(4,7)
88 constexpr
89 #endif
90 static inline C &
91 ContainerCast(A &a, A C::*member)
92 {
93  return *OffsetCast<C, A>(&a, ContainerAttributeOffset<C, A>(member));
94 }
95 
99 template<class C, class A>
100 #if CLANG_OR_GCC_VERSION(4,7)
101 constexpr
102 #endif
103 static inline const C &
104 ContainerCast(const A &a, A C::*member)
105 {
106  return *OffsetCast<const C, const A>(&a, ContainerAttributeOffset<C, A>(member));
107 }
108 
109 #endif
static constexpr ptrdiff_t ContainerAttributeOffset(const C *null_c, const A C::*p)
Definition: Cast.hxx:71
static C & ContainerCast(A &a, A C::*member)
Cast the given pointer to a struct member to its parent structure.
Definition: Cast.hxx:91
static constexpr void * OffsetPointer(void *p, ptrdiff_t offset)
Offset the given pointer by the specified number of bytes.
Definition: Cast.hxx:41
static constexpr T * OffsetCast(U *p, ptrdiff_t offset)
Definition: Cast.hxx:57