williamr@4: /*
williamr@4:  * Copyright (c) 1999
williamr@4:  * Silicon Graphics Computer Systems, Inc.
williamr@4:  *
williamr@4:  * Copyright (c) 1999
williamr@4:  * Boris Fomitchev
williamr@4:  *
williamr@4:  * This material is provided "as is", with absolutely no warranty expressed
williamr@4:  * or implied. Any use is at your own risk.
williamr@4:  *
williamr@4:  * Permission to use or copy this software for any purpose is hereby granted
williamr@4:  * without fee, provided the above notices are retained on all copies.
williamr@4:  * Permission to modify the code and to distribute modified code is granted,
williamr@4:  * provided the above notices are retained, and a notice that the code was
williamr@4:  * modified is included with the above copyright notice.
williamr@4:  *
williamr@4:  */
williamr@4: #ifndef _STLP_IOS_BASE_H
williamr@4: #define _STLP_IOS_BASE_H
williamr@4: 
williamr@4: #ifndef _STLP_INTERNAL_STDEXCEPT_BASE
williamr@4: #  include <stl/_stdexcept_base.h>
williamr@4: #endif
williamr@4: 
williamr@4: #ifndef _STLP_UTILITY
williamr@4: #  include <utility>
williamr@4: #endif
williamr@4: 
williamr@4: #ifndef _STLP_INTERNAL_LOCALE_H
williamr@4: #  include <stl/_locale.h>
williamr@4: #endif
williamr@4: 
williamr@4: #ifndef _STLP_INTERNAL_STRING_H
williamr@4: #  include <stl/_string.h>
williamr@4: #endif
williamr@4: 
williamr@4: _STLP_BEGIN_NAMESPACE
williamr@4: 
williamr@4: // ----------------------------------------------------------------------
williamr@4: 
williamr@4: // Class ios_base.  This is the base class of the ios hierarchy, which
williamr@4: // includes basic_istream and basic_ostream.  Classes in the ios
williamr@4: // hierarchy are actually quite simple: they are just glorified
williamr@4: // wrapper classes.  They delegate buffering and physical character
williamr@4: // manipulation to the streambuf classes, and they delegate most
williamr@4: // formatting tasks to a locale.
williamr@4: 
williamr@4: class _STLP_CLASS_DECLSPEC ios_base {
williamr@4: public:
williamr@4: 
williamr@4:   class _STLP_CLASS_DECLSPEC failure : public __Named_exception {
williamr@4:   public:
williamr@4:     explicit failure(const string&);
williamr@4:     virtual ~failure() _STLP_NOTHROW_INHERENTLY;
williamr@4:   };
williamr@4: 
williamr@4:   typedef int fmtflags;
williamr@4:   typedef int iostate;
williamr@4:   typedef int openmode;
williamr@4:   typedef int seekdir;
williamr@4: 
williamr@4: # ifndef _STLP_NO_ANACHRONISMS
williamr@4:   typedef fmtflags fmt_flags;
williamr@4: # endif
williamr@4: 
williamr@4:   // Formatting flags.
williamr@4: #if defined (_STLP_STATIC_CONST_INIT_BUG)
williamr@4:   enum  {
williamr@4: #else
williamr@4:   // boris : type for all those constants is int
williamr@4:   static const int
williamr@4: #endif
williamr@4:     left       = 0x0001,
williamr@4:     right      = 0x0002,
williamr@4:     internal   = 0x0004,
williamr@4:     dec        = 0x0008,
williamr@4:     hex        = 0x0010,
williamr@4:     oct        = 0x0020,
williamr@4:     fixed      = 0x0040,
williamr@4:     scientific = 0x0080,
williamr@4:     boolalpha  = 0x0100,
williamr@4:     showbase   = 0x0200,
williamr@4:     showpoint  = 0x0400,
williamr@4:     showpos    = 0x0800,
williamr@4:     skipws     = 0x1000,
williamr@4:     unitbuf    = 0x2000,
williamr@4:     uppercase  = 0x4000,
williamr@4:     adjustfield = left | right | internal,
williamr@4:     basefield   = dec | hex | oct,
williamr@4:     floatfield  = scientific | fixed,
williamr@4: 
williamr@4:     // State flags.
williamr@4:     goodbit = 0x00,
williamr@4:     badbit  = 0x01,
williamr@4:     eofbit  = 0x02,
williamr@4:     failbit = 0x04,
williamr@4: 
williamr@4:     // Openmode flags.
williamr@4:     __default_mode = 0x0, /* implementation detail */
williamr@4:     app    = 0x01,
williamr@4:     ate    = 0x02,
williamr@4:     binary = 0x04,
williamr@4:     in     = 0x08,
williamr@4:     out    = 0x10,
williamr@4:     trunc  = 0x20,
williamr@4: 
williamr@4:     // Seekdir flags
williamr@4: 
williamr@4:     beg = 0x01,
williamr@4:     cur = 0x02,
williamr@4:     end = 0x04
williamr@4: # ifdef _STLP_STATIC_CONST_INIT_BUG
williamr@4:   }
williamr@4: # endif
williamr@4:   ;
williamr@4: 
williamr@4: public:                         // Flag-manipulation functions.
williamr@4:   fmtflags flags() const { return _M_fmtflags; }
williamr@4:   fmtflags flags(fmtflags __flags) {
williamr@4:     fmtflags __tmp = _M_fmtflags;
williamr@4:     _M_fmtflags = __flags;
williamr@4:     return __tmp;
williamr@4:   }
williamr@4: 
williamr@4:   fmtflags setf(fmtflags __flag) {
williamr@4:     fmtflags __tmp = _M_fmtflags;
williamr@4:     _M_fmtflags |= __flag;
williamr@4:     return __tmp;
williamr@4:   }
williamr@4:   fmtflags setf(fmtflags __flag, fmtflags __mask) {
williamr@4:     fmtflags __tmp = _M_fmtflags;
williamr@4:     _M_fmtflags &= ~__mask;
williamr@4:     _M_fmtflags |= __flag & __mask;
williamr@4:     return __tmp;
williamr@4:   }
williamr@4:   void unsetf(fmtflags __mask) { _M_fmtflags &= ~__mask; }
williamr@4: 
williamr@4:   streamsize precision() const { return _M_precision; }
williamr@4:   streamsize precision(streamsize __newprecision) {
williamr@4:     streamsize __tmp = _M_precision;
williamr@4:     _M_precision = __newprecision;
williamr@4:     return __tmp;
williamr@4:   }
williamr@4: 
williamr@4:   streamsize width() const { return _M_width; }
williamr@4:   streamsize width(streamsize __newwidth) {
williamr@4:     streamsize __tmp = _M_width;
williamr@4:     _M_width = __newwidth;
williamr@4:     return __tmp;
williamr@4:   }
williamr@4: 
williamr@4: public:                         // Locales
williamr@4:   locale imbue(const locale&);
williamr@4:   locale getloc() const { return _M_locale; }
williamr@4: 
williamr@4: public:                         // Auxiliary storage.
williamr@4:   static int _STLP_CALL xalloc();
williamr@4:   long&  iword(int __index);
williamr@4:   void*& pword(int __index);
williamr@4: 
williamr@4: public:                         // Destructor.
williamr@4:   virtual ~ios_base();
williamr@4: 
williamr@4: public:                         // Callbacks.
williamr@4:   enum event { erase_event, imbue_event, copyfmt_event };
williamr@4:   typedef void (*event_callback)(event, ios_base&, int __index);
williamr@4:   void register_callback(event_callback __fn, int __index);
williamr@4: 
williamr@4: public:                         // This member function affects only
williamr@4:                                 // the eight predefined ios objects:
williamr@4:                                 // cin, cout, etc.
williamr@4:   static bool _STLP_CALL sync_with_stdio(bool __sync = true);
williamr@4: 
williamr@4: public:                         // The C++ standard requires only that these
williamr@4:                                 // member functions be defined in basic_ios.
williamr@4:                                 // We define them in the non-template
williamr@4:                                 // base class to avoid code duplication.
williamr@4:   operator void*() const { return !fail() ? (void*) __CONST_CAST(ios_base*,this) : (void*) 0; }
williamr@4:   bool operator!() const { return fail(); }
williamr@4: 
williamr@4:   iostate rdstate() const { return _M_iostate; }
williamr@4: 
williamr@4:   bool good() const { return _M_iostate == 0; }
williamr@4:   bool eof() const { return (_M_iostate & eofbit) != 0; }
williamr@4:   bool fail() const { return (_M_iostate & (failbit | badbit)) != 0; }
williamr@4:   bool bad() const { return (_M_iostate & badbit) != 0; }
williamr@4: 
williamr@4: protected:                      // The functional protected interface.
williamr@4: 
williamr@4:   // Copies the state of __x to *this.  This member function makes it
williamr@4:   // possible to implement basic_ios::copyfmt without having to expose
williamr@4:   // ios_base's private data members.  Does not copy _M_exception_mask
williamr@4:   // or _M_iostate.
williamr@4:   void _M_copy_state(const ios_base& __x);
williamr@4: 
williamr@4:   void _M_setstate_nothrow(iostate __state) { _M_iostate |= __state; }
williamr@4:   void _M_clear_nothrow(iostate __state) { _M_iostate = __state; }
williamr@4:   iostate _M_get_exception_mask() const { return _M_exception_mask; }
williamr@4:   void _M_set_exception_mask(iostate __mask) { _M_exception_mask = __mask; }
williamr@4:   void _M_check_exception_mask() {
williamr@4:     if (_M_iostate & _M_exception_mask)
williamr@4:       _M_throw_failure();
williamr@4:   }
williamr@4: 
williamr@4:   void _M_invoke_callbacks(event);
williamr@4:   void _STLP_FUNCTION_THROWS _M_throw_failure();
williamr@4: 
williamr@4:   ios_base();                   // Default constructor.
williamr@4: 
williamr@4: protected:                        // Initialization of the I/O system
williamr@4:   static void _STLP_CALL _S_initialize();
williamr@4:   static void _STLP_CALL _S_uninitialize();
williamr@4:   static bool _S_was_synced;
williamr@4: 
williamr@4: private:                        // Invalidate the copy constructor and
williamr@4:                                 // assignment operator.
williamr@4:   ios_base(const ios_base&);
williamr@4:   void operator=(const ios_base&);
williamr@4: 
williamr@4: private:                        // Data members.
williamr@4: 
williamr@4:   fmtflags _M_fmtflags;         // Flags
williamr@4:   iostate _M_iostate;
williamr@4:   openmode _M_openmode;
williamr@4:   seekdir _M_seekdir;
williamr@4:   iostate _M_exception_mask;
williamr@4: 
williamr@4:   streamsize _M_precision;
williamr@4:   streamsize _M_width;
williamr@4: 
williamr@4:   locale _M_locale;
williamr@4: 
williamr@4:   pair<event_callback, int>* _M_callbacks;
williamr@4:   size_t _M_num_callbacks;      // Size of the callback array.
williamr@4:   size_t _M_callback_index;     // Index of the next available callback;
williamr@4:                                 // initially zero.
williamr@4: 
williamr@4:   long* _M_iwords;              // Auxiliary storage.  The count is zero
williamr@4:   size_t _M_num_iwords;         // if and only if the pointer is null.
williamr@4: 
williamr@4:   void** _M_pwords;
williamr@4:   size_t _M_num_pwords;
williamr@4: 
williamr@4: protected:
williamr@4:   // Cached copies of the curent locale's facets.  Set by init() and imbue().
williamr@4:   locale::facet* _M_cached_ctype;
williamr@4:   locale::facet* _M_cached_numpunct;
williamr@4:   string         _M_cached_grouping;
williamr@4: public:
williamr@4:   // Equivalent to &use_facet< Facet >(getloc()), but faster.
williamr@4:   const locale::facet* _M_ctype_facet() const { return _M_cached_ctype; }
williamr@4:   const locale::facet* _M_numpunct_facet() const { return _M_cached_numpunct; }
williamr@4:   const string&  _M_grouping() const { return _M_cached_grouping; }
williamr@4: public:
williamr@4: 
williamr@4:   // ----------------------------------------------------------------------
williamr@4:   // Nested initializer class.  This is an implementation detail, but it's
williamr@4:   // prescribed by the standard.  The static initializer object (on
williamr@4:   // implementations where such a thing is required) is declared in
williamr@4:   // <iostream>
williamr@4: 
williamr@4:   class _STLP_CLASS_DECLSPEC Init
williamr@4:   {
williamr@4:     public:
williamr@4:       Init();
williamr@4:       ~Init();
williamr@4:     private:
williamr@4:       static long _S_count;
williamr@4:       friend class ios_base;
williamr@4:   };
williamr@4: 
williamr@4:   friend class Init;
williamr@4: 
williamr@4: public:
williamr@4: # ifndef _STLP_NO_ANACHRONISMS
williamr@4:   //  31.6  Old iostreams members                         [depr.ios.members]
williamr@4:   typedef iostate  io_state;
williamr@4:   typedef openmode open_mode;
williamr@4:   typedef seekdir  seek_dir;
williamr@4:   typedef _STLP_STD::streamoff  streamoff;
williamr@4:   typedef _STLP_STD::streampos  streampos;
williamr@4: # endif
williamr@4: };
williamr@4: 
williamr@4: // ----------------------------------------------------------------------
williamr@4: // ios_base manipulator functions, from section 27.4.5 of the C++ standard.
williamr@4: // All of them are trivial one-line wrapper functions.
williamr@4: 
williamr@4: // fmtflag manipulators, section 27.4.5.1
williamr@4: inline ios_base& _STLP_CALL boolalpha(ios_base& __s)
williamr@4:   { __s.setf(ios_base::boolalpha); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL noboolalpha(ios_base& __s)
williamr@4:   { __s.unsetf(ios_base::boolalpha); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL showbase(ios_base& __s)
williamr@4:   { __s.setf(ios_base::showbase); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL noshowbase(ios_base& __s)
williamr@4:   { __s.unsetf(ios_base::showbase); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL showpoint(ios_base& __s)
williamr@4:   { __s.setf(ios_base::showpoint); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL noshowpoint(ios_base& __s)
williamr@4:   { __s.unsetf(ios_base::showpoint); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL showpos(ios_base& __s)
williamr@4:   { __s.setf(ios_base::showpos); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL noshowpos(ios_base& __s)
williamr@4:   { __s.unsetf(ios_base::showpos); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL skipws(ios_base& __s)
williamr@4:   { __s.setf(ios_base::skipws); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL noskipws(ios_base& __s)
williamr@4:   { __s.unsetf(ios_base::skipws); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL uppercase(ios_base& __s)
williamr@4:   { __s.setf(ios_base::uppercase); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL nouppercase(ios_base& __s)
williamr@4:   { __s.unsetf(ios_base::uppercase); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL unitbuf(ios_base& __s)
williamr@4:   { __s.setf(ios_base::unitbuf); return __s;}
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL nounitbuf(ios_base& __s)
williamr@4:   { __s.unsetf(ios_base::unitbuf); return __s;}
williamr@4: 
williamr@4: 
williamr@4: // adjustfield manipulators, section 27.4.5.2
williamr@4: inline ios_base& _STLP_CALL internal(ios_base& __s)
williamr@4:   { __s.setf(ios_base::internal, ios_base::adjustfield); return __s; }
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL left(ios_base& __s)
williamr@4:   { __s.setf(ios_base::left, ios_base::adjustfield); return __s; }
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL right(ios_base& __s)
williamr@4:   { __s.setf(ios_base::right, ios_base::adjustfield); return __s; }
williamr@4: 
williamr@4: // basefield manipulators, section 27.4.5.3
williamr@4: inline ios_base& _STLP_CALL dec(ios_base& __s)
williamr@4:   { __s.setf(ios_base::dec, ios_base::basefield); return __s; }
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL hex(ios_base& __s)
williamr@4:   { __s.setf(ios_base::hex, ios_base::basefield); return __s; }
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL oct(ios_base& __s)
williamr@4:   { __s.setf(ios_base::oct, ios_base::basefield); return __s; }
williamr@4: 
williamr@4: 
williamr@4: // floatfield manipulators, section 27.4.5.3
williamr@4: inline ios_base& _STLP_CALL fixed(ios_base& __s)
williamr@4:   { __s.setf(ios_base::fixed, ios_base::floatfield); return __s; }
williamr@4: 
williamr@4: inline ios_base& _STLP_CALL scientific(ios_base& __s)
williamr@4:   { __s.setf(ios_base::scientific, ios_base::floatfield); return __s; }
williamr@4: 
williamr@4: _STLP_END_NAMESPACE
williamr@4: 
williamr@4: #endif /* _STLP_IOS_BASE */
williamr@4: 
williamr@4: // Local Variables:
williamr@4: // mode:C++
williamr@4: // End:
williamr@4: