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);
Lines 297 ... 306 are skipped.
307             }
308         }
309
310     void _Swap(_Myt& _Right)
311         {    // swap contents with contents of _Right
312         if (this == &_Right)
313             {
314             return; // same object, do nothing
315             }
316
317         if (_Local())
318             {
319             if (_Right._Local())
320                 {    // both local
321                 _Myt _Temp;
322                 _Temp._Reset(*this);
323                 _Tidy();
324                 _Reset(_Right);
325                 _Right._Tidy();
326                 _Right._Reset(_Temp);
327                 _Temp._Tidy();
328                 }
329             else
330                 {    // *this local, _Right remote/null
331                 _Ptrt * _Temp = _Right._Impl;
332                 _Right._Reset(*this);
333                 _Tidy();
334                 _Set(_Temp);
335                 }
336             }
337         else
338             {
339             if (_Right._Local())
340                 {    // *this remote/null, _Right local
341                 _Ptrt * _Temp = _Impl;
342                 _Reset(_Right);
343                 _Right._Tidy();
344                 _Right._Set(_Temp);
345                 }
346             else
347                 {    // both remote/null
348                 _STD swap(_Impl, _Right._Impl);
349                 }
350             }
351         }
352
353     const _XSTD2 type_info& _Target_type() const
354         {    // return type information for stored object
355         return (_Impl ? _Impl->_Target_type() : typeid(void));
356         }
357
358     const void *_Target(const _XSTD2 type_info& _Info) const
359         {    // return pointer to stored object
360         return (_Impl ? _Impl->_Target(_Info) : 0);
361         }
362
363 private:
364     void _Set(_Ptrt *_Ptr)
365         {    // store pointer to object
366         _Impl = _Ptr;
367         }
368
369     bool _Local() const
370         {
371         return ((void *)_Impl == (void *)&_Space);
372         }
373
374     typedef void (*_Pfnty)();
375     union
376         {    // storage for small wrappers
377         _Pfnty _Pfn[3];
378         void *_Pobj[3];
379         long double _Ldbl;    // for maximum alignment
380         } _Space;
381
382     _Ptrt *_Impl;
383     };
384
385 template<class _Ret _C_CLASS_ARG0>
386     struct _Get_function_impl<_Ret(_ARG0_ARG1)>
387     {    // determine type from argument list
388     typedef _NAME<_Ret _C_ARG0_ARG1> _Type;
389     };
390
391 #undef _IMPL_NAME
392 #undef _BASE_NAME
393 #undef _NAME
394
395 /*
396  * Copyright (c) 1992-2008 by P.J. Plauger.  ALL RIGHTS RESERVED.
397  * Consult your license regarding permissions and restrictions.
398 V5.05:0009 */
399