#ifndef _IOSTREAM_MATT_H
#define _IOSTREAM_MATT_H

/*

IOStreams class library for standard C++.

Author: Matthew W. Coan
Date: Thu Jul 26 19:00:59 EDT 2012

*/


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>

using namespace std;

namespace std {

class istream {
protected:
public:
   FILE * in;
   istream(FILE * i) {  in = i; }
   istream() {  in = stdin; }
   virtual ~istream() { }
   istream & operator>>(int & arg) {
      fscanf(in, "%d", &arg);
      return *this;
   }
   istream & operator>>(float & arg) {
      fscanf(in, "%f", &arg);
      return *this;
   }
   istream & operator>>(double & arg) {
      fscanf(in, "%f", &arg);
      return *this;
   }
   istream & operator>>(short & arg) {
      fscanf(in, "%d", &arg);
      return *this;
   }
   istream & operator>>(char & arg) {
      fscanf(in, "%c", &arg);
      return *this;
   }
   istream & operator>>(long & arg) {
      fscanf(in, "%ld", &arg);
      return *this;
   }
   istream & getline(char * buffer, const size_t N, const char delim) {
      size_t n = 0;
      char ch = fgetc(in);
      memset((void*)buffer, 0, n);
      while(ch != delim) {
         if(ch == delim) {
            break;
         }
         if(n >= N) {
            break;
         }
         buffer[n] = ch;
         n++;
         ch = fgetc(in);
      }
      return *this;
   }
   istream & getline(char * buffer, const size_t N) {
      size_t n = 0;
      char ch = fgetc(in);
      memset((void*)buffer, 0, n);
      while(ch != '\n') {
         if(ch == '\n') {
            break;
         }
         if(n >= N) {
            break;
         }
         buffer[n] = ch;
         n++;
         ch = fgetc(in);
      }
      return *this;
   }
   char get() {
      return fgetc(in);
   }
   void unget(char ch) {
      ungetc((int)ch, in);
   }
   char peek() {
      int ch;
      ch = fgetc(in);
      ungetc(ch, in);
      return ch;
   }
   size_t read(char * ptr, size_t sz) {
      size_t count;
      count = 0;
      for(size_t i = 0; i < sz; i++) {
         ptr[i] = fgetc(in);
      }
      return count;
   }
   operator void*() {
      return (void*)(feof(in) == 0);
   }
};

class ostream {
protected:
public:
   FILE * out;
   ostream(FILE * o) { out = o; }
   ostream() { out = stdout; }
   virtual ~ostream() { }
   ostream & operator<<(const void* arg) {
      fprintf(out, "%d", arg);
      return *this;
   }
   ostream & operator<<(const size_t arg) {
      fprintf(out, "%d", arg);
      return *this;
   }
   ostream & operator<<(const int arg) {
      fprintf(out, "%d", arg);
      return *this;
   }
   ostream & operator<<(const float arg) {
      fprintf(out, "%f", arg);
      return *this;
   }
   ostream & operator<<(const double & arg) {
      fprintf(out, "%f", arg);
      return *this;
   }
   ostream & operator<<(const short arg) {
      fprintf(out, "%d", (int)arg);
      return *this;
   }
   ostream & operator<<(const char arg) { 
      fprintf(out, "%c", arg);
      return *this;
   }
   ostream & operator<<(const long & arg) {
      fprintf(out, "%ld", arg);
      return *this;
   }
   ostream & operator<<(const char * arg) {
      fprintf(out, "%s", arg);
      return *this;
   }
   void flush() {
      fflush(out);
   }
   ostream & operator<<(const string & str) {
      fprintf(out, "%s", str.c_str());
      return *this;
   }
   ostream & operator<<(ostream & (*pf)(ostream &)) {
      return pf(*this);
   } 
   operator void*() {
      return (void*)true;
   }
};

inline
ostream & endl(ostream & out) {
   out << "\n";
   out.flush();
   return out;
}

inline
ostream & flush(ostream & out) {
   out.flush();
   return out; 
}

extern istream cin;

extern ostream cout;

extern ostream cerr;

}

#endif /* _IOSTREAM */
