1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * @author Eric Niebler (eniebler@fb.com), Sven Over (over@fb.com)
19  * Acknowledgements: Giuseppe Ottaviano (ott@fb.com)
20  */
21 
22 /**
23  * @class Function
24  *
25  * @brief A polymorphic function wrapper that is not copyable and does not
26  *    require the wrapped function to be copy constructible.
27  *
28  * `folly::Function` is a polymorphic function wrapper, similar to
29  * `std::function`. The template parameters of the `folly::Function` define
30  * the parameter signature of the wrapped callable, but not the specific
31  * type of the embedded callable. E.g. a `folly::Function<int(int)>`
32  * can wrap callables that return an `int` when passed an `int`. This can be a
33  * function pointer or any class object implementing one or both of
34  *
35  *     int operator(int);
36  *     int operator(int) const;
37  *
38  * If both are defined, the non-const one takes precedence.
39  *
40  * Unlike `std::function`, a `folly::Function` can wrap objects that are not
41  * copy constructible. As a consequence of this, `folly::Function` itself
42  * is not copyable, either.
43  *
44  * Another difference is that, unlike `std::function`, `folly::Function` treats
45  * const-ness of methods correctly. While a `std::function` allows to wrap
46  * an object that only implements a non-const `operator()` and invoke
47  * a const-reference of the `std::function`, `folly::Function` requires you to
48  * declare a function type as const in order to be able to execute it on a
49  * const-reference.
50  *
51  * For example:
52  *
53  *     class Foo {
54  *      public:
55  *       void operator()() {
56  *         // mutates the Foo object
57  *       }
58  *     };
59  *
60  *     class Bar {
61  *       std::function<void(void)> foo_; // wraps a Foo object
62  *      public:
63  *       void mutateFoo() const
64  *       {
65  *         foo_();
66  *       }
67  *     };
68  *
69  * Even though `mutateFoo` is a const-method, so it can only reference `foo_`
70  * as const, it is able to call the non-const `operator()` of the Foo
71  * object that is embedded in the foo_ function.
72  *
73  * `folly::Function` will not allow you to do that. You will have to decide
74  * whether you need to invoke your wrapped callable from a const reference
75  * (like in the example above), in which case it will only wrap a
76  * `operator() const`. If your functor does not implement that,
77  * compilation will fail. If you do not require to be able to invoke the
78  * wrapped function in a const context, you can wrap any functor that
79  * implements either or both of const and non-const `operator()`.
80  *
81  * The template parameter of `folly::Function`, the `FunctionType`, can be
82  * const-qualified. Be aware that the const is part of the function signature.
83  * It does not mean that the function type is a const type.
84  *
85  *   using FunctionType = R(Args...);
86  *   using ConstFunctionType = R(Args...) const;
87  *
88  * In this example, `FunctionType` and `ConstFunctionType` are different
89  * types. `ConstFunctionType` is not the same as `const FunctionType`.
90  * As a matter of fact, trying to use the latter should emit a compiler
91  * warning or error, because it has no defined meaning.
92  *
93  *     // This will not compile:
94  *     folly::Function<void(void) const> func = Foo();
95  *     // because Foo does not have a member function of the form:
96  *     //   void operator()() const;
97  *
98  *     // This will compile just fine:
99  *     folly::Function<void(void)> func = Foo();
100  *     // and it will wrap the existing member function:
101  *     //   void operator()();
102  *
103  * When should a const function type be used? As a matter of fact, you will
104  * probably not need to use const function types very often. See the following
105  * example:
106  *
107  *     class Bar {
108  *       folly::Function<void()> func_;
109  *       folly::Function<void() const> constFunc_;
110  *
111  *       void someMethod() {
112  *         // Can call func_.
113  *         func_();
114  *         // Can call constFunc_.
115  *         constFunc_();
116  *       }
117  *
118  *       void someConstMethod() const {
119  *         // Can call constFunc_.
120  *         constFunc_();
121  *         // However, cannot call func_ because a non-const method cannot
122  *         // be called from a const one.
123  *       }
124  *     };
125  *
126  * As you can see, whether the `folly::Function`'s function type should
127  * be declared const or not is identical to whether a corresponding method
128  * would be declared const or not.
129  *
130  * You only require a `folly::Function` to hold a const function type, if you
131  * intend to invoke it from within a const context. This is to ensure that
132  * you cannot mutate its inner state when calling in a const context.
133  *
134  * This is how the const/non-const choice relates to lambda functions:
135  *
136  *     // Non-mutable lambdas: can be stored in a non-const...
137  *     folly::Function<void(int)> print_number =
138  *       [] (int number) { std::cout << number << std::endl; };
139  *
140  *     // ...as well as in a const folly::Function
141  *     folly::Function<void(int) const> print_number_const =
142  *       [] (int number) { std::cout << number << std::endl; };
143  *
144  *     // Mutable lambda: can only be stored in a non-const folly::Function:
145  *     int number = 0;
146  *     folly::Function<void()> print_number =
147  *       [number] () mutable { std::cout << ++number << std::endl; };
148  *     // Trying to store the above mutable lambda in a
149  *     // `folly::Function<void() const>` would lead to a compiler error:
150  *     // error: no viable conversion from '(lambda at ...)' to
151  *     // 'folly::Function<void () const>'
152  *
153  * Casting between const and non-const `folly::Function`s:
154  * conversion from const to non-const signatures happens implicitly. Any
155  * function that takes a `folly::Function<R(Args...)>` can be passed
156  * a `folly::Function<R(Args...) const>` without explicit conversion.
157  * This is safe, because casting from const to non-const only entails giving
158  * up the ability to invoke the function from a const context.
159  * Casting from a non-const to a const signature is potentially dangerous,
160  * as it means that a function that may change its inner state when invoked
161  * is made possible to call from a const context. Therefore this cast does
162  * not happen implicitly. The function `folly::constCastFunction` can
163  * be used to perform the cast.
164  *
165  *     // Mutable lambda: can only be stored in a non-const folly::Function:
166  *     int number = 0;
167  *     folly::Function<void()> print_number =
168  *       [number] () mutable { std::cout << ++number << std::endl; };
169  *
170  *     // const-cast to a const folly::Function:
171  *     folly::Function<void() const> print_number_const =
172  *       constCastFunction(std::move(print_number));
173  *
174  * When to use const function types?
175  * Generally, only when you need them. When you use a `folly::Function` as a
176  * member of a struct or class, only use a const function signature when you
177  * need to invoke the function from const context.
178  * When passing a `folly::Function` to a function, the function should accept
179  * a non-const `folly::Function` whenever possible, i.e. when it does not
180  * need to pass on or store a const `folly::Function`. This is the least
181  * possible constraint: you can always pass a const `folly::Function` when
182  * the function accepts a non-const one.
183  *
184  * How does the const behaviour compare to `std::function`?
185  * `std::function` can wrap object with non-const invocation behaviour but
186  * exposes them as const. The equivalent behaviour can be achieved with
187  * `folly::Function` like so:
188  *
189  *     std::function<void(void)> stdfunc = someCallable;
190  *
191  *     folly::Function<void(void) const> uniqfunc = constCastFunction(
192  *       folly::Function<void(void)>(someCallable)
193  *     );
194  *
195  * You need to wrap the callable first in a non-const `folly::Function` to
196  * select a non-const invoke operator (or the const one if no non-const one is
197  * present), and then move it into a const `folly::Function` using
198  * `constCastFunction`.
199  * The name of `constCastFunction` should warn you that something
200  * potentially dangerous is happening. As a matter of fact, using
201  * `std::function` always involves this potentially dangerous aspect, which
202  * is why it is not considered fully const-safe or even const-correct.
203  * However, in most of the cases you will not need the dangerous aspect at all.
204  * Either you do not require invocation of the function from a const context,
205  * in which case you do not need to use `constCastFunction` and just
206  * use the inner `folly::Function` in the example above, i.e. just use a
207  * non-const `folly::Function`. Or, you may need invocation from const, but
208  * the callable you are wrapping does not mutate its state (e.g. it is a class
209  * object and implements `operator() const`, or it is a normal,
210  * non-mutable lambda), in which case you can wrap the callable in a const
211  * `folly::Function` directly, without using `constCastFunction`.
212  * Only if you require invocation from a const context of a callable that
213  * may mutate itself when invoked you have to go through the above procedure.
214  * However, in that case what you do is potentially dangerous and requires
215  * the equivalent of a `const_cast`, hence you need to call
216  * `constCastFunction`.
217  */
218 
219 #pragma once
220 
221 #include <functional>
222 #include <memory>
223 #include <new>
224 #include <type_traits>
225 #include <utility>
226 
227 #include <folly/CppAttributes.h>
228 #include <folly/Portability.h>
229 #include <folly/Traits.h>
230 #include <folly/functional/Invoke.h>
231 #include <folly/lang/Exception.h>
232 
233 namespace folly {
234 
235 template <typename FunctionType>
236 class Function;
237 
238 template <typename ReturnType, typename... Args>
239 Function<ReturnType(Args...) const> constCastFunction(
240     Function<ReturnType(Args...)>&&) noexcept;
241 
242 #if FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE
243 template <typename ReturnType, typename... Args>
244 Function<ReturnType(Args...) const noexcept> constCastFunction(
245     Function<ReturnType(Args...) noexcept>&&) noexcept;
246 #endif
247 
248 namespace detail {
249 namespace function {
250 
251 enum class Op { MOVE, NUKE, HEAP };
252 
253 union Data {
Data()254   Data() {}
255   void* big;
256   std::aligned_storage<6 * sizeof(void*)>::type tiny;
257 };
258 
259 template <typename Fun, typename = Fun*>
260 using IsSmall = Conjunction<
261     bool_constant<(sizeof(Fun) <= sizeof(Data::tiny))>,
262     std::is_nothrow_move_constructible<Fun>>;
263 using SmallTag = std::true_type;
264 using HeapTag = std::false_type;
265 
266 struct CoerceTag {};
267 
268 template <typename T>
269 using FunctionNullptrTest =
270     decltype(static_cast<bool>(static_cast<T const&>(T(nullptr)) == nullptr));
271 
272 template <
273     typename T,
274     std::enable_if_t<!is_detected_v<FunctionNullptrTest, T>, int> = 0>
isEmptyFunction(T const &)275 constexpr bool isEmptyFunction(T const&) {
276   return false;
277 }
278 template <
279     typename T,
280     std::enable_if_t<is_detected_v<FunctionNullptrTest, T>, int> = 0>
isEmptyFunction(T const & t)281 constexpr bool isEmptyFunction(T const& t) {
282   return static_cast<bool>(t == nullptr);
283 }
284 
285 template <typename F, typename... Args>
286 using CallableResult = decltype(std::declval<F>()(std::declval<Args>()...));
287 
288 template <
289     typename From,
290     typename To,
291     typename = typename std::enable_if<
292         !std::is_reference<To>::value || std::is_reference<From>::value>::type>
293 using IfSafeResultImpl = decltype(void(static_cast<To>(std::declval<From>())));
294 
295 #if defined(_MSC_VER)
296 //  Need a workaround for MSVC to avoid the inscrutable error:
297 //
298 //      folly\function.h(...) : fatal error C1001: An internal error has
299 //          occurred in the compiler.
300 //      (compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c', line 258)
301 //      To work around this problem, try simplifying or changing the program
302 //          near the locations listed above.
303 template <typename T>
304 using CallArg = T&&;
305 #else
306 template <typename T>
307 using CallArg = conditional_t<is_trivially_copyable<T>::value, T, T&&>;
308 #endif
309 
310 template <typename F, typename R, typename... A>
311 class FunctionTraitsSharedProxy {
312   std::shared_ptr<Function<F>> sp_;
313 
314  public:
FunctionTraitsSharedProxy(std::nullptr_t)315   explicit FunctionTraitsSharedProxy(std::nullptr_t) noexcept {}
FunctionTraitsSharedProxy(Function<F> && func)316   explicit FunctionTraitsSharedProxy(Function<F>&& func)
317       : sp_(func ? std::make_shared<Function<F>>(std::move(func))
318                  : std::shared_ptr<Function<F>>()) {}
operator()319   R operator()(A&&... args) const {
320     if (!sp_) {
321       throw_exception<std::bad_function_call>();
322     }
323     return (*sp_)(static_cast<A&&>(args)...);
324   }
325 
326   explicit operator bool() const noexcept { return sp_ != nullptr; }
327 
328   friend bool operator==(
329       FunctionTraitsSharedProxy<F, R, A...> const& proxy,
330       std::nullptr_t) noexcept {
331     return proxy.sp_ == nullptr;
332   }
333   friend bool operator!=(
334       FunctionTraitsSharedProxy<F, R, A...> const& proxy,
335       std::nullptr_t) noexcept {
336     return proxy.sp_ != nullptr;
337   }
338 
339   friend bool operator==(
340       std::nullptr_t,
341       FunctionTraitsSharedProxy<F, R, A...> const& proxy) noexcept {
342     return proxy.sp_ == nullptr;
343   }
344   friend bool operator!=(
345       std::nullptr_t,
346       FunctionTraitsSharedProxy<F, R, A...> const& proxy) noexcept {
347     return proxy.sp_ != nullptr;
348   }
349 };
350 
351 template <typename FunctionType>
352 struct FunctionTraits;
353 
354 template <typename ReturnType, typename... Args>
355 struct FunctionTraits<ReturnType(Args...)> {
356   using Call = ReturnType (*)(CallArg<Args>..., Data&);
357   using IsConst = std::false_type;
358   using ConstSignature = ReturnType(Args...) const;
359   using NonConstSignature = ReturnType(Args...);
360   using OtherSignature = ConstSignature;
361 
362   template <typename F, typename R = CallableResult<std::decay_t<F>&, Args...>>
363   using IfSafeResult = IfSafeResultImpl<R, ReturnType>;
364 
365   template <typename Fun>
366   static ReturnType callSmall(CallArg<Args>... args, Data& p) {
367     auto& fn = *static_cast<Fun*>(static_cast<void*>(&p.tiny));
368 #if __cpp_if_constexpr >= 201606L
369     if constexpr (std::is_void<ReturnType>::value) {
370       fn(static_cast<Args&&>(args)...);
371     } else {
372       return fn(static_cast<Args&&>(args)...);
373     }
374 #else
375     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
376 #endif
377   }
378 
379   template <typename Fun>
380   static ReturnType callBig(CallArg<Args>... args, Data& p) {
381     auto& fn = *static_cast<Fun*>(p.big);
382 #if __cpp_if_constexpr >= 201606L
383     if constexpr (std::is_void<ReturnType>::value) {
384       fn(static_cast<Args&&>(args)...);
385     } else {
386       return fn(static_cast<Args&&>(args)...);
387     }
388 #else
389     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
390 #endif
391   }
392 
393   static ReturnType uninitCall(CallArg<Args>..., Data&) {
394     throw_exception<std::bad_function_call>();
395   }
396 
397   ReturnType operator()(Args... args) {
398     auto& fn = *static_cast<Function<NonConstSignature>*>(this);
399     return fn.call_(static_cast<Args&&>(args)..., fn.data_);
400   }
401 
402   using SharedProxy =
403       FunctionTraitsSharedProxy<NonConstSignature, ReturnType, Args...>;
404 };
405 
406 template <typename ReturnType, typename... Args>
407 struct FunctionTraits<ReturnType(Args...) const> {
408   using Call = ReturnType (*)(CallArg<Args>..., Data&);
409   using IsConst = std::true_type;
410   using ConstSignature = ReturnType(Args...) const;
411   using NonConstSignature = ReturnType(Args...);
412   using OtherSignature = NonConstSignature;
413 
414   template <
415       typename F,
416       typename R = CallableResult<const std::decay_t<F>&, Args...>>
417   using IfSafeResult = IfSafeResultImpl<R, ReturnType>;
418 
419   template <typename Fun>
420   static ReturnType callSmall(CallArg<Args>... args, Data& p) {
421     auto& fn = *static_cast<const Fun*>(static_cast<void*>(&p.tiny));
422 #if __cpp_if_constexpr >= 201606L
423     if constexpr (std::is_void<ReturnType>::value) {
424       fn(static_cast<Args&&>(args)...);
425     } else {
426       return fn(static_cast<Args&&>(args)...);
427     }
428 #else
429     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
430 #endif
431   }
432 
433   template <typename Fun>
434   static ReturnType callBig(CallArg<Args>... args, Data& p) {
435     auto& fn = *static_cast<const Fun*>(p.big);
436 #if __cpp_if_constexpr >= 201606L
437     if constexpr (std::is_void<ReturnType>::value) {
438       fn(static_cast<Args&&>(args)...);
439     } else {
440       return fn(static_cast<Args&&>(args)...);
441     }
442 #else
443     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
444 #endif
445   }
446 
447   static ReturnType uninitCall(CallArg<Args>..., Data&) {
448     throw_exception<std::bad_function_call>();
449   }
450 
451   ReturnType operator()(Args... args) const {
452     auto& fn = *static_cast<const Function<ConstSignature>*>(this);
453     return fn.call_(static_cast<Args&&>(args)..., fn.data_);
454   }
455 
456   using SharedProxy =
457       FunctionTraitsSharedProxy<ConstSignature, ReturnType, Args...>;
458 };
459 
460 #if FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE
461 template <typename ReturnType, typename... Args>
462 struct FunctionTraits<ReturnType(Args...) noexcept> {
463   using Call = ReturnType (*)(CallArg<Args>..., Data&) noexcept;
464   using IsConst = std::false_type;
465   using ConstSignature = ReturnType(Args...) const noexcept;
466   using NonConstSignature = ReturnType(Args...) noexcept;
467   using OtherSignature = ConstSignature;
468 
469   template <typename F, typename R = CallableResult<std::decay_t<F>&, Args...>>
470   using IfSafeResult = IfSafeResultImpl<R, ReturnType>;
471 
472   template <typename Fun>
473   static ReturnType callSmall(CallArg<Args>... args, Data& p) noexcept {
474     auto& fn = *static_cast<Fun*>(static_cast<void*>(&p.tiny));
475 #if __cpp_if_constexpr >= 201606L
476     if constexpr (std::is_void<ReturnType>::value) {
477       fn(static_cast<Args&&>(args)...);
478     } else {
479       return fn(static_cast<Args&&>(args)...);
480     }
481 #else
482     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
483 #endif
484   }
485 
486   template <typename Fun>
487   static ReturnType callBig(CallArg<Args>... args, Data& p) noexcept {
488     auto& fn = *static_cast<Fun*>(p.big);
489 #if __cpp_if_constexpr >= 201606L
490     if constexpr (std::is_void<ReturnType>::value) {
491       fn(static_cast<Args&&>(args)...);
492     } else {
493       return fn(static_cast<Args&&>(args)...);
494     }
495 #else
496     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
497 #endif
498   }
499 
500   static ReturnType uninitCall(CallArg<Args>..., Data&) noexcept {
501     terminate_with<std::bad_function_call>();
502   }
503 
504   ReturnType operator()(Args... args) noexcept {
505     auto& fn = *static_cast<Function<NonConstSignature>*>(this);
506     return fn.call_(static_cast<Args&&>(args)..., fn.data_);
507   }
508 
509   using SharedProxy =
510       FunctionTraitsSharedProxy<NonConstSignature, ReturnType, Args...>;
511 };
512 
513 template <typename ReturnType, typename... Args>
514 struct FunctionTraits<ReturnType(Args...) const noexcept> {
515   using Call = ReturnType (*)(CallArg<Args>..., Data&) noexcept;
516   using IsConst = std::true_type;
517   using ConstSignature = ReturnType(Args...) const noexcept;
518   using NonConstSignature = ReturnType(Args...) noexcept;
519   using OtherSignature = NonConstSignature;
520 
521   template <
522       typename F,
523       typename R = CallableResult<const std::decay_t<F>&, Args...>>
524   using IfSafeResult = IfSafeResultImpl<R, ReturnType>;
525 
526   template <typename Fun>
527   static ReturnType callSmall(CallArg<Args>... args, Data& p) noexcept {
528     auto& fn = *static_cast<const Fun*>(static_cast<void*>(&p.tiny));
529 #if __cpp_if_constexpr >= 201606L
530     if constexpr (std::is_void<ReturnType>::value) {
531       fn(static_cast<Args&&>(args)...);
532     } else {
533       return fn(static_cast<Args&&>(args)...);
534     }
535 #else
536     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
537 #endif
538   }
539 
540   template <typename Fun>
541   static ReturnType callBig(CallArg<Args>... args, Data& p) noexcept {
542     auto& fn = *static_cast<const Fun*>(p.big);
543 #if __cpp_if_constexpr >= 201606L
544     if constexpr (std::is_void<ReturnType>::value) {
545       fn(static_cast<Args&&>(args)...);
546     } else {
547       return fn(static_cast<Args&&>(args)...);
548     }
549 #else
550     return static_cast<ReturnType>(fn(static_cast<Args&&>(args)...));
551 #endif
552   }
553 
554   static ReturnType uninitCall(CallArg<Args>..., Data&) noexcept {
555     throw_exception<std::bad_function_call>();
556   }
557 
558   ReturnType operator()(Args... args) const noexcept {
559     auto& fn = *static_cast<const Function<ConstSignature>*>(this);
560     return fn.call_(static_cast<Args&&>(args)..., fn.data_);
561   }
562 
563   using SharedProxy =
564       FunctionTraitsSharedProxy<ConstSignature, ReturnType, Args...>;
565 };
566 #endif
567 
568 template <typename Fun>
569 std::size_t execSmall(Op o, Data* src, Data* dst) {
570   switch (o) {
571     case Op::MOVE:
572       ::new (static_cast<void*>(&dst->tiny))
573           Fun(std::move(*static_cast<Fun*>(static_cast<void*>(&src->tiny))));
574       FOLLY_FALLTHROUGH;
575     case Op::NUKE:
576       static_cast<Fun*>(static_cast<void*>(&src->tiny))->~Fun();
577       break;
578     case Op::HEAP:
579       break;
580   }
581   return 0U;
582 }
583 
584 template <typename Fun>
585 std::size_t execBig(Op o, Data* src, Data* dst) {
586   switch (o) {
587     case Op::MOVE:
588       dst->big = src->big;
589       src->big = nullptr;
590       break;
591     case Op::NUKE:
592       delete static_cast<Fun*>(src->big);
593       break;
594     case Op::HEAP:
595       break;
596   }
597   return sizeof(Fun);
598 }
599 
600 } // namespace function
601 } // namespace detail
602 
603 template <typename FunctionType>
604 class Function final : private detail::function::FunctionTraits<FunctionType> {
605   // These utility types are defined outside of the template to reduce
606   // the number of instantiations, and then imported in the class
607   // namespace for convenience.
608   using Data = detail::function::Data;
609   using Op = detail::function::Op;
610   using SmallTag = detail::function::SmallTag;
611   using HeapTag = detail::function::HeapTag;
612   using CoerceTag = detail::function::CoerceTag;
613 
614   using Traits = detail::function::FunctionTraits<FunctionType>;
615   using Call = typename Traits::Call;
616   using Exec = std::size_t (*)(Op, Data*, Data*);
617 
618   template <typename Fun>
619   using IsSmall = detail::function::IsSmall<Fun>;
620 
621   // The `data_` member is mutable to allow `constCastFunction` to work without
622   // invoking undefined behavior. Const-correctness is only violated when
623   // `FunctionType` is a const function type (e.g., `int() const`) and `*this`
624   // is the result of calling `constCastFunction`.
625   mutable Data data_{};
626   Call call_{&Traits::uninitCall};
627   Exec exec_{nullptr};
628 
629   std::size_t exec(Op o, Data* src, Data* dst) const {
630     if (!exec_) {
631       return 0U;
632     }
633     return exec_(o, src, dst);
634   }
635 
636   friend Traits;
637   friend Function<typename Traits::ConstSignature> folly::constCastFunction<>(
638       Function<typename Traits::NonConstSignature>&&) noexcept;
639   friend class Function<typename Traits::OtherSignature>;
640 
641   template <typename Fun>
642   Function(Fun&& fun, SmallTag) noexcept {
643     using FunT = typename std::decay<Fun>::type;
644     if (!detail::function::isEmptyFunction(fun)) {
645       ::new (static_cast<void*>(&data_.tiny)) FunT(static_cast<Fun&&>(fun));
646       call_ = &Traits::template callSmall<FunT>;
647       exec_ = &detail::function::execSmall<FunT>;
648     }
649   }
650 
651   template <typename Fun>
652   Function(Fun&& fun, HeapTag) {
653     using FunT = typename std::decay<Fun>::type;
654     if (!detail::function::isEmptyFunction(fun)) {
655       data_.big = new FunT(static_cast<Fun&&>(fun));
656       call_ = &Traits::template callBig<FunT>;
657       exec_ = &detail::function::execBig<FunT>;
658     }
659   }
660 
661   template <typename Signature>
662   Function(Function<Signature>&& that, CoerceTag)
663       : Function(static_cast<Function<Signature>&&>(that), HeapTag{}) {}
664 
665   Function(Function<typename Traits::OtherSignature>&& that, CoerceTag) noexcept
666       : call_(that.call_), exec_(that.exec_) {
667     that.call_ = &Traits::uninitCall;
668     that.exec_ = nullptr;
669     exec(Op::MOVE, &that.data_, &data_);
670   }
671 
672  public:
673   /**
674    * Default constructor. Constructs an empty Function.
675    */
676   Function() = default;
677 
678   // not copyable
679   Function(const Function&) = delete;
680 
681 #ifdef __OBJC__
682   // Make sure Objective C blocks are copied
683   template <class ReturnType, class... Args>
684   /*implicit*/ Function(ReturnType (^objCBlock)(Args... args))
685       : Function([blockCopy = (ReturnType(^)(Args...))[objCBlock copy]](
686                      Args... args) { return blockCopy(args...); }){};
687 #endif
688 
689   /**
690    * Move constructor
691    */
692   Function(Function&& that) noexcept : call_(that.call_), exec_(that.exec_) {
693     // that must be uninitialized before exec() call in the case of self move
694     that.call_ = &Traits::uninitCall;
695     that.exec_ = nullptr;
696     exec(Op::MOVE, &that.data_, &data_);
697   }
698 
699   /**
700    * Constructs an empty `Function`.
701    */
702   /* implicit */ Function(std::nullptr_t) noexcept {}
703 
704   /**
705    * Constructs a new `Function` from any callable object that is _not_ a
706    * `folly::Function`. This handles function pointers, pointers to static
707    * member functions, `std::reference_wrapper` objects, `std::function`
708    * objects, and arbitrary objects that implement `operator()` if the parameter
709    * signature matches (i.e. it returns an object convertible to `R` when called
710    * with `Args...`).
711    *
712    * \note `typename Traits::template IfSafeResult<Fun>` prevents this overload
713    * from being selected by overload resolution when `fun` is not a compatible
714    * function.
715    *
716    * \note The noexcept requires some explanation. `IsSmall` is true when the
717    * decayed type fits within the internal buffer and is noexcept-movable. But
718    * this ctor might copy, not move. What we need here, if this ctor does a
719    * copy, is that this ctor be noexcept when the copy is noexcept. That is not
720    * checked in `IsSmall`, and shouldn't be, because once the `Function` is
721    * constructed, the contained object is never copied. This check is for this
722    * ctor only, in the case that this ctor does a copy.
723    */
724   template <
725       typename Fun,
726       typename =
727           std::enable_if_t<!detail::is_similar_instantiation_v<Function, Fun>>,
728       typename = typename Traits::template IfSafeResult<Fun>>
729   /* implicit */ Function(Fun fun) noexcept(
730       IsSmall<Fun>::value&& noexcept(Fun(std::declval<Fun>())))
731       : Function(std::move(fun), IsSmall<Fun>{}) {}
732 
733   /**
734    * For move-constructing from a `folly::Function<X(Ys...) [const?]>`.
735    * For a `Function` with a `const` function type, the object must be
736    * callable from a `const`-reference, i.e. implement `operator() const`.
737    * For a `Function` with a non-`const` function type, the object will
738    * be called from a non-const reference, which means that it will execute
739    * a non-const `operator()` if it is defined, and falls back to
740    * `operator() const` otherwise.
741    */
742   template <
743       typename Signature,
744       typename = typename Traits::template IfSafeResult<Function<Signature>>>
745   Function(Function<Signature>&& that) noexcept(
746       noexcept(Function(std::move(that), CoerceTag{})))
747       : Function(std::move(that), CoerceTag{}) {}
748 
749   /**
750    * If `ptr` is null, constructs an empty `Function`. Otherwise,
751    * this constructor is equivalent to `Function(std::mem_fn(ptr))`.
752    */
753   template <
754       typename Member,
755       typename Class,
756       // Prevent this overload from being selected when `ptr` is not a
757       // compatible member function pointer.
758       typename = decltype(Function(std::mem_fn((Member Class::*)0)))>
759   /* implicit */ Function(Member Class::*ptr) noexcept {
760     if (ptr) {
761       *this = std::mem_fn(ptr);
762     }
763   }
764 
765   ~Function() { exec(Op::NUKE, &data_, nullptr); }
766 
767   Function& operator=(const Function&) = delete;
768 
769 #ifdef __OBJC__
770   // Make sure Objective C blocks are copied
771   template <class ReturnType, class... Args>
772   /* implicit */ Function& operator=(ReturnType (^objCBlock)(Args... args)) {
773     (*this) = [blockCopy = (ReturnType(^)(Args...))[objCBlock copy]](
774                   Args... args) { return blockCopy(args...); };
775     return *this;
776   }
777 #endif
778 
779   /**
780    * Move assignment operator
781    *
782    * \note Leaves `that` in a valid but unspecified state. If `&that == this`
783    * then `*this` is left in a valid but unspecified state.
784    */
785   Function& operator=(Function&& that) noexcept {
786     // Q: Why is it safe to destroy and reconstruct this object in place?
787     // A: Two reasons: First, `Function` is a final class, so in doing this
788     //    we aren't slicing off any derived parts. And second, the move
789     //    operation is guaranteed not to throw so we always leave the object
790     //    in a valid state.
791     // In the case of self-move (this == &that), this leaves the object in
792     // a default-constructed state. First the object is destroyed, then we
793     // pass the destroyed object to the move constructor. The first thing the
794     // move constructor does is default-construct the object. That object is
795     // "moved" into itself, which is a no-op for a default-constructed Function.
796     this->~Function();
797     ::new (this) Function(std::move(that));
798     return *this;
799   }
800 
801   /**
802    * Assigns a callable object to this `Function`. If the operation fails,
803    * `*this` is left unmodified.
804    *
805    * \note `typename = decltype(Function(std::declval<Fun>()))` prevents this
806    * overload from being selected by overload resolution when `fun` is not a
807    * compatible function.
808    */
809   template <typename Fun, typename = decltype(Function(std::declval<Fun>()))>
810   Function& operator=(Fun fun) noexcept(
811       noexcept(/* implicit */ Function(std::declval<Fun>()))) {
812     // Doing this in place is more efficient when we can do so safely.
813     if (noexcept(/* implicit */ Function(std::declval<Fun>()))) {
814       // Q: Why is is safe to destroy and reconstruct this object in place?
815       // A: See the explanation in the move assignment operator.
816       this->~Function();
817       ::new (this) Function(std::move(fun));
818     } else {
819       // Construct a temporary and (nothrow) swap.
820       Function(std::move(fun)).swap(*this);
821     }
822     return *this;
823   }
824 
825   /**
826    * For assigning from a `Function<X(Ys..) [const?]>`.
827    */
828   template <
829       typename Signature,
830       typename = typename Traits::template IfSafeResult<Function<Signature>>>
831   Function& operator=(Function<Signature>&& that) noexcept(
832       noexcept(Function(std::move(that)))) {
833     return (*this = Function(std::move(that)));
834   }
835 
836   /**
837    * Clears this `Function`.
838    */
839   Function& operator=(std::nullptr_t) noexcept { return (*this = Function()); }
840 
841   /**
842    * If `ptr` is null, clears this `Function`. Otherwise, this assignment
843    * operator is equivalent to `*this = std::mem_fn(ptr)`.
844    */
845   template <typename Member, typename Class>
846   auto operator=(Member Class::*ptr) noexcept
847       // Prevent this overload from being selected when `ptr` is not a
848       // compatible member function pointer.
849       -> decltype(operator=(std::mem_fn(ptr))) {
850     return ptr ? (*this = std::mem_fn(ptr)) : (*this = Function());
851   }
852 
853   /**
854    * Call the wrapped callable object with the specified arguments.
855    */
856   using Traits::operator();
857 
858   /**
859    * Exchanges the callable objects of `*this` and `that`.
860    */
861   void swap(Function& that) noexcept { std::swap(*this, that); }
862 
863   /**
864    * Returns `true` if this `Function` contains a callable, i.e. is
865    * non-empty.
866    */
867   explicit operator bool() const noexcept { return exec_ != nullptr; }
868 
869   /**
870    * Returns the size of the allocation made to store the callable on the
871    * heap. If `0` is returned, there has been no additional memory
872    * allocation because the callable is stored within the `Function` object.
873    */
874   std::size_t heapAllocatedMemory() const noexcept {
875     return exec(Op::HEAP, nullptr, nullptr);
876   }
877 
878   using typename Traits::SharedProxy;
879 
880   /**
881    * Move this `Function` into a copyable callable object, of which all copies
882    * share the state.
883    */
884   SharedProxy asSharedProxy() && { return SharedProxy{std::move(*this)}; }
885 
886   /**
887    * Construct a `std::function` by moving in the contents of this `Function`.
888    * Note that the returned `std::function` will share its state (i.e. captured
889    * data) across all copies you make of it, so be very careful when copying.
890    */
891   std::function<typename Traits::NonConstSignature> asStdFunction() && {
892     return std::move(*this).asSharedProxy();
893   }
894 };
895 
896 template <typename FunctionType>
897 void swap(Function<FunctionType>& lhs, Function<FunctionType>& rhs) noexcept {
898   lhs.swap(rhs);
899 }
900 
901 template <typename FunctionType>
902 bool operator==(const Function<FunctionType>& fn, std::nullptr_t) {
903   return !fn;
904 }
905 
906 template <typename FunctionType>
907 bool operator==(std::nullptr_t, const Function<FunctionType>& fn) {
908   return !fn;
909 }
910 
911 template <typename FunctionType>
912 bool operator!=(const Function<FunctionType>& fn, std::nullptr_t) {
913   return !(fn == nullptr);
914 }
915 
916 template <typename FunctionType>
917 bool operator!=(std::nullptr_t, const Function<FunctionType>& fn) {
918   return !(nullptr == fn);
919 }
920 
921 /**
922  * NOTE: See detailed note about `constCastFunction` at the top of the file.
923  * This is potentially dangerous and requires the equivalent of a `const_cast`.
924  */
925 template <typename ReturnType, typename... Args>
926 Function<ReturnType(Args...) const> constCastFunction(
927     Function<ReturnType(Args...)>&& that) noexcept {
928   return Function<ReturnType(Args...) const>{
929       std::move(that), detail::function::CoerceTag{}};
930 }
931 
932 template <typename ReturnType, typename... Args>
933 Function<ReturnType(Args...) const> constCastFunction(
934     Function<ReturnType(Args...) const>&& that) noexcept {
935   return std::move(that);
936 }
937 
938 #if FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE
939 template <typename ReturnType, typename... Args>
940 Function<ReturnType(Args...) const noexcept> constCastFunction(
941     Function<ReturnType(Args...) noexcept>&& that) noexcept {
942   return Function<ReturnType(Args...) const noexcept>{
943       std::move(that), detail::function::CoerceTag{}};
944 }
945 
946 template <typename ReturnType, typename... Args>
947 Function<ReturnType(Args...) const noexcept> constCastFunction(
948     Function<ReturnType(Args...) const noexcept>&& that) noexcept {
949   return std::move(that);
950 }
951 #endif
952 
953 /**
954  * @class FunctionRef
955  *
956  * @brief A reference wrapper for callable objects
957  *
958  * FunctionRef is similar to std::reference_wrapper, but the template parameter
959  * is the function signature type rather than the type of the referenced object.
960  * A folly::FunctionRef is cheap to construct as it contains only a pointer to
961  * the referenced callable and a pointer to a function which invokes the
962  * callable.
963  *
964  * The user of FunctionRef must be aware of the reference semantics: storing a
965  * copy of a FunctionRef is potentially dangerous and should be avoided unless
966  * the referenced object definitely outlives the FunctionRef object. Thus any
967  * function that accepts a FunctionRef parameter should only use it to invoke
968  * the referenced function and not store a copy of it. Knowing that FunctionRef
969  * itself has reference semantics, it is generally okay to use it to reference
970  * lambdas that capture by reference.
971  */
972 
973 template <typename FunctionType>
974 class FunctionRef;
975 
976 template <typename ReturnType, typename... Args>
977 class FunctionRef<ReturnType(Args...)> final {
978   template <typename Arg>
979   using CallArg = detail::function::CallArg<Arg>;
980 
981   using Call = ReturnType (*)(CallArg<Args>..., void*);
982 
983   static ReturnType uninitCall(CallArg<Args>..., void*) {
984     throw_exception<std::bad_function_call>();
985   }
986 
987   template <
988       typename Fun,
989       std::enable_if_t<!std::is_pointer<Fun>::value, int> = 0>
990   static ReturnType call(CallArg<Args>... args, void* object) {
991     using Pointer = std::add_pointer_t<Fun>;
992     return static_cast<ReturnType>(invoke(
993         static_cast<Fun&&>(*static_cast<Pointer>(object)),
994         static_cast<Args&&>(args)...));
995   }
996   template <
997       typename Fun,
998       std::enable_if_t<std::is_pointer<Fun>::value, int> = 0>
999   static ReturnType call(CallArg<Args>... args, void* object) {
1000     return static_cast<ReturnType>(
1001         invoke(reinterpret_cast<Fun>(object), static_cast<Args&&>(args)...));
1002   }
1003 
1004   void* object_{nullptr};
1005   Call call_{&FunctionRef::uninitCall};
1006 
1007  public:
1008   /**
1009    * Default constructor. Constructs an empty FunctionRef.
1010    *
1011    * Invoking it will throw std::bad_function_call.
1012    */
1013   constexpr FunctionRef() = default;
1014 
1015   /**
1016    * Like default constructor. Constructs an empty FunctionRef.
1017    *
1018    * Invoking it will throw std::bad_function_call.
1019    */
1020   constexpr explicit FunctionRef(std::nullptr_t) noexcept {}
1021 
1022   /**
1023    * Construct a FunctionRef from a reference to a callable object. If the
1024    * callable is considered to be an empty callable, the FunctionRef will be
1025    * empty.
1026    */
1027   template <
1028       typename Fun,
1029       std::enable_if_t<
1030           Conjunction<
1031               Negation<std::is_same<FunctionRef, std::decay_t<Fun>>>,
1032               is_invocable_r<ReturnType, Fun&&, Args&&...>>::value,
1033           int> = 0>
1034   constexpr /* implicit */ FunctionRef(Fun&& fun) noexcept {
1035     // `Fun` may be a const type, in which case we have to do a const_cast
1036     // to store the address in a `void*`. This is safe because the `void*`
1037     // will be cast back to `Fun*` (which is a const pointer whenever `Fun`
1038     // is a const type) inside `FunctionRef::call`
1039     auto& ref = fun; // work around forwarding lint advice
1040     if (!detail::function::isEmptyFunction(ref)) {
1041       auto ptr = std::addressof(ref);
1042       object_ = const_cast<void*>(static_cast<void const*>(ptr));
1043       call_ = &FunctionRef::template call<Fun>;
1044     }
1045   }
1046 
1047   /**
1048    * Constructs a FunctionRef from a pointer to a function. If the
1049    * pointer is nullptr, the FunctionRef will be empty.
1050    */
1051   template <
1052       typename Fun,
1053       std::enable_if_t<std::is_function<Fun>::value, int> = 0,
1054       std::enable_if_t<is_invocable_r_v<ReturnType, Fun&, Args&&...>, int> = 0>
1055   constexpr /* implicit */ FunctionRef(Fun* fun) noexcept {
1056     if (fun) {
1057       object_ = const_cast<void*>(reinterpret_cast<void const*>(fun));
1058       call_ = &FunctionRef::template call<Fun*>;
1059     }
1060   }
1061 
1062   ReturnType operator()(Args... args) const {
1063     return call_(static_cast<Args&&>(args)..., object_);
1064   }
1065 
1066   constexpr explicit operator bool() const noexcept { return object_; }
1067 
1068   constexpr friend bool operator==(
1069       FunctionRef<ReturnType(Args...)> ref, std::nullptr_t) noexcept {
1070     return ref.object_ == nullptr;
1071   }
1072   constexpr friend bool operator!=(
1073       FunctionRef<ReturnType(Args...)> ref, std::nullptr_t) noexcept {
1074     return ref.object_ != nullptr;
1075   }
1076 
1077   constexpr friend bool operator==(
1078       std::nullptr_t, FunctionRef<ReturnType(Args...)> ref) noexcept {
1079     return ref.object_ == nullptr;
1080   }
1081   constexpr friend bool operator!=(
1082       std::nullptr_t, FunctionRef<ReturnType(Args...)> ref) noexcept {
1083     return ref.object_ != nullptr;
1084   }
1085 };
1086 
1087 } // namespace folly
1088