Merge pull request #3376 from harfbuzz/auto-vector
[vector] Automatic item allocation / destruction
This commit is contained in:
commit
0b54f92416
|
@ -186,7 +186,7 @@ struct graph_t
|
|||
|
||||
~graph_t ()
|
||||
{
|
||||
vertices_.fini_deep ();
|
||||
vertices_.fini ();
|
||||
}
|
||||
|
||||
bool in_error () const
|
||||
|
@ -309,7 +309,7 @@ struct graph_t
|
|||
remap_all_obj_indices (id_map, &sorted_graph);
|
||||
|
||||
hb_swap (vertices_, sorted_graph);
|
||||
sorted_graph.fini_deep ();
|
||||
sorted_graph.fini ();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -369,7 +369,7 @@ struct graph_t
|
|||
remap_all_obj_indices (id_map, &sorted_graph);
|
||||
|
||||
hb_swap (vertices_, sorted_graph);
|
||||
sorted_graph.fini_deep ();
|
||||
sorted_graph.fini ();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -82,6 +82,7 @@ struct hb_vector_t
|
|||
|
||||
void fini ()
|
||||
{
|
||||
shrink_vector (0);
|
||||
hb_free (arrayZ);
|
||||
init ();
|
||||
}
|
||||
|
@ -223,13 +224,73 @@ struct hb_vector_t
|
|||
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 ();
|
||||
unsigned old_length = length;
|
||||
shrink_vector (0);
|
||||
length = old_length;
|
||||
hb_free (arrayZ);
|
||||
}
|
||||
return new_array;
|
||||
}
|
||||
|
||||
template <typename T = Type,
|
||||
hb_enable_if (std::is_trivially_constructible<T>::value ||
|
||||
!std::is_default_constructible<T>::value)>
|
||||
void
|
||||
grow_vector (unsigned size)
|
||||
{
|
||||
memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
|
||||
length = size;
|
||||
}
|
||||
template <typename T = Type,
|
||||
hb_enable_if (!std::is_trivially_constructible<T>::value &&
|
||||
std::is_default_constructible<T>::value)>
|
||||
void
|
||||
grow_vector (unsigned size)
|
||||
{
|
||||
while (length < size)
|
||||
{
|
||||
length++;
|
||||
new (std::addressof (arrayZ[length - 1])) Type ();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T = Type,
|
||||
hb_enable_if (std::is_trivially_destructible<T>::value)>
|
||||
void
|
||||
shrink_vector (unsigned size)
|
||||
{
|
||||
length = size;
|
||||
}
|
||||
template <typename T = Type,
|
||||
hb_enable_if (!std::is_trivially_destructible<T>::value)>
|
||||
void
|
||||
shrink_vector (unsigned size)
|
||||
{
|
||||
while ((unsigned) length > size)
|
||||
{
|
||||
arrayZ[(unsigned) length - 1].~Type ();
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T = Type,
|
||||
hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
|
||||
void
|
||||
shift_down_vector (unsigned i)
|
||||
{
|
||||
memmove (static_cast<void *> (&arrayZ[i - 1]),
|
||||
static_cast<void *> (&arrayZ[i]),
|
||||
(length - i) * sizeof (Type));
|
||||
}
|
||||
template <typename T = Type,
|
||||
hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
|
||||
void
|
||||
shift_down_vector (unsigned i)
|
||||
{
|
||||
for (; i < length; i++)
|
||||
arrayZ[i - 1] = std::move (arrayZ[i]);
|
||||
}
|
||||
|
||||
/* Allocate for size but don't adjust length. */
|
||||
bool alloc (unsigned int size)
|
||||
{
|
||||
|
@ -272,8 +333,9 @@ struct hb_vector_t
|
|||
return false;
|
||||
|
||||
if (size > length)
|
||||
// XXX reconstruct objects?! / destruct objects...
|
||||
memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
|
||||
grow_vector (size);
|
||||
else if (size < length)
|
||||
shrink_vector (size);
|
||||
|
||||
length = size;
|
||||
return true;
|
||||
|
@ -282,25 +344,28 @@ struct hb_vector_t
|
|||
Type pop ()
|
||||
{
|
||||
if (!length) return Null (Type);
|
||||
return std::move (arrayZ[--length]); /* Does this move actually work? */
|
||||
// XXX Destruct?
|
||||
Type v = std::move (arrayZ[length - 1]);
|
||||
arrayZ[length - 1].~Type ();
|
||||
length--;
|
||||
return v;
|
||||
}
|
||||
|
||||
void remove (unsigned int i)
|
||||
{
|
||||
if (unlikely (i >= length))
|
||||
return;
|
||||
memmove (static_cast<void *> (&arrayZ[i]),
|
||||
static_cast<void *> (&arrayZ[i + 1]),
|
||||
(length - i - 1) * sizeof (Type));
|
||||
arrayZ[i].~Type ();
|
||||
shift_down_vector (i + 1);
|
||||
length--;
|
||||
}
|
||||
|
||||
void shrink (int size_)
|
||||
{
|
||||
unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
|
||||
if (size < length)
|
||||
length = size;
|
||||
if (size >= length)
|
||||
return;
|
||||
|
||||
shrink_vector (size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
Loading…
Reference in New Issue