[binutils-gdb] [gdb] Add unit test for iterator_range
Tom de Vries via Gdb-cvs <[email protected]>
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5ff6e5b9685a7c11956c0142afed9cd4edd77f58 commit 5ff6e5b9685a7c11956c0142afed9cd4edd77f58 Author: Tom de Vries <[email protected]> Date: Tue Apr 21 18:12:05 2026 +0200 [gdb] Add unit test for iterator_range I noticed iterator_range doesn't have a selftest. I found int_array_iterator in filtered_iterator-selftests.c, and decided to use that as iterator. Factor out int-array-iterator.h out of filtered_iterator-selftests.c, and use it in new unit test iterator-range-selftests.c. Approved-By: Simon Marchi <[email protected]> Diff: --- gdb/Makefile.in | 1 + gdb/unittests/filtered_iterator-selftests.c | 75 +-------------------- gdb/unittests/int-array-iterator.h | 101 ++++++++++++++++++++++++++++ gdb/unittests/iterator-range-selftests.c | 100 +++++++++++++++++++++++++++ 4 files changed, 203 insertions(+), 74 deletions(-) diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 1acf99e3346..e38ba95eebd 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -472,6 +472,7 @@ SELFTESTS_SRCS = \ unittests/gdb_tilde_expand-selftests.c \ unittests/gmp-utils-selftests.c \ unittests/intrusive_list-selftests.c \ + unittests/iterator-range-selftests.c \ unittests/lookup_name_info-selftests.c \ unittests/memory-map-selftests.c \ unittests/memrange-selftests.c \ diff --git a/gdb/unittests/filtered_iterator-selftests.c b/gdb/unittests/filtered_iterator-selftests.c index 17408b2798b..f40c2a1c4ab 100644 --- a/gdb/unittests/filtered_iterator-selftests.c +++ b/gdb/unittests/filtered_iterator-selftests.c @@ -19,83 +19,10 @@ #include "gdbsupport/selftest.h" #include "gdbsupport/filtered-iterator.h" - -#include <iterator> +#include "int-array-iterator.h" namespace selftests { -/* An iterator class that iterates on integer arrays. */ - -struct int_array_iterator -{ - using value_type = int; - using reference = int &; - using pointer = int *; - using iterator_category = std::forward_iterator_tag; - using difference_type = int; - - /* Create an iterator that points at the first element of an integer - array at ARRAY of size SIZE. */ - int_array_iterator (int *array, size_t size) - : m_array (array), m_size (size) - {} - - /* Create a past-the-end iterator. */ - int_array_iterator () - : m_array (nullptr), m_size (0) - {} - - bool operator== (const int_array_iterator &other) const - { - /* If both are past-the-end, they are equal. */ - if (m_array == nullptr && other.m_array == nullptr) - return true; - - /* If just one of them is past-the-end, they are not equal. */ - if (m_array == nullptr || other.m_array == nullptr) - return false; - - /* If they are both not past-the-end, make sure they iterate on the - same array (we shouldn't compare iterators that iterate on different - things). */ - SELF_CHECK (m_array == other.m_array); - - /* They are equal if they have the same current index. */ - return m_cur_idx == other.m_cur_idx; - } - - bool operator!= (const int_array_iterator &other) const - { - return !(*this == other); - } - - void operator++ () - { - /* Make sure nothing tries to increment a past the end iterator. */ - SELF_CHECK (m_cur_idx < m_size); - - m_cur_idx++; - - /* Mark the iterator as "past-the-end" if we have reached the end. */ - if (m_cur_idx == m_size) - m_array = nullptr; - } - - int operator* () const - { - /* Make sure nothing tries to dereference a past the end iterator. */ - SELF_CHECK (m_cur_idx < m_size); - - return m_array[m_cur_idx]; - } - -private: - /* A nullptr value in M_ARRAY indicates a past-the-end iterator. */ - int *m_array; - size_t m_size; - size_t m_cur_idx = 0; -}; - /* Filter to only keep the even numbers. */ struct even_numbers_only diff --git a/gdb/unittests/int-array-iterator.h b/gdb/unittests/int-array-iterator.h new file mode 100644 index 00000000000..03b0e038501 --- /dev/null +++ b/gdb/unittests/int-array-iterator.h @@ -0,0 +1,101 @@ +/* An iterator class that iterates on integer arrays. + + Copyright (C) 2019-2026 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDB_UNITTESTS_INT_ARRAY_ITERATOR_H +#define GDB_UNITTESTS_INT_ARRAY_ITERATOR_H + +#include "gdbsupport/selftest.h" + +#include <iterator> + +namespace selftests { + +struct int_array_iterator +{ + using value_type = int; + using reference = int &; + using pointer = int *; + using iterator_category = std::forward_iterator_tag; + using difference_type = int; + + /* Create an iterator that points at the first element of an integer + array at ARRAY of size SIZE. */ + int_array_iterator (int *array, size_t size) + : m_array (array), m_size (size) + {} + + /* Create a past-the-end iterator. */ + int_array_iterator () + : m_array (nullptr), m_size (0) + {} + + bool operator== (const int_array_iterator &other) const + { + /* If both are past-the-end, they are equal. */ + if (m_array == nullptr && other.m_array == nullptr) + return true; + + /* If just one of them is past-the-end, they are not equal. */ + if (m_array == nullptr || other.m_array == nullptr) + return false; + + /* If they are both not past-the-end, make sure they iterate on the + same array (we shouldn't compare iterators that iterate on different + things). */ + SELF_CHECK (m_array == other.m_array); + + /* They are equal if they have the same current index. */ + return m_cur_idx == other.m_cur_idx; + } + + bool operator!= (const int_array_iterator &other) const + { + return !(*this == other); + } + + void operator++ () + { + /* Make sure nothing tries to increment a past the end iterator. */ + SELF_CHECK (m_cur_idx < m_size); + + m_cur_idx++; + + /* Mark the iterator as "past-the-end" if we have reached the end. */ + if (m_cur_idx == m_size) + m_array = nullptr; + } + + int operator* () const + { + /* Make sure nothing tries to dereference a past the end iterator. */ + SELF_CHECK (m_cur_idx < m_size); + + return m_array[m_cur_idx]; + } + +private: + /* A nullptr value in M_ARRAY indicates a past-the-end iterator. */ + int *m_array; + size_t m_size; + size_t m_cur_idx = 0; +}; + +} /* namespace selftests */ + +#endif /* GDB_UNITTESTS_INT_ARRAY_ITERATOR_H */ diff --git a/gdb/unittests/iterator-range-selftests.c b/gdb/unittests/iterator-range-selftests.c new file mode 100644 index 00000000000..a05531d95e0 --- /dev/null +++ b/gdb/unittests/iterator-range-selftests.c @@ -0,0 +1,100 @@ +/* Self tests for the iterator_range class. + + Copyright (C) 2026 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "gdbsupport/selftest.h" +#include "gdbsupport/iterator-range.h" +#include "int-array-iterator.h" + +namespace selftests { + +using int_array_iterator_range = iterator_range<int_array_iterator>; + +static void +test_iterator_range_1 (int_array_iterator_range &r, int array[], int size, + int_array_iterator &begin, int_array_iterator &end) +{ + SELF_CHECK (r.begin () == begin); + SELF_CHECK (r.end () == end); + SELF_CHECK (r.size () == size); + SELF_CHECK (r.empty () == (size == 0)); + + int j = 0; + for (auto i : r) + { + SELF_CHECK (j < size); + SELF_CHECK (i == array[j]); + j++; + } + SELF_CHECK (j == size); +} + +static void +test_iterator_range () +{ + int array[] = { 4, 4, 5, 6, 7, 8, 9 }; + int array_size = ARRAY_SIZE (array); + + int_array_iterator begin (array, array_size); + int_array_iterator end; + + { + /* Constructor using begin and end. */ + auto r = int_array_iterator_range (begin, end); + test_iterator_range_1 (r, array, array_size, begin, end); + } + + { + /* Constructor using begin, assuming end can be default-constructed. */ + auto r2 = int_array_iterator_range (begin); + test_iterator_range_1 (r2, array, array_size, begin, end); + } + + { + /* Empty range. */ + auto r3 = int_array_iterator_range (end, end); + test_iterator_range_1 (r3, nullptr, 0, end, end); + } + + { + auto r4 = int_array_iterator_range (begin, end); + + /* Copy constructor. */ + auto r5 (r4); + test_iterator_range_1 (r5, array, array_size, begin, end); + + /* Move constructor. */ + auto r6 (std::move (r4)); + test_iterator_range_1 (r6, array, array_size, begin, end); + } + + { + const auto r7 = int_array_iterator_range (begin, end); + + /* Const copy constructor. */ + auto r8 (r7); + test_iterator_range_1 (r8, array, array_size, begin, end); + } +} + +} /* namespace selftests */ + +INIT_GDB_FILE (iterator_range_selftests) +{ + selftests::register_test ("iterator_range", selftests::test_iterator_range); +}