#include <pvm++/pvm++.hh>

#include <examples/mult/random.hh>

#include <cassert>

#define ARRAYSIZE 10

static const Pvm::StructId SubTestId = 42;
static const Pvm::StructId TestId = 43;

struct SubTestStruct : Pvm::Struct
{
  PvmSetStructId (SubTestId);
  PvmRegistration ()
  {
    Pvm::Register (test_crazy_type);
  }

  std::list< std::deque< std::set< int > > > test_crazy_type;
};

struct TestCustom : public Pvm::Custom
{
  std::string Text;
  void Pack () const
  {
    std::string CypherText;
    for (unsigned int i = 0; i < Text.length(); i++)
      {
	if (Text[i] >= 'a' && Text[i] <= 'z')
	  CypherText += 'z' - Text[i] + 'a';
	else if (Text[i] >= 'A' && Text[i] <= 'Z')
	  CypherText += 'Z' - Text[i] + 'A';
	else
	  CypherText += Text[i];
      }
    Pvm::Pack (CypherText);
  }
  void UnPack ()
  {
    std::string CypherText;
    Pvm::UnPack (CypherText);
    Text.erase ();
    for (unsigned int i = 0; i < CypherText.length(); i++)
      {
	if (CypherText[i] >= 'a' && CypherText[i] <= 'z')
	  Text += 'z' - CypherText[i] + 'a';
	else if (CypherText[i] >= 'A' && CypherText[i] <= 'Z')
	  Text += 'Z' - CypherText[i] + 'A';
	else
	  Text += CypherText[i];
      }
  }
};

struct TestStruct : public Pvm::Struct
{
  PvmSetStructId (TestId);
  PvmRegistration ()
  {
    Pvm::Register (test_char);
    Pvm::Register (test_char_array, ARRAYSIZE);
    Pvm::Register (test_unsigned_char);
    Pvm::Register (test_unsigned_char_array, ARRAYSIZE);
    Pvm::Register (test_short_int);
    Pvm::Register (test_short_int_array, ARRAYSIZE);
    Pvm::Register (test_int);
    Pvm::Register (test_int_array, ARRAYSIZE);
    Pvm::Register (test_float);
    Pvm::Register (test_float_array, ARRAYSIZE);
    Pvm::Register (test_double);
    Pvm::Register (test_double_array, ARRAYSIZE);
    Pvm::Register (test_long_int);
    Pvm::Register (test_long_int_array, ARRAYSIZE);
    Pvm::Register (test_unsigned_short_int);
    Pvm::Register (test_unsigned_short_int_array, ARRAYSIZE);
    Pvm::Register (test_unsigned_int);
    Pvm::Register (test_unsigned_int_array, ARRAYSIZE);
    Pvm::Register (test_unsigned_long_int);
    Pvm::Register (test_unsigned_long_int_array, ARRAYSIZE);
    Pvm::Register (test_bool);
    Pvm::Register (test_bool_array, ARRAYSIZE);
    Pvm::Register (test_string);
    Pvm::Register (test_string_array, ARRAYSIZE);
    Pvm::Register (test_complex);
    Pvm::Register (test_complex_array, ARRAYSIZE);
    Pvm::Register (test_struct);  
    Pvm::Register (test_custom);  
    Pvm::Register (test_host);
    Pvm::Register (test_host_array, ARRAYSIZE);
    Pvm::Register (test_task);
    Pvm::Register (test_task_array, ARRAYSIZE);
    Pvm::Register (test_pair);
    Pvm::Register (test_pair_array, ARRAYSIZE);
    Pvm::Register (test_vector);
    Pvm::Register (test_vector_array, ARRAYSIZE);
    Pvm::Register (test_list);
    Pvm::Register (test_list_array, ARRAYSIZE);
    Pvm::Register (test_deque);
    Pvm::Register (test_deque_array, ARRAYSIZE);
    Pvm::Register (test_set);
    Pvm::Register (test_set_array, ARRAYSIZE);
    Pvm::Register (test_map);
    Pvm::Register (test_map_array, ARRAYSIZE);
  }

  char test_char;
  char test_char_array[ARRAYSIZE];
  unsigned char test_unsigned_char;
  unsigned char test_unsigned_char_array[ARRAYSIZE];
  short int test_short_int;
  short int test_short_int_array[ARRAYSIZE];
  int test_int;
  int test_int_array[ARRAYSIZE];
  float test_float;
  float test_float_array[ARRAYSIZE];
  double test_double;
  double test_double_array[ARRAYSIZE];
  long int test_long_int;
  long int test_long_int_array[ARRAYSIZE];
  unsigned short int test_unsigned_short_int;
  unsigned short int test_unsigned_short_int_array[ARRAYSIZE];
  unsigned int test_unsigned_int;
  unsigned int test_unsigned_int_array[ARRAYSIZE];
  unsigned long int test_unsigned_long_int;
  unsigned long int test_unsigned_long_int_array[ARRAYSIZE];
  bool test_bool;
  bool test_bool_array[ARRAYSIZE];
  std::string test_string;
  std::string test_string_array[ARRAYSIZE];
  std::complex< double > test_complex;
  std::complex< double > test_complex_array[ARRAYSIZE];
  SubTestStruct test_struct;
  TestCustom test_custom;
  Pvm::Host test_host;
  Pvm::Host test_host_array[ARRAYSIZE];
  Pvm::Task test_task;
  Pvm::Task test_task_array[ARRAYSIZE];
  std::pair< double, int > test_pair;
  std::pair< double, int > test_pair_array[ARRAYSIZE];
  std::vector< double > test_vector;
  std::vector< double > test_vector_array[ARRAYSIZE];
  std::list< double > test_list;
  std::list< double > test_list_array[ARRAYSIZE];
  std::deque< double > test_deque;
  std::deque< double > test_deque_array[ARRAYSIZE];
  std::set< double > test_set;
  std::set< double > test_set_array[ARRAYSIZE];
  std::map< int, double > test_map;
  std::map< int, double > test_map_array[ARRAYSIZE];
};

int
main()
{
  TestStruct Sent;

  for (int i = 0; i < ARRAYSIZE; ++i)
    {
      Sent.test_char_array[i] = Random ('a', 'z');
      Sent.test_unsigned_char_array[i] = Random ('a', 'z');
      Sent.test_short_int_array[i] = Random (42);
      Sent.test_int_array[i] = Random (421);
      Sent.test_float_array[i] = Random (42.0);
      Sent.test_double_array[i] = Random (42.0e5);
      Sent.test_long_int_array[i] = Random (40000);
      Sent.test_unsigned_short_int_array[i] = Random (42);
      Sent.test_unsigned_int_array[i] = Random (421);
      Sent.test_unsigned_long_int_array[i] = Random (40000);
      Sent.test_bool_array[i] = (Random (0, 40000) % 2 == 0);
      Sent.test_string_array[i] = "Test string";
      Sent.test_complex_array[i] = 
	std::complex< double > ( Random (42.0), Random (42.0));
      Sent.test_host_array[i] = Pvm::Pvm ().I ().Host ();
      Sent.test_task_array[i] = Pvm::Pvm ().I ();
      Sent.test_pair_array[i] = 
	std::pair < double, int > (Random (42.0), Random (400));
      for (int j = 0; j < Random (20); j++)
	{
	  Sent.test_vector_array[i].push_back (Random (42.0));
	  Sent.test_list_array[i].push_back (Random (420.0));
	  Sent.test_deque_array[i].push_back (Random (4200.0));
	  Sent.test_set_array[i].insert (Random (142.0));
	  Sent.test_map_array[i].insert (std::make_pair (Random (5), 
							 Random (1.0)));
	}
    }

  Sent.test_char = Random ('a', 'z');
  Sent.test_unsigned_char = Random ('a', 'z');
  Sent.test_short_int= Random (42);
  Sent.test_int = Random (421);
  Sent.test_float = Random (42.0);
  Sent.test_double = Random (42.0e5);
  Sent.test_long_int = Random (40000);
  Sent.test_unsigned_short_int = Random (42);
  Sent.test_unsigned_int = Random (421);
  Sent.test_unsigned_long_int = Random (40000);
  Sent.test_bool = (Random (0, 40000) % 2 == 0);
  Sent.test_string = "Test string";
  Sent.test_complex = std::complex< double > ( Random (42.0), Random (42.0));
  for (int i = 0; i < Random (20); i++)
    {
      std::deque< std::set< int > > d;
      for (int j = 0; j < Random (20); j++)
	{
	  std::set< int > s;
	  for (int k = 0; k < Random (20); k++)
	    {
	      s.insert (Random (42));
	    }
	  d.push_back (s);
	}
      Sent.test_struct.test_crazy_type.push_back(d);
    }
  Sent.test_custom.Text = "This is the ultimate test.";
  Sent.test_host = Pvm::Pvm ().I ().Host ();
  Sent.test_task = Pvm::Pvm ().I ();
  Sent.test_pair = std::pair < double, int > (Random (42.0), Random (400));
  for (int i = 0; i < Random (20); i++)
    {
      Sent.test_vector.push_back (Random (42.0)); 
      Sent.test_list.push_back (Random (420.0));
      Sent.test_deque.push_back (Random (4200.0));
      Sent.test_set.insert (Random (142.0));
      Sent.test_map.insert (std::make_pair (Random (5), Random (1.0)));
    }
  
  Sent.Send (Pvm::Pvm (). I ());

  TestStruct Received;
  Received.Receive ();

  for (int i = 0; i < ARRAYSIZE; ++i)
    {
      assert (Sent.test_char_array[i] == Received.test_char_array[i]);
      assert (Sent.test_unsigned_char_array[i] ==
	      Received.test_unsigned_char_array[i]);
      assert (Sent.test_short_int_array[i] == 
	      Received.test_short_int_array[i]);
      assert (Sent.test_int_array[i] == Received.test_int_array[i]);
      assert (Sent.test_float_array[i] == Received.test_float_array[i]);
      assert (Sent.test_double_array[i] == Received.test_double_array[i]);
      assert (Sent.test_long_int_array[i] == Received.test_long_int_array[i]);
      assert (Sent.test_unsigned_short_int_array[i] == 
	      Received.test_unsigned_short_int_array[i]);
      assert (Sent.test_unsigned_int_array[i] == 
	      Received.test_unsigned_int_array[i]);
      assert (Sent.test_unsigned_long_int_array[i] == 
	      Received.test_unsigned_long_int_array[i]);
      assert (Sent.test_bool_array[i] == Received.test_bool_array[i]);
      assert (Sent.test_string_array[i] == Received.test_string_array[i]);
      assert (Sent.test_complex_array[i] == Received.test_complex_array[i]);
      assert (Sent.test_host_array[i] == Received.test_host_array[i]);
      assert (Sent.test_task_array[i] == Received.test_task_array[i]);
      assert (Sent.test_pair_array[i] == Received.test_pair_array[i]);
      assert (Sent.test_vector_array[i] == Received.test_vector_array[i]);
      assert (Sent.test_list_array[i] == Received.test_list_array[i]);
      assert (Sent.test_deque_array[i] == Received.test_deque_array[i]);
      assert (Sent.test_set_array[i] == Received.test_set_array[i]);
      assert (Sent.test_map_array[i] == Received.test_map_array[i]);
    }
  
  assert (Sent.test_char == Received.test_char);
  assert (Sent.test_unsigned_char == Received.test_unsigned_char);
  assert (Sent.test_short_int == Received.test_short_int);
  assert (Sent.test_int == Received.test_int);
  assert (Sent.test_float == Received.test_float); 
  assert (Sent.test_double == Received.test_double);
  assert (Sent.test_long_int == Received.test_long_int);
  assert (Sent.test_unsigned_short_int == Received.test_unsigned_short_int);
  assert (Sent.test_unsigned_int == Received.test_unsigned_int);
  assert (Sent.test_unsigned_long_int == Received.test_unsigned_long_int);
  assert (Sent.test_bool == Received.test_bool);
  assert (Sent.test_string == Received.test_string);
  assert (Sent.test_complex == Received.test_complex);
  assert (Sent.test_struct.test_crazy_type == 
	  Received.test_struct.test_crazy_type);  
  assert (Sent.test_custom.Text == Received.test_custom.Text);
  assert (Sent.test_host == Received.test_host);
  assert (Sent.test_task == Received.test_task);
  assert (Sent.test_pair == Received.test_pair);
  assert (Sent.test_vector == Received.test_vector);
  assert (Sent.test_list == Received.test_list);
  assert (Sent.test_deque == Received.test_deque );
  assert (Sent.test_set == Received.test_set);
  assert (Sent.test_map == Received.test_map);
}


syntax highlighted by Code2HTML, v. 0.9.1