//=-- SerializeEx.h - Serialize and deserialize complex data -------*- C++ -*-=
//
//  The file defines some serialization functions for classes that are more 
//  complex than the primitive types.  These serialization functions are not 
//  included in the original class because we want to reduce dependancies on
//  Serialize.h, because most files don't need it!  If you do need extended
//  serialization, include SerializeEx.h instead.
//
//=---------------------------------------------------------------------------=
//  This file is copyright (c) 1997-2000 Chris Lattner and stuff...
//=---------------------------------------------------------------------------=

#ifndef SERIALIZE_EX_H
#define SERIALIZE_EX_H

#include "Serialize.h"
#include "LinkedList.h"
#include "Table.h"

// Serialization functions for fixed size arrays... they have to be fixed size
// because we have to know that we have a big enough array to deserialize into
// You shouldn't be using arrays for something if it isn't intrinsically fixed
// size!! (like the number of days in a week or month).
//
template <class T> inline
Serialize &SerializeArray(Serialize &O, const T S[], int Size) {
  while (Size--) O << S[Size];
  return O;
}

template <class T> inline
Serialize &DeSerializeArray(Serialize &I, T S[], int Size) {
  while (Size--) I >> S[Size];
  return I;
}


// Serialization Methods for DataPair<x,y> Objects...
//
template <class Primary, class Secondary> inline
Serialize &operator<<(Serialize &I, const DataPair<Primary,Secondary> &S) {
  return I << S.P << S.S;
}

template <class Primary, class Secondary> inline
Serialize &operator>>(Serialize &I, DataPair<Primary,Secondary> &S) {
  return I >> S.P >> S.S;
}


// Serialization Methods for LinkedList<T> Objects...
//
template <class T>
Serialize &operator<<(Serialize &O, const LinkedList<T> &L) {
  O << L.GetLength();

  LinkedList<T>::Iterator I = L.GetIterator();
  for (; I; I++) 
    O << *I;
  return O;
}

template <class T>
Serialize &operator>>(Serialize &I, LinkedList<T> &L) {
  L.ClearList();
  int Length;
  T Value;

  I >> Length;
  while (Length--) {
    I >> Value;
    L.AddToTail(Value);
  }
  return I;
}


// Serialization Methods for Table<key,value> Objects...
//
template <class Key, class Value> 
Serialize &operator<<(Serialize &O, const Table<Key,Value> &T) {
  Value Default;
  int DefaultSet;

  T.GetDefaultState(DefaultSet, Default);
  O << DefaultSet;
  if (DefaultSet) O << Default;

  O << T.GetNumElements();

  Table<Key,Value>::Iterator It = T.GetStart();
  for (; It; It++)
    O << It.GetKey() << It.GetValue();
  return O;
}

template <class Key, class Value> 
Serialize &operator>>(Serialize &I, Table<Key, Value> &T) {
  int NumElements;
  T.Clear();

  I >> NumElements; // Really is DefaultSet
  if (NumElements) {
    Value Default;
    I >> Default;
    T.SetDefault(Default);
  }

  I >> NumElements;

  while (NumElements--) {
    Key K; Value V;
    I >> K >> V;
    T.SetElementTo(K, V);
  }

  return I;
}

#endif
