QuISP
Loading...
Searching...
No Matches
AccessPrivate.h
Go to the documentation of this file.
1
27
// copy of https://github.com/martong/access_private/tree/c65d54b17bf7b212cb4df867edf143f2ebb0186a
28
// clang-format off
29
30
#include <utility>
31
#include <type_traits>
32
33
#if __cplusplus == 201103L
34
namespace
std
{
35
template
<
bool
B,
class
T =
void
>
36
using
enable_if_t =
typename
enable_if<B, T>::type;
37
template
<
class
T>
38
using
remove_reference_t =
typename
remove_reference<T>::type;
39
}
// std
40
#endif
41
42
// Unnamed namespace is used to avoid duplicate symbols if the macros are used
43
// in several translation units. See test1.
44
namespace
{
45
namespace
private_access_detail
{
46
47
// @tparam TagType, used to declare different "get" funciton overloads for
48
// different members/statics
49
template
<
typename
PtrType, PtrType PtrValue,
typename
TagType>
50
struct
private_access {
51
// Normal lookup cannot find in-class defined (inline) friend functions.
52
friend
PtrType get(TagType) {
return
PtrValue; }
53
};
54
55
}
// namespace private_access_detail
56
}
// namespace
57
58
// Used macro naming conventions:
59
// The "namespace" of this macro library is PRIVATE_ACCESS, i.e. all
60
// macro here has this prefix.
61
// All implementation macro, which are not meant to be used directly have the
62
// PRIVATE_ACCESS_DETAIL prefix.
63
// Some macros have the ABCD_IMPL form, which means they contain the
64
// implementation details for the specific ABCD macro.
65
66
#define PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) x##y
67
#define PRIVATE_ACCESS_DETAIL_CONCATENATE(x, y) \
68
PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y)
69
70
// @param PtrTypeKind E.g if we have "class A", then it can be "A::*" in case of
71
// members, or it can be "*" in case of statics.
72
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, \
73
PtrTypeKind) \
74
namespace { \
75
namespace private_access_detail { \
76
/* Tag type, used to declare different get funcitons for different \
77
* members \
78
*/
\
79
struct Tag {}; \
80
/* Explicit instantiation */
\
81
template struct private_access<decltype(&Class::Name), &Class::Name, \
82
Tag>; \
83
/* We can build the PtrType only with two aliases */
\
84
/* E.g. using PtrType = int(int) *; would be illformed */
\
85
using PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) = Type; \
86
using PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) = \
87
PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) PtrTypeKind; \
88
/* Declare the friend function, now it is visible in namespace scope. \
89
* Note, \
90
* we could declare it inside the Tag type too, in that case ADL would \
91
* find \
92
* the declaration. By choosing to declare it here, the Tag type remains \
93
* a \
94
* simple tag type, it has no other responsibilities. */
\
95
PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) get(Tag); \
96
} \
97
}
98
99
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(Tag, Class, Type, Name) \
100
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \
101
namespace { \
102
namespace access_private { \
103
Type &Name(Class &&t) { return t.*get(private_access_detail::Tag{}); } \
104
Type &Name(Class &t) { return t.*get(private_access_detail::Tag{}); } \
105
/* The following usings are here to avoid duplicate const qualifier \
106
* warnings \
107
*/
\
108
using PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag) = Type; \
109
using PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) = \
110
const PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag); \
111
PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) & Name(const Class &t) { \
112
return t.*get(private_access_detail::Tag{}); \
113
} \
114
} \
115
}
116
117
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(Tag, Class, Type, Name) \
118
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \
119
namespace { \
120
namespace call_private { \
121
/* We do perfect forwarding, but we want to restrict the overload set \
122
* only for objects which have the type Class. */
\
123
template <typename Obj, \
124
std::enable_if_t<std::is_same<std::remove_reference_t<Obj>, \
125
Class>::value> * = nullptr, \
126
typename... Args> \
127
auto Name(Obj &&o, Args &&... args) -> decltype( \
128
(std::forward<Obj>(o).* \
129
get(private_access_detail::Tag{}))(std::forward<Args>(args)...)) { \
130
return (std::forward<Obj>(o).*get(private_access_detail::Tag{}))( \
131
std::forward<Args>(args)...); \
132
} \
133
} \
134
}
135
136
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(Tag, Class, Type, \
137
Name) \
138
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \
139
namespace { \
140
namespace access_private_static { \
141
namespace Class { \
142
Type &Name() { return *get(private_access_detail::Tag{}); } \
143
} \
144
} \
145
}
146
147
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(Tag, Class, Type, \
148
Name) \
149
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \
150
namespace { \
151
namespace call_private_static { \
152
namespace Class { \
153
template <typename... Args> \
154
auto Name(Args &&... args) -> decltype( \
155
get(private_access_detail::Tag{})(std::forward<Args>(args)...)) { \
156
return get(private_access_detail::Tag{})( \
157
std::forward<Args>(args)...); \
158
} \
159
} \
160
} \
161
}
162
163
#define PRIVATE_ACCESS_DETAIL_UNIQUE_TAG \
164
PRIVATE_ACCESS_DETAIL_CONCATENATE(PrivateAccessTag, __COUNTER__)
165
166
#define ACCESS_PRIVATE_FIELD(Class, Type, Name) \
167
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \
168
Class, Type, Name)
169
170
#define ACCESS_PRIVATE_FUN(Class, Type, Name) \
171
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \
172
Class, Type, Name)
173
174
#define ACCESS_PRIVATE_STATIC_FIELD(Class, Type, Name) \
175
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD( \
176
PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name)
177
178
#define ACCESS_PRIVATE_STATIC_FUN(Class, Type, Name) \
179
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN( \
180
PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name)
181
private_access_detail
Definition
AccessPrivate.h:45
std
Definition
QNIC.h:49
quisp
test_utils
AccessPrivate.h
Generated by
1.12.0