Commit e4d2203e by David Malcolm Committed by David Malcolm

vec.h: add auto_delete_vec

This patch adds a class auto_delete_vec<T>, a subclass of auto_vec <T *>
that deletes all of its elements on destruction; it's used in many
places in the analyzer patch kit.

This is a crude way for a vec to "own" the objects it points to
and clean up automatically (essentially a workaround for not being able
to use unique_ptr, due to C++98).

gcc/ChangeLog:
	* vec.c (class selftest::count_dtor): New class.
	(selftest::test_auto_delete_vec): New test.
	(selftest::vec_c_tests): Call it.
	* vec.h (class auto_delete_vec): New class template.
	(auto_delete_vec<T>::~auto_delete_vec): New dtor.

From-SVN: r280027
parent b3de347f
2020-01-08 David Malcolm <dmalcolm@redhat.com> 2020-01-08 David Malcolm <dmalcolm@redhat.com>
* vec.c (class selftest::count_dtor): New class.
(selftest::test_auto_delete_vec): New test.
(selftest::vec_c_tests): Call it.
* vec.h (class auto_delete_vec): New class template.
(auto_delete_vec<T>::~auto_delete_vec): New dtor.
2020-01-08 David Malcolm <dmalcolm@redhat.com>
* sbitmap.h (auto_sbitmap): Add operator const_sbitmap. * sbitmap.h (auto_sbitmap): Add operator const_sbitmap.
2020-01-08 Jim Wilson <jimw@sifive.com> 2020-01-08 Jim Wilson <jimw@sifive.com>
......
...@@ -516,6 +516,32 @@ test_reverse () ...@@ -516,6 +516,32 @@ test_reverse ()
} }
} }
/* A test class that increments a counter every time its dtor is called. */
class count_dtor
{
public:
count_dtor (int *counter) : m_counter (counter) {}
~count_dtor () { (*m_counter)++; }
private:
int *m_counter;
};
/* Verify that auto_delete_vec deletes the elements within it. */
static void
test_auto_delete_vec ()
{
int dtor_count = 0;
{
auto_delete_vec <count_dtor> v;
v.safe_push (new count_dtor (&dtor_count));
v.safe_push (new count_dtor (&dtor_count));
}
ASSERT_EQ (dtor_count, 2);
}
/* Run all of the selftests within this file. */ /* Run all of the selftests within this file. */
void void
...@@ -533,6 +559,7 @@ vec_c_tests () ...@@ -533,6 +559,7 @@ vec_c_tests ()
test_block_remove (); test_block_remove ();
test_qsort (); test_qsort ();
test_reverse (); test_reverse ();
test_auto_delete_vec ();
} }
} // namespace selftest } // namespace selftest
......
...@@ -1547,6 +1547,31 @@ class auto_string_vec : public auto_vec <char *> ...@@ -1547,6 +1547,31 @@ class auto_string_vec : public auto_vec <char *>
~auto_string_vec (); ~auto_string_vec ();
}; };
/* A subclass of auto_vec <T *> that deletes all of its elements on
destruction.
This is a crude way for a vec to "own" the objects it points to
and clean up automatically.
For example, no attempt is made to delete elements when an item
within the vec is overwritten.
We can't rely on gnu::unique_ptr within a container,
since we can't rely on move semantics in C++98. */
template <typename T>
class auto_delete_vec : public auto_vec <T *>
{
public:
auto_delete_vec () {}
auto_delete_vec (size_t s) : auto_vec <T *> (s) {}
~auto_delete_vec ();
private:
DISABLE_COPY_AND_ASSIGN(auto_delete_vec<T>);
};
/* Conditionally allocate heap memory for VEC and its internal vector. */ /* Conditionally allocate heap memory for VEC and its internal vector. */
template<typename T> template<typename T>
...@@ -1651,6 +1676,19 @@ auto_string_vec::~auto_string_vec () ...@@ -1651,6 +1676,19 @@ auto_string_vec::~auto_string_vec ()
free (str); free (str);
} }
/* auto_delete_vec's dtor, deleting all contained items, automatically
chaining up to ~auto_vec <T*>, which frees the internal buffer. */
template <typename T>
inline
auto_delete_vec<T>::~auto_delete_vec ()
{
int i;
T *item;
FOR_EACH_VEC_ELT (*this, i, item)
delete item;
}
/* Return a copy of this vector. */ /* Return a copy of this vector. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment