/* 
 * PVM++ - A C++ library for easy use of PVM
 * Copyright (C) 1997-2001 Sebastian Wilhelmi; University of Karlsruhe
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* This file is generated by the shell script generate_pack_ii.sh */
/* DO NOT EDIT DIRECTLY */

#ifndef __PVM_PACK_II__
#define __PVM_PACK_II__

#include <pvm++/host.hh>
#include <pvm++/hostset.hh>
#include <pvm++/task.hh>
#include <pvm++/taskset.hh>
#include <pvm++/struct.hh>

#include <cstdio>
#include <pvm3.h>
#include <string>
#include <complex>

#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>

namespace Pvm
{

/* Hack to get a non-const type out of a const one without a cast */
template< class Type > 
inline 
Type & 
UnConst (const Type &What)
{
  return const_cast< Type & > (What);
}


/* char */

inline
void
Pack (const char &What)
{
  THROW (pvm_pkbyte ((char *) &What, 1, 1));
}

inline
void
UnPack (char &What)
{
  THROW (pvm_upkbyte ((char *) &What, 1, 1));
}

inline
void
Pack (char *What, int Num)
{
  THROW (pvm_pkbyte ((char *) What, Num, 1));
}

inline
void
UnPack (char *What, int Num)
{
  THROW (pvm_upkbyte ((char *) What, Num, 1));
}

inline
void
Register (char &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (char *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* unsigned char */

inline
void
Pack (const unsigned char &What)
{
  THROW (pvm_pkbyte ((char *) &What, 1, 1));
}

inline
void
UnPack (unsigned char &What)
{
  THROW (pvm_upkbyte ((char *) &What, 1, 1));
}

inline
void
Pack (unsigned char *What, int Num)
{
  THROW (pvm_pkbyte ((char *) What, Num, 1));
}

inline
void
UnPack (unsigned char *What, int Num)
{
  THROW (pvm_upkbyte ((char *) What, Num, 1));
}

inline
void
Register (unsigned char &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (unsigned char *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* short int */

inline
void
Pack (const short int &What)
{
  THROW (pvm_pkshort ((short int *) &What, 1, 1));
}

inline
void
UnPack (short int &What)
{
  THROW (pvm_upkshort ((short int *) &What, 1, 1));
}

inline
void
Pack (short int *What, int Num)
{
  THROW (pvm_pkshort ((short int *) What, Num, 1));
}

inline
void
UnPack (short int *What, int Num)
{
  THROW (pvm_upkshort ((short int *) What, Num, 1));
}

inline
void
Register (short int &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (short int *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* int */

inline
void
Pack (const int &What)
{
  THROW (pvm_pkint ((int *) &What, 1, 1));
}

inline
void
UnPack (int &What)
{
  THROW (pvm_upkint ((int *) &What, 1, 1));
}

inline
void
Pack (int *What, int Num)
{
  THROW (pvm_pkint ((int *) What, Num, 1));
}

inline
void
UnPack (int *What, int Num)
{
  THROW (pvm_upkint ((int *) What, Num, 1));
}

inline
void
Register (int &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (int *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* float */

inline
void
Pack (const float &What)
{
  THROW (pvm_pkfloat ((float *) &What, 1, 1));
}

inline
void
UnPack (float &What)
{
  THROW (pvm_upkfloat ((float *) &What, 1, 1));
}

inline
void
Pack (float *What, int Num)
{
  THROW (pvm_pkfloat ((float *) What, Num, 1));
}

inline
void
UnPack (float *What, int Num)
{
  THROW (pvm_upkfloat ((float *) What, Num, 1));
}

inline
void
Register (float &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (float *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* double */

inline
void
Pack (const double &What)
{
  THROW (pvm_pkdouble ((double *) &What, 1, 1));
}

inline
void
UnPack (double &What)
{
  THROW (pvm_upkdouble ((double *) &What, 1, 1));
}

inline
void
Pack (double *What, int Num)
{
  THROW (pvm_pkdouble ((double *) What, Num, 1));
}

inline
void
UnPack (double *What, int Num)
{
  THROW (pvm_upkdouble ((double *) What, Num, 1));
}

inline
void
Register (double &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (double *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* long int */

inline
void
Pack (const long int &What)
{
  THROW (pvm_pklong ((long int *) &What, 1, 1));
}

inline
void
UnPack (long int &What)
{
  THROW (pvm_upklong ((long int *) &What, 1, 1));
}

inline
void
Pack (long int *What, int Num)
{
  THROW (pvm_pklong ((long int *) What, Num, 1));
}

inline
void
UnPack (long int *What, int Num)
{
  THROW (pvm_upklong ((long int *) What, Num, 1));
}

inline
void
Register (long int &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (long int *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* unsigned short int */

inline
void
Pack (const unsigned short int &What)
{
  THROW (pvm_pkushort ((unsigned short *) &What, 1, 1));
}

inline
void
UnPack (unsigned short int &What)
{
  THROW (pvm_upkushort ((unsigned short *) &What, 1, 1));
}

inline
void
Pack (unsigned short int *What, int Num)
{
  THROW (pvm_pkushort ((unsigned short *) What, Num, 1));
}

inline
void
UnPack (unsigned short int *What, int Num)
{
  THROW (pvm_upkushort ((unsigned short *) What, Num, 1));
}

inline
void
Register (unsigned short int &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (unsigned short int *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* unsigned int */

inline
void
Pack (const unsigned int &What)
{
  THROW (pvm_pkuint ((unsigned int *) &What, 1, 1));
}

inline
void
UnPack (unsigned int &What)
{
  THROW (pvm_upkuint ((unsigned int *) &What, 1, 1));
}

inline
void
Pack (unsigned int *What, int Num)
{
  THROW (pvm_pkuint ((unsigned int *) What, Num, 1));
}

inline
void
UnPack (unsigned int *What, int Num)
{
  THROW (pvm_upkuint ((unsigned int *) What, Num, 1));
}

inline
void
Register (unsigned int &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (unsigned int *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* unsigned long int */

inline
void
Pack (const unsigned long int &What)
{
  THROW (pvm_pkulong ((unsigned long int *) &What, 1, 1));
}

inline
void
UnPack (unsigned long int &What)
{
  THROW (pvm_upkulong ((unsigned long int *) &What, 1, 1));
}

inline
void
Pack (unsigned long int *What, int Num)
{
  THROW (pvm_pkulong ((unsigned long int *) What, Num, 1));
}

inline
void
UnPack (unsigned long int *What, int Num)
{
  THROW (pvm_upkulong ((unsigned long int *) What, Num, 1));
}

inline
void
Register (unsigned long int &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (unsigned long int *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* bool */

inline
void
Pack (const bool &What)
{
  Pack ((unsigned char) What);
}

inline
void
UnPack (bool &What)
{
  unsigned char Value;
  UnPack (Value);
  What = Value;
}

inline
void
Pack (bool *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

inline
void
UnPack (bool *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

inline
void
Register (bool &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (bool *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::string */

inline
void
Pack (const std::string &What)
{
  unsigned int Size = What.size ();
  THROW (pvm_pkuint (&Size, 1, 1));
  THROW (pvm_pkbyte ((char *) What.c_str (), Size, 1));
}

inline
void
UnPack (std::string &What)
{
  unsigned int Size;
  THROW (pvm_upkuint (&Size, 1, 1));
  char *Temp = new char[Size + 1];
  int Error = pvm_upkbyte (Temp, Size, 1);
  if (Error < 0)
    {
      delete Temp;
      THROW (Error);
    }
  Temp[Size] = '\000';
  What = Temp;
  delete Temp;
}

inline
void
Pack (std::string *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

inline
void
UnPack (std::string *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

inline
void
Register (std::string &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (std::string *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::complex< Type > */

template< class Type >
inline
void
Pack (const std::complex< Type > &What)
{
  Pack (What.real ());
  Pack (What.imag ());
}

template< class Type >
inline
void
UnPack (std::complex< Type > &What)
{
  Type Real, Imag;
  UnPack (Real);
  UnPack (Imag);
  What = std::complex< Type > (Real, Imag);
}

template< class Type >
inline
void
Pack (std::complex< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Type >
inline
void
UnPack (std::complex< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Type >
inline
void
Register (std::complex< Type > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Type >
inline
void
Register (std::complex< Type > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* Struct */

inline
void
Pack (const Struct &What)
{
  What.Pack();
}

inline
void
UnPack (Struct &What)
{
  What.UnPack();
}

inline
void
Register (Struct &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

/* Custom */

inline
void
Pack (const Custom &What)
{
  What.Pack();
}

inline
void
UnPack (Custom &What)
{
  What.UnPack();
}

inline
void
Register (Custom &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

/* Host */

inline
void
Pack (const Host &What)
{
  unsigned int Id = What;
  THROW (pvm_pkuint (&Id, 1, 1));
}

inline
void
UnPack (Host &What)
{
  unsigned int Id;
  THROW (pvm_upkuint (&Id, 1, 1));
  What = Id;
}

inline
void
Pack (Host *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

inline
void
UnPack (Host *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

inline
void
Register (Host &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (Host *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* Task */

inline
void
Pack (const Task &What)
{
  unsigned int Id = What;
  THROW (pvm_pkuint (&Id, 1, 1));
}

inline
void
UnPack (Task &What)
{
  unsigned int Id;
  THROW (pvm_upkuint (&Id, 1, 1));
  What = Id;
}

inline
void
Pack (Task *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

inline
void
UnPack (Task *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

inline
void
Register (Task &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

inline
void
Register (Task *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::pair< First, Second > */

template< class First, class Second >
inline
void
Pack (const std::pair< First, Second > &What)
{
  Pack (What.first);
  Pack (What.second);
}

template< class First, class Second >
inline
void
UnPack (std::pair< First, Second > &What)
{
  UnPack (UnConst (What.first));
  UnPack (UnConst (What.second));
}

template< class First, class Second >
inline
void
Pack (std::pair< First, Second > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class First, class Second >
inline
void
UnPack (std::pair< First, Second > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class First, class Second >
inline
void
Register (std::pair< First, Second > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class First, class Second >
inline
void
Register (std::pair< First, Second > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::vector< Type > */

template< class Type >
inline
void
Pack (const std::vector< Type > &What)
{
  typename std::vector< Type >::const_iterator Current = What.begin ();
  unsigned long int Size = What.size ();
  Pack (Size);
  while (Size > 0)
    {
      Pack (*Current);
      --Size;
      ++Current;
    }
}

template< class Type >
inline
void
UnPack (std::vector< Type > &What)
{
  What.erase (What.begin (), What.end ());
  std::insert_iterator< std::vector< Type > > Current (What, What.begin ());
  unsigned long int Size = 0;
  UnPack (Size);
  typename std::vector< Type >::value_type UnPacked;
  while (Size > 0)
    {
      UnPack (UnPacked);
      *Current = UnPacked;
      --Size;
      ++Current;
    }
}

template< class Type >
inline
void
Pack (std::vector< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Type >
inline
void
UnPack (std::vector< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Type >
inline
void
Register (std::vector< Type > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Type >
inline
void
Register (std::vector< Type > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::list< Type > */

template< class Type >
inline
void
Pack (const std::list< Type > &What)
{
  typename std::list< Type >::const_iterator Current = What.begin ();
  unsigned long int Size = What.size ();
  Pack (Size);
  while (Size > 0)
    {
      Pack (*Current);
      --Size;
      ++Current;
    }
}

template< class Type >
inline
void
UnPack (std::list< Type > &What)
{
  What.erase (What.begin (), What.end ());
  std::insert_iterator< std::list< Type > > Current (What, What.begin ());
  unsigned long int Size = 0;
  UnPack (Size);
  typename std::list< Type >::value_type UnPacked;
  while (Size > 0)
    {
      UnPack (UnPacked);
      *Current = UnPacked;
      --Size;
      ++Current;
    }
}

template< class Type >
inline
void
Pack (std::list< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Type >
inline
void
UnPack (std::list< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Type >
inline
void
Register (std::list< Type > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Type >
inline
void
Register (std::list< Type > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::deque< Type > */

template< class Type >
inline
void
Pack (const std::deque< Type > &What)
{
  typename std::deque< Type >::const_iterator Current = What.begin ();
  unsigned long int Size = What.size ();
  Pack (Size);
  while (Size > 0)
    {
      Pack (*Current);
      --Size;
      ++Current;
    }
}

template< class Type >
inline
void
UnPack (std::deque< Type > &What)
{
  What.erase (What.begin (), What.end ());
  std::insert_iterator< std::deque< Type > > Current (What, What.begin ());
  unsigned long int Size = 0;
  UnPack (Size);
  typename std::deque< Type >::value_type UnPacked;
  while (Size > 0)
    {
      UnPack (UnPacked);
      *Current = UnPacked;
      --Size;
      ++Current;
    }
}

template< class Type >
inline
void
Pack (std::deque< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Type >
inline
void
UnPack (std::deque< Type > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Type >
inline
void
Register (std::deque< Type > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Type >
inline
void
Register (std::deque< Type > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::set< Key, Compare > */

template< class Key, class Compare >
inline
void
Pack (const std::set< Key, Compare > &What)
{
  typename std::set< Key, Compare >::const_iterator Current = What.begin ();
  unsigned long int Size = What.size ();
  Pack (Size);
  while (Size > 0)
    {
      Pack (*Current);
      --Size;
      ++Current;
    }
}

template< class Key, class Compare >
inline
void
UnPack (std::set< Key, Compare > &What)
{
  What.erase (What.begin (), What.end ());
  std::insert_iterator< std::set< Key, Compare > > Current (What, What.begin ());
  unsigned long int Size = 0;
  UnPack (Size);
  typename std::set< Key, Compare >::value_type UnPacked;
  while (Size > 0)
    {
      UnPack (UnPacked);
      *Current = UnPacked;
      --Size;
      ++Current;
    }
}

template< class Key, class Compare >
inline
void
Pack (std::set< Key, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Key, class Compare >
inline
void
UnPack (std::set< Key, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Key, class Compare >
inline
void
Register (std::set< Key, Compare > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Key, class Compare >
inline
void
Register (std::set< Key, Compare > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::multiset< Key, Compare > */

template< class Key, class Compare >
inline
void
Pack (const std::multiset< Key, Compare > &What)
{
  typename std::multiset< Key, Compare >::const_iterator Current = What.begin ();
  unsigned long int Size = What.size ();
  Pack (Size);
  while (Size > 0)
    {
      Pack (*Current);
      --Size;
      ++Current;
    }
}

template< class Key, class Compare >
inline
void
UnPack (std::multiset< Key, Compare > &What)
{
  What.erase (What.begin (), What.end ());
  std::insert_iterator< std::multiset< Key, Compare > > Current (What, What.begin ());
  unsigned long int Size = 0;
  UnPack (Size);
  typename std::multiset< Key, Compare >::value_type UnPacked;
  while (Size > 0)
    {
      UnPack (UnPacked);
      *Current = UnPacked;
      --Size;
      ++Current;
    }
}

template< class Key, class Compare >
inline
void
Pack (std::multiset< Key, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Key, class Compare >
inline
void
UnPack (std::multiset< Key, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Key, class Compare >
inline
void
Register (std::multiset< Key, Compare > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Key, class Compare >
inline
void
Register (std::multiset< Key, Compare > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::map< Key, Value, Compare > */

template< class Key, class Value, class Compare >
inline
void
Pack (const std::map< Key, Value, Compare > &What)
{
  typename std::map< Key, Value, Compare >::const_iterator Current = What.begin ();
  unsigned long int Size = What.size ();
  Pack (Size);
  while (Size > 0)
    {
      Pack (*Current);
      --Size;
      ++Current;
    }
}

template< class Key, class Value, class Compare >
inline
void
UnPack (std::map< Key, Value, Compare > &What)
{
  What.erase (What.begin (), What.end ());
  std::insert_iterator< std::map< Key, Value, Compare > > Current (What, What.begin ());
  unsigned long int Size = 0;
  UnPack (Size);
  typename std::map< Key, Value, Compare >::value_type UnPacked;
  while (Size > 0)
    {
      UnPack (UnPacked);
      *Current = UnPacked;
      --Size;
      ++Current;
    }
}

template< class Key, class Value, class Compare >
inline
void
Pack (std::map< Key, Value, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Key, class Value, class Compare >
inline
void
UnPack (std::map< Key, Value, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Key, class Value, class Compare >
inline
void
Register (std::map< Key, Value, Compare > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Key, class Value, class Compare >
inline
void
Register (std::map< Key, Value, Compare > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}

/* std::multimap< Key, Value, Compare > */

template< class Key, class Value, class Compare >
inline
void
Pack (const std::multimap< Key, Value, Compare > &What)
{
  typename std::multimap< Key, Value, Compare >::const_iterator Current = What.begin ();
  unsigned long int Size = What.size ();
  Pack (Size);
  while (Size > 0)
    {
      Pack (*Current);
      --Size;
      ++Current;
    }
}

template< class Key, class Value, class Compare >
inline
void
UnPack (std::multimap< Key, Value, Compare > &What)
{
  What.erase (What.begin (), What.end ());
  std::insert_iterator< std::multimap< Key, Value, Compare > > Current (What, What.begin ());
  unsigned long int Size = 0;
  UnPack (Size);
  typename std::multimap< Key, Value, Compare >::value_type UnPacked;
  while (Size > 0)
    {
      UnPack (UnPacked);
      *Current = UnPacked;
      --Size;
      ++Current;
    }
}

template< class Key, class Value, class Compare >
inline
void
Pack (std::multimap< Key, Value, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      Pack (*What);
      What++;
    }
}

template< class Key, class Value, class Compare >
inline
void
UnPack (std::multimap< Key, Value, Compare > *What, int Num)
{
  for (int i = 0; i < Num; ++i)
    {
      UnPack (*What);
      What++;
    }
}

template< class Key, class Value, class Compare >
inline
void
Register (std::multimap< Key, Value, Compare > &What)
{
  if (Struct::CurrentlyPacking)
    Pack (What);
  else
    UnPack (What);
}

template< class Key, class Value, class Compare >
inline
void
Register (std::multimap< Key, Value, Compare > *What, int Num)
{
  if (Struct::CurrentlyPacking)
    Pack (What, Num);
  else
    UnPack (What, Num);
}
}

#endif /* __PVM_PACK_II__ */
