diff options
| author | Howard Hinnant <hhinnant@apple.com> | 2012-02-15 00:41:34 +0000 |
|---|---|---|
| committer | Howard Hinnant <hhinnant@apple.com> | 2012-02-15 00:41:34 +0000 |
| commit | 9741d6c96e861260c9f90b04c09f66dc9f87bb14 (patch) | |
| tree | a2da17a210c3e2a9253324369ce447f9534ef62e /libcxx/include/memory | |
| parent | 49d6cc8457edaf98f199eaf936103d010883c8d7 (diff) | |
| download | bcm5719-llvm-9741d6c96e861260c9f90b04c09f66dc9f87bb14.tar.gz bcm5719-llvm-9741d6c96e861260c9f90b04c09f66dc9f87bb14.zip | |
Implement a few optimizations for vector push_back and insert. Fixes r10828365.
llvm-svn: 150542
Diffstat (limited to 'libcxx/include/memory')
| -rw-r--r-- | libcxx/include/memory | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/libcxx/include/memory b/libcxx/include/memory index 0e14275c114..e841b2cf051 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -597,6 +597,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #include <__functional_base> #include <iosfwd> #include <tuple> +#include <cstring> #if defined(_LIBCPP_NO_EXCEPTIONS) #include <cassert> #endif @@ -1395,6 +1396,14 @@ struct __has_construct { }; +#else // _LIBCPP_HAS_NO_VARIADICS + +template <class _Alloc, class _Pointer, class _Args> +struct __has_construct + : false_type +{ +}; + #endif // _LIBCPP_HAS_NO_VARIADICS template <class _Alloc, class _Pointer> @@ -1524,6 +1533,60 @@ struct _LIBCPP_VISIBLE allocator_traits __has_select_on_container_copy_construction<const allocator_type>(), __a);} + template <class _Ptr> + _LIBCPP_INLINE_VISIBILITY + static + void + __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) + { + for (; __begin1 != __end1; ++__begin1, ++__begin2) + construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1)); + } + + template <class _Tp> + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + (is_same<allocator_type, allocator<_Tp> >::value + || !__has_construct<allocator_type, _Tp*, _Tp>::value) && + is_trivially_move_constructible<_Tp>::value, + void + >::type + __construct_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + { + ptrdiff_t _Np = __end1 - __begin1; + _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp)); + __begin2 += _Np; + } + + template <class _Ptr> + _LIBCPP_INLINE_VISIBILITY + static + void + __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) + { + while (__end1 != __begin1) + construct(__a, _VSTD::__to_raw_pointer(--__end2), _VSTD::move_if_noexcept(*--__end1)); + } + + template <class _Tp> + _LIBCPP_INLINE_VISIBILITY + static + typename enable_if + < + (is_same<allocator_type, allocator<_Tp> >::value + || !__has_construct<allocator_type, _Tp*, _Tp>::value) && + is_trivially_move_constructible<_Tp>::value, + void + >::type + __construct_backward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) + { + ptrdiff_t _Np = __end1 - __begin1; + __end2 -= _Np; + _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp)); + } + private: _LIBCPP_INLINE_VISIBILITY |

