|
|
|
1 |
|
// xxfunction TR1 internal header |
2 |
|
// NOTE: no include guard |
3 |
|
|
4 |
|
#define _NAME _CLASS_NAME(_Function_impl) |
5 |
|
#define _BASE_NAME _CLASS_NAME(_Impl_base) |
6 |
|
#define _IMPL_NAME _CLASS_NAME(_Impl) |
7 |
|
|
8 |
|
// TEMPLATE CLASS _BASE_NAME |
9 |
|
template<class _Rx _C_CLASS_ARG0> |
10 |
|
class _BASE_NAME |
11 |
|
{ // abstract base for implementation types |
12 |
|
public: |
13 |
|
virtual _BASE_NAME *_Copy(void * = 0) = 0; |
14 |
|
virtual _Rx _Do_call(_ARG0_A0) = 0; |
15 |
|
virtual const _XSTD2 type_info& _Target_type() const = 0; |
16 |
|
virtual void _Delete_this(bool) = 0; |
17 |
|
|
18 |
|
const void *_Target(const _XSTD2 type_info& _Info) const |
19 |
|
{ // return pointer to stored object of type _Info |
20 |
|
return (_Target_type() == _Info ? _Get() : 0); |
21 |
|
} |
22 |
|
|
23 |
|
virtual ~_BASE_NAME() |
24 |
|
{ // destroy the object |
25 |
|
} |
26 |
|
|
27 |
|
private: |
28 |
|
virtual const void *_Get() const = 0; |
29 |
|
}; |
30 |
|
|
31 |
|
// TEMPLATE CLASS _IMPL_NAME |
32 |
|
template<class _Callable, |
33 |
|
class _Rx _C_CLASS_ARG0, |
34 |
|
class _Alloc> |
35 |
|
class _IMPL_NAME |
36 |
|
: public _BASE_NAME<_Rx _C_ARG0_ARG1> |
37 |
|
{ // derived class for specific implementation types |
38 |
|
public: |
39 |
|
typedef _IMPL_NAME _Myty; |
40 |
|
typedef typename _Alloc::template rebind<_Myty>::other _Myalty; |
41 |
|
|
42 |
|
_IMPL_NAME(typename _Callable::_MyTy& _Val, |
43 |
|
_Myalty _Ax = _Myalty()) |
44 |
|
: _Callee(_Val), _Myal(_Ax) |
45 |
|
{ // construct |
46 |
|
} |
47 |
|
|
48 |
|
virtual ~_IMPL_NAME() |
49 |
|
{ // destroy the object |
50 |
|
} |
51 |
|
|
52 |
|
virtual _BASE_NAME<_Rx _C_ARG0_ARG1> *_Copy(void *_Where = 0) |
53 |
|
{ // return clone of *this |
54 |
|
if (_Where == 0) |
55 |
|
_Where = _Myal.allocate(1); |
56 |
|
new (_Where) _IMPL_NAME(*this); |
57 |
|
return ((_BASE_NAME<_Rx _C_ARG0_ARG1> *)_Where); |
58 |
|
} |
59 |
|
|
60 |
|
_Rx _Do_call(_ARG0_A0) |
61 |
|
{ // call wrapped function |
62 |
|
return (_Callee.template _ApplyX<_Rx>(_A0_A1)); |
63 |
|
} |
64 |
|
|
65 |
|
const _XSTD2 type_info& _Target_type() const |
66 |
|
{ // return type information for stored object |
67 |
|
return (typeid(typename _Callable::_MyTy)); |
68 |
|
} |
69 |
|
|
70 |
|
private: |
71 |
|
const void *_Get() const |
72 |
|
{ // return address of stored object |
73 |
|
return (&_Callee._Get()); |
74 |
|
} |
75 |
|
|
76 |
|
virtual void _Delete_this(bool _Deallocate) |
77 |
|
{ // destroy self |
78 |
|
_Myalty _Al = _Myal; |
79 |
|
_Al.destroy(this); // _Dest_val(_Al, this) |
80 |
|
if (_Deallocate) |
81 |
|
_Al.deallocate(this, 1); |
82 |
|
} |
83 |
|
|
84 |
|
_Callable _Callee; |
85 |
|
_Myalty _Myal; |
86 |
|
}; |
87 |
|
|
88 |
|
// TEMPLATE CLASS _NAME |
89 |
|
template<class _Ret _C_CLASS_ARG0> |
90 |
|
class _NAME |
91 |
|
|
92 |
|
#if _NARGS == 1 |
93 |
|
: public _STD unary_function<_Arg0, _Ret> |
94 |
|
|
95 |
|
#elif _NARGS == 2 |
96 |
|
: public _STD binary_function<_Arg0, _Arg1, _Ret> |
97 |
|
#endif /* _NARGS */ |
98 |
|
|
99 |
|
{ // implement _STD tr1::function template |
100 |
|
typedef _NAME<_Ret _C_ARG0_ARG1> _Myt; |
101 |
|
typedef _BASE_NAME<_Ret _C_ARG0_ARG1> _Ptrt; |
102 |
|
|
103 |
|
public: |
104 |
|
typedef _Ret result_type; |
105 |
|
|
106 |
|
_Ret operator()(_ARG0_A0) const |
107 |
|
{ // call through stored object |
108 |
|
if (_Impl == 0) |
109 |
|
_Xfunc(); |
110 |
|
return (_Impl->_Do_call(_A0_A1)); |
111 |
|
} |
112 |
|
|
113 |
|
bool _Empty() const |
114 |
|
{ // return true if no stored object |
115 |
|
return (_Impl == 0); |
116 |
|
} |
117 |
|
|
118 |
|
protected: |
119 |
|
void _Reset() |
120 |
|
{ // remove stored object |
121 |
|
_Set(0); |
122 |
|
} |
123 |
|
|
124 |
|
void _Reset(const _Myt& _Right) |
125 |
|
{ // store copy of _Right's stored object |
126 |
|
if (_Right._Impl == 0) |
127 |
|
_Set(0); |
128 |
|
else if (_Right._Local()) |
129 |
|
_Set(_Right._Impl->_Copy((void *)&_Space)); |
130 |
|
else |
131 |
|
_Set(_Right._Impl->_Copy()); |
132 |
|
} |
133 |
|
|
134 |
|
template<class _Fret _C_CLASS_FARG0, |
135 |
|
class _Alloc> |
136 |
|
void _Reset(_Fret (*const _Val)(_FARG0_FARG1), _Alloc _Ax) |
137 |
|
{ // store copy of _Val |
138 |
|
typedef _Callable_fun<_Fret (*const)(_FARG0_FARG1)> _MyWrapper; |
139 |
|
typedef _IMPL_NAME<_MyWrapper, _Ret _C_ARG0_ARG1, _Alloc> _Myimpl; |
140 |
|
|
141 |
|
if (sizeof (_Myimpl) <= sizeof (_Space)) |
142 |
|
{ // small enough, allocate locally |
143 |
|
new ((void *)&_Space) _Myimpl(_Val); |
144 |
|
_Set((_Ptrt *)&_Space); |
145 |
|
} |
146 |
|
else |
147 |
|
{ // use allocator |
148 |
|
typename _Alloc::template rebind<_Myimpl>::other _Al = _Ax; |
149 |
|
_Myimpl *_Ptr = _Al.allocate(1); |
150 |
|
|
151 |
|
new (_Ptr) _Myimpl(_Val, _Al); |
152 |
|
_Set(_Ptr); |
153 |
|
} |
154 |
|
} |
155 |
|
|
156 |
|
template<class _Fty, |
157 |
|
class _Alloc> |
158 |
|
void _Reset(_Fty _Val, _Alloc _Ax) |
159 |
|
{ // store copy of _Val |
160 |
|
typedef _Callable_obj<_Fty> _MyWrapper; |
161 |
|
typedef _IMPL_NAME<_MyWrapper, _Ret _C_ARG0_ARG1, _Alloc> _Myimpl; |
162 |
|
|
163 |
|
if (sizeof (_Myimpl) <= sizeof (_Space)) |
164 |
|
{ // small enough, allocate locally |
165 |
|
new ((void *)&_Space) _Myimpl(_Val); |
166 |
|
_Set((_Ptrt *)&_Space); |
167 |
|
} |
168 |
|
else |
169 |
|
{ // use allocator |
170 |
|
typename _Alloc::template rebind<_Myimpl>::other _Al = _Ax; |
171 |
|
_Myimpl *_Ptr = _Al.allocate(1); |
172 |
|
|
173 |
|
new (_Ptr) _Myimpl(_Val, _Al); |
174 |
|
_Set(_Ptr); |
175 |
|
} |
176 |
|
} |
177 |
|
|
178 |
|
#if _NARGS == 1 |
179 |
|
template<class _Fret, |
180 |
|
class _Farg0, |
181 |
|
class _Alloc> |
182 |
|
void _Reset(_Fret _Farg0::*const _Val, _Alloc _Ax) |
183 |
|
{ // store copy of _Val |
184 |
|
typedef _Callable_pmd<_Fret _Farg0::*const, _Arg0> _MyWrapper; |
185 |
|
typedef _IMPL_NAME<_MyWrapper, _Ret, _Arg0, _Alloc> _Myimpl; |
186 |
|
|
187 |
|
if (sizeof (_Myimpl) <= sizeof (_Space)) |
188 |
|
{ // small enough, allocate locally |
189 |
|
new ((void *)&_Space) _Myimpl(_Val); |
190 |
|
_Set((_Ptrt *)&_Space); |
191 |
|
} |
192 |
|
else |
193 |
|
{ // use allocator |
194 |
|
typename _Alloc::template rebind<_Myimpl>::other _Al = _Ax; |
195 |
|
_Myimpl *_Ptr = _Al.allocate(1); |
196 |
|
|
197 |
|
new (_Ptr) _Myimpl(_Val, _Al); |
198 |
|
_Set(_Ptr); |
199 |
|
} |
200 |
|
} |
201 |
|
#endif /* _NARGS == 1 */ |
202 |
|
|
203 |
|
#if _NARGS != 0 |
204 |
|
template<class _Fret _C_CLASS_FARG0, |
205 |
|
class _Alloc> |
206 |
|
void _Reset(_Fret (_Farg0::*const _Val)(_FARG1_FARG2), _Alloc _Ax) |
207 |
|
{ // store copy of _Val |
208 |
|
typedef _Callable_pmf<_Fret (_Farg0::*const)(_FARG1_FARG2), _Arg0> |
209 |
|
_MyWrapper; |
210 |
|
typedef _IMPL_NAME<_MyWrapper, _Ret, _ARG0_ARG1, _Alloc> _Myimpl; |
211 |
|
|
212 |
|
if (sizeof (_Myimpl) <= sizeof (_Space)) |
213 |
|
{ // small enough, allocate locally |
214 |
|
new ((void *)&_Space) _Myimpl(_Val); |
215 |
|
_Set((_Ptrt *)&_Space); |
216 |
|
} |
217 |
|
else |
218 |
|
{ // use allocator |
219 |
|
typename _Alloc::template rebind<_Myimpl>::other _Al = _Ax; |
220 |
|
_Myimpl *_Ptr = _Al.allocate(1); |
221 |
|
|
222 |
|
new (_Ptr) _Myimpl(_Val, _Al); |
223 |
|
_Set(_Ptr); |
224 |
|
} |
225 |
|
} |
226 |
|
|
227 |
|
template<class _Fret _C_CLASS_FARG0, |
228 |
|
class _Alloc> |
229 |
|
void _Reset(_Fret (_Farg0::*const _Val)(_FARG1_FARG2) const, |
230 |
|
_Alloc _Ax) |
231 |
|
{ // store copy of _Val |
232 |
|
typedef _Callable_pmf< |
233 |
|
_Fret (_Farg0::*const)(_FARG1_FARG2) const, _Arg0> _MyWrapper; |
234 |
|
typedef _IMPL_NAME<_MyWrapper, _Ret, _ARG0_ARG1, _Alloc> _Myimpl; |
235 |
|
|
236 |
|
if (sizeof (_Myimpl) <= sizeof (_Space)) |
237 |
|
{ // small enough, allocate locally |
238 |
|
new ((void *)&_Space) _Myimpl(_Val); |
239 |
|
_Set((_Ptrt *)&_Space); |
240 |
|
} |
241 |
|
else |
242 |
|
{ // use allocator |
243 |
|
typename _Alloc::template rebind<_Myimpl>::other _Al = _Ax; |
244 |
|
_Myimpl *_Ptr = _Al.allocate(1); |
245 |
|
|
246 |
|
new (_Ptr) _Myimpl(_Val, _Al); |
247 |
|
_Set(_Ptr); |
248 |
|
} |
249 |
|
} |
250 |
|
|
251 |
|
template<class _Fret _C_CLASS_FARG0, |
252 |
|
class _Alloc> |
253 |
|
void _Reset(_Fret (_Farg0::*const _Val)(_FARG1_FARG2) volatile, |
254 |
|
_Alloc _Ax) |
255 |
|
{ // store copy of _Val |
256 |
|
typedef _Callable_pmf< |
257 |
|
_Fret (_Farg0::*const)(_FARG1_FARG2) volatile,_Arg0> _MyWrapper; |
258 |
|
typedef _IMPL_NAME<_MyWrapper, _Ret, _ARG0_ARG1, _Alloc> _Myimpl; |
259 |
|
|
260 |
|
if (sizeof (_Myimpl) <= sizeof (_Space)) |
261 |
|
{ // small enough, allocate locally |
262 |
|
new ((void *)&_Space) _Myimpl(_Val); |
263 |
|
_Set((_Ptrt *)&_Space); |
264 |
|
} |
265 |
|
else |
266 |
|
{ // use allocator |
267 |
|
typename _Alloc::template rebind<_Myimpl>::other _Al = _Ax; |
268 |
|
_Myimpl *_Ptr = _Al.allocate(1); |
269 |
|
|
270 |
|
new (_Ptr) _Myimpl(_Val, _Al); |
271 |
|
_Set(_Ptr); |
272 |
|
} |
273 |
|
} |
274 |
|
|
275 |
|
template<class _Fret _C_CLASS_FARG0, |
276 |
|
class _Alloc> |
277 |
|
void _Reset(_Fret (_Farg0::*const _Val)(_FARG1_FARG2) const volatile, |
278 |
|
_Alloc _Ax) |
279 |
|
{ // store copy of _Val |
280 |
|
typedef _Callable_pmf< |
281 |
|
_Fret (_Farg0::*const)(_FARG1_FARG2) const volatile, _Arg0> |
282 |
|
_MyWrapper; |
283 |
|
typedef _IMPL_NAME<_MyWrapper, _Ret, _ARG0_ARG1, _Alloc> _Myimpl; |
284 |
|
|
285 |
|
if (sizeof (_Myimpl) <= sizeof (_Space)) |
286 |
|
{ // small enough, allocate locally |
287 |
|
new ((void *)&_Space) _Myimpl(_Val); |
288 |
|
_Set((_Ptrt *)&_Space); |
289 |
|
} |
290 |
|
else |
291 |
|
{ // use allocator |
292 |
|
typename _Alloc::template rebind<_Myimpl>::other _Al = _Ax; |
293 |
|
_Myimpl *_Ptr = _Al.allocate(1); |
294 |
|
|
295 |
|
new (_Ptr) _Myimpl(_Val, _Al); |
296 |
|
_Set(_Ptr); |