// { dg-do run { target c++17 } }

// Copyright (C) 2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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.

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

// libstdc++/96088

#include <string_view>
#include <string>
#include <unordered_set>
#include <vector>

#include <testsuite_hooks.h>
#include <replacement_memory_operators.h>

static constexpr std::initializer_list<const char*> lst = {
  "long_str_for_dynamic_allocating"
};

void
test01()
{
  __gnu_test::counter::reset();
  std::unordered_set<std::string> us;
  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );

  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
}

void
test02()
{
  __gnu_test::counter::reset();
  std::unordered_set<std::string,
		     std::hash<std::string_view>,
		     std::equal_to<std::string_view>> us;
  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );

  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
}

std::size_t
hash_string_f(const std::string& str) noexcept
{
  std::hash<std::string> h;
  return h(str);
}

void
test11()
{
  typedef std::size_t (*hash_string_t)(const std::string&) noexcept;
  __gnu_test::counter::reset();
  hash_string_t hasher = &hash_string_f;
  std::unordered_set<std::string,
		     hash_string_t,
		     std::equal_to<std::string>> us(0, hasher);
  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );

  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
}

std::size_t
hash_string_view_f(const std::string_view& str) noexcept
{
  std::hash<std::string_view> h;
  return h(str);
}

void
test12()
{
  typedef std::size_t (*hash_stringview_t)(const std::string_view&) noexcept;
  __gnu_test::counter::reset();
  hash_stringview_t hasher = &hash_string_view_f;
  std::unordered_set<std::string,
		     hash_stringview_t,
		     std::equal_to<std::string_view>> us(0, hasher);
  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );

  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
}

struct hash_string_functor
{
  std::size_t
  operator()(const std::string& str) const noexcept
  {
    std::hash<std::string> h;
    return h(str);
  }
};

void
test21()
{
  __gnu_test::counter::reset();
  std::unordered_set<std::string,
		     hash_string_functor,
		     std::equal_to<std::string>> us;
  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );

  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
}

struct hash_string_view_noexcept_functor
{
  std::size_t
  operator()(const std::string_view& str) const noexcept
  {
    std::hash<std::string_view> h;
    return h(str);
  }
};

void
test22()
{
  __gnu_test::counter::reset();
  std::unordered_set<std::string,
		     hash_string_view_noexcept_functor,
		     std::equal_to<std::string_view>> us;
  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );

  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
}

struct hash_string_view_functor
{
  std::size_t
  operator()(const std::string_view& str) const
  {
    std::hash<std::string_view> h;
    return h(str);
  }
};

void
test23()
{
  __gnu_test::counter::reset();
  std::unordered_set<std::string,
		     hash_string_view_functor,
		     std::equal_to<std::string_view>> us;
  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );

  us.insert(lst.begin(), lst.end());
  VERIFY( us.size() == 1 );

  VERIFY( __gnu_test::counter::count() == 3 );
  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
}

void
test03()
{
  std::vector<std::string> v;
  v.insert(v.end(), lst.begin(), lst.end());

  const auto origin = __gnu_test::counter::count();

  {
    __gnu_test::counter::reset();
    std::unordered_set<std::string,
		       std::hash<std::string_view>,
		       std::equal_to<std::string_view>> us;
    us.insert(v.begin(), v.end());
    VERIFY( us.size() == 1 );

    // Allocate array of buckets, a node, and the std::string (unless COW).
    constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 3 : 2;

    VERIFY( __gnu_test::counter::count() == origin + increments );
    VERIFY( __gnu_test::counter::get()._M_increments == increments );

    us.insert(v.begin(), v.end());
    VERIFY( us.size() == 1 );

    VERIFY( __gnu_test::counter::count() == origin + increments );
    VERIFY( __gnu_test::counter::get()._M_increments == increments );
  }
  VERIFY( __gnu_test::counter::count() == origin );

  {
    __gnu_test::counter::reset();
    std::unordered_set<std::string,
		       std::hash<std::string_view>,
		       std::equal_to<std::string_view>> us;
    us.insert(std::make_move_iterator(v.begin()),
	      std::make_move_iterator(v.end()));
    VERIFY( us.size() == 1 );

    // Allocate array of buckets and a node. String is moved.
    constexpr std::size_t increments = 2;

    VERIFY( __gnu_test::counter::count() == origin + increments );
    VERIFY( __gnu_test::counter::get()._M_increments == increments );
  }
}

int
main()
{
  test01();
  test02();
  test11();
  test12();
  test21();
  test22();
  test23();
  test03();
  return 0;
}
