Last active
August 26, 2015 18:08
-
-
Save EricWF/3a35b140a66d4826a9d0 to your computer and use it in GitHub Desktop.
Function Fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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