summaryrefslogtreecommitdiffstats
path: root/libcxx/include/memory
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2012-02-15 00:41:34 +0000
committerHoward Hinnant <hhinnant@apple.com>2012-02-15 00:41:34 +0000
commit9741d6c96e861260c9f90b04c09f66dc9f87bb14 (patch)
treea2da17a210c3e2a9253324369ce447f9534ef62e /libcxx/include/memory
parent49d6cc8457edaf98f199eaf936103d010883c8d7 (diff)
downloadbcm5719-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/memory63
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
OpenPOWER on IntegriCloud