[vector] Move semantics when resizing

This commit is contained in:
Behdad Esfahbod 2022-01-13 16:05:42 -07:00
parent 1c50106608
commit 63affc4eae
3 changed files with 53 additions and 1 deletions

View File

@ -360,6 +360,16 @@ struct IndexSubtable
struct IndexSubtableRecord
{
/* XXX Remove this and fix by not inserting it into vector. */
IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
{
firstGlyphIndex = o.firstGlyphIndex;
lastGlyphIndex = o.lastGlyphIndex;
offsetToSubtable = (unsigned) o.offsetToSubtable;
assert (offsetToSubtable.is_null ());
return *this;
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);

View File

@ -204,6 +204,32 @@ struct hb_vector_t
bool in_error () const { return allocated < 0; }
template <typename T = Type,
hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
Type *
realloc_vector (unsigned new_allocated)
{
return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
}
template <typename T = Type,
hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
Type *
realloc_vector (unsigned new_allocated)
{
Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type));
if (likely (new_array))
{
for (unsigned i = 0; i < length; i++)
new (std::addressof (new_array[i])) Type ();
for (unsigned i = 0; i < (unsigned) length; i++)
new_array[i] = std::move (arrayZ[i]);
for (unsigned i = 0; i < (unsigned) length; i++)
arrayZ[i].~Type ();
hb_free (arrayZ);
}
return new_array;
}
/* Allocate for size but don't adjust length. */
bool alloc (unsigned int size)
{
@ -225,7 +251,7 @@ struct hb_vector_t
(new_allocated < (unsigned) allocated) ||
hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
if (likely (!overflows))
new_array = (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
new_array = realloc_vector (new_allocated);
if (unlikely (!new_array))
{
@ -246,6 +272,7 @@ struct hb_vector_t
return false;
if (size > length)
// XXX reconstruct objects?! / destruct objects...
memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
length = size;
@ -256,6 +283,7 @@ struct hb_vector_t
{
if (!length) return Null (Type);
return std::move (arrayZ[--length]); /* Does this move actually work? */
// XXX Destruct?
}
void remove (unsigned int i)

View File

@ -26,6 +26,7 @@
#include "hb.hh"
#include "hb-vector.hh"
#include "hb-set.hh"
#include <string>
int
@ -136,5 +137,18 @@ main (int argc, char **argv)
assert (v2[2] == 3);
}
#if 0
{
hb_vector_t<std::string> v;
std::string s;
for (unsigned i = 1; i < 100; i++)
{
s += "x";
v.push (s);
}
}
#endif
return 0;
}