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