1 // -*- C++ -*-
2 //===------------------------ functional ----------------------------------===//
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 // STL common functionality
12 //
13 // Some aspects of STL are core language concepts that should be used from all C++ code, regardless
14 // of whether exceptions are enabled in the component.  Common library code that expects to be used
15 // from exception-free components want these concepts, but including STL headers directly introduces
16 // friction as it requires components not using STL to declare their STL version.  Doing so creates
17 // ambiguity around whether STL use is safe in a particular component and implicitly brings in
18 // a long list of headers (including <new>) which can create further ambiguity around throwing new
19 // support (some routines pulled in may expect it).  Secondarily, pulling in these headers also has
20 // the potential to create naming conflicts or other implied dependencies.
21 //
22 // To promote the use of these core language concepts outside of STL-based binaries, this file is
23 // selectively pulling those concepts *directly* from corresponding STL headers.  The corresponding
24 // "std::" namespace STL functions and types should be preferred over these in code that is bound to
25 // STL.  The implementation and naming of all functions are taken directly from STL, instead using
26 // "wistd" (Windows Implementation std) as the namespace.
27 //
28 // Routines in this namespace should always be considered a reflection of the *current* STL implementation
29 // of those routines.  Updates from STL should be taken, but no "bugs" should be fixed here.
30 //
31 // New, exception-based code should not use this namespace, but instead should prefer the std:: implementation.
32 // Only code that is not exception-based and libraries that expect to be utilized across both exception
33 // and non-exception based code should utilize this functionality.
34 
35 #ifndef _WISTD_FUNCTIONAL_H_
36 #define _WISTD_FUNCTIONAL_H_
37 
38 // DO NOT add *any* additional includes to this file -- there should be no dependencies from its usage
39 #include "wistd_memory.h"
40 #include <intrin.h> // For __fastfail
41 #include <new.h> // For placement new
42 
43 #if !defined(__WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
44 #pragma GCC system_header
45 #endif
46 
47 #pragma warning(push)
48 #pragma warning(disable: 4324)
49 
50 /// @cond
51 namespace wistd     // ("Windows Implementation" std)
52 {
53     // wistd::function
54     //
55     // All of the code below is in direct support of wistd::function.  This class is identical to std::function
56     // with the following exceptions:
57     //
58     // 1) It never allocates and is safe to use from exception-free code (custom allocators are not supported)
59     // 2) It's slightly bigger on the stack (64 bytes, rather than 24 for 32bit)
60     // 3) There is an explicit static-assert if a lambda becomes too large to hold in the internal buffer (rather than an allocation)
61 
62     template <class _Ret>
63     struct __invoke_void_return_wrapper
64     {
65 #ifndef __WI_LIBCPP_CXX03_LANG
66         template <class ..._Args>
__call__invoke_void_return_wrapper67         static _Ret __call(_Args&&... __args) {
68             return __invoke(wistd::forward<_Args>(__args)...);
69         }
70 #else
71         template <class _Fn>
72         static _Ret __call(_Fn __f) {
73             return __invoke(__f);
74         }
75 
76         template <class _Fn, class _A0>
77         static _Ret __call(_Fn __f, _A0& __a0) {
78             return __invoke(__f, __a0);
79         }
80 
81         template <class _Fn, class _A0, class _A1>
82         static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
83             return __invoke(__f, __a0, __a1);
84         }
85 
86         template <class _Fn, class _A0, class _A1, class _A2>
87         static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
88             return __invoke(__f, __a0, __a1, __a2);
89         }
90 #endif
91     };
92 
93     template <>
94     struct __invoke_void_return_wrapper<void>
95     {
96 #ifndef __WI_LIBCPP_CXX03_LANG
97         template <class ..._Args>
98         static void __call(_Args&&... __args) {
99             (void)__invoke(wistd::forward<_Args>(__args)...);
100         }
101 #else
102         template <class _Fn>
103         static void __call(_Fn __f) {
104             __invoke(__f);
105         }
106 
107         template <class _Fn, class _A0>
108         static void __call(_Fn __f, _A0& __a0) {
109             __invoke(__f, __a0);
110         }
111 
112         template <class _Fn, class _A0, class _A1>
113         static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
114             __invoke(__f, __a0, __a1);
115         }
116 
117         template <class _Fn, class _A0, class _A1, class _A2>
118         static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
119             __invoke(__f, __a0, __a1, __a2);
120         }
121 #endif
122     };
123 
124     ////////////////////////////////////////////////////////////////////////////////
125     //                                FUNCTION
126     //==============================================================================
127 
128     // bad_function_call
129 
130     __WI_LIBCPP_NORETURN inline __WI_LIBCPP_INLINE_VISIBILITY
131     void __throw_bad_function_call()
132     {
133         __fastfail(7); // FAST_FAIL_FATAL_APP_EXIT
134     }
135 
136     template<class _Fp> class __WI_LIBCPP_TEMPLATE_VIS function; // undefined
137 
138     namespace __function
139     {
140 
141         template<class _Rp>
142         struct __maybe_derive_from_unary_function
143         {
144         };
145 
146         template<class _Rp, class _A1>
147         struct __maybe_derive_from_unary_function<_Rp(_A1)>
148             : public unary_function<_A1, _Rp>
149         {
150         };
151 
152         template<class _Rp>
153         struct __maybe_derive_from_binary_function
154         {
155         };
156 
157         template<class _Rp, class _A1, class _A2>
158         struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
159             : public binary_function<_A1, _A2, _Rp>
160         {
161         };
162 
163         template <class _Fp>
164         __WI_LIBCPP_INLINE_VISIBILITY
165         bool __not_null(_Fp const&) { return true; }
166 
167         template <class _Fp>
168         __WI_LIBCPP_INLINE_VISIBILITY
169         bool __not_null(_Fp* __ptr) { return __ptr; }
170 
171         template <class _Ret, class _Class>
172         __WI_LIBCPP_INLINE_VISIBILITY
173         bool __not_null(_Ret _Class::*__ptr) { return __ptr; }
174 
175         template <class _Fp>
176         __WI_LIBCPP_INLINE_VISIBILITY
177         bool __not_null(function<_Fp> const& __f) { return !!__f; }
178 
179     } // namespace __function
180 
181 #ifndef __WI_LIBCPP_CXX03_LANG
182 
183     namespace __function {
184 
185         template<class _Fp> class __base;
186 
187         template<class _Rp, class ..._ArgTypes>
188         class __base<_Rp(_ArgTypes...)>
189         {
190             __base(const __base&);
191             __base& operator=(const __base&);
192         public:
193             __WI_LIBCPP_INLINE_VISIBILITY __base() {}
194             __WI_LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
195             virtual void __clone(__base*) const = 0;
196             virtual void __move(__base*) = 0;
197             virtual void destroy() WI_NOEXCEPT = 0;
198             virtual _Rp operator()(_ArgTypes&& ...) = 0;
199         };
200 
201         template<class _FD, class _FB> class __func;
202 
203         template<class _Fp, class _Rp, class ..._ArgTypes>
204         class __func<_Fp, _Rp(_ArgTypes...)>
205             : public  __base<_Rp(_ArgTypes...)>
206         {
207             _Fp __f_;
208         public:
209             __WI_LIBCPP_INLINE_VISIBILITY
210             explicit __func(_Fp&& __f)
211                 : __f_(wistd::move(__f)) {}
212 
213             __WI_LIBCPP_INLINE_VISIBILITY
214             explicit __func(const _Fp& __f)
215                 : __f_(__f) {}
216 
217             virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
218             virtual void __move(__base<_Rp(_ArgTypes...)>*);
219             virtual void destroy() WI_NOEXCEPT;
220             virtual _Rp operator()(_ArgTypes&& ... __arg);
221         };
222 
223         template<class _Fp, class _Rp, class ..._ArgTypes>
224         void
225         __func<_Fp, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
226         {
227             ::new (__p) __func(__f_);
228         }
229 
230         template<class _Fp, class _Rp, class ..._ArgTypes>
231         void
232         __func<_Fp, _Rp(_ArgTypes...)>::__move(__base<_Rp(_ArgTypes...)>* __p)
233         {
234             ::new (__p) __func(wistd::move(__f_));
235         }
236 
237         template<class _Fp, class _Rp, class ..._ArgTypes>
238         void
239         __func<_Fp, _Rp(_ArgTypes...)>::destroy() WI_NOEXCEPT
240         {
241             __f_.~_Fp();
242         }
243 
244         template<class _Fp, class _Rp, class ..._ArgTypes>
245         _Rp
246         __func<_Fp, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
247         {
248             typedef __invoke_void_return_wrapper<_Rp> _Invoker;
249             return _Invoker::__call(__f_, wistd::forward<_ArgTypes>(__arg)...);
250         }
251 
252     }  // __function
253 
254     template<class _Rp, class ..._ArgTypes>
255     class __WI_LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
256         : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
257           public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
258     {
259         // 'wistd::function' is most similar to 'inplace_function' in that it _only_ permits holding function objects
260         // that can fit within its internal buffer. Therefore, we expand this size to accommodate space for at least 12
261         // pointers (__base vtable takes an additional one).
262         static constexpr size_t __buffer_size = 13 * sizeof(void*);
263 
264         typedef __function::__base<_Rp(_ArgTypes...)> __base;
265         __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
266         typename aligned_storage<__buffer_size>::type __buf_;
267         __base* __f_;
268 
269         __WI_LIBCPP_NO_CFI static __base *__as_base(void *p) {
270           return reinterpret_cast<__base*>(p);
271         }
272 
273         template <class _Fp, bool>
274         struct __callable_imp
275         {
276             static const bool value = is_same<void, _Rp>::value ||
277                 is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type,
278                                 _Rp>::value;
279         };
280 
281         template <class _Fp>
282         struct __callable_imp<_Fp, false>
283         {
284             static const bool value = false;
285         };
286 
287         template <class _Fp>
288         struct __callable
289         {
290             static const bool value = __callable_imp<_Fp, __lazy_and<
291                 integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>,
292                 __invokable<_Fp&, _ArgTypes...>
293             >::value>::value;
294         };
295 
296       template <class _Fp>
297       using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type;
298     public:
299         typedef _Rp result_type;
300 
301         // construct/copy/destroy:
302         __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
303         function() WI_NOEXCEPT : __f_(0) {}
304         __WI_LIBCPP_INLINE_VISIBILITY
305         function(nullptr_t) WI_NOEXCEPT : __f_(0) {}
306         function(const function&);
307         function(function&&);
308         template<class _Fp, class = _EnableIfCallable<_Fp>>
309         function(_Fp);
310 
311         function& operator=(const function&);
312         function& operator=(function&&);
313         function& operator=(nullptr_t) WI_NOEXCEPT;
314         template<class _Fp, class = _EnableIfCallable<_Fp>>
315         function& operator=(_Fp&&);
316 
317         ~function();
318 
319         // function modifiers:
320         void swap(function&);
321 
322         // function capacity:
323         __WI_LIBCPP_INLINE_VISIBILITY
324             __WI_LIBCPP_EXPLICIT operator bool() const WI_NOEXCEPT {return __f_;}
325 
326         // deleted overloads close possible hole in the type system
327         template<class _R2, class... _ArgTypes2>
328           bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
329         template<class _R2, class... _ArgTypes2>
330           bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
331     public:
332         // function invocation:
333         _Rp operator()(_ArgTypes...) const;
334 
335         // NOTE: type_info is very compiler specific, and on top of that, we're operating in a namespace other than
336         // 'std' so all functions requiring RTTI have been removed
337     };
338 
339     template<class _Rp, class ..._ArgTypes>
340     __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
341     function<_Rp(_ArgTypes...)>::function(const function& __f)
342     {
343         if (__f.__f_ == 0)
344             __f_ = 0;
345         else
346         {
347             __f_ = __as_base(&__buf_);
348             __f.__f_->__clone(__f_);
349         }
350     }
351 
352     template<class _Rp, class ..._ArgTypes>
353     __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS __WI_LIBCPP_SUPPRESS_NOEXCEPT_ANALYSIS
354     function<_Rp(_ArgTypes...)>::function(function&& __f)
355     {
356         if (__f.__f_ == 0)
357             __f_ = 0;
358         else
359         {
360             __f_ = __as_base(&__buf_);
361             __f.__f_->__move(__f_);
362             __f.__f_->destroy();
363             __f.__f_ = 0;
364         }
365     }
366 
367     template<class _Rp, class ..._ArgTypes>
368     template <class _Fp, class>
369     __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS
370     function<_Rp(_ArgTypes...)>::function(_Fp __f)
371         : __f_(0)
372     {
373         if (__function::__not_null(__f))
374         {
375             typedef __function::__func<_Fp, _Rp(_ArgTypes...)> _FF;
376             static_assert(sizeof(_FF) <= sizeof(__buf_),
377                 "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers).  Refactor to reduce size of the capture.");
378             __f_ = ::new((void*)&__buf_) _FF(wistd::move(__f));
379         }
380     }
381 
382     template<class _Rp, class ..._ArgTypes>
383     function<_Rp(_ArgTypes...)>&
384     function<_Rp(_ArgTypes...)>::operator=(const function& __f)
385     {
386         *this = nullptr;
387         if (__f.__f_)
388         {
389             __f_ = __as_base(&__buf_);
390             __f.__f_->__clone(__f_);
391         }
392         return *this;
393     }
394 
395     template<class _Rp, class ..._ArgTypes>
396     function<_Rp(_ArgTypes...)>&
397     function<_Rp(_ArgTypes...)>::operator=(function&& __f)
398     {
399         *this = nullptr;
400         if (__f.__f_)
401         {
402             __f_ = __as_base(&__buf_);
403             __f.__f_->__move(__f_);
404             __f.__f_->destroy();
405             __f.__f_ = 0;
406         }
407         return *this;
408     }
409 
410     template<class _Rp, class ..._ArgTypes>
411     function<_Rp(_ArgTypes...)>&
412     function<_Rp(_ArgTypes...)>::operator=(nullptr_t) WI_NOEXCEPT
413     {
414         __base* __t = __f_;
415         __f_ = 0;
416         if (__t)
417             __t->destroy();
418         return *this;
419     }
420 
421     template<class _Rp, class ..._ArgTypes>
422     template <class _Fp, class>
423     function<_Rp(_ArgTypes...)>&
424     function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
425     {
426         *this = nullptr;
427         if (__function::__not_null(__f))
428         {
429             typedef __function::__func<typename decay<_Fp>::type, _Rp(_ArgTypes...)> _FF;
430             static_assert(sizeof(_FF) <= sizeof(__buf_),
431                 "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers).  Refactor to reduce size of the capture.");
432             __f_ = ::new((void*)&__buf_) _FF(wistd::move(__f));
433         }
434 
435         return *this;
436     }
437 
438     template<class _Rp, class ..._ArgTypes>
439     function<_Rp(_ArgTypes...)>::~function()
440     {
441         if (__f_)
442             __f_->destroy();
443     }
444 
445     template<class _Rp, class ..._ArgTypes>
446     void
447     function<_Rp(_ArgTypes...)>::swap(function& __f)
448     {
449         if (wistd::addressof(__f) == this)
450           return;
451         if (__f_ && __f.__f_)
452         {
453             typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
454             __base* __t = __as_base(&__tempbuf);
455             __f_->__move(__t);
456             __f_->destroy();
457             __f_ = 0;
458             __f.__f_->__move(__as_base(&__buf_));
459             __f.__f_->destroy();
460             __f.__f_ = 0;
461             __f_ = __as_base(&__buf_);
462             __t->__move(__as_base(&__f.__buf_));
463             __t->destroy();
464             __f.__f_ = __as_base(&__f.__buf_);
465         }
466         else if (__f_)
467         {
468             __f_->__move(__as_base(&__f.__buf_));
469             __f_->destroy();
470             __f_ = 0;
471             __f.__f_ = __as_base(&__f.__buf_);
472         }
473         else if (__f.__f_)
474         {
475             __f.__f_->__move(__as_base(&__buf_));
476             __f.__f_->destroy();
477             __f.__f_ = 0;
478             __f_ = __as_base(&__buf_);
479         }
480     }
481 
482     template<class _Rp, class ..._ArgTypes>
483     _Rp
484     function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
485     {
486         if (__f_ == 0)
487             __throw_bad_function_call();
488         return (*__f_)(wistd::forward<_ArgTypes>(__arg)...);
489     }
490 
491     template <class _Rp, class... _ArgTypes>
492     inline __WI_LIBCPP_INLINE_VISIBILITY
493     bool
494     operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return !__f;}
495 
496     template <class _Rp, class... _ArgTypes>
497     inline __WI_LIBCPP_INLINE_VISIBILITY
498     bool
499     operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return !__f;}
500 
501     template <class _Rp, class... _ArgTypes>
502     inline __WI_LIBCPP_INLINE_VISIBILITY
503     bool
504     operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return (bool)__f;}
505 
506     template <class _Rp, class... _ArgTypes>
507     inline __WI_LIBCPP_INLINE_VISIBILITY
508     bool
509     operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return (bool)__f;}
510 
511     // Provide both 'swap_wil' and 'swap' since we now have two ADL scenarios that we need to work
512     template <class _Rp, class... _ArgTypes>
513     inline __WI_LIBCPP_INLINE_VISIBILITY
514     void
515     swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y)
516     {return __x.swap(__y);}
517 
518     template <class _Rp, class... _ArgTypes>
519     inline __WI_LIBCPP_INLINE_VISIBILITY
520     void
521     swap_wil(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y)
522     {return __x.swap(__y);}
523 
524     // std::invoke
525     template <class _Fn, class ..._Args>
526     typename __invoke_of<_Fn, _Args...>::type
527     invoke(_Fn&& __f, _Args&&... __args)
528         __WI_NOEXCEPT_((__nothrow_invokable<_Fn, _Args...>::value))
529     {
530         return wistd::__invoke(wistd::forward<_Fn>(__f), wistd::forward<_Args>(__args)...);
531     }
532 
533 #else // __WI_LIBCPP_CXX03_LANG
534 
535 #error wistd::function and wistd::invoke not implemented for pre-C++11
536 
537 #endif
538 }
539 /// @endcond
540 
541 #pragma warning(pop)
542 
543 #endif  // _WISTD_FUNCTIONAL_H_
544