/* Unit tests for ordered-hash-map.h.
   Copyright (C) 2015-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "opts.h"
#include "hash-set.h"
#include "fixed-value.h"
#include "alias.h"
#include "flags.h"
#include "symtab.h"
#include "tree-core.h"
#include "stor-layout.h"
#include "tree.h"
#include "stringpool.h"
#include "ordered-hash-map.h"
#include "selftest.h"

#if CHECKING_P

namespace selftest {

/* Populate *OUT_KVS with the key/value pairs of M.  */

template <typename HashMap, typename Key, typename Value>
static void
get_kv_pairs (const HashMap &m,
	      auto_vec<std::pair<Key, Value> > *out_kvs)
{
  for (typename HashMap::iterator iter = m.begin ();
       iter != m.end ();
       ++iter)
    out_kvs->safe_push (std::make_pair ((*iter).first, (*iter).second));
}

/* Construct an ordered_hash_map <const char *, int> and verify that
   various operations work correctly.  */

static void
test_map_of_strings_to_int ()
{
  ordered_hash_map <const char *, int> m;

  const char *ostrich = "ostrich";
  const char *elephant = "elephant";
  const char *ant = "ant";
  const char *spider = "spider";
  const char *millipede = "Illacme plenipes";
  const char *eric = "half a bee";

  /* A fresh hash_map should be empty.  */
  ASSERT_EQ (0, m.elements ());
  ASSERT_EQ (NULL, m.get (ostrich));

  /* Populate the hash_map.  */
  ASSERT_EQ (false, m.put (ostrich, 2));
  ASSERT_EQ (false, m.put (elephant, 4));
  ASSERT_EQ (false, m.put (ant, 6));
  ASSERT_EQ (false, m.put (spider, 8));
  ASSERT_EQ (false, m.put (millipede, 750));
  ASSERT_EQ (false, m.put (eric, 3));

  /* Verify that we can recover the stored values.  */
  ASSERT_EQ (6, m.elements ());
  ASSERT_EQ (2, *m.get (ostrich));
  ASSERT_EQ (4, *m.get (elephant));
  ASSERT_EQ (6, *m.get (ant));
  ASSERT_EQ (8, *m.get (spider));
  ASSERT_EQ (750, *m.get (millipede));
  ASSERT_EQ (3, *m.get (eric));

  /* Verify that the order of insertion is preserved.  */
  auto_vec<std::pair<const char *, int> > kvs;
  get_kv_pairs (m, &kvs);
  ASSERT_EQ (kvs.length (), 6);
  ASSERT_EQ (kvs[0].first, ostrich);
  ASSERT_EQ (kvs[0].second, 2);
  ASSERT_EQ (kvs[1].first, elephant);
  ASSERT_EQ (kvs[1].second, 4);
  ASSERT_EQ (kvs[2].first, ant);
  ASSERT_EQ (kvs[2].second, 6);
  ASSERT_EQ (kvs[3].first, spider);
  ASSERT_EQ (kvs[3].second, 8);
  ASSERT_EQ (kvs[4].first, millipede);
  ASSERT_EQ (kvs[4].second, 750);
  ASSERT_EQ (kvs[5].first, eric);
  ASSERT_EQ (kvs[5].second, 3);
}

/* Construct an ordered_hash_map using int_hash and verify that various
   operations work correctly.  */

static void
test_map_of_int_to_strings ()
{
  const int EMPTY = -1;
  const int DELETED = -2;
  typedef int_hash <int, EMPTY, DELETED> int_hash_t;
  ordered_hash_map <int_hash_t, const char *> m;

  const char *ostrich = "ostrich";
  const char *elephant = "elephant";
  const char *ant = "ant";
  const char *spider = "spider";
  const char *millipede = "Illacme plenipes";
  const char *eric = "half a bee";

  /* A fresh hash_map should be empty.  */
  ASSERT_EQ (0, m.elements ());
  ASSERT_EQ (NULL, m.get (2));

  /* Populate the hash_map.  */
  ASSERT_EQ (false, m.put (2, ostrich));
  ASSERT_EQ (false, m.put (4, elephant));
  ASSERT_EQ (false, m.put (6, ant));
  ASSERT_EQ (false, m.put (8, spider));
  ASSERT_EQ (false, m.put (750, millipede));
  ASSERT_EQ (false, m.put (3, eric));

  /* Verify that we can recover the stored values.  */
  ASSERT_EQ (6, m.elements ());
  ASSERT_EQ (*m.get (2), ostrich);
  ASSERT_EQ (*m.get (4), elephant);
  ASSERT_EQ (*m.get (6), ant);
  ASSERT_EQ (*m.get (8), spider);
  ASSERT_EQ (*m.get (750), millipede);
  ASSERT_EQ (*m.get (3), eric);

  /* Verify that the order of insertion is preserved.  */
  auto_vec<std::pair<int, const char *> > kvs;
  get_kv_pairs (m, &kvs);
  ASSERT_EQ (kvs.length (), 6);
  ASSERT_EQ (kvs[0].first, 2);
  ASSERT_EQ (kvs[0].second, ostrich);
  ASSERT_EQ (kvs[1].first, 4);
  ASSERT_EQ (kvs[1].second, elephant);
  ASSERT_EQ (kvs[2].first, 6);
  ASSERT_EQ (kvs[2].second, ant);
  ASSERT_EQ (kvs[3].first, 8);
  ASSERT_EQ (kvs[3].second, spider);
  ASSERT_EQ (kvs[4].first, 750);
  ASSERT_EQ (kvs[4].second, millipede);
  ASSERT_EQ (kvs[5].first, 3);
  ASSERT_EQ (kvs[5].second, eric);
}

/* Verify that we can remove items from an ordered_hash_map.  */

static void
test_removal ()
{
  ordered_hash_map <const char *, int> m;

  const char *ostrich = "ostrich";
  ASSERT_EQ (false, m.put (ostrich, 2));

  ASSERT_EQ (1, m.elements ());
  ASSERT_EQ (2, *m.get (ostrich));

  {
    auto_vec<std::pair<const char *, int> > kvs;
    get_kv_pairs (m, &kvs);
    ASSERT_EQ (kvs.length (), 1);
    ASSERT_EQ (kvs[0].first, ostrich);
    ASSERT_EQ (kvs[0].second, 2);
  }

  m.remove (ostrich);

  ASSERT_EQ (0, m.elements ());
  {
    auto_vec<std::pair<const char *, int> > kvs;
    get_kv_pairs (m, &kvs);
    ASSERT_EQ (kvs.length (), 0);
  }

  /* Reinsertion (with a different value).  */
  ASSERT_EQ (false, m.put (ostrich, 42));
  ASSERT_EQ (1, m.elements ());
  ASSERT_EQ (42, *m.get (ostrich));
  {
    auto_vec<std::pair<const char *, int> > kvs;
    get_kv_pairs (m, &kvs);
    ASSERT_EQ (kvs.length (), 1);
    ASSERT_EQ (kvs[0].first, ostrich);
    ASSERT_EQ (kvs[0].second, 42);
  }
}

/* Verify that ordered_hash_map's copy-ctor works.  */

static void
test_copy_ctor ()
{
  ordered_hash_map <const char *, int> m;

  const char *ostrich = "ostrich";
  ASSERT_EQ (false, m.put (ostrich, 2));

  ASSERT_EQ (1, m.elements ());
  ASSERT_EQ (2, *m.get (ostrich));

  ordered_hash_map <const char *, int> copy (m);
  ASSERT_EQ (1, copy.elements ());
  ASSERT_EQ (2, *copy.get (ostrich));

  /* Remove from source.  */
  m.remove (ostrich);
  ASSERT_EQ (0, m.elements ());

  /* Copy should be unaffected.  */
  ASSERT_EQ (1, copy.elements ());
  ASSERT_EQ (2, *copy.get (ostrich));
}

/* Run all of the selftests within this file.  */

void
ordered_hash_map_tests_cc_tests ()
{
  test_map_of_strings_to_int ();
  test_map_of_int_to_strings ();
  test_removal ();
  test_copy_ctor ();
}

} // namespace selftest

#endif /* CHECKING_P */
