root / lab4 / .minix-src / include / c++ / __functional_03
History | View | Annotate | Download (43.1 KB)
1 |
// -*- C++ -*- |
---|---|
2 |
//===----------------------------------------------------------------------===// |
3 |
// |
4 |
// The LLVM Compiler Infrastructure |
5 |
// |
6 |
// This file is dual licensed under the MIT and the University of Illinois Open |
7 |
// Source Licenses. See LICENSE.TXT for details. |
8 |
// |
9 |
//===----------------------------------------------------------------------===// |
10 | |
11 |
#ifndef _LIBCPP_FUNCTIONAL_03 |
12 |
#define _LIBCPP_FUNCTIONAL_03 |
13 | |
14 |
// manual variadic expansion for <functional> |
15 | |
16 |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
17 |
#pragma GCC system_header |
18 |
#endif |
19 | |
20 |
namespace __function { |
21 | |
22 |
template<class _Fp> class __base; |
23 | |
24 |
template<class _Rp> |
25 |
class __base<_Rp()> |
26 |
{ |
27 |
__base(const __base&); |
28 |
__base& operator=(const __base&); |
29 |
public: |
30 |
__base() {} |
31 |
virtual ~__base() {} |
32 |
virtual __base* __clone() const = 0; |
33 |
virtual void __clone(__base*) const = 0; |
34 |
virtual void destroy() = 0; |
35 |
virtual void destroy_deallocate() = 0; |
36 |
virtual _Rp operator()() = 0; |
37 |
#ifndef _LIBCPP_NO_RTTI |
38 |
virtual const void* target(const type_info&) const = 0; |
39 |
virtual const std::type_info& target_type() const = 0; |
40 |
#endif // _LIBCPP_NO_RTTI |
41 |
}; |
42 | |
43 |
template<class _Rp, class _A0> |
44 |
class __base<_Rp(_A0)> |
45 |
{ |
46 |
__base(const __base&); |
47 |
__base& operator=(const __base&); |
48 |
public: |
49 |
__base() {} |
50 |
virtual ~__base() {} |
51 |
virtual __base* __clone() const = 0; |
52 |
virtual void __clone(__base*) const = 0; |
53 |
virtual void destroy() = 0; |
54 |
virtual void destroy_deallocate() = 0; |
55 |
virtual _Rp operator()(_A0) = 0; |
56 |
#ifndef _LIBCPP_NO_RTTI |
57 |
virtual const void* target(const type_info&) const = 0; |
58 |
virtual const std::type_info& target_type() const = 0; |
59 |
#endif // _LIBCPP_NO_RTTI |
60 |
}; |
61 | |
62 |
template<class _Rp, class _A0, class _A1> |
63 |
class __base<_Rp(_A0, _A1)> |
64 |
{ |
65 |
__base(const __base&); |
66 |
__base& operator=(const __base&); |
67 |
public: |
68 |
__base() {} |
69 |
virtual ~__base() {} |
70 |
virtual __base* __clone() const = 0; |
71 |
virtual void __clone(__base*) const = 0; |
72 |
virtual void destroy() = 0; |
73 |
virtual void destroy_deallocate() = 0; |
74 |
virtual _Rp operator()(_A0, _A1) = 0; |
75 |
#ifndef _LIBCPP_NO_RTTI |
76 |
virtual const void* target(const type_info&) const = 0; |
77 |
virtual const std::type_info& target_type() const = 0; |
78 |
#endif // _LIBCPP_NO_RTTI |
79 |
}; |
80 | |
81 |
template<class _Rp, class _A0, class _A1, class _A2> |
82 |
class __base<_Rp(_A0, _A1, _A2)> |
83 |
{ |
84 |
__base(const __base&); |
85 |
__base& operator=(const __base&); |
86 |
public: |
87 |
__base() {} |
88 |
virtual ~__base() {} |
89 |
virtual __base* __clone() const = 0; |
90 |
virtual void __clone(__base*) const = 0; |
91 |
virtual void destroy() = 0; |
92 |
virtual void destroy_deallocate() = 0; |
93 |
virtual _Rp operator()(_A0, _A1, _A2) = 0; |
94 |
#ifndef _LIBCPP_NO_RTTI |
95 |
virtual const void* target(const type_info&) const = 0; |
96 |
virtual const std::type_info& target_type() const = 0; |
97 |
#endif // _LIBCPP_NO_RTTI |
98 |
}; |
99 | |
100 |
template<class _FD, class _Alloc, class _FB> class __func; |
101 | |
102 |
template<class _Fp, class _Alloc, class _Rp> |
103 |
class __func<_Fp, _Alloc, _Rp()> |
104 |
: public __base<_Rp()> |
105 |
{ |
106 |
__compressed_pair<_Fp, _Alloc> __f_; |
107 |
public: |
108 |
explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} |
109 |
explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} |
110 |
virtual __base<_Rp()>* __clone() const; |
111 |
virtual void __clone(__base<_Rp()>*) const; |
112 |
virtual void destroy(); |
113 |
virtual void destroy_deallocate(); |
114 |
virtual _Rp operator()(); |
115 |
#ifndef _LIBCPP_NO_RTTI |
116 |
virtual const void* target(const type_info&) const; |
117 |
virtual const std::type_info& target_type() const; |
118 |
#endif // _LIBCPP_NO_RTTI |
119 |
}; |
120 | |
121 |
template<class _Fp, class _Alloc, class _Rp> |
122 |
__base<_Rp()>* |
123 |
__func<_Fp, _Alloc, _Rp()>::__clone() const |
124 |
{ |
125 |
typedef allocator_traits<_Alloc> __alloc_traits; |
126 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
127 |
_Ap __a(__f_.second()); |
128 |
typedef __allocator_destructor<_Ap> _Dp; |
129 |
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
130 |
::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); |
131 |
return __hold.release(); |
132 |
} |
133 | |
134 |
template<class _Fp, class _Alloc, class _Rp> |
135 |
void |
136 |
__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const |
137 |
{ |
138 |
::new (__p) __func(__f_.first(), __f_.second()); |
139 |
} |
140 | |
141 |
template<class _Fp, class _Alloc, class _Rp> |
142 |
void |
143 |
__func<_Fp, _Alloc, _Rp()>::destroy() |
144 |
{ |
145 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
146 |
} |
147 | |
148 |
template<class _Fp, class _Alloc, class _Rp> |
149 |
void |
150 |
__func<_Fp, _Alloc, _Rp()>::destroy_deallocate() |
151 |
{ |
152 |
typedef allocator_traits<_Alloc> __alloc_traits; |
153 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
154 |
_Ap __a(__f_.second()); |
155 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
156 |
__a.deallocate(this, 1); |
157 |
} |
158 | |
159 |
template<class _Fp, class _Alloc, class _Rp> |
160 |
_Rp |
161 |
__func<_Fp, _Alloc, _Rp()>::operator()() |
162 |
{ |
163 |
typedef __invoke_void_return_wrapper<_Rp> _Invoker; |
164 |
return _Invoker::__call(__f_.first()); |
165 |
} |
166 | |
167 |
#ifndef _LIBCPP_NO_RTTI |
168 | |
169 |
template<class _Fp, class _Alloc, class _Rp> |
170 |
const void* |
171 |
__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const |
172 |
{ |
173 |
if (__ti == typeid(_Fp)) |
174 |
return &__f_.first(); |
175 |
return (const void*)0; |
176 |
} |
177 | |
178 |
template<class _Fp, class _Alloc, class _Rp> |
179 |
const std::type_info& |
180 |
__func<_Fp, _Alloc, _Rp()>::target_type() const |
181 |
{ |
182 |
return typeid(_Fp); |
183 |
} |
184 | |
185 |
#endif // _LIBCPP_NO_RTTI |
186 | |
187 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
188 |
class __func<_Fp, _Alloc, _Rp(_A0)> |
189 |
: public __base<_Rp(_A0)> |
190 |
{ |
191 |
__compressed_pair<_Fp, _Alloc> __f_; |
192 |
public: |
193 |
_LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} |
194 |
_LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) |
195 |
: __f_(_VSTD::move(__f), _VSTD::move(__a)) {} |
196 |
virtual __base<_Rp(_A0)>* __clone() const; |
197 |
virtual void __clone(__base<_Rp(_A0)>*) const; |
198 |
virtual void destroy(); |
199 |
virtual void destroy_deallocate(); |
200 |
virtual _Rp operator()(_A0); |
201 |
#ifndef _LIBCPP_NO_RTTI |
202 |
virtual const void* target(const type_info&) const; |
203 |
virtual const std::type_info& target_type() const; |
204 |
#endif // _LIBCPP_NO_RTTI |
205 |
}; |
206 | |
207 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
208 |
__base<_Rp(_A0)>* |
209 |
__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const |
210 |
{ |
211 |
typedef allocator_traits<_Alloc> __alloc_traits; |
212 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
213 |
_Ap __a(__f_.second()); |
214 |
typedef __allocator_destructor<_Ap> _Dp; |
215 |
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
216 |
::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); |
217 |
return __hold.release(); |
218 |
} |
219 | |
220 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
221 |
void |
222 |
__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const |
223 |
{ |
224 |
::new (__p) __func(__f_.first(), __f_.second()); |
225 |
} |
226 | |
227 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
228 |
void |
229 |
__func<_Fp, _Alloc, _Rp(_A0)>::destroy() |
230 |
{ |
231 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
232 |
} |
233 | |
234 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
235 |
void |
236 |
__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate() |
237 |
{ |
238 |
typedef allocator_traits<_Alloc> __alloc_traits; |
239 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
240 |
_Ap __a(__f_.second()); |
241 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
242 |
__a.deallocate(this, 1); |
243 |
} |
244 | |
245 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
246 |
_Rp |
247 |
__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0) |
248 |
{ |
249 |
typedef __invoke_void_return_wrapper<_Rp> _Invoker; |
250 |
return _Invoker::__call(__f_.first(), __a0); |
251 |
} |
252 | |
253 |
#ifndef _LIBCPP_NO_RTTI |
254 | |
255 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
256 |
const void* |
257 |
__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const |
258 |
{ |
259 |
if (__ti == typeid(_Fp)) |
260 |
return &__f_.first(); |
261 |
return (const void*)0; |
262 |
} |
263 | |
264 |
template<class _Fp, class _Alloc, class _Rp, class _A0> |
265 |
const std::type_info& |
266 |
__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const |
267 |
{ |
268 |
return typeid(_Fp); |
269 |
} |
270 | |
271 |
#endif // _LIBCPP_NO_RTTI |
272 | |
273 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
274 |
class __func<_Fp, _Alloc, _Rp(_A0, _A1)> |
275 |
: public __base<_Rp(_A0, _A1)> |
276 |
{ |
277 |
__compressed_pair<_Fp, _Alloc> __f_; |
278 |
public: |
279 |
_LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} |
280 |
_LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) |
281 |
: __f_(_VSTD::move(__f), _VSTD::move(__a)) {} |
282 |
virtual __base<_Rp(_A0, _A1)>* __clone() const; |
283 |
virtual void __clone(__base<_Rp(_A0, _A1)>*) const; |
284 |
virtual void destroy(); |
285 |
virtual void destroy_deallocate(); |
286 |
virtual _Rp operator()(_A0, _A1); |
287 |
#ifndef _LIBCPP_NO_RTTI |
288 |
virtual const void* target(const type_info&) const; |
289 |
virtual const std::type_info& target_type() const; |
290 |
#endif // _LIBCPP_NO_RTTI |
291 |
}; |
292 | |
293 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
294 |
__base<_Rp(_A0, _A1)>* |
295 |
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const |
296 |
{ |
297 |
typedef allocator_traits<_Alloc> __alloc_traits; |
298 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
299 |
_Ap __a(__f_.second()); |
300 |
typedef __allocator_destructor<_Ap> _Dp; |
301 |
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
302 |
::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); |
303 |
return __hold.release(); |
304 |
} |
305 | |
306 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
307 |
void |
308 |
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const |
309 |
{ |
310 |
::new (__p) __func(__f_.first(), __f_.second()); |
311 |
} |
312 | |
313 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
314 |
void |
315 |
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy() |
316 |
{ |
317 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
318 |
} |
319 | |
320 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
321 |
void |
322 |
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate() |
323 |
{ |
324 |
typedef allocator_traits<_Alloc> __alloc_traits; |
325 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
326 |
_Ap __a(__f_.second()); |
327 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
328 |
__a.deallocate(this, 1); |
329 |
} |
330 | |
331 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
332 |
_Rp |
333 |
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) |
334 |
{ |
335 |
typedef __invoke_void_return_wrapper<_Rp> _Invoker; |
336 |
return _Invoker::__call(__f_.first(), __a0, __a1); |
337 |
} |
338 | |
339 |
#ifndef _LIBCPP_NO_RTTI |
340 | |
341 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
342 |
const void* |
343 |
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const |
344 |
{ |
345 |
if (__ti == typeid(_Fp)) |
346 |
return &__f_.first(); |
347 |
return (const void*)0; |
348 |
} |
349 | |
350 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1> |
351 |
const std::type_info& |
352 |
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const |
353 |
{ |
354 |
return typeid(_Fp); |
355 |
} |
356 | |
357 |
#endif // _LIBCPP_NO_RTTI |
358 | |
359 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
360 |
class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> |
361 |
: public __base<_Rp(_A0, _A1, _A2)> |
362 |
{ |
363 |
__compressed_pair<_Fp, _Alloc> __f_; |
364 |
public: |
365 |
_LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} |
366 |
_LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) |
367 |
: __f_(_VSTD::move(__f), _VSTD::move(__a)) {} |
368 |
virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; |
369 |
virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const; |
370 |
virtual void destroy(); |
371 |
virtual void destroy_deallocate(); |
372 |
virtual _Rp operator()(_A0, _A1, _A2); |
373 |
#ifndef _LIBCPP_NO_RTTI |
374 |
virtual const void* target(const type_info&) const; |
375 |
virtual const std::type_info& target_type() const; |
376 |
#endif // _LIBCPP_NO_RTTI |
377 |
}; |
378 | |
379 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
380 |
__base<_Rp(_A0, _A1, _A2)>* |
381 |
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const |
382 |
{ |
383 |
typedef allocator_traits<_Alloc> __alloc_traits; |
384 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
385 |
_Ap __a(__f_.second()); |
386 |
typedef __allocator_destructor<_Ap> _Dp; |
387 |
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
388 |
::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); |
389 |
return __hold.release(); |
390 |
} |
391 | |
392 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
393 |
void |
394 |
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const |
395 |
{ |
396 |
::new (__p) __func(__f_.first(), __f_.second()); |
397 |
} |
398 | |
399 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
400 |
void |
401 |
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy() |
402 |
{ |
403 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
404 |
} |
405 | |
406 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
407 |
void |
408 |
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate() |
409 |
{ |
410 |
typedef allocator_traits<_Alloc> __alloc_traits; |
411 |
typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; |
412 |
_Ap __a(__f_.second()); |
413 |
__f_.~__compressed_pair<_Fp, _Alloc>(); |
414 |
__a.deallocate(this, 1); |
415 |
} |
416 | |
417 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
418 |
_Rp |
419 |
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) |
420 |
{ |
421 |
typedef __invoke_void_return_wrapper<_Rp> _Invoker; |
422 |
return _Invoker::__call(__f_.first(), __a0, __a1, __a2); |
423 |
} |
424 | |
425 |
#ifndef _LIBCPP_NO_RTTI |
426 | |
427 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
428 |
const void* |
429 |
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const |
430 |
{ |
431 |
if (__ti == typeid(_Fp)) |
432 |
return &__f_.first(); |
433 |
return (const void*)0; |
434 |
} |
435 | |
436 |
template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2> |
437 |
const std::type_info& |
438 |
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const |
439 |
{ |
440 |
return typeid(_Fp); |
441 |
} |
442 | |
443 |
#endif // _LIBCPP_NO_RTTI |
444 | |
445 |
} // __function |
446 | |
447 |
template<class _Rp> |
448 |
class _LIBCPP_TYPE_VIS_ONLY function<_Rp()> |
449 |
{ |
450 |
typedef __function::__base<_Rp()> __base; |
451 |
aligned_storage<3*sizeof(void*)>::type __buf_; |
452 |
__base* __f_; |
453 | |
454 |
public: |
455 |
typedef _Rp result_type; |
456 | |
457 |
// 20.7.16.2.1, construct/copy/destroy: |
458 |
_LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} |
459 |
_LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} |
460 |
function(const function&); |
461 |
template<class _Fp> |
462 |
function(_Fp, |
463 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
464 | |
465 |
template<class _Alloc> |
466 |
_LIBCPP_INLINE_VISIBILITY |
467 |
function(allocator_arg_t, const _Alloc&) : __f_(0) {} |
468 |
template<class _Alloc> |
469 |
_LIBCPP_INLINE_VISIBILITY |
470 |
function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} |
471 |
template<class _Alloc> |
472 |
function(allocator_arg_t, const _Alloc&, const function&); |
473 |
template<class _Fp, class _Alloc> |
474 |
function(allocator_arg_t, const _Alloc& __a, _Fp __f, |
475 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
476 | |
477 |
function& operator=(const function&); |
478 |
function& operator=(nullptr_t); |
479 |
template<class _Fp> |
480 |
typename enable_if |
481 |
< |
482 |
!is_integral<_Fp>::value, |
483 |
function& |
484 |
>::type |
485 |
operator=(_Fp); |
486 | |
487 |
~function(); |
488 | |
489 |
// 20.7.16.2.2, function modifiers: |
490 |
void swap(function&); |
491 |
template<class _Fp, class _Alloc> |
492 |
_LIBCPP_INLINE_VISIBILITY |
493 |
void assign(_Fp __f, const _Alloc& __a) |
494 |
{function(allocator_arg, __a, __f).swap(*this);} |
495 | |
496 |
// 20.7.16.2.3, function capacity: |
497 |
_LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} |
498 | |
499 |
private: |
500 |
// deleted overloads close possible hole in the type system |
501 |
template<class _R2> |
502 |
bool operator==(const function<_R2()>&) const;// = delete; |
503 |
template<class _R2> |
504 |
bool operator!=(const function<_R2()>&) const;// = delete; |
505 |
public: |
506 |
// 20.7.16.2.4, function invocation: |
507 |
_Rp operator()() const; |
508 | |
509 |
#ifndef _LIBCPP_NO_RTTI |
510 |
// 20.7.16.2.5, function target access: |
511 |
const std::type_info& target_type() const; |
512 |
template <typename _Tp> _Tp* target(); |
513 |
template <typename _Tp> const _Tp* target() const; |
514 |
#endif // _LIBCPP_NO_RTTI |
515 |
}; |
516 | |
517 |
template<class _Rp> |
518 |
function<_Rp()>::function(const function& __f) |
519 |
{ |
520 |
if (__f.__f_ == 0) |
521 |
__f_ = 0; |
522 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
523 |
{ |
524 |
__f_ = (__base*)&__buf_; |
525 |
__f.__f_->__clone(__f_); |
526 |
} |
527 |
else |
528 |
__f_ = __f.__f_->__clone(); |
529 |
} |
530 | |
531 |
template<class _Rp> |
532 |
template<class _Alloc> |
533 |
function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f) |
534 |
{ |
535 |
if (__f.__f_ == 0) |
536 |
__f_ = 0; |
537 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
538 |
{ |
539 |
__f_ = (__base*)&__buf_; |
540 |
__f.__f_->__clone(__f_); |
541 |
} |
542 |
else |
543 |
__f_ = __f.__f_->__clone(); |
544 |
} |
545 | |
546 |
template<class _Rp> |
547 |
template <class _Fp> |
548 |
function<_Rp()>::function(_Fp __f, |
549 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
550 |
: __f_(0) |
551 |
{ |
552 |
if (__function::__not_null(__f)) |
553 |
{ |
554 |
typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF; |
555 |
if (sizeof(_FF) <= sizeof(__buf_)) |
556 |
{ |
557 |
__f_ = (__base*)&__buf_; |
558 |
::new (__f_) _FF(__f); |
559 |
} |
560 |
else |
561 |
{ |
562 |
typedef allocator<_FF> _Ap; |
563 |
_Ap __a; |
564 |
typedef __allocator_destructor<_Ap> _Dp; |
565 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
566 |
::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); |
567 |
__f_ = __hold.release(); |
568 |
} |
569 |
} |
570 |
} |
571 | |
572 |
template<class _Rp> |
573 |
template <class _Fp, class _Alloc> |
574 |
function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, |
575 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
576 |
: __f_(0) |
577 |
{ |
578 |
typedef allocator_traits<_Alloc> __alloc_traits; |
579 |
if (__function::__not_null(__f)) |
580 |
{ |
581 |
typedef __function::__func<_Fp, _Alloc, _Rp()> _FF; |
582 |
if (sizeof(_FF) <= sizeof(__buf_)) |
583 |
{ |
584 |
__f_ = (__base*)&__buf_; |
585 |
::new (__f_) _FF(__f, __a0); |
586 |
} |
587 |
else |
588 |
{ |
589 |
typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; |
590 |
_Ap __a(__a0); |
591 |
typedef __allocator_destructor<_Ap> _Dp; |
592 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
593 |
::new (__hold.get()) _FF(__f, _Alloc(__a)); |
594 |
__f_ = __hold.release(); |
595 |
} |
596 |
} |
597 |
} |
598 | |
599 |
template<class _Rp> |
600 |
function<_Rp()>& |
601 |
function<_Rp()>::operator=(const function& __f) |
602 |
{ |
603 |
function(__f).swap(*this); |
604 |
return *this; |
605 |
} |
606 | |
607 |
template<class _Rp> |
608 |
function<_Rp()>& |
609 |
function<_Rp()>::operator=(nullptr_t) |
610 |
{ |
611 |
if (__f_ == (__base*)&__buf_) |
612 |
__f_->destroy(); |
613 |
else if (__f_) |
614 |
__f_->destroy_deallocate(); |
615 |
__f_ = 0; |
616 |
return *this; |
617 |
} |
618 | |
619 |
template<class _Rp> |
620 |
template <class _Fp> |
621 |
typename enable_if |
622 |
< |
623 |
!is_integral<_Fp>::value, |
624 |
function<_Rp()>& |
625 |
>::type |
626 |
function<_Rp()>::operator=(_Fp __f) |
627 |
{ |
628 |
function(_VSTD::move(__f)).swap(*this); |
629 |
return *this; |
630 |
} |
631 | |
632 |
template<class _Rp> |
633 |
function<_Rp()>::~function() |
634 |
{ |
635 |
if (__f_ == (__base*)&__buf_) |
636 |
__f_->destroy(); |
637 |
else if (__f_) |
638 |
__f_->destroy_deallocate(); |
639 |
} |
640 | |
641 |
template<class _Rp> |
642 |
void |
643 |
function<_Rp()>::swap(function& __f) |
644 |
{ |
645 |
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) |
646 |
{ |
647 |
typename aligned_storage<sizeof(__buf_)>::type __tempbuf; |
648 |
__base* __t = (__base*)&__tempbuf; |
649 |
__f_->__clone(__t); |
650 |
__f_->destroy(); |
651 |
__f_ = 0; |
652 |
__f.__f_->__clone((__base*)&__buf_); |
653 |
__f.__f_->destroy(); |
654 |
__f.__f_ = 0; |
655 |
__f_ = (__base*)&__buf_; |
656 |
__t->__clone((__base*)&__f.__buf_); |
657 |
__t->destroy(); |
658 |
__f.__f_ = (__base*)&__f.__buf_; |
659 |
} |
660 |
else if (__f_ == (__base*)&__buf_) |
661 |
{ |
662 |
__f_->__clone((__base*)&__f.__buf_); |
663 |
__f_->destroy(); |
664 |
__f_ = __f.__f_; |
665 |
__f.__f_ = (__base*)&__f.__buf_; |
666 |
} |
667 |
else if (__f.__f_ == (__base*)&__f.__buf_) |
668 |
{ |
669 |
__f.__f_->__clone((__base*)&__buf_); |
670 |
__f.__f_->destroy(); |
671 |
__f.__f_ = __f_; |
672 |
__f_ = (__base*)&__buf_; |
673 |
} |
674 |
else |
675 |
_VSTD::swap(__f_, __f.__f_); |
676 |
} |
677 | |
678 |
template<class _Rp> |
679 |
_Rp |
680 |
function<_Rp()>::operator()() const |
681 |
{ |
682 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
683 |
if (__f_ == 0) |
684 |
throw bad_function_call(); |
685 |
#endif // _LIBCPP_NO_EXCEPTIONS |
686 |
return (*__f_)(); |
687 |
} |
688 | |
689 |
#ifndef _LIBCPP_NO_RTTI |
690 | |
691 |
template<class _Rp> |
692 |
const std::type_info& |
693 |
function<_Rp()>::target_type() const |
694 |
{ |
695 |
if (__f_ == 0) |
696 |
return typeid(void); |
697 |
return __f_->target_type(); |
698 |
} |
699 | |
700 |
template<class _Rp> |
701 |
template <typename _Tp> |
702 |
_Tp* |
703 |
function<_Rp()>::target() |
704 |
{ |
705 |
if (__f_ == 0) |
706 |
return (_Tp*)0; |
707 |
return (_Tp*)__f_->target(typeid(_Tp)); |
708 |
} |
709 | |
710 |
template<class _Rp> |
711 |
template <typename _Tp> |
712 |
const _Tp* |
713 |
function<_Rp()>::target() const |
714 |
{ |
715 |
if (__f_ == 0) |
716 |
return (const _Tp*)0; |
717 |
return (const _Tp*)__f_->target(typeid(_Tp)); |
718 |
} |
719 | |
720 |
#endif // _LIBCPP_NO_RTTI |
721 | |
722 |
template<class _Rp, class _A0> |
723 |
class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)> |
724 |
: public unary_function<_A0, _Rp> |
725 |
{ |
726 |
typedef __function::__base<_Rp(_A0)> __base; |
727 |
aligned_storage<3*sizeof(void*)>::type __buf_; |
728 |
__base* __f_; |
729 | |
730 |
public: |
731 |
typedef _Rp result_type; |
732 | |
733 |
// 20.7.16.2.1, construct/copy/destroy: |
734 |
_LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} |
735 |
_LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} |
736 |
function(const function&); |
737 |
template<class _Fp> |
738 |
function(_Fp, |
739 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
740 | |
741 |
template<class _Alloc> |
742 |
_LIBCPP_INLINE_VISIBILITY |
743 |
function(allocator_arg_t, const _Alloc&) : __f_(0) {} |
744 |
template<class _Alloc> |
745 |
_LIBCPP_INLINE_VISIBILITY |
746 |
function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} |
747 |
template<class _Alloc> |
748 |
function(allocator_arg_t, const _Alloc&, const function&); |
749 |
template<class _Fp, class _Alloc> |
750 |
function(allocator_arg_t, const _Alloc& __a, _Fp __f, |
751 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
752 | |
753 |
function& operator=(const function&); |
754 |
function& operator=(nullptr_t); |
755 |
template<class _Fp> |
756 |
typename enable_if |
757 |
< |
758 |
!is_integral<_Fp>::value, |
759 |
function& |
760 |
>::type |
761 |
operator=(_Fp); |
762 | |
763 |
~function(); |
764 | |
765 |
// 20.7.16.2.2, function modifiers: |
766 |
void swap(function&); |
767 |
template<class _Fp, class _Alloc> |
768 |
_LIBCPP_INLINE_VISIBILITY |
769 |
void assign(_Fp __f, const _Alloc& __a) |
770 |
{function(allocator_arg, __a, __f).swap(*this);} |
771 | |
772 |
// 20.7.16.2.3, function capacity: |
773 |
_LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} |
774 | |
775 |
private: |
776 |
// deleted overloads close possible hole in the type system |
777 |
template<class _R2, class _B0> |
778 |
bool operator==(const function<_R2(_B0)>&) const;// = delete; |
779 |
template<class _R2, class _B0> |
780 |
bool operator!=(const function<_R2(_B0)>&) const;// = delete; |
781 |
public: |
782 |
// 20.7.16.2.4, function invocation: |
783 |
_Rp operator()(_A0) const; |
784 | |
785 |
#ifndef _LIBCPP_NO_RTTI |
786 |
// 20.7.16.2.5, function target access: |
787 |
const std::type_info& target_type() const; |
788 |
template <typename _Tp> _Tp* target(); |
789 |
template <typename _Tp> const _Tp* target() const; |
790 |
#endif // _LIBCPP_NO_RTTI |
791 |
}; |
792 | |
793 |
template<class _Rp, class _A0> |
794 |
function<_Rp(_A0)>::function(const function& __f) |
795 |
{ |
796 |
if (__f.__f_ == 0) |
797 |
__f_ = 0; |
798 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
799 |
{ |
800 |
__f_ = (__base*)&__buf_; |
801 |
__f.__f_->__clone(__f_); |
802 |
} |
803 |
else |
804 |
__f_ = __f.__f_->__clone(); |
805 |
} |
806 | |
807 |
template<class _Rp, class _A0> |
808 |
template<class _Alloc> |
809 |
function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f) |
810 |
{ |
811 |
if (__f.__f_ == 0) |
812 |
__f_ = 0; |
813 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
814 |
{ |
815 |
__f_ = (__base*)&__buf_; |
816 |
__f.__f_->__clone(__f_); |
817 |
} |
818 |
else |
819 |
__f_ = __f.__f_->__clone(); |
820 |
} |
821 | |
822 |
template<class _Rp, class _A0> |
823 |
template <class _Fp> |
824 |
function<_Rp(_A0)>::function(_Fp __f, |
825 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
826 |
: __f_(0) |
827 |
{ |
828 |
if (__function::__not_null(__f)) |
829 |
{ |
830 |
typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF; |
831 |
if (sizeof(_FF) <= sizeof(__buf_)) |
832 |
{ |
833 |
__f_ = (__base*)&__buf_; |
834 |
::new (__f_) _FF(__f); |
835 |
} |
836 |
else |
837 |
{ |
838 |
typedef allocator<_FF> _Ap; |
839 |
_Ap __a; |
840 |
typedef __allocator_destructor<_Ap> _Dp; |
841 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
842 |
::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); |
843 |
__f_ = __hold.release(); |
844 |
} |
845 |
} |
846 |
} |
847 | |
848 |
template<class _Rp, class _A0> |
849 |
template <class _Fp, class _Alloc> |
850 |
function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, |
851 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
852 |
: __f_(0) |
853 |
{ |
854 |
typedef allocator_traits<_Alloc> __alloc_traits; |
855 |
if (__function::__not_null(__f)) |
856 |
{ |
857 |
typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF; |
858 |
if (sizeof(_FF) <= sizeof(__buf_)) |
859 |
{ |
860 |
__f_ = (__base*)&__buf_; |
861 |
::new (__f_) _FF(__f, __a0); |
862 |
} |
863 |
else |
864 |
{ |
865 |
typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; |
866 |
_Ap __a(__a0); |
867 |
typedef __allocator_destructor<_Ap> _Dp; |
868 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
869 |
::new (__hold.get()) _FF(__f, _Alloc(__a)); |
870 |
__f_ = __hold.release(); |
871 |
} |
872 |
} |
873 |
} |
874 | |
875 |
template<class _Rp, class _A0> |
876 |
function<_Rp(_A0)>& |
877 |
function<_Rp(_A0)>::operator=(const function& __f) |
878 |
{ |
879 |
function(__f).swap(*this); |
880 |
return *this; |
881 |
} |
882 | |
883 |
template<class _Rp, class _A0> |
884 |
function<_Rp(_A0)>& |
885 |
function<_Rp(_A0)>::operator=(nullptr_t) |
886 |
{ |
887 |
if (__f_ == (__base*)&__buf_) |
888 |
__f_->destroy(); |
889 |
else if (__f_) |
890 |
__f_->destroy_deallocate(); |
891 |
__f_ = 0; |
892 |
return *this; |
893 |
} |
894 | |
895 |
template<class _Rp, class _A0> |
896 |
template <class _Fp> |
897 |
typename enable_if |
898 |
< |
899 |
!is_integral<_Fp>::value, |
900 |
function<_Rp(_A0)>& |
901 |
>::type |
902 |
function<_Rp(_A0)>::operator=(_Fp __f) |
903 |
{ |
904 |
function(_VSTD::move(__f)).swap(*this); |
905 |
return *this; |
906 |
} |
907 | |
908 |
template<class _Rp, class _A0> |
909 |
function<_Rp(_A0)>::~function() |
910 |
{ |
911 |
if (__f_ == (__base*)&__buf_) |
912 |
__f_->destroy(); |
913 |
else if (__f_) |
914 |
__f_->destroy_deallocate(); |
915 |
} |
916 | |
917 |
template<class _Rp, class _A0> |
918 |
void |
919 |
function<_Rp(_A0)>::swap(function& __f) |
920 |
{ |
921 |
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) |
922 |
{ |
923 |
typename aligned_storage<sizeof(__buf_)>::type __tempbuf; |
924 |
__base* __t = (__base*)&__tempbuf; |
925 |
__f_->__clone(__t); |
926 |
__f_->destroy(); |
927 |
__f_ = 0; |
928 |
__f.__f_->__clone((__base*)&__buf_); |
929 |
__f.__f_->destroy(); |
930 |
__f.__f_ = 0; |
931 |
__f_ = (__base*)&__buf_; |
932 |
__t->__clone((__base*)&__f.__buf_); |
933 |
__t->destroy(); |
934 |
__f.__f_ = (__base*)&__f.__buf_; |
935 |
} |
936 |
else if (__f_ == (__base*)&__buf_) |
937 |
{ |
938 |
__f_->__clone((__base*)&__f.__buf_); |
939 |
__f_->destroy(); |
940 |
__f_ = __f.__f_; |
941 |
__f.__f_ = (__base*)&__f.__buf_; |
942 |
} |
943 |
else if (__f.__f_ == (__base*)&__f.__buf_) |
944 |
{ |
945 |
__f.__f_->__clone((__base*)&__buf_); |
946 |
__f.__f_->destroy(); |
947 |
__f.__f_ = __f_; |
948 |
__f_ = (__base*)&__buf_; |
949 |
} |
950 |
else |
951 |
_VSTD::swap(__f_, __f.__f_); |
952 |
} |
953 | |
954 |
template<class _Rp, class _A0> |
955 |
_Rp |
956 |
function<_Rp(_A0)>::operator()(_A0 __a0) const |
957 |
{ |
958 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
959 |
if (__f_ == 0) |
960 |
throw bad_function_call(); |
961 |
#endif // _LIBCPP_NO_EXCEPTIONS |
962 |
return (*__f_)(__a0); |
963 |
} |
964 | |
965 |
#ifndef _LIBCPP_NO_RTTI |
966 | |
967 |
template<class _Rp, class _A0> |
968 |
const std::type_info& |
969 |
function<_Rp(_A0)>::target_type() const |
970 |
{ |
971 |
if (__f_ == 0) |
972 |
return typeid(void); |
973 |
return __f_->target_type(); |
974 |
} |
975 | |
976 |
template<class _Rp, class _A0> |
977 |
template <typename _Tp> |
978 |
_Tp* |
979 |
function<_Rp(_A0)>::target() |
980 |
{ |
981 |
if (__f_ == 0) |
982 |
return (_Tp*)0; |
983 |
return (_Tp*)__f_->target(typeid(_Tp)); |
984 |
} |
985 | |
986 |
template<class _Rp, class _A0> |
987 |
template <typename _Tp> |
988 |
const _Tp* |
989 |
function<_Rp(_A0)>::target() const |
990 |
{ |
991 |
if (__f_ == 0) |
992 |
return (const _Tp*)0; |
993 |
return (const _Tp*)__f_->target(typeid(_Tp)); |
994 |
} |
995 | |
996 |
#endif // _LIBCPP_NO_RTTI |
997 | |
998 |
template<class _Rp, class _A0, class _A1> |
999 |
class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)> |
1000 |
: public binary_function<_A0, _A1, _Rp> |
1001 |
{ |
1002 |
typedef __function::__base<_Rp(_A0, _A1)> __base; |
1003 |
aligned_storage<3*sizeof(void*)>::type __buf_; |
1004 |
__base* __f_; |
1005 | |
1006 |
public: |
1007 |
typedef _Rp result_type; |
1008 | |
1009 |
// 20.7.16.2.1, construct/copy/destroy: |
1010 |
_LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} |
1011 |
_LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} |
1012 |
function(const function&); |
1013 |
template<class _Fp> |
1014 |
function(_Fp, |
1015 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
1016 | |
1017 |
template<class _Alloc> |
1018 |
_LIBCPP_INLINE_VISIBILITY |
1019 |
function(allocator_arg_t, const _Alloc&) : __f_(0) {} |
1020 |
template<class _Alloc> |
1021 |
_LIBCPP_INLINE_VISIBILITY |
1022 |
function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} |
1023 |
template<class _Alloc> |
1024 |
function(allocator_arg_t, const _Alloc&, const function&); |
1025 |
template<class _Fp, class _Alloc> |
1026 |
function(allocator_arg_t, const _Alloc& __a, _Fp __f, |
1027 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
1028 | |
1029 |
function& operator=(const function&); |
1030 |
function& operator=(nullptr_t); |
1031 |
template<class _Fp> |
1032 |
typename enable_if |
1033 |
< |
1034 |
!is_integral<_Fp>::value, |
1035 |
function& |
1036 |
>::type |
1037 |
operator=(_Fp); |
1038 | |
1039 |
~function(); |
1040 | |
1041 |
// 20.7.16.2.2, function modifiers: |
1042 |
void swap(function&); |
1043 |
template<class _Fp, class _Alloc> |
1044 |
_LIBCPP_INLINE_VISIBILITY |
1045 |
void assign(_Fp __f, const _Alloc& __a) |
1046 |
{function(allocator_arg, __a, __f).swap(*this);} |
1047 | |
1048 |
// 20.7.16.2.3, function capacity: |
1049 |
operator bool() const {return __f_;} |
1050 | |
1051 |
private: |
1052 |
// deleted overloads close possible hole in the type system |
1053 |
template<class _R2, class _B0, class _B1> |
1054 |
bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete; |
1055 |
template<class _R2, class _B0, class _B1> |
1056 |
bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete; |
1057 |
public: |
1058 |
// 20.7.16.2.4, function invocation: |
1059 |
_Rp operator()(_A0, _A1) const; |
1060 | |
1061 |
#ifndef _LIBCPP_NO_RTTI |
1062 |
// 20.7.16.2.5, function target access: |
1063 |
const std::type_info& target_type() const; |
1064 |
template <typename _Tp> _Tp* target(); |
1065 |
template <typename _Tp> const _Tp* target() const; |
1066 |
#endif // _LIBCPP_NO_RTTI |
1067 |
}; |
1068 | |
1069 |
template<class _Rp, class _A0, class _A1> |
1070 |
function<_Rp(_A0, _A1)>::function(const function& __f) |
1071 |
{ |
1072 |
if (__f.__f_ == 0) |
1073 |
__f_ = 0; |
1074 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
1075 |
{ |
1076 |
__f_ = (__base*)&__buf_; |
1077 |
__f.__f_->__clone(__f_); |
1078 |
} |
1079 |
else |
1080 |
__f_ = __f.__f_->__clone(); |
1081 |
} |
1082 | |
1083 |
template<class _Rp, class _A0, class _A1> |
1084 |
template<class _Alloc> |
1085 |
function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f) |
1086 |
{ |
1087 |
if (__f.__f_ == 0) |
1088 |
__f_ = 0; |
1089 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
1090 |
{ |
1091 |
__f_ = (__base*)&__buf_; |
1092 |
__f.__f_->__clone(__f_); |
1093 |
} |
1094 |
else |
1095 |
__f_ = __f.__f_->__clone(); |
1096 |
} |
1097 | |
1098 |
template<class _Rp, class _A0, class _A1> |
1099 |
template <class _Fp> |
1100 |
function<_Rp(_A0, _A1)>::function(_Fp __f, |
1101 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
1102 |
: __f_(0) |
1103 |
{ |
1104 |
if (__function::__not_null(__f)) |
1105 |
{ |
1106 |
typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF; |
1107 |
if (sizeof(_FF) <= sizeof(__buf_)) |
1108 |
{ |
1109 |
__f_ = (__base*)&__buf_; |
1110 |
::new (__f_) _FF(__f); |
1111 |
} |
1112 |
else |
1113 |
{ |
1114 |
typedef allocator<_FF> _Ap; |
1115 |
_Ap __a; |
1116 |
typedef __allocator_destructor<_Ap> _Dp; |
1117 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1118 |
::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); |
1119 |
__f_ = __hold.release(); |
1120 |
} |
1121 |
} |
1122 |
} |
1123 | |
1124 |
template<class _Rp, class _A0, class _A1> |
1125 |
template <class _Fp, class _Alloc> |
1126 |
function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, |
1127 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
1128 |
: __f_(0) |
1129 |
{ |
1130 |
typedef allocator_traits<_Alloc> __alloc_traits; |
1131 |
if (__function::__not_null(__f)) |
1132 |
{ |
1133 |
typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF; |
1134 |
if (sizeof(_FF) <= sizeof(__buf_)) |
1135 |
{ |
1136 |
__f_ = (__base*)&__buf_; |
1137 |
::new (__f_) _FF(__f, __a0); |
1138 |
} |
1139 |
else |
1140 |
{ |
1141 |
typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; |
1142 |
_Ap __a(__a0); |
1143 |
typedef __allocator_destructor<_Ap> _Dp; |
1144 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1145 |
::new (__hold.get()) _FF(__f, _Alloc(__a)); |
1146 |
__f_ = __hold.release(); |
1147 |
} |
1148 |
} |
1149 |
} |
1150 | |
1151 |
template<class _Rp, class _A0, class _A1> |
1152 |
function<_Rp(_A0, _A1)>& |
1153 |
function<_Rp(_A0, _A1)>::operator=(const function& __f) |
1154 |
{ |
1155 |
function(__f).swap(*this); |
1156 |
return *this; |
1157 |
} |
1158 | |
1159 |
template<class _Rp, class _A0, class _A1> |
1160 |
function<_Rp(_A0, _A1)>& |
1161 |
function<_Rp(_A0, _A1)>::operator=(nullptr_t) |
1162 |
{ |
1163 |
if (__f_ == (__base*)&__buf_) |
1164 |
__f_->destroy(); |
1165 |
else if (__f_) |
1166 |
__f_->destroy_deallocate(); |
1167 |
__f_ = 0; |
1168 |
return *this; |
1169 |
} |
1170 | |
1171 |
template<class _Rp, class _A0, class _A1> |
1172 |
template <class _Fp> |
1173 |
typename enable_if |
1174 |
< |
1175 |
!is_integral<_Fp>::value, |
1176 |
function<_Rp(_A0, _A1)>& |
1177 |
>::type |
1178 |
function<_Rp(_A0, _A1)>::operator=(_Fp __f) |
1179 |
{ |
1180 |
function(_VSTD::move(__f)).swap(*this); |
1181 |
return *this; |
1182 |
} |
1183 | |
1184 |
template<class _Rp, class _A0, class _A1> |
1185 |
function<_Rp(_A0, _A1)>::~function() |
1186 |
{ |
1187 |
if (__f_ == (__base*)&__buf_) |
1188 |
__f_->destroy(); |
1189 |
else if (__f_) |
1190 |
__f_->destroy_deallocate(); |
1191 |
} |
1192 | |
1193 |
template<class _Rp, class _A0, class _A1> |
1194 |
void |
1195 |
function<_Rp(_A0, _A1)>::swap(function& __f) |
1196 |
{ |
1197 |
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) |
1198 |
{ |
1199 |
typename aligned_storage<sizeof(__buf_)>::type __tempbuf; |
1200 |
__base* __t = (__base*)&__tempbuf; |
1201 |
__f_->__clone(__t); |
1202 |
__f_->destroy(); |
1203 |
__f_ = 0; |
1204 |
__f.__f_->__clone((__base*)&__buf_); |
1205 |
__f.__f_->destroy(); |
1206 |
__f.__f_ = 0; |
1207 |
__f_ = (__base*)&__buf_; |
1208 |
__t->__clone((__base*)&__f.__buf_); |
1209 |
__t->destroy(); |
1210 |
__f.__f_ = (__base*)&__f.__buf_; |
1211 |
} |
1212 |
else if (__f_ == (__base*)&__buf_) |
1213 |
{ |
1214 |
__f_->__clone((__base*)&__f.__buf_); |
1215 |
__f_->destroy(); |
1216 |
__f_ = __f.__f_; |
1217 |
__f.__f_ = (__base*)&__f.__buf_; |
1218 |
} |
1219 |
else if (__f.__f_ == (__base*)&__f.__buf_) |
1220 |
{ |
1221 |
__f.__f_->__clone((__base*)&__buf_); |
1222 |
__f.__f_->destroy(); |
1223 |
__f.__f_ = __f_; |
1224 |
__f_ = (__base*)&__buf_; |
1225 |
} |
1226 |
else |
1227 |
_VSTD::swap(__f_, __f.__f_); |
1228 |
} |
1229 | |
1230 |
template<class _Rp, class _A0, class _A1> |
1231 |
_Rp |
1232 |
function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const |
1233 |
{ |
1234 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1235 |
if (__f_ == 0) |
1236 |
throw bad_function_call(); |
1237 |
#endif // _LIBCPP_NO_EXCEPTIONS |
1238 |
return (*__f_)(__a0, __a1); |
1239 |
} |
1240 | |
1241 |
#ifndef _LIBCPP_NO_RTTI |
1242 | |
1243 |
template<class _Rp, class _A0, class _A1> |
1244 |
const std::type_info& |
1245 |
function<_Rp(_A0, _A1)>::target_type() const |
1246 |
{ |
1247 |
if (__f_ == 0) |
1248 |
return typeid(void); |
1249 |
return __f_->target_type(); |
1250 |
} |
1251 | |
1252 |
template<class _Rp, class _A0, class _A1> |
1253 |
template <typename _Tp> |
1254 |
_Tp* |
1255 |
function<_Rp(_A0, _A1)>::target() |
1256 |
{ |
1257 |
if (__f_ == 0) |
1258 |
return (_Tp*)0; |
1259 |
return (_Tp*)__f_->target(typeid(_Tp)); |
1260 |
} |
1261 | |
1262 |
template<class _Rp, class _A0, class _A1> |
1263 |
template <typename _Tp> |
1264 |
const _Tp* |
1265 |
function<_Rp(_A0, _A1)>::target() const |
1266 |
{ |
1267 |
if (__f_ == 0) |
1268 |
return (const _Tp*)0; |
1269 |
return (const _Tp*)__f_->target(typeid(_Tp)); |
1270 |
} |
1271 | |
1272 |
#endif // _LIBCPP_NO_RTTI |
1273 | |
1274 |
template<class _Rp, class _A0, class _A1, class _A2> |
1275 |
class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)> |
1276 |
{ |
1277 |
typedef __function::__base<_Rp(_A0, _A1, _A2)> __base; |
1278 |
aligned_storage<3*sizeof(void*)>::type __buf_; |
1279 |
__base* __f_; |
1280 | |
1281 |
public: |
1282 |
typedef _Rp result_type; |
1283 | |
1284 |
// 20.7.16.2.1, construct/copy/destroy: |
1285 |
_LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {} |
1286 |
_LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {} |
1287 |
function(const function&); |
1288 |
template<class _Fp> |
1289 |
function(_Fp, |
1290 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
1291 | |
1292 |
template<class _Alloc> |
1293 |
_LIBCPP_INLINE_VISIBILITY |
1294 |
function(allocator_arg_t, const _Alloc&) : __f_(0) {} |
1295 |
template<class _Alloc> |
1296 |
_LIBCPP_INLINE_VISIBILITY |
1297 |
function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {} |
1298 |
template<class _Alloc> |
1299 |
function(allocator_arg_t, const _Alloc&, const function&); |
1300 |
template<class _Fp, class _Alloc> |
1301 |
function(allocator_arg_t, const _Alloc& __a, _Fp __f, |
1302 |
typename enable_if<!is_integral<_Fp>::value>::type* = 0); |
1303 | |
1304 |
function& operator=(const function&); |
1305 |
function& operator=(nullptr_t); |
1306 |
template<class _Fp> |
1307 |
typename enable_if |
1308 |
< |
1309 |
!is_integral<_Fp>::value, |
1310 |
function& |
1311 |
>::type |
1312 |
operator=(_Fp); |
1313 | |
1314 |
~function(); |
1315 | |
1316 |
// 20.7.16.2.2, function modifiers: |
1317 |
void swap(function&); |
1318 |
template<class _Fp, class _Alloc> |
1319 |
_LIBCPP_INLINE_VISIBILITY |
1320 |
void assign(_Fp __f, const _Alloc& __a) |
1321 |
{function(allocator_arg, __a, __f).swap(*this);} |
1322 | |
1323 |
// 20.7.16.2.3, function capacity: |
1324 |
_LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;} |
1325 | |
1326 |
private: |
1327 |
// deleted overloads close possible hole in the type system |
1328 |
template<class _R2, class _B0, class _B1, class _B2> |
1329 |
bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; |
1330 |
template<class _R2, class _B0, class _B1, class _B2> |
1331 |
bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete; |
1332 |
public: |
1333 |
// 20.7.16.2.4, function invocation: |
1334 |
_Rp operator()(_A0, _A1, _A2) const; |
1335 | |
1336 |
#ifndef _LIBCPP_NO_RTTI |
1337 |
// 20.7.16.2.5, function target access: |
1338 |
const std::type_info& target_type() const; |
1339 |
template <typename _Tp> _Tp* target(); |
1340 |
template <typename _Tp> const _Tp* target() const; |
1341 |
#endif // _LIBCPP_NO_RTTI |
1342 |
}; |
1343 | |
1344 |
template<class _Rp, class _A0, class _A1, class _A2> |
1345 |
function<_Rp(_A0, _A1, _A2)>::function(const function& __f) |
1346 |
{ |
1347 |
if (__f.__f_ == 0) |
1348 |
__f_ = 0; |
1349 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
1350 |
{ |
1351 |
__f_ = (__base*)&__buf_; |
1352 |
__f.__f_->__clone(__f_); |
1353 |
} |
1354 |
else |
1355 |
__f_ = __f.__f_->__clone(); |
1356 |
} |
1357 | |
1358 |
template<class _Rp, class _A0, class _A1, class _A2> |
1359 |
template<class _Alloc> |
1360 |
function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&, |
1361 |
const function& __f) |
1362 |
{ |
1363 |
if (__f.__f_ == 0) |
1364 |
__f_ = 0; |
1365 |
else if (__f.__f_ == (const __base*)&__f.__buf_) |
1366 |
{ |
1367 |
__f_ = (__base*)&__buf_; |
1368 |
__f.__f_->__clone(__f_); |
1369 |
} |
1370 |
else |
1371 |
__f_ = __f.__f_->__clone(); |
1372 |
} |
1373 | |
1374 |
template<class _Rp, class _A0, class _A1, class _A2> |
1375 |
template <class _Fp> |
1376 |
function<_Rp(_A0, _A1, _A2)>::function(_Fp __f, |
1377 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
1378 |
: __f_(0) |
1379 |
{ |
1380 |
if (__function::__not_null(__f)) |
1381 |
{ |
1382 |
typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF; |
1383 |
if (sizeof(_FF) <= sizeof(__buf_)) |
1384 |
{ |
1385 |
__f_ = (__base*)&__buf_; |
1386 |
::new (__f_) _FF(__f); |
1387 |
} |
1388 |
else |
1389 |
{ |
1390 |
typedef allocator<_FF> _Ap; |
1391 |
_Ap __a; |
1392 |
typedef __allocator_destructor<_Ap> _Dp; |
1393 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1394 |
::new (__hold.get()) _FF(__f, allocator<_Fp>(__a)); |
1395 |
__f_ = __hold.release(); |
1396 |
} |
1397 |
} |
1398 |
} |
1399 | |
1400 |
template<class _Rp, class _A0, class _A1, class _A2> |
1401 |
template <class _Fp, class _Alloc> |
1402 |
function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, |
1403 |
typename enable_if<!is_integral<_Fp>::value>::type*) |
1404 |
: __f_(0) |
1405 |
{ |
1406 |
typedef allocator_traits<_Alloc> __alloc_traits; |
1407 |
if (__function::__not_null(__f)) |
1408 |
{ |
1409 |
typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF; |
1410 |
if (sizeof(_FF) <= sizeof(__buf_)) |
1411 |
{ |
1412 |
__f_ = (__base*)&__buf_; |
1413 |
::new (__f_) _FF(__f, __a0); |
1414 |
} |
1415 |
else |
1416 |
{ |
1417 |
typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; |
1418 |
_Ap __a(__a0); |
1419 |
typedef __allocator_destructor<_Ap> _Dp; |
1420 |
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); |
1421 |
::new (__hold.get()) _FF(__f, _Alloc(__a)); |
1422 |
__f_ = __hold.release(); |
1423 |
} |
1424 |
} |
1425 |
} |
1426 | |
1427 |
template<class _Rp, class _A0, class _A1, class _A2> |
1428 |
function<_Rp(_A0, _A1, _A2)>& |
1429 |
function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f) |
1430 |
{ |
1431 |
function(__f).swap(*this); |
1432 |
return *this; |
1433 |
} |
1434 | |
1435 |
template<class _Rp, class _A0, class _A1, class _A2> |
1436 |
function<_Rp(_A0, _A1, _A2)>& |
1437 |
function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t) |
1438 |
{ |
1439 |
if (__f_ == (__base*)&__buf_) |
1440 |
__f_->destroy(); |
1441 |
else if (__f_) |
1442 |
__f_->destroy_deallocate(); |
1443 |
__f_ = 0; |
1444 |
return *this; |
1445 |
} |
1446 | |
1447 |
template<class _Rp, class _A0, class _A1, class _A2> |
1448 |
template <class _Fp> |
1449 |
typename enable_if |
1450 |
< |
1451 |
!is_integral<_Fp>::value, |
1452 |
function<_Rp(_A0, _A1, _A2)>& |
1453 |
>::type |
1454 |
function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f) |
1455 |
{ |
1456 |
function(_VSTD::move(__f)).swap(*this); |
1457 |
return *this; |
1458 |
} |
1459 | |
1460 |
template<class _Rp, class _A0, class _A1, class _A2> |
1461 |
function<_Rp(_A0, _A1, _A2)>::~function() |
1462 |
{ |
1463 |
if (__f_ == (__base*)&__buf_) |
1464 |
__f_->destroy(); |
1465 |
else if (__f_) |
1466 |
__f_->destroy_deallocate(); |
1467 |
} |
1468 | |
1469 |
template<class _Rp, class _A0, class _A1, class _A2> |
1470 |
void |
1471 |
function<_Rp(_A0, _A1, _A2)>::swap(function& __f) |
1472 |
{ |
1473 |
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) |
1474 |
{ |
1475 |
typename aligned_storage<sizeof(__buf_)>::type __tempbuf; |
1476 |
__base* __t = (__base*)&__tempbuf; |
1477 |
__f_->__clone(__t); |
1478 |
__f_->destroy(); |
1479 |
__f_ = 0; |
1480 |
__f.__f_->__clone((__base*)&__buf_); |
1481 |
__f.__f_->destroy(); |
1482 |
__f.__f_ = 0; |
1483 |
__f_ = (__base*)&__buf_; |
1484 |
__t->__clone((__base*)&__f.__buf_); |
1485 |
__t->destroy(); |
1486 |
__f.__f_ = (__base*)&__f.__buf_; |
1487 |
} |
1488 |
else if (__f_ == (__base*)&__buf_) |
1489 |
{ |
1490 |
__f_->__clone((__base*)&__f.__buf_); |
1491 |
__f_->destroy(); |
1492 |
__f_ = __f.__f_; |
1493 |
__f.__f_ = (__base*)&__f.__buf_; |
1494 |
} |
1495 |
else if (__f.__f_ == (__base*)&__f.__buf_) |
1496 |
{ |
1497 |
__f.__f_->__clone((__base*)&__buf_); |
1498 |
__f.__f_->destroy(); |
1499 |
__f.__f_ = __f_; |
1500 |
__f_ = (__base*)&__buf_; |
1501 |
} |
1502 |
else |
1503 |
_VSTD::swap(__f_, __f.__f_); |
1504 |
} |
1505 | |
1506 |
template<class _Rp, class _A0, class _A1, class _A2> |
1507 |
_Rp |
1508 |
function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const |
1509 |
{ |
1510 |
#ifndef _LIBCPP_NO_EXCEPTIONS |
1511 |
if (__f_ == 0) |
1512 |
throw bad_function_call(); |
1513 |
#endif // _LIBCPP_NO_EXCEPTIONS |
1514 |
return (*__f_)(__a0, __a1, __a2); |
1515 |
} |
1516 | |
1517 |
#ifndef _LIBCPP_NO_RTTI |
1518 | |
1519 |
template<class _Rp, class _A0, class _A1, class _A2> |
1520 |
const std::type_info& |
1521 |
function<_Rp(_A0, _A1, _A2)>::target_type() const |
1522 |
{ |
1523 |
if (__f_ == 0) |
1524 |
return typeid(void); |
1525 |
return __f_->target_type(); |
1526 |
} |
1527 | |
1528 |
template<class _Rp, class _A0, class _A1, class _A2> |
1529 |
template <typename _Tp> |
1530 |
_Tp* |
1531 |
function<_Rp(_A0, _A1, _A2)>::target() |
1532 |
{ |
1533 |
if (__f_ == 0) |
1534 |
return (_Tp*)0; |
1535 |
return (_Tp*)__f_->target(typeid(_Tp)); |
1536 |
} |
1537 | |
1538 |
template<class _Rp, class _A0, class _A1, class _A2> |
1539 |
template <typename _Tp> |
1540 |
const _Tp* |
1541 |
function<_Rp(_A0, _A1, _A2)>::target() const |
1542 |
{ |
1543 |
if (__f_ == 0) |
1544 |
return (const _Tp*)0; |
1545 |
return (const _Tp*)__f_->target(typeid(_Tp)); |
1546 |
} |
1547 | |
1548 |
#endif // _LIBCPP_NO_RTTI |
1549 | |
1550 |
template <class _Fp> |
1551 |
inline _LIBCPP_INLINE_VISIBILITY |
1552 |
bool |
1553 |
operator==(const function<_Fp>& __f, nullptr_t) {return !__f;} |
1554 | |
1555 |
template <class _Fp> |
1556 |
inline _LIBCPP_INLINE_VISIBILITY |
1557 |
bool |
1558 |
operator==(nullptr_t, const function<_Fp>& __f) {return !__f;} |
1559 | |
1560 |
template <class _Fp> |
1561 |
inline _LIBCPP_INLINE_VISIBILITY |
1562 |
bool |
1563 |
operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;} |
1564 | |
1565 |
template <class _Fp> |
1566 |
inline _LIBCPP_INLINE_VISIBILITY |
1567 |
bool |
1568 |
operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;} |
1569 | |
1570 |
template <class _Fp> |
1571 |
inline _LIBCPP_INLINE_VISIBILITY |
1572 |
void |
1573 |
swap(function<_Fp>& __x, function<_Fp>& __y) |
1574 |
{return __x.swap(__y);} |
1575 | |
1576 |
#endif // _LIBCPP_FUNCTIONAL_03 |