#ifndef TINYSTL_IOS
#define TINYSTL_IOS

#include <iosfwd>
#include <streambuf> 

// off_t
#include <sys/types.h>

namespace std {
  typedef off_t streamoff;
  typedef size_t streamsize;
  
  class ios_base
  {
  public:
    typedef int streamsize;
    
    typedef int iostate;
    static const iostate goodbit = 0;
    static const iostate badbit  = (1<<0);
    static const iostate eofbit  = (1<<1);
    static const iostate failbit = (1<<2);
    
    typedef int fmtflags;
    static const fmtflags boolalpha  = (1<<0);
    static const fmtflags dec        = (1<<1);
    static const fmtflags fixed      = (1<<2);
    static const fmtflags hex        = (1<<3);
    static const fmtflags internal   = (1<<4);
    static const fmtflags left       = (1<<5);
    static const fmtflags oct        = (1<<6);
    static const fmtflags right      = (1<<7);
    static const fmtflags scientific = (1<<8);
    static const fmtflags showbase   = (1<<9);
    static const fmtflags showpoint  = (1<<10);
    static const fmtflags showpos    = (1<<11);
    static const fmtflags skipws     = (1<<12);
    static const fmtflags unitbuf    = (1<<13);
    static const fmtflags uppercase  = (1<<14);
    static const fmtflags adjustfield = left | right | internal;
    static const fmtflags basefield   = dec | oct | hex;
    static const fmtflags floatfield  = scientific | fixed;
    
    typedef int openmode;
    static const openmode app    = (1<<0);
    static const openmode ate    = (1<<0);
    static const openmode binary = (1<<1);
    static const openmode in     = (1<<2);
    static const openmode out    = (1<<3);
    static const openmode trunc  = (1<<4);

    typedef enum {
      beg,
      cur,
      end
    } seekdir;
    
    fmtflags setf(fmtflags fmtfl)
    {
      fmtflags old = m_flags;
      m_flags = (fmtflags) (m_flags | fmtfl);
      return old;
    }
    
    fmtflags setf (fmtflags fmtfl, fmtflags mask) {
      fmtflags old = m_flags;
      m_flags = (fmtflags) (m_flags & ~mask);
      m_flags = (fmtflags) (m_flags | (fmtfl & mask));
      return old;
    }
    
    void unsetf(fmtflags mask);
    
    fmtflags flags() const {
      return m_flags;
    }
    
    fmtflags flags(fmtflags fmtfl) {
      return m_flags = fmtfl;
    }


    streamsize precision() const {
      return m_precision;
    }
    
    streamsize precision (streamsize prec) {
      streamsize old = m_precision;
      m_precision = prec;
      return old;
    }
    
    streamsize width() const {
      return m_width;
    }
    
    streamsize width (streamsize w) {
      streamsize old = m_width;
      m_width = w;
      return old;
    }

    char fill() const {
      return m_fill;
    }
    
    char fill (char f) {
      streamsize old = m_fill;
      m_fill = f;
      return old;
    }
    
    ios_base ()
      : m_state (goodbit), m_flags(dec) {
    }
    
  protected:
    streamsize m_precision;
    streamsize m_width;
    
    char m_fill;
    
    iostate m_state;
    fmtflags m_flags;
  };

  //template <class charT, class traits = char_traits<charT> >
  class basic_ios : public ios_base
  {
  public:

    iostate rdstate() const {
      return m_state;
    }
    
    void clear (iostate state = goodbit) {
      m_state = state;
    }
    
    void setstate(iostate state) {
      m_state = m_state | state;
    }
    
    bool good () const {
      return rdstate() == 0;
    }
    
    bool eof () const {
      return (rdstate() & eofbit) != 0;
    }
    
    bool fail () const {
      return (rdstate() & (badbit | failbit)) != 0;
    }
    
    bool bad () const {
      return (rdstate() & badbit) != 0; 
    }
    
    operator void*() const {
      return fail() ? 0 : const_cast<basic_ios*>(this);
    }
    
    bool operator!() const {
      return fail();
    }
    
    // ...
    
    // TODO: including sentry Stroustrup p624
    // basic_ostream* tie () const;
    // basic_ostream* ite (basic_ostream* s);
    
    basic_streambuf* rdbuf () const {
      return streambuf;
    }
    
    basic_streambuf* rdbuf (basic_streambuf* sb) {
      basic_streambuf* t = streambuf;
      streambuf = sb;
      return t;
    }
    
  protected:
    basic_streambuf* streambuf;
  };
  
  typedef basic_ios /*<char>*/ ios;
  
  // 27.4.5, manipulators:
  ios_base& boolalpha (ios_base& str);
  ios_base& noboolalpha(ios_base& str);
  ios_base& showbase (ios_base& str);
  ios_base& noshowbase (ios_base& str);
  ios_base& showpoint (ios_base& str);
  ios_base& noshowpoint(ios_base& str);
  ios_base& showpos  (ios_base& str);
  ios_base& noshowpos  (ios_base& str);
  ios_base& skipws  (ios_base& str);
  ios_base& noskipws  (ios_base& str);
  ios_base& uppercase (ios_base& str);
  ios_base& nouppercase(ios_base& str);
  
  // 27.4.5.2 adjustfield:
  ios_base& internal (ios_base& str);
  ios_base& left (ios_base& str);
  ios_base& right (ios_base& str);

  // 27.4.5.3 basefield:
  ios_base& dec (ios_base& str);
  ios_base& hex (ios_base& str);
  ios_base& oct (ios_base& str);
 
  // 27.4.5.4 floatfield:
  ios_base& fixed (ios_base& str);
  ios_base& scientific (ios_base& str);
 
}

/*
  template <class stateT> class fpos;
  

namespace std {
  class ios_base {
  public:
    class failure;
    typedef T1 fmtflags;
    static const fmtflags  boolalpha;
    static const fmtflags  dec;
    static const fmtflags  fixed;
    static const fmtflags  hex;
    static const fmtflags  internal;
    static const fmtflags  left;
    static const fmtflags  oct;
    static const fmtflags  right;
    static const fmtflags  scientific;
    static const fmtflags  showbase;
    static const fmtflags  showpoint;
    static const fmtflags  showpos;
    static const fmtflags  skipws;
    static const fmtflags  unitbuf;
    static const fmtflags  uppercase;
    static const fmtflags  adjustfield;
    static const fmtflags  basefield;
    static const fmtflags  floatfield;
    typedef T2 iostate;
    static const iostate  badbit;
    static const iostate  eofbit;
    static const iostate  failbit;
    static const iostate  goodbit;
    typedef T3 openmode;
    static const openmode  app;
    static const openmode  ate;
    static const openmode  binary;
    static const openmode  in;
    static const openmode  out;
    static const openmode  trunc;
    typedef T4 seekdir;
    static const seekdir beg;
    static const seekdir cur;
    static const seekdir end;
    class Init;
    
    // 27.4.2.2 fmtflags state:
    fmtflags flags() const;
    fmtflags flags(fmtflags fmtfl);
    fmtflags setf(fmtflags fmtfl);
    fmtflags setf(fmtflags fmtfl, fmtflags mask);
    void unsetf(fmtflags mask);
    streamsize       precision() const;
                     
    streamsize      precision(streamsize prec);
     streamsize      width() const;

     streamsize                     width(streamsize wide);
    
     // 27.4.2.3 locales:
    locale imbue(const locale& loc);
    locale getloc() const;
    // 27.4.2.5 storage:
    static int xalloc();
    long& iword(int index);
     void*& pword(int index);
     // destructor
    virtual ~ios_base();
     // 27.4.2.6 callbacks;
    enum event { erase_event, imbue_event, copyfmt_event };
     typedef void (*event_callback)(event, ios_base&, int index);
    void register_callback(event_call_back fn, int index);
    static bool sync_with_stdio(bool sync = true);
  protected:
    ios_base();
  private:
    exposition only
    // static int index;
    exposition only
    // long* iarray;
    exposition only
    // void** parray;
  };

}

namespace std {
  class ios_base::failure : public exception {
  public:
    explicit failure(const string& msg);
     virtual ~failure();
     virtual const char* what() const throw();
  };

*/

#endif
