/* Self tests for array_view for GDB, the GNU debugger.

   Copyright (C) 2017-2024 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/array-view.h"
#include <array>
#include <vector>

namespace selftests {
namespace array_view_tests {

/* Triviality checks.  */
#define CHECK_TRAIT(TRAIT)			\
  static_assert (std::TRAIT<gdb::array_view<gdb_byte>>::value, "")

CHECK_TRAIT (is_trivially_copyable);
CHECK_TRAIT (is_trivially_move_assignable);
CHECK_TRAIT (is_trivially_move_constructible);
CHECK_TRAIT (is_trivially_destructible);

#undef CHECK_TRAIT

/* Wrapper around std::is_convertible to make the code using it a bit
   shorter.  (With C++14 we'd use a variable template instead.)  */

template<typename From, typename To>
static constexpr bool
is_convertible ()
{
  return std::is_convertible<From, To>::value;
}

/* Check for implicit conversion to immutable and mutable views.  */

static constexpr bool
check_convertible ()
{
  using T = gdb_byte;
  using gdb::array_view;

  return (true
	  /* immutable array_view */
	  &&  is_convertible<const T (&) [1],	array_view<const T>> ()
	  &&  is_convertible<T (&) [1], 	array_view<const T>> ()
	  &&  is_convertible<const T, 		array_view<const T>> ()
	  &&  is_convertible<T, 		array_view<const T>> ()

	  /* mutable array_view */
	  &&  is_convertible<T (&) [1], 	array_view<T>> ()
	  && !is_convertible<const T (&) [1],	array_view<T>> ()
	  &&  is_convertible<T, 		array_view<T>> ()
	  && !is_convertible<const T,		array_view<T>> ()

	  /* While float is implicitly convertible to gdb_byte, we
	     don't want implicit float->array_view<gdb_byte>
	     conversion.  */
	  && !is_convertible<float, 		array_view<const T>> ()
	  && !is_convertible<float, 		array_view<T>> ());
}

static_assert (check_convertible (), "");

namespace no_slicing
{
struct A { int i; };
struct B : A { int j; };
struct C : A { int l; };

/* Check that there's no array->view conversion for arrays of derived types or
   subclasses.  */
static constexpr bool
check ()
{
  using gdb::array_view;

  return (true

	  /* array->view  */

	  &&  is_convertible <A (&)[1], array_view<A>> ()
	  && !is_convertible <B (&)[1], array_view<A>> ()
	  && !is_convertible <C (&)[1], array_view<A>> ()

	  && !is_convertible <A (&)[1], array_view<B>> ()
	  &&  is_convertible <B (&)[1], array_view<B>> ()
	  && !is_convertible <C (&)[1], array_view<B>> ()

	  /* elem->view  */

	  &&  is_convertible <A, array_view<A>> ()
	  && !is_convertible <B, array_view<A>> ()
	  && !is_convertible <C, array_view<A>> ()

	  && !is_convertible <A, array_view<B>> ()
	  &&  is_convertible <B, array_view<B>> ()
	  && !is_convertible <C, array_view<B>> ());
}

/* Check that there's no container->view conversion for containers of derived
   types or subclasses.  */

template<template<typename ...> class Container>
static constexpr bool
check_ctor_from_container ()
{
  using gdb::array_view;

  return (    is_convertible <Container<A>, array_view<A>> ()
	  && !is_convertible <Container<B>, array_view<A>> ()
	  && !is_convertible <Container<C>, array_view<A>> ()

	  && !is_convertible <Container<A>, array_view<B>> ()
	  &&  is_convertible <Container<B>, array_view<B>> ()
	  && !is_convertible <Container<C>, array_view<B>> ());
}

} /* namespace no_slicing */

/* std::array with only one template argument, so we can pass it to
   check_ctor_from_container.  */
template<typename T> using StdArray1 = std::array<T, 1>;

static_assert (no_slicing::check (), "");
static_assert (no_slicing::check_ctor_from_container<std::vector> (), "");
static_assert (no_slicing::check_ctor_from_container<StdArray1> (), "");
static_assert (no_slicing::check_ctor_from_container<gdb::array_view> (), "");

/* Check that array_view implicitly converts from std::vector.  */

static constexpr bool
check_convertible_from_std_vector ()
{
  using gdb::array_view;
  using T = gdb_byte;

  /* Note there's no such thing as std::vector<const T>.  */

  return (true
	  &&  is_convertible <std::vector<T>, array_view<T>> ()
	  &&  is_convertible <std::vector<T>, array_view<const T>> ());
}

static_assert (check_convertible_from_std_vector (), "");

/* Check that array_view implicitly converts from std::array.  */

static constexpr bool
check_convertible_from_std_array ()
{
  using gdb::array_view;
  using T = gdb_byte;

  /* Note: a non-const T view can't refer to a const T array.  */

  return (true
	  &&  is_convertible <std::array<T, 1>,		array_view<T>> ()
	  &&  is_convertible <std::array<T, 1>,		array_view<const T>> ()
	  && !is_convertible <std::array<const T, 1>,	array_view<T>> ()
	  &&  is_convertible <std::array<const T, 1>,	array_view<const T>> ());
}

static_assert (check_convertible_from_std_array (), "");

/* Check that VIEW views C (a container like std::vector/std::array)
   correctly.  */

template<typename View, typename Container>
static bool
check_container_view (const View &view, const Container &c)
{
  if (view.empty ())
    return false;
  if (view.size () != c.size ())
    return false;
  if (view.data () != c.data ())
    return false;
  for (size_t i = 0; i < c.size (); i++)
    {
      if (&view[i] != &c[i])
	return false;
      if (view[i] != c[i])
	return false;
    }
  return true;
}

/* Check that VIEW views E (an object of the type of a view element)
   correctly.  */

template<typename View, typename Elem>
static bool
check_elem_view (const View &view, const Elem &e)
{
  if (view.empty ())
    return false;
  if (view.size () != 1)
    return false;
  if (view.data () != &e)
    return false;
  if (&view[0] != &e)
    return false;
  if (view[0] != e)
    return false;
  return true;
}

/* Check for operator[].  The first overload is taken iff
   'view<T>()[0] = T()' is a valid expression.  */

template<typename View,
	 typename = decltype (std::declval<View> ()[0]
			      = std::declval<typename View::value_type> ())>
static bool
check_op_subscript (const View &view)
{
  return true;
}

/* This overload is taken iff 'view<T>()[0] = T()' is not a valid
   expression.  */

static bool
check_op_subscript (...)
{
  return false;
}

/* Check construction with pointer + size.  This is a template in
   order to test both gdb_byte and const gdb_byte.  */

template<typename T>
static void
check_ptr_size_ctor ()
{
  T data[] = {0x11, 0x22, 0x33, 0x44};

  gdb::array_view<T> view (data + 1, 2);

  SELF_CHECK (!view.empty ());
  SELF_CHECK (view.size () == 2);
  SELF_CHECK (view.data () == &data[1]);
  SELF_CHECK (view[0] == data[1]);
  SELF_CHECK (view[1] == data[2]);

  gdb::array_view<const T> cview (data + 1, 2);
  SELF_CHECK (!cview.empty ());
  SELF_CHECK (cview.size () == 2);
  SELF_CHECK (cview.data () == &data[1]);
  SELF_CHECK (cview[0] == data[1]);
  SELF_CHECK (cview[1] == data[2]);
}

/* Asserts std::is_constructible.  */

template<typename T, typename... Args>
static constexpr bool
require_not_constructible ()
{
  static_assert (!std::is_constructible<T, Args...>::value, "");

  /* constexpr functions can't return void in C++11 (N3444).  */
  return true;
};

/* Check the array_view<T>(PTR, SIZE) ctor, when T is a pointer.  */

static void
check_ptr_size_ctor2 ()
{
  struct A {};
  A an_a;

  A *array[] = { &an_a };
  const A * const carray[] = { &an_a };

  gdb::array_view<A *> v1 = {array, ARRAY_SIZE (array)};
  gdb::array_view<A *> v2 = {array, (char) ARRAY_SIZE (array)};
  gdb::array_view<A * const> v3 = {array, ARRAY_SIZE (array)};
  gdb::array_view<const A * const> cv1 = {carray, ARRAY_SIZE (carray)};

  require_not_constructible<gdb::array_view<A *>, decltype (carray), size_t> ();

  SELF_CHECK (v1[0] == array[0]);
  SELF_CHECK (v2[0] == array[0]);
  SELF_CHECK (v3[0] == array[0]);

  SELF_CHECK (!v1.empty ());
  SELF_CHECK (v1.size () == 1);
  SELF_CHECK (v1.data () == &array[0]);

  SELF_CHECK (cv1[0] == carray[0]);

  SELF_CHECK (!cv1.empty ());
  SELF_CHECK (cv1.size () == 1);
  SELF_CHECK (cv1.data () == &carray[0]);
}

/* Check construction with a pair of pointers.  This is a template in
   order to test both gdb_byte and const gdb_byte.  */

template<typename T>
static void
check_ptr_ptr_ctor ()
{
  T data[] = {0x11, 0x22, 0x33, 0x44};

  gdb::array_view<T> view (data + 1, data + 3);

  SELF_CHECK (!view.empty ());
  SELF_CHECK (view.size () == 2);
  SELF_CHECK (view.data () == &data[1]);
  SELF_CHECK (view[0] == data[1]);
  SELF_CHECK (view[1] == data[2]);

  gdb_byte array[] = {0x11, 0x22, 0x33, 0x44};
  const gdb_byte *p1 = array;
  gdb_byte *p2 = array + ARRAY_SIZE (array);
  gdb::array_view<const gdb_byte> view2 (p1, p2);
}

/* Check construction with a pair of pointers of mixed constness.  */

static void
check_ptr_ptr_mixed_cv ()
{
  gdb_byte array[] = {0x11, 0x22, 0x33, 0x44};
  const gdb_byte *cp = array;
  gdb_byte *p = array;
  gdb::array_view<const gdb_byte> view1 (cp, p);
  gdb::array_view<const gdb_byte> view2 (p, cp);
  SELF_CHECK (view1.empty ());
  SELF_CHECK (view2.empty ());
}

/* Check range-for support (i.e., begin()/end()).  This is a template
   in order to test both gdb_byte and const gdb_byte.  */

template<typename T>
static void
check_range_for ()
{
  T data[] = {1, 2, 3, 4};
  gdb::array_view<T> view (data);

  typename std::decay<T>::type sum = 0;
  for (auto &elem : view)
    sum += elem;
  SELF_CHECK (sum == 1 + 2 + 3 + 4);
}

template<typename T>
static void
check_iterator ()
{
  T data[] = {1, 2, 3, 4};
  gdb::array_view<T> view (data);

  typename std::decay<T>::type sum = 0;
  for (typename gdb::array_view<T>::iterator it = view.begin ();
       it != view.end (); it++)
    {
      *it *= 2;
      sum += *it;
    }

  SELF_CHECK (sum == 2 + 4 + 6 + 8);
}

template<typename T>
static void
check_const_iterator ()
{
  T data[] = {1, 2, 3, 4};
  gdb::array_view<T> view (data);

  typename std::decay<T>::type sum = 0;
  for (typename gdb::array_view<T>::const_iterator it = view.cbegin ();
       it != view.cend (); it++)
    sum += *it;

  SELF_CHECK (sum == 1 + 2 + 3 + 4);
}

/* Entry point.  */

static void
run_tests ()
{
  /* Empty views.  */
  {
    constexpr gdb::array_view<gdb_byte> view1;
    constexpr gdb::array_view<const gdb_byte> view2;

    static_assert (view1.empty (), "");
    static_assert (view1.data () == nullptr, "");
    static_assert (view1.size () == 0, "");
    static_assert (view2.empty (), "");
    static_assert (view2.size () == 0, "");
    static_assert (view2.data () == nullptr, "");
  }

  std::vector<gdb_byte> vec = {0x11, 0x22, 0x33, 0x44 };
  std::array<gdb_byte, 4> array = {{0x11, 0x22, 0x33, 0x44}};

  /* Various tests of views over std::vector.  */
  {
    gdb::array_view<gdb_byte> view = vec;
    SELF_CHECK (check_container_view (view, vec));
    gdb::array_view<const gdb_byte> cview = vec;
    SELF_CHECK (check_container_view (cview, vec));
  }

  /* Likewise, over std::array.  */
  {
    gdb::array_view<gdb_byte> view = array;
    SELF_CHECK (check_container_view (view, array));
    gdb::array_view<gdb_byte> cview = array;
    SELF_CHECK (check_container_view (cview, array));
  }

  /* op=(std::vector/std::array/elem) */
  {
    gdb::array_view<gdb_byte> view;

    view = vec;
    SELF_CHECK (check_container_view (view, vec));
    view = std::move (vec);
    SELF_CHECK (check_container_view (view, vec));

    view = array;
    SELF_CHECK (check_container_view (view, array));
    view = std::move (array);
    SELF_CHECK (check_container_view (view, array));

    gdb_byte elem = 0;
    view = elem;
    SELF_CHECK (check_elem_view (view, elem));
    view = std::move (elem);
    SELF_CHECK (check_elem_view (view, elem));
  }

  /* Test copy/move ctor and mutable->immutable conversion.  */
  {
    gdb_byte data[] = {0x11, 0x22, 0x33, 0x44};
    gdb::array_view<gdb_byte> view1 = data;
    gdb::array_view<gdb_byte> view2 = view1;
    gdb::array_view<gdb_byte> view3 = std::move (view1);
    gdb::array_view<const gdb_byte> cview1 = data;
    gdb::array_view<const gdb_byte> cview2 = cview1;
    gdb::array_view<const gdb_byte> cview3 = std::move (cview1);
    SELF_CHECK (view1[0] == data[0]);
    SELF_CHECK (view2[0] == data[0]);
    SELF_CHECK (view3[0] == data[0]);
    SELF_CHECK (cview1[0] == data[0]);
    SELF_CHECK (cview2[0] == data[0]);
    SELF_CHECK (cview3[0] == data[0]);
  }

  /* Same, but op=(view).  */
  {
    gdb_byte data[] = {0x55, 0x66, 0x77, 0x88};
    gdb::array_view<gdb_byte> view1;
    gdb::array_view<gdb_byte> view2;
    gdb::array_view<gdb_byte> view3;
    gdb::array_view<const gdb_byte> cview1;
    gdb::array_view<const gdb_byte> cview2;
    gdb::array_view<const gdb_byte> cview3;

    view1 = data;
    view2 = view1;
    view3 = std::move (view1);
    cview1 = data;
    cview2 = cview1;
    cview3 = std::move (cview1);
    SELF_CHECK (view1[0] == data[0]);
    SELF_CHECK (view2[0] == data[0]);
    SELF_CHECK (view3[0] == data[0]);
    SELF_CHECK (cview1[0] == data[0]);
    SELF_CHECK (cview2[0] == data[0]);
    SELF_CHECK (cview3[0] == data[0]);
  }

  /* op[] */
  {
    std::vector<gdb_byte> vec2 = {0x11, 0x22};
    gdb::array_view<gdb_byte> view = vec2;
    gdb::array_view<const gdb_byte> cview = vec2;

    /* Check that op[] on a non-const view of non-const T returns a
       mutable reference.  */
    view[0] = 0x33;
    SELF_CHECK (vec2[0] == 0x33);

    /* OTOH, check that assigning through op[] on a view of const T
       wouldn't compile.  */
    SELF_CHECK (!check_op_subscript (cview));
    /* For completeness.  */
    SELF_CHECK (check_op_subscript (view));
  }

  check_ptr_size_ctor<const gdb_byte> ();
  check_ptr_size_ctor<gdb_byte> ();
  check_ptr_size_ctor2 ();
  check_ptr_ptr_ctor<const gdb_byte> ();
  check_ptr_ptr_ctor<gdb_byte> ();
  check_ptr_ptr_mixed_cv ();

  check_range_for<gdb_byte> ();
  check_range_for<const gdb_byte> ();
  check_iterator<gdb_byte> ();
  check_const_iterator<gdb_byte> ();
  check_const_iterator<const gdb_byte> ();

  /* Check that the right ctor overloads are taken when the element is
     a container.  */
  {
    using Vec = std::vector<gdb_byte>;
    Vec vecs[3];

    gdb::array_view<Vec> view_array = vecs;
    SELF_CHECK (view_array.size () == 3);

    Vec elem;
    gdb::array_view<Vec> view_elem = elem;
    SELF_CHECK (view_elem.size () == 1);
  }

  /* gdb::make_array_view, int length.  */
  {
    gdb_byte data[] = {0x55, 0x66, 0x77, 0x88};
    int len = sizeof (data) / sizeof (data[0]);
    auto view = gdb::make_array_view (data, len);

    SELF_CHECK (view.data () == data);
    SELF_CHECK (view.size () == len);

    for (size_t i = 0; i < len; i++)
      SELF_CHECK (view[i] == data[i]);
  }

  /* Test slicing.  */
  {
    gdb_byte data[] = {0x55, 0x66, 0x77, 0x88, 0x99};
    gdb::array_view<gdb_byte> view = data;

    {
      auto slc = view.slice (1, 3);
      SELF_CHECK (slc.data () == data + 1);
      SELF_CHECK (slc.size () == 3);
      SELF_CHECK (slc[0] == data[1]);
      SELF_CHECK (slc[0] == view[1]);
    }

    {
      auto slc = view.slice (2);
      SELF_CHECK (slc.data () == data + 2);
      SELF_CHECK (slc.size () == 3);
      SELF_CHECK (slc[0] == view[2]);
      SELF_CHECK (slc[0] == data[2]);
    }
  }
}

template <typename T>
void
run_copy_test ()
{
  /* Test non-overlapping copy.  */
  {
    const std::vector<T> src_v = {1, 2, 3, 4};
    std::vector<T> dest_v (4, -1);

    SELF_CHECK (dest_v != src_v);
    copy (gdb::array_view<const T> (src_v), gdb::array_view<T> (dest_v));
    SELF_CHECK (dest_v == src_v);
  }

  /* Test overlapping copy, where the source is before the destination.  */
  {
    std::vector<T> vec = {1, 2, 3, 4, 5, 6, 7, 8};
    gdb::array_view<T> v = vec;

    copy (v.slice (1, 4),
	  v.slice (2, 4));

    std::vector<T> expected = {1, 2, 2, 3, 4, 5, 7, 8};
    SELF_CHECK (vec == expected);
  }

  /* Test overlapping copy, where the source is after the destination.  */
  {
    std::vector<T> vec = {1, 2, 3, 4, 5, 6, 7, 8};
    gdb::array_view<T> v = vec;

    copy (v.slice (2, 4),
	  v.slice (1, 4));

    std::vector<T> expected = {1, 3, 4, 5, 6, 6, 7, 8};
    SELF_CHECK (vec == expected);
  }

  /* Test overlapping copy, where the source is the same as the destination.  */
  {
    std::vector<T> vec = {1, 2, 3, 4, 5, 6, 7, 8};
    gdb::array_view<T> v = vec;

    copy (v.slice (2, 4),
	  v.slice (2, 4));

    std::vector<T> expected = {1, 2, 3, 4, 5, 6, 7, 8};
    SELF_CHECK (vec == expected);
  }
}

/* Class with a non-trivial copy assignment operator, used to test the
   array_view copy function.  */
struct foo
{
  /* Can be implicitly constructed from an int, such that we can use the same
     templated test function to test against array_view<int> and
     array_view<foo>.  */
  foo (int n)
    : n (n)
  {}

  /* Needed to avoid -Wdeprecated-copy-with-user-provided-copy error with
     Clang.  */
  foo (const foo &other) = default;

  void operator= (const foo &other)
  {
    this->n = other.n;
    this->n_assign_op_called++;
  }

  bool operator==(const foo &other) const
  {
    return this->n == other.n;
  }

  int n;

  /* Number of times the assignment operator has been called.  */
  static int n_assign_op_called;
};

int foo::n_assign_op_called = 0;

/* Test the array_view copy free function.  */

static void
run_copy_tests ()
{
  /* Test with a trivial type.  */
  run_copy_test<int> ();

  /* Test with a non-trivial type.  */
  foo::n_assign_op_called = 0;
  run_copy_test<foo> ();

  /* Make sure that for the non-trivial type foo, the assignment operator was
     called an amount of times that makes sense.  */
  SELF_CHECK (foo::n_assign_op_called == 12);
}

} /* namespace array_view_tests */
} /* namespace selftests */

void _initialize_array_view_selftests ();
void
_initialize_array_view_selftests ()
{
  selftests::register_test ("array_view",
			    selftests::array_view_tests::run_tests);
  selftests::register_test ("array_view-copy",
			    selftests::array_view_tests::run_copy_tests);
}
