[vector] Optimize vector copy

This commit is contained in:
Behdad Esfahbod 2022-05-19 15:02:10 -06:00
parent 28b44ac46a
commit fb77f48ffd
2 changed files with 32 additions and 2 deletions

View File

@ -192,11 +192,15 @@ template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigne
#define hb_is_trivially_copyable(T) __has_trivial_copy(T) #define hb_is_trivially_copyable(T) __has_trivial_copy(T)
#define hb_is_trivially_copy_assignable(T) (__has_trivial_copy(T) && __has_trivial_assign(T)) #define hb_is_trivially_copy_assignable(T) (__has_trivial_copy(T) && __has_trivial_assign(T))
#define hb_is_trivially_constructible(T) __has_trivial_constructor(T) #define hb_is_trivially_constructible(T) __has_trivial_constructor(T)
#define hb_is_copy_constructible(T) __has_copy_constructor(T)
#define hb_is_trivially_copy_constructible(T) __has_trivial_copy_constructor(T)
#define hb_is_trivially_destructible(T) __has_trivial_destructor(T) #define hb_is_trivially_destructible(T) __has_trivial_destructor(T)
#else #else
#define hb_is_trivially_copyable(T) std::is_trivially_copyable<T>::value #define hb_is_trivially_copyable(T) std::is_trivially_copyable<T>::value
#define hb_is_trivially_copy_assignable(T) std::is_trivially_copy_assignable<T>::value #define hb_is_trivially_copy_assignable(T) std::is_trivially_copy_assignable<T>::value
#define hb_is_trivially_constructible(T) std::is_trivially_constructible<T>::value #define hb_is_trivially_constructible(T) std::is_trivially_constructible<T>::value
#define hb_is_copy_constructible(T) std::is_copy_constructible<T>::value
#define hb_is_trivially_copy_constructible(T) std::is_trivially_copy_constructible<T>::value
#define hb_is_trivially_destructible(T) std::is_trivially_destructible<T>::value #define hb_is_trivially_destructible(T) std::is_trivially_destructible<T>::value
#endif #endif

View File

@ -61,7 +61,8 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty
hb_vector_t (const hb_vector_t &o) : hb_vector_t () hb_vector_t (const hb_vector_t &o) : hb_vector_t ()
{ {
alloc (o.length); alloc (o.length);
hb_copy (o, *this); if (unlikely (in_error ())) return;
copy_vector (o);
} }
hb_vector_t (hb_vector_t &&o) hb_vector_t (hb_vector_t &&o)
{ {
@ -109,7 +110,10 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty
{ {
reset (); reset ();
alloc (o.length); alloc (o.length);
hb_copy (o, *this); if (unlikely (in_error ())) return *this;
copy_vector (o);
return *this; return *this;
} }
hb_vector_t& operator = (hb_vector_t &&o) hb_vector_t& operator = (hb_vector_t &&o)
@ -250,6 +254,28 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty
} }
} }
template <typename T = Type,
hb_enable_if (hb_is_trivially_copyable (T))>
void
copy_vector (const hb_vector_t &other)
{
length = other.length;
hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
}
template <typename T = Type,
hb_enable_if (!hb_is_trivially_copyable (T) &&
hb_is_copy_constructible (T))>
void
copy_vector (const hb_vector_t &other)
{
length = 0;
while (length < other.length)
{
length++;
new (std::addressof (arrayZ[length - 1])) Type (other.arrayZ[length - 1]);
}
}
template <typename T = Type, template <typename T = Type,
hb_enable_if (hb_is_trivially_destructible(T))> hb_enable_if (hb_is_trivially_destructible(T))>
void void