// -*- C++ -*-
#ifndef __STD_IOS__
#define __STD_IOS__

/***************************************************************************
 *
 * ios - Declarations for the Standard Library basic stream I/O
 *
 ***************************************************************************
 *    
 *  Copyright 2000 Compaq Computer Corporation
 *
 *  COMPAQ Registered in U.S. Patent and Trademark Office.
 *
 *  Confidential computer software. Valid license from Compaq required for
 *  possession, use or copying. Consistent with FAR 12.211 and 12.212,
 *  Commercial Computer Software, Computer Software Documentation, and
 *  Technical Data for Commercial Items are licensed to the U.S. Government
 *  under vendor's standard commercial license.
 *
 ****************************************************************************
 *
 * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
 * ALL RIGHTS RESERVED
 *
 * The software and information contained herein are proprietary to, and
 * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
 * intends to preserve as trade secrets such software and information.
 * This software is furnished pursuant to a written license agreement and
 * may be used, copied, transmitted, and stored only in accordance with
 * the terms of such license and with the inclusion of the above copyright
 * notice.  This software and information or any other copies thereof may
 * not be provided or otherwise made available to any other person.
 *
 * Notwithstanding any other lease or license that may pertain to, or
 * accompany the delivery of, this computer software and information, the
 * rights of the Government regarding its use, reproduction and disclosure
 * are as set forth in Section 52.227-19 of the FARS Computer
 * Software-Restricted Rights clause.
 * 
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7013.
 * Contractor/Manufacturer is Rogue Wave Software, Inc.,
 * P.O. Box 2328, Corvallis, Oregon 97339.
 *
 * This computer software and information is distributed with "restricted
 * rights."  Use, duplication or disclosure is subject to restrictions as
 * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
 * Computer Software-Restricted Rights (April 1985)."  If the Clause at
 * 18-52.227-74 "Rights in Data General" is specified in the contract,
 * then the "Alternate III" clause applies.
 *
 **************************************************************************/

#include <compnent.hxx>
#ifndef __USE_STD_IOSTREAM
#error "cannot include ios -- define __USE_STD_IOSTREAM to override default - see section 7.1.2 of the C++ Using Guide"
#else

#include <stdcomp>

#include <rwstderr>        // error messages
#include <rwlocale>          // locale class
#include <ctype>             // facets
#include <codecvt>           // code coversion facet
#include <numeral>           // numeric facet 
#include <vendor>            // standard xxx_byname facets & vendor-defined extensions
#include <usefacet>          // usefacet and hasfacet


#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __save
#      pragma __environment __cxx_header_defaults
#   endif
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#pragma __extern_prefix __save
#pragma __extern_prefix "CXXL$" 
#endif


#ifndef _RWSTD_NO_NAMESPACE
namespace _RWrwstd {
#endif

#ifdef _RWSTD_LOCALIZED_ERRORS
  extern const unsigned int _RWSTDExport rwse_failbit_set;
  extern const unsigned int _RWSTDExport rwse_badbit_set;
  extern const unsigned int _RWSTDExport rwse_eofbit_set;
#else
  extern const char _RWSTDExportFunc(*) rwse_failbit_set;
  extern const char _RWSTDExportFunc(*) rwse_badbit_set;
  extern const char _RWSTDExportFunc(*) rwse_eofbit_set;
#endif // _RWSTD_LOCALIZED_ERRORS


#ifndef _RWSTD_NO_NAMESPACE
}
namespace std {
#endif
 
  /*
   *    Class basic_ios
   */

  template<class charT, class traits>
  class _RWSTDExportTemplate basic_ios : public ios_base
  { 

  public:
    //
    // Types:
    //
    typedef _TYPENAME traits::char_type        char_type;
    typedef _TYPENAME traits::int_type         int_type;
    typedef _TYPENAME traits::pos_type         pos_type;
    typedef _TYPENAME traits::off_type         off_type;
    typedef traits                             traits_type;
      
    typedef basic_ios<charT, traits>           ios_type;
    typedef basic_streambuf<charT, traits>     streambuf_type; 
    typedef basic_ostream<charT, traits>       ostream_type;

    inline operator void*() const;
    inline bool operator! () const;
    inline iostate rdstate() const;
    inline void clear(iostate state = goodbit);
    inline void setstate(iostate state);

    inline bool good() const;
    inline bool eof()  const;
    inline bool fail() const;
    inline bool bad()  const;
      
    inline iostate exceptions() const;
    inline void exceptions(iostate excpt);
      
    _EXPLICIT basic_ios(basic_streambuf<charT, traits> *sb_arg);
    virtual ~basic_ios();

    inline ostream_type *tie() const;
    ostream_type *tie(ostream_type *tie_arg);

    inline streambuf_type *rdbuf() const;
    streambuf_type *rdbuf( streambuf_type *sb);

    ios_type& copyfmt(const ios_type& rhs);
      
    char_type fill() const
    {
      return _RWfillch;
    }
    char_type fill(char_type ch)
    {
#ifdef _RWSTD_MULTI_THREAD
      _RWSTDGuard guard(this->_RWstream_mutex);
#endif
      char_type    temp = _RWfillch;
      _RWfillch = ch;
      return temp;
    }


    locale imbue(const locale& loc);

    inline char  narrow(charT, char) const;
    inline charT widen(char) const;

  protected:
    basic_ios();
    void init(basic_streambuf<charT, traits> *sb);
      
    inline void _RW_UNSAFE_clear(iostate state = goodbit);

  private:
    streambuf_type       *_RWsb;    
    ostream_type         *_RWtiestr;   
    char_type            _RWfillch; 
    iostate              _RWstate;   
    iostate              _Except; 

  };



  /*
   * basic_streambuf *rdbuf() const
   */

  template<class charT, class traits>
  inline basic_streambuf<charT, traits> *
  basic_ios<charT, traits>::rdbuf() const
  {
    return _RWsb;
  }

  /*
   * basic_ostream *tie() const
   */

  template<class charT, class traits>
  inline basic_ostream<charT, traits> *
  basic_ios<charT, traits>::tie() const
  {
    return _RWtiestr;
  }

  /*
   * void exceptions(iostate)
   */

  template<class charT, class traits>
  inline void 
  basic_ios<charT, traits>::exceptions(ios_base::iostate st)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif
    _Except = st;

#ifdef _RWSTD_MULTI_THREAD
    _RW_UNSAFE_clear(rdstate()); 
#else
    clear(rdstate());
#endif //  _RWSTD_MULTI_THREAD
  }

  /*
   * iostate exceptions() const
   */

  template<class charT, class traits>
  inline ios_base::iostate 
  basic_ios<charT, traits>::exceptions() const
  { 
    return _Except;
  }

  /*
   * void clear(iostate )
   */

  template<class charT, class traits>
  inline void 
  basic_ios<charT, traits>::clear(iostate st)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif 
    _RW_UNSAFE_clear(st); 
  }

  /*
   * void setstate(iostate)
   */

  template<class charT, class traits>
  inline void
  basic_ios<charT, traits>::setstate(iostate st)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif // _RWSTD_MULTI_THREAD

#ifdef _RWSTD_MULTI_THREAD
    _RW_UNSAFE_clear(_RWstate | st); 
#else
    clear(_RWstate | st);
#endif // _RWSTD_MULTI_THREAD
  }

  /*
   * iostate rdstate() const
   */

  template<class charT, class traits>
  inline ios_base::iostate 
  basic_ios<charT, traits>::rdstate() const
  {
    return _RWstate;
  }

  /*
   * operator bool() const
   */

  template<class charT, class traits>
  inline basic_ios<charT, traits>::operator void*() const
  {
    return fail() ? (void*)0 : (void*)1;
  }

  /*
   * bool operator!() const
   */

  template<class charT, class traits>
  inline bool 
  basic_ios<charT, traits>::operator!() const
  {
    return fail();
  }

  /*
   * bool good() const
   */

  template<class charT, class traits>
  inline bool 
  basic_ios<charT, traits>::good() const
  {
    return (_RWstate == ios_base::goodbit);
  }

  /*
   * bool eof() const
   */

  template<class charT, class traits>
  inline bool 
  basic_ios<charT, traits>::eof() const
  {
    return (_RWstate & ios_base::eofbit);
  }

  /*
   * bool fail() const
   */

  template<class charT, class traits>
  inline bool 
  basic_ios<charT, traits>::fail() const
  {
    return (_RWstate & (ios_base::failbit | ios_base::badbit));
  }

  /*
   * bool bad() const
   */

  template<class charT, class traits>
  inline bool 
  basic_ios<charT, traits>::bad() const
  {
    return (_RWstate & ios_base::badbit);
  }

  /*
   * void _RW_UNSAFE_clear(iostate )
   */

  template<class charT, class traits>
  inline void 
  basic_ios<charT, traits>::_RW_UNSAFE_clear(iostate st)
  {
    if ( !_RWsb ) 
    {
      st |= ios_base::badbit;
      _RWstate |= ios_base::badbit; 
    }

    _RWstate = st;

    if( rdstate() & exceptions() )
    {
#ifdef _RW_STD_EXCEPT
#ifndef _RWSTD_NO_EXCEPTIONS
      if ( rdstate() & exceptions() & ios_base::failbit )
      { 
        _RWstate=st;
        throw ios_base::failure( string(__RWSTD::except_msg_string(__RWSTD::rwse_failbit_set).msgstr()) );
      }

      if ( rdstate() & exceptions() & ios_base::badbit )
      { 
        _RWstate=st;
        throw ios_base::failure( string(__RWSTD::except_msg_string(__RWSTD::rwse_badbit_set).msgstr()) );
      }
      if ( rdstate() & exceptions() & ios_base::eofbit )
      { 
        _RWstate=st;
        throw ios_base::failure( string(__RWSTD::except_msg_string(__RWSTD::rwse_eofbit_set).msgstr()) );
      }
#endif //  _RWSTD_NO_EXCEPTIONS
#endif //  _RW_STD_EXCEPT
    }
  }

  /*
   * char narrow(charT, char) const
   */

  template<class charT, class traits>
  inline char 
  basic_ios<charT, traits>::narrow(charT c, char dfault) const
  {
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
    return use_facet< ctype<charT> >(getloc()).narrow(c,dfault);
#else
    return use_facet(getloc(),(ctype<charT>*)0).narrow(c,dfault);
#endif
     
  }

  /*
   * charT widen(char) const
   */

  template<class charT, class traits>
  inline charT 
  basic_ios<charT, traits>::widen(char c) const
  {
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
    return use_facet< ctype<charT> >(getloc()).widen(c);
#else
    return use_facet(getloc(),(ctype<charT>*)0).widen(c);
#endif
     
  }

#ifndef _RWSTD_NO_COMPLEX_DEFAULT_TEMPLATES
  typedef basic_ios<char>                          ios;
#else
  typedef basic_ios<char, char_traits<char> >      ios;
#endif

#ifndef _RWSTD_NO_WIDE_CHAR
#ifndef _RWSTD_NO_COMPLEX_DEFAULT_TEMPLATES
  typedef basic_ios<wchar_t>                         wios;
#else
  typedef basic_ios<wchar_t, char_traits<wchar_t> >  wios;
#endif //  _RWSTD_NO_COMPLEX_DEFAULT_TEMPLATES
#endif //  _RWSTD_NO_WIDE_CHAR

  /*
   *     external declarations for manipulators
   */

#ifdef _RWSTD_MULTI_THREAD
  template <class charT, class traits>
  basic_ios<charT,traits>& _RWlock(basic_ios<charT,traits>&);

  template <class charT, class traits>
  basic_ios<charT,traits>& _RWunlock(basic_ios<charT,traits>&);
#endif // _RWSTD_MULTI_THREAD


#ifndef _RWSTD_NO_NAMESPACE
}
#endif

#ifndef __FORCE_INSTANTIATIONS
// basic_ios do_not_instantiations
#pragma do_not_instantiate std::basic_ios<char, std::char_traits<char > >::~basic_ios()
#pragma do_not_instantiate std::basic_ios<char, std::char_traits<char > >::basic_ios()
#pragma do_not_instantiate void std::basic_ios<char, std::char_traits<char > >::init(std::basic_streambuf<char, std::char_traits<char > > *)
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#   pragma __extern_prefix __restore
#endif

#ifdef _RWSTD_COMPILE_INSTANTIATE
#include <ios.cc>
#endif // _RWSTD_COMPILE_INSTANTIATE


#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __restore
#   endif
#endif

#endif // __USE_STD_IOSTREAM

#endif // __STD_IOS_
