/*
    $Id$

    Copyright (C) 2007 by The Regents of the University of California

    Redistribution of this file is permitted under the terms of the
    GNU Public License (GPL).

    Date: 01/30/2007
    Author: Rares Vernica <rvernica@ics.uci.edu>
*/

#ifndef _output_h_
#define _output_h_

#include <ostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <tr1/unordered_map>
#include <tr1/unordered_set>

using namespace std;
using namespace tr1;

template <class T>
ostream& operator<<(ostream& out, const vector<T> &v) 
{
  out << '[';
  for(typename vector<T>::const_iterator it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) {
      out << ", ";
    }
    out << *it;
  }
  out << ']';

  return out;
}

template <class T>
ostream& operator<<(ostream& out, const set<T> &v) 
{
  out << '(';
  for(typename set<T>::const_iterator it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) {
      out << ", ";
    }
    out << *it;
  }
  out << ')';

  return out;
}


template <class T>
ostream& operator<<(ostream& out, const unordered_set<T> &v) 
{
  out << '(';
  for(typename unordered_set<T>::const_iterator it = v.begin();
      it != v.end(); it++) {
    if (it != v.begin()) {
      out << ", ";
    }
    out << *it;
  }
  out << ')';

  return out;
}

template <class T, class V>
ostream& operator<<(ostream& out, const map<T, V> &v) 
{
  out << '(';
  for(typename map<T, V>::const_iterator it = v.begin(); it != v.end(); it++) {
    if (it != v.begin()) {
      out << ", ";
    }
    out << *it;
  }
  out << ')';

  return out;
}

template <class T, class V>
ostream& operator<<(ostream& out, const unordered_map<T, V> &v) 
{
  out << '(';
  for(typename unordered_map<T, V>::const_iterator it = v.begin();
      it != v.end(); it++) {
    if (it != v.begin()) {
      out << ", ";
    }
    out << *it;
  }
  out << ')';

  return out;
}


template <class T, class V>
ostream& operator<<(ostream& out, const pair<T, V> &p) 
{
  return out << '(' << p.first << ',' << p.second << ')';
}

#endif

