1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
|
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
/////////////////////////////////////////////////////////////////////////////
#ifndef EASTL_INTERNAL_MEM_FN_H
#define EASTL_INTERNAL_MEM_FN_H
#if defined(EA_PRAGMA_ONCE_SUPPORTED)
#pragma once
#endif
////////////////////////////////////////////////////////////////////////////////
// The code in this file is a modification of the libcxx implementation. We copy
// the license information here as required.
//
// We implement only enough of mem_fn to implement eastl::function.
////////////////////////////////////////////////////////////////////////////////
//===------------------------ functional ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
namespace eastl
{
//
// apply_cv
//
template <class T, class U,
bool = is_const<typename remove_reference<T>::type>::value,
bool = is_volatile<typename remove_reference<T>::type>::value>
struct apply_cv { typedef U type; };
template <class T, class U> struct apply_cv<T, U, true, false> { typedef const U type; };
template <class T, class U> struct apply_cv<T, U, false, true> { typedef volatile U type; };
template <class T, class U> struct apply_cv<T, U, true, true> { typedef const volatile U type; };
template <class T, class U> struct apply_cv<T&, U, false, false> { typedef U& type; };
template <class T, class U> struct apply_cv<T&, U, true, false> { typedef const U& type; };
template <class T, class U> struct apply_cv<T&, U, false, true> { typedef volatile U& type; };
template <class T, class U> struct apply_cv<T&, U, true, true> { typedef const volatile U& type; };
//
// has_result_type
//
template <class T>
struct has_result_type
{
private:
template <class U>
static eastl::no_type test(...);
template <class U>
static eastl::yes_type test(typename U::result_type* = 0);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(eastl::yes_type);
};
//
// derives_from_unary_function
// derives_from_binary_function
//
template <class T>
struct derives_from_unary_function
{
private:
static eastl::no_type test(...);
template <class A, class R>
static unary_function<A, R> test(const volatile unary_function<A, R>*);
public:
static const bool value = !is_same<decltype(test((T*)0)), eastl::no_type>::value;
typedef decltype(test((T*)0)) type;
};
template <class T>
struct derives_from_binary_function
{
private:
static eastl::no_type test(...);
template <class A1, class A2, class R>
static binary_function<A1, A2, R> test(const volatile binary_function<A1, A2, R>*);
public:
static const bool value = !is_same<decltype(test((T*)0)), eastl::no_type>::value;
typedef decltype(test((T*)0)) type;
};
//
// maybe_derives_from_unary_function
// maybe_derives_from_binary_function
//
template <class T, bool = derives_from_unary_function<T>::value>
struct maybe_derive_from_unary_function // bool is true
: public derives_from_unary_function<T>::type { };
template <class T>
struct maybe_derive_from_unary_function<T, false> { };
template <class T, bool = derives_from_binary_function<T>::value>
struct maybe_derive_from_binary_function // bool is true
: public derives_from_binary_function<T>::type { };
template <class T>
struct maybe_derive_from_binary_function<T, false> { };
//
// weak_result_type_imp
//
template <class T, bool = has_result_type<T>::value>
struct weak_result_type_imp // bool is true
: public maybe_derive_from_unary_function<T>,
public maybe_derive_from_binary_function<T>
{
typedef typename T::result_type result_type;
};
template <class T>
struct weak_result_type_imp<T, false> : public maybe_derive_from_unary_function<T>,
public maybe_derive_from_binary_function<T> { };
//
// weak_result_type
//
template <class T>
struct weak_result_type : public weak_result_type_imp<T> { };
// 0 argument case
template <class R> struct weak_result_type<R()> { typedef R result_type; };
template <class R> struct weak_result_type<R(&)()> { typedef R result_type; };
template <class R> struct weak_result_type<R (*)()> { typedef R result_type; };
// 1 argument case
template <class R, class A1> struct weak_result_type<R(A1)> : public unary_function<A1, R> { };
template <class R, class A1> struct weak_result_type<R(&)(A1)> : public unary_function<A1, R> { };
template <class R, class A1> struct weak_result_type<R (*)(A1)> : public unary_function<A1, R> { };
template <class R, class C> struct weak_result_type<R (C::*)()> : public unary_function<C*, R> { };
template <class R, class C> struct weak_result_type<R (C::*)() const> : public unary_function<const C*, R> { };
template <class R, class C> struct weak_result_type<R (C::*)() volatile> : public unary_function<volatile C*, R> { };
template <class R, class C> struct weak_result_type<R (C::*)() const volatile> : public unary_function<const volatile C*, R> { };
// 2 argument case
template <class R, class A1, class A2> struct weak_result_type<R(A1, A2)> : public binary_function<A1, A2, R> { };
template <class R, class A1, class A2> struct weak_result_type<R (*)(A1, A2)> : public binary_function<A1, A2, R> { };
template <class R, class A1, class A2> struct weak_result_type<R(&)(A1, A2)> : public binary_function<A1, A2, R> { };
template <class R, class C, class A1> struct weak_result_type<R (C::*)(A1)> : public binary_function<C*, A1, R> { };
template <class R, class C, class A1> struct weak_result_type<R (C::*)(A1) const> : public binary_function<const C*, A1, R> { };
template <class R, class C, class A1> struct weak_result_type<R (C::*)(A1) volatile> : public binary_function<volatile C*, A1, R> { };
template <class R, class C, class A1> struct weak_result_type<R (C::*)(A1) const volatile> : public binary_function<const volatile C*, A1, R> { };
// 3 or more arguments
#if EASTL_VARIADIC_TEMPLATES_ENABLED
template <class R, class A1, class A2, class A3, class... A4> struct weak_result_type<R(A1, A2, A3, A4...)> { typedef R result_type; };
template <class R, class A1, class A2, class A3, class... A4> struct weak_result_type<R(&)(A1, A2, A3, A4...)> { typedef R result_type; };
template <class R, class A1, class A2, class A3, class... A4> struct weak_result_type<R (*)(A1, A2, A3, A4...)> { typedef R result_type; };
template <class R, class C, class A1, class A2, class... A3> struct weak_result_type<R (C::*)(A1, A2, A3...)> { typedef R result_type; };
template <class R, class C, class A1, class A2, class... A3> struct weak_result_type<R (C::*)(A1, A2, A3...) const> { typedef R result_type; };
template <class R, class C, class A1, class A2, class... A3> struct weak_result_type<R (C::*)(A1, A2, A3...) volatile> { typedef R result_type; };
template <class R, class C, class A1, class A2, class... A3> struct weak_result_type<R (C::*)(A1, A2, A3...) const volatile> { typedef R result_type; };
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// mem_fn_impl
//
template <class T>
class mem_fn_impl
#if defined(_MSC_VER) && (_MSC_VER >= 1900) // VS2015 or later
// Due to a (seemingly random) internal compiler error on VS2013 we disable eastl::unary_function and
// binary_function support for eastl::mem_fn as its not widely (if at all) used. If you require this support
// on VS2013 or below please contact us.
: public weak_result_type<T>
#endif
{
public:
typedef T type;
private:
type func;
public:
EASTL_FORCE_INLINE mem_fn_impl(type _func) : func(_func) {}
#if EASTL_VARIADIC_TEMPLATES_ENABLED
template <class... ArgTypes>
typename invoke_result<type, ArgTypes...>::type operator()(ArgTypes&&... args) const
{
return invoke(func, eastl::forward<ArgTypes>(args)...);
}
#else
typename invoke_result<type>::type operator()() const { return invoke_impl(func); }
template <class A0>
typename invoke_result0<type, A0>::type operator()(A0& a0) const
{
return invoke(func, a0);
}
template <class A0, class A1>
typename invoke_result1<type, A0, A1>::type operator()(A0& a0, A1& a1) const
{
return invoke(func, a0, a1);
}
template <class A0, class A1, class A2>
typename invoke_result2<type, A0, A1, A2>::type operator()(A0& a0, A1& a1, A2& a2) const
{
return invoke(func, a0, a1, a2);
}
#endif
}; // mem_fn_impl
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// mem_fn -> mem_fn_impl adapters
//
template <class R, class T>
EASTL_FORCE_INLINE mem_fn_impl<R T::*> mem_fn(R T::*pm)
{ return mem_fn_impl<R T::*>(pm); }
template <class R, class T>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)()> mem_fn(R (T::*pm)())
{ return mem_fn_impl<R (T::*)()>(pm); }
template <class R, class T, class A0>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0)> mem_fn(R (T::*pm)(A0))
{ return mem_fn_impl<R (T::*)(A0)>(pm); }
template <class R, class T, class A0, class A1>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1)> mem_fn(R (T::*pm)(A0, A1))
{ return mem_fn_impl<R (T::*)(A0, A1)>(pm); }
template <class R, class T, class A0, class A1, class A2>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2)> mem_fn(R (T::*pm)(A0, A1, A2))
{ return mem_fn_impl<R (T::*)(A0, A1, A2)>(pm); }
template <class R, class T>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)() const> mem_fn(R (T::*pm)() const)
{ return mem_fn_impl<R (T::*)() const>(pm); }
template <class R, class T, class A0>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0) const> mem_fn(R (T::*pm)(A0) const)
{ return mem_fn_impl<R (T::*)(A0) const>(pm); }
template <class R, class T, class A0, class A1>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1) const> mem_fn(R (T::*pm)(A0, A1) const)
{ return mem_fn_impl<R (T::*)(A0, A1) const>(pm); }
template <class R, class T, class A0, class A1, class A2>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2) const> mem_fn(R (T::*pm)(A0, A1, A2) const)
{ return mem_fn_impl<R (T::*)(A0, A1, A2) const>(pm); }
template <class R, class T>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)() volatile> mem_fn(R (T::*pm)() volatile)
{ return mem_fn_impl<R (T::*)() volatile>(pm); }
template <class R, class T, class A0>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0) volatile> mem_fn(R (T::*pm)(A0) volatile)
{ return mem_fn_impl<R (T::*)(A0) volatile>(pm); }
template <class R, class T, class A0, class A1>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1) volatile> mem_fn(R (T::*pm)(A0, A1) volatile)
{ return mem_fn_impl<R (T::*)(A0, A1) volatile>(pm); }
template <class R, class T, class A0, class A1, class A2>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2) volatile> mem_fn(R (T::*pm)(A0, A1, A2) volatile)
{ return mem_fn_impl<R (T::*)(A0, A1, A2) volatile>(pm); }
template <class R, class T>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)() const volatile> mem_fn(R (T::*pm)() const volatile)
{ return mem_fn_impl<R (T::*)() const volatile>(pm); }
template <class R, class T, class A0>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0) const volatile> mem_fn(R (T::*pm)(A0) const volatile)
{ return mem_fn_impl<R (T::*)(A0) const volatile>(pm); }
template <class R, class T, class A0, class A1>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1) const volatile> mem_fn(R (T::*pm)(A0, A1) const volatile)
{ return mem_fn_impl<R (T::*)(A0, A1) const volatile>(pm); }
template <class R, class T, class A0, class A1, class A2>
EASTL_FORCE_INLINE mem_fn_impl<R (T::*)(A0, A1, A2) const volatile> mem_fn(R (T::*pm)(A0, A1, A2) const volatile)
{ return mem_fn_impl<R (T::*)(A0, A1, A2) const volatile>(pm); }
} // namespace eastl
#endif // EASTL_INTERNAL_MEM_FN_H
|