// 2005-12-20  Paolo Carlini  <pcarlini@suse.de>

// Copyright (C) 2005 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 2, 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 COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// 6.3.4.6 unordered_multimap::swap

#include <tr1/unordered_map>
#include <map>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>

// uneq_allocator, two different personalities.
void
test01()
{
  bool test __attribute__((unused)) = true;
  using namespace std;
  using namespace tr1;

  typedef pair<const char, int> my_pair;
  typedef __gnu_test::uneq_allocator<my_pair> my_alloc;
  typedef unordered_multimap<char, int, hash<char>, equal_to<char>, my_alloc>
    my_ummap;

  const char title01[] = "Rivers of sand";
  const char title02[] = "Concret PH";
  const char title03[] = "Sonatas and Interludes for Prepared Piano";
  const char title04[] = "never as tired as when i'm waking up";

  const size_t N1 = sizeof(title01);
  const size_t N2 = sizeof(title02);
  const size_t N3 = sizeof(title03);
  const size_t N4 = sizeof(title04);

  typedef multimap<char, int> my_mmap;
  my_mmap mmap01_ref;
  for (size_t i = 0; i < N1; ++i)
    mmap01_ref.insert(my_pair(title01[i], i));
  my_mmap mmap02_ref;
  for (size_t i = 0; i < N2; ++i)
    mmap02_ref.insert(my_pair(title02[i], i));
  my_mmap mmap03_ref;
  for (size_t i = 0; i < N3; ++i)
    mmap03_ref.insert(my_pair(title03[i], i));
  my_mmap mmap04_ref;
  for (size_t i = 0; i < N4; ++i)
    mmap04_ref.insert(my_pair(title04[i], i));

  typedef map<char, int> my_map;

  my_ummap::size_type size01, size02;

  my_alloc alloc01(1), alloc02(2);
  int personality01, personality02;

  my_ummap ummap01(10, hash<char>(), equal_to<char>(), alloc01);
  size01 = ummap01.size();
  personality01 = ummap01.get_allocator().get_personality();
  my_ummap ummap02(10, hash<char>(), equal_to<char>(), alloc02);
  size02 = ummap02.size();
  personality02 = ummap02.get_allocator().get_personality();

  ummap01.swap(ummap02);
  VERIFY( ummap01.size() == size02 );
  VERIFY( ummap01.empty() );
  VERIFY( ummap02.size() == size01 );
  VERIFY( ummap02.empty() );
  VERIFY( ummap01.get_allocator().get_personality() == personality02 );
  VERIFY( ummap02.get_allocator().get_personality() == personality01 );

  my_ummap ummap03(10, hash<char>(), equal_to<char>(), alloc02);
  size01 = ummap03.size();
  personality01 = ummap03.get_allocator().get_personality();
  my_ummap ummap04(mmap02_ref.begin(), mmap02_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc01);
  size02 = ummap04.size();
  personality02 = ummap04.get_allocator().get_personality();

  ummap03.swap(ummap04);
  VERIFY( ummap03.size() == size02 );
  VERIFY( my_map(ummap03.begin(), ummap03.end())
	  == my_map(mmap02_ref.begin(), mmap02_ref.end()) );
  VERIFY( ummap04.size() == size01 );
  VERIFY( ummap04.empty() );
  VERIFY( ummap03.get_allocator().get_personality() == personality02 );
  VERIFY( ummap04.get_allocator().get_personality() == personality01 );
  
  my_ummap ummap05(mmap01_ref.begin(), mmap01_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc01);
  size01 = ummap05.size();
  personality01 = ummap05.get_allocator().get_personality();
  my_ummap ummap06(mmap02_ref.begin(), mmap02_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc02);
  size02 = ummap06.size();
  personality02 = ummap06.get_allocator().get_personality();

  ummap05.swap(ummap06);
  VERIFY( ummap05.size() == size02 );
  VERIFY( my_map(ummap05.begin(), ummap05.end())
	  == my_map(mmap02_ref.begin(), mmap02_ref.end()) );
  VERIFY( ummap06.size() == size01 );
  VERIFY( my_map(ummap06.begin(), ummap06.end())
	  == my_map(mmap01_ref.begin(), mmap01_ref.end()) );
  VERIFY( ummap05.get_allocator().get_personality() == personality02 );
  VERIFY( ummap06.get_allocator().get_personality() == personality01 );

  my_ummap ummap07(mmap01_ref.begin(), mmap01_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc02);
  size01 = ummap07.size();
  personality01 = ummap07.get_allocator().get_personality();
  my_ummap ummap08(mmap03_ref.begin(), mmap03_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc01);
  size02 = ummap08.size();
  personality02 = ummap08.get_allocator().get_personality();

  ummap07.swap(ummap08);
  VERIFY( ummap07.size() == size02 );
  VERIFY( my_map(ummap07.begin(), ummap07.end())
	  == my_map(mmap03_ref.begin(), mmap03_ref.end()) );
  VERIFY( ummap08.size() == size01 );
  VERIFY( my_map(ummap08.begin(), ummap08.end()) 
	  == my_map(mmap01_ref.begin(), mmap01_ref.end()) );
  VERIFY( ummap07.get_allocator().get_personality() == personality02 );
  VERIFY( ummap08.get_allocator().get_personality() == personality01 );

  my_ummap ummap09(mmap03_ref.begin(), mmap03_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc01);
  size01 = ummap09.size();
  personality01 = ummap09.get_allocator().get_personality();
  my_ummap ummap10(mmap04_ref.begin(), mmap04_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc02);
  size02 = ummap10.size();
  personality02 = ummap10.get_allocator().get_personality();

  ummap09.swap(ummap10);
  VERIFY( ummap09.size() == size02 );
  VERIFY( my_map(ummap09.begin(), ummap09.end())
	  == my_map(mmap04_ref.begin(), mmap04_ref.end()) );
  VERIFY( ummap10.size() == size01 );
  VERIFY( my_map(ummap10.begin(), ummap10.end())
	  == my_map(mmap03_ref.begin(), mmap03_ref.end()) );
  VERIFY( ummap09.get_allocator().get_personality() == personality02 );
  VERIFY( ummap10.get_allocator().get_personality() == personality01 );

  my_ummap ummap11(mmap04_ref.begin(), mmap04_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc02);
  size01 = ummap11.size();
  personality01 = ummap11.get_allocator().get_personality();
  my_ummap ummap12(mmap01_ref.begin(), mmap01_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc01);
  size02 = ummap12.size();
  personality02 = ummap12.get_allocator().get_personality();

  ummap11.swap(ummap12);
  VERIFY( ummap11.size() == size02 );
  VERIFY( my_map(ummap11.begin(), ummap11.end())
	  == my_map(mmap01_ref.begin(), mmap01_ref.end()) );
  VERIFY( ummap12.size() == size01 );
  VERIFY( my_map(ummap12.begin(), ummap12.end())
	  == my_map(mmap04_ref.begin(), mmap04_ref.end()) );
  VERIFY( ummap11.get_allocator().get_personality() == personality02 );
  VERIFY( ummap12.get_allocator().get_personality() == personality01 );

  my_ummap ummap13(mmap03_ref.begin(), mmap03_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc01);
  size01 = ummap13.size();
  personality01 = ummap13.get_allocator().get_personality();
  my_ummap ummap14(mmap03_ref.begin(), mmap03_ref.end(), 10, hash<char>(),
		   equal_to<char>(), alloc02);
  size02 = ummap14.size();
  personality02 = ummap14.get_allocator().get_personality();

  ummap13.swap(ummap14);
  VERIFY( ummap13.size() == size02 );
  VERIFY( my_map(ummap13.begin(), ummap13.end())
	  == my_map(mmap03_ref.begin(), mmap03_ref.end()) );
  VERIFY( ummap14.size() == size01 );
  VERIFY( my_map(ummap14.begin(), ummap14.end())
	  == my_map(mmap03_ref.begin(), mmap03_ref.end()) );
  VERIFY( ummap13.get_allocator().get_personality() == personality02 );
  VERIFY( ummap14.get_allocator().get_personality() == personality01 );
}

int main()
{ 
  test01();
  return 0;
}
