Skip to content

Instantly share code, notes, and snippets.

@EricWF
Last active August 26, 2015 18:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EricWF/3a35b140a66d4826a9d0 to your computer and use it in GitHub Desktop.
Save EricWF/3a35b140a66d4826a9d0 to your computer and use it in GitHub Desktop.
Function Fix
diff --git a/include/functional b/include/functional
index 3c9f5a7..539a708 100644
--- a/include/functional
+++ b/include/functional
@@ -1475,13 +1475,25 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
} // __function
+typedef typename aligned_storage<3*sizeof(void*)>::type _SmallFuncBuf;
+
+template <class _Tp>
+ struct _IsSmallFunc
+ : public integral_constant<bool
+ , sizeof(_Tp) <= 3*sizeof(void*)
+ && alignment_of<_SmallFuncBuf>::value
+ % alignment_of<_Tp>::value == 0
+ && is_nothrow_copy_constructible<_Tp>::value
+ >
+ {};
+
template<class _Rp, class ..._ArgTypes>
class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_ArgTypes...)>
: public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
{
typedef __function::__base<_Rp(_ArgTypes...)> __base;
- typename aligned_storage<3*sizeof(void*)>::type __buf_;
+ _SmallFuncBuf __buf_;
__base* __f_;
template <class _Fp, bool = !is_same<_Fp, function>::value &&
@@ -1651,7 +1663,7 @@ function<_Rp(_ArgTypes...)>::function(_Fp __f,
if (__function::__not_null(__f))
{
typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF;
- if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value)
+ if (_IsSmallFunc<_Fp>::value)
{
__f_ = (__base*)&__buf_;
::new (__f_) _FF(_VSTD::move(__f));
@@ -1680,8 +1692,7 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp _
typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;
typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
_Ap __a(__a0);
- if (sizeof(_FF) <= sizeof(__buf_) &&
- is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)
+ if (_IsSmallFunc<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)
{
__f_ = (__base*)&__buf_;
::new (__f_) _FF(_VSTD::move(__f), _Alloc(__a));
@@ -1769,7 +1780,7 @@ function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
{
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
{
- typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+ _SmallFuncBuf __tempbuf;
__base* __t = (__base*)&__tempbuf;
__f_->__clone(__t);
__f_->destroy();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment