/* Self tests for the filtered_iterator class.

   Copyright (C) 2019-2021 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/common-defs.h"
#include "gdbsupport/selftest.h"
#include "gdbsupport/filtered-iterator.h"

#include <iterator>

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).  */
    gdb_assert (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. */
    gdb_assert (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.  */
    gdb_assert (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
{
  bool operator() (int n)
  {
    return n % 2 == 0;
  }
};

/* Test typical usage.  */

static void
test_filtered_iterator ()
{
  int array[] = { 4, 4, 5, 6, 7, 8, 9 };
  std::vector<int> even_ints;
  const std::vector<int> expected_even_ints { 4, 4, 6, 8 };

  filtered_iterator<int_array_iterator, even_numbers_only>
    iter (array, ARRAY_SIZE (array));
  filtered_iterator<int_array_iterator, even_numbers_only> end;

  for (; iter != end; ++iter)
    even_ints.push_back (*iter);

  gdb_assert (even_ints == expected_even_ints);
}

/* Test operator== and operator!=. */

static void
test_filtered_iterator_eq ()
{
  int array[] = { 4, 4, 5, 6, 7, 8, 9 };

  filtered_iterator<int_array_iterator, even_numbers_only>
    iter1(array, ARRAY_SIZE (array));
  filtered_iterator<int_array_iterator, even_numbers_only>
    iter2(array, ARRAY_SIZE (array));

  /* They start equal.  */
  gdb_assert (iter1 == iter2);
  gdb_assert (!(iter1 != iter2));

  /* Advance 1, now they aren't equal (despite pointing to equal values).  */
  ++iter1;
  gdb_assert (!(iter1 == iter2));
  gdb_assert (iter1 != iter2);

  /* Advance 2, now they are equal again.  */
  ++iter2;
  gdb_assert (iter1 == iter2);
  gdb_assert (!(iter1 != iter2));
}

} /* namespace selftests */

void _initialize_filtered_iterator_selftests ();
void
_initialize_filtered_iterator_selftests ()
{
  selftests::register_test ("filtered_iterator",
			    selftests::test_filtered_iterator);
  selftests::register_test ("filtered_iterator_eq",
			    selftests::test_filtered_iterator_eq);
}
