From 63affc4eaea73a70667f346926a3a289c35773c5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 13 Jan 2022 16:05:42 -0700 Subject: [PATCH] [vector] Move semantics when resizing --- src/hb-ot-color-cbdt-table.hh | 10 ++++++++++ src/hb-vector.hh | 30 +++++++++++++++++++++++++++++- src/test-vector.cc | 14 ++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 14459914e..963cf2ae6 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -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); diff --git a/src/hb-vector.hh b/src/hb-vector.hh index b0a1e5e96..963b44630 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -204,6 +204,32 @@ struct hb_vector_t bool in_error () const { return allocated < 0; } + template ::value)> + Type * + realloc_vector (unsigned new_allocated) + { + return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); + } + template ::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) diff --git a/src/test-vector.cc b/src/test-vector.cc index 6418a84ae..521f2a171 100644 --- a/src/test-vector.cc +++ b/src/test-vector.cc @@ -26,6 +26,7 @@ #include "hb.hh" #include "hb-vector.hh" #include "hb-set.hh" +#include int @@ -136,5 +137,18 @@ main (int argc, char **argv) assert (v2[2] == 3); } +#if 0 + { + hb_vector_t v; + + std::string s; + for (unsigned i = 1; i < 100; i++) + { + s += "x"; + v.push (s); + } + } +#endif + return 0; }