libstdc++
basic_ios.h
Go to the documentation of this file.
00001 // Iostreams base classes -*- C++ -*-
00002 
00003 // Copyright (C) 1997-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/basic_ios.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{ios}
00028  */
00029 
00030 #ifndef _BASIC_IOS_H
00031 #define _BASIC_IOS_H 1
00032 
00033 #pragma GCC system_header
00034 
00035 #include <bits/localefwd.h>
00036 #include <bits/locale_classes.h>
00037 #include <bits/locale_facets.h>
00038 #include <bits/streambuf_iterator.h>
00039 #include <bits/move.h>
00040 
00041 namespace std _GLIBCXX_VISIBILITY(default)
00042 {
00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00044 
00045   template<typename _Facet>
00046     inline const _Facet&
00047     __check_facet(const _Facet* __f)
00048     {
00049       if (!__f)
00050         __throw_bad_cast();
00051       return *__f;
00052     }
00053 
00054   /**
00055    *  @brief Template class basic_ios, virtual base class for all
00056    *  stream classes. 
00057    *  @ingroup io
00058    *
00059    *  @tparam _CharT  Type of character stream.
00060    *  @tparam _Traits  Traits for character type, defaults to
00061    *                   char_traits<_CharT>.
00062    *
00063    *  Most of the member functions called dispatched on stream objects
00064    *  (e.g., @c std::cout.foo(bar);) are consolidated in this class.
00065   */
00066   template<typename _CharT, typename _Traits>
00067     class basic_ios : public ios_base
00068     {
00069     public:
00070       //@{
00071       /**
00072        *  These are standard types.  They permit a standardized way of
00073        *  referring to names of (or names dependent on) the template
00074        *  parameters, which are specific to the implementation.
00075       */
00076       typedef _CharT                                 char_type;
00077       typedef typename _Traits::int_type             int_type;
00078       typedef typename _Traits::pos_type             pos_type;
00079       typedef typename _Traits::off_type             off_type;
00080       typedef _Traits                                traits_type;
00081       //@}
00082 
00083       //@{
00084       /**
00085        *  These are non-standard types.
00086       */
00087       typedef ctype<_CharT>                          __ctype_type;
00088       typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> >
00089                                                      __num_put_type;
00090       typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> >
00091                                                      __num_get_type;
00092       //@}
00093 
00094       // Data members:
00095     protected:
00096       basic_ostream<_CharT, _Traits>*                _M_tie;
00097       mutable char_type                              _M_fill;
00098       mutable bool                                   _M_fill_init;
00099       basic_streambuf<_CharT, _Traits>*              _M_streambuf;
00100 
00101       // Cached use_facet<ctype>, which is based on the current locale info.
00102       const __ctype_type*                            _M_ctype;
00103       // For ostream.
00104       const __num_put_type*                          _M_num_put;
00105       // For istream.
00106       const __num_get_type*                          _M_num_get;
00107 
00108     public:
00109       //@{
00110       /**
00111        *  @brief  The quick-and-easy status check.
00112        *
00113        *  This allows you to write constructs such as
00114        *  <code>if (!a_stream) ...</code> and <code>while (a_stream) ...</code>
00115       */
00116 #if __cplusplus >= 201103L
00117       explicit operator bool() const
00118       { return !this->fail(); }
00119 #else
00120       operator void*() const
00121       { return this->fail() ? 0 : const_cast<basic_ios*>(this); }
00122 #endif
00123 
00124       bool
00125       operator!() const
00126       { return this->fail(); }
00127       //@}
00128 
00129       /**
00130        *  @brief  Returns the error state of the stream buffer.
00131        *  @return  A bit pattern (well, isn't everything?)
00132        *
00133        *  See std::ios_base::iostate for the possible bit values.  Most
00134        *  users will call one of the interpreting wrappers, e.g., good().
00135       */
00136       iostate
00137       rdstate() const
00138       { return _M_streambuf_state; }
00139 
00140       /**
00141        *  @brief  [Re]sets the error state.
00142        *  @param  __state  The new state flag(s) to set.
00143        *
00144        *  See std::ios_base::iostate for the possible bit values.  Most
00145        *  users will not need to pass an argument.
00146       */
00147       void
00148       clear(iostate __state = goodbit);
00149 
00150       /**
00151        *  @brief  Sets additional flags in the error state.
00152        *  @param  __state  The additional state flag(s) to set.
00153        *
00154        *  See std::ios_base::iostate for the possible bit values.
00155       */
00156       void
00157       setstate(iostate __state)
00158       { this->clear(this->rdstate() | __state); }
00159 
00160       // Flip the internal state on for the proper state bits, then re
00161       // throws the propagated exception if bit also set in
00162       // exceptions().
00163       void
00164       _M_setstate(iostate __state)
00165       {
00166         // 27.6.1.2.1 Common requirements.
00167         // Turn this on without causing an ios::failure to be thrown.
00168         _M_streambuf_state |= __state;
00169         if (this->exceptions() & __state)
00170           __throw_exception_again;
00171       }
00172 
00173       /**
00174        *  @brief  Fast error checking.
00175        *  @return  True if no error flags are set.
00176        *
00177        *  A wrapper around rdstate.
00178       */
00179       bool
00180       good() const
00181       { return this->rdstate() == 0; }
00182 
00183       /**
00184        *  @brief  Fast error checking.
00185        *  @return  True if the eofbit is set.
00186        *
00187        *  Note that other iostate flags may also be set.
00188       */
00189       bool
00190       eof() const
00191       { return (this->rdstate() & eofbit) != 0; }
00192 
00193       /**
00194        *  @brief  Fast error checking.
00195        *  @return  True if either the badbit or the failbit is set.
00196        *
00197        *  Checking the badbit in fail() is historical practice.
00198        *  Note that other iostate flags may also be set.
00199       */
00200       bool
00201       fail() const
00202       { return (this->rdstate() & (badbit | failbit)) != 0; }
00203 
00204       /**
00205        *  @brief  Fast error checking.
00206        *  @return  True if the badbit is set.
00207        *
00208        *  Note that other iostate flags may also be set.
00209       */
00210       bool
00211       bad() const
00212       { return (this->rdstate() & badbit) != 0; }
00213 
00214       /**
00215        *  @brief  Throwing exceptions on errors.
00216        *  @return  The current exceptions mask.
00217        *
00218        *  This changes nothing in the stream.  See the one-argument version
00219        *  of exceptions(iostate) for the meaning of the return value.
00220       */
00221       iostate
00222       exceptions() const
00223       { return _M_exception; }
00224 
00225       /**
00226        *  @brief  Throwing exceptions on errors.
00227        *  @param  __except  The new exceptions mask.
00228        *
00229        *  By default, error flags are set silently.  You can set an
00230        *  exceptions mask for each stream; if a bit in the mask becomes set
00231        *  in the error flags, then an exception of type
00232        *  std::ios_base::failure is thrown.
00233        *
00234        *  If the error flag is already set when the exceptions mask is
00235        *  added, the exception is immediately thrown.  Try running the
00236        *  following under GCC 3.1 or later:
00237        *  @code
00238        *  #include <iostream>
00239        *  #include <fstream>
00240        *  #include <exception>
00241        *
00242        *  int main()
00243        *  {
00244        *      std::set_terminate (__gnu_cxx::__verbose_terminate_handler);
00245        *
00246        *      std::ifstream f ("/etc/motd");
00247        *
00248        *      std::cerr << "Setting badbit\n";
00249        *      f.setstate (std::ios_base::badbit);
00250        *
00251        *      std::cerr << "Setting exception mask\n";
00252        *      f.exceptions (std::ios_base::badbit);
00253        *  }
00254        *  @endcode
00255       */
00256       void
00257       exceptions(iostate __except)
00258       {
00259         _M_exception = __except;
00260         this->clear(_M_streambuf_state);
00261       }
00262 
00263       // Constructor/destructor:
00264       /**
00265        *  @brief  Constructor performs initialization.
00266        *
00267        *  The parameter is passed by derived streams.
00268       */
00269       explicit
00270       basic_ios(basic_streambuf<_CharT, _Traits>* __sb)
00271       : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0),
00272         _M_ctype(0), _M_num_put(0), _M_num_get(0)
00273       { this->init(__sb); }
00274 
00275       /**
00276        *  @brief  Empty.
00277        *
00278        *  The destructor does nothing.  More specifically, it does not
00279        *  destroy the streambuf held by rdbuf().
00280       */
00281       virtual
00282       ~basic_ios() { }
00283 
00284       // Members:
00285       /**
00286        *  @brief  Fetches the current @e tied stream.
00287        *  @return  A pointer to the tied stream, or NULL if the stream is
00288        *           not tied.
00289        *
00290        *  A stream may be @e tied (or synchronized) to a second output
00291        *  stream.  When this stream performs any I/O, the tied stream is
00292        *  first flushed.  For example, @c std::cin is tied to @c std::cout.
00293       */
00294       basic_ostream<_CharT, _Traits>*
00295       tie() const
00296       { return _M_tie; }
00297 
00298       /**
00299        *  @brief  Ties this stream to an output stream.
00300        *  @param  __tiestr  The output stream.
00301        *  @return  The previously tied output stream, or NULL if the stream
00302        *           was not tied.
00303        *
00304        *  This sets up a new tie; see tie() for more.
00305       */
00306       basic_ostream<_CharT, _Traits>*
00307       tie(basic_ostream<_CharT, _Traits>* __tiestr)
00308       {
00309         basic_ostream<_CharT, _Traits>* __old = _M_tie;
00310         _M_tie = __tiestr;
00311         return __old;
00312       }
00313 
00314       /**
00315        *  @brief  Accessing the underlying buffer.
00316        *  @return  The current stream buffer.
00317        *
00318        *  This does not change the state of the stream.
00319       */
00320       basic_streambuf<_CharT, _Traits>*
00321       rdbuf() const
00322       { return _M_streambuf; }
00323 
00324       /**
00325        *  @brief  Changing the underlying buffer.
00326        *  @param  __sb  The new stream buffer.
00327        *  @return  The previous stream buffer.
00328        *
00329        *  Associates a new buffer with the current stream, and clears the
00330        *  error state.
00331        *
00332        *  Due to historical accidents which the LWG refuses to correct, the
00333        *  I/O library suffers from a design error:  this function is hidden
00334        *  in derived classes by overrides of the zero-argument @c rdbuf(),
00335        *  which is non-virtual for hysterical raisins.  As a result, you
00336        *  must use explicit qualifications to access this function via any
00337        *  derived class.  For example:
00338        *
00339        *  @code
00340        *  std::fstream     foo;         // or some other derived type
00341        *  std::streambuf*  p = .....;
00342        *
00343        *  foo.ios::rdbuf(p);            // ios == basic_ios<char>
00344        *  @endcode
00345       */
00346       basic_streambuf<_CharT, _Traits>*
00347       rdbuf(basic_streambuf<_CharT, _Traits>* __sb);
00348 
00349       /**
00350        *  @brief  Copies fields of __rhs into this.
00351        *  @param  __rhs  The source values for the copies.
00352        *  @return  Reference to this object.
00353        *
00354        *  All fields of __rhs are copied into this object except that rdbuf()
00355        *  and rdstate() remain unchanged.  All values in the pword and iword
00356        *  arrays are copied.  Before copying, each callback is invoked with
00357        *  erase_event.  After copying, each (new) callback is invoked with
00358        *  copyfmt_event.  The final step is to copy exceptions().
00359       */
00360       basic_ios&
00361       copyfmt(const basic_ios& __rhs);
00362 
00363       /**
00364        *  @brief  Retrieves the @a empty character.
00365        *  @return  The current fill character.
00366        *
00367        *  It defaults to a space (' ') in the current locale.
00368       */
00369       char_type
00370       fill() const
00371       {
00372         if (!_M_fill_init)
00373           {
00374             _M_fill = this->widen(' ');
00375             _M_fill_init = true;
00376           }
00377         return _M_fill;
00378       }
00379 
00380       /**
00381        *  @brief  Sets a new @a empty character.
00382        *  @param  __ch  The new character.
00383        *  @return  The previous fill character.
00384        *
00385        *  The fill character is used to fill out space when P+ characters
00386        *  have been requested (e.g., via setw), Q characters are actually
00387        *  used, and Q<P.  It defaults to a space (' ') in the current locale.
00388       */
00389       char_type
00390       fill(char_type __ch)
00391       {
00392         char_type __old = this->fill();
00393         _M_fill = __ch;
00394         return __old;
00395       }
00396 
00397       // Locales:
00398       /**
00399        *  @brief  Moves to a new locale.
00400        *  @param  __loc  The new locale.
00401        *  @return  The previous locale.
00402        *
00403        *  Calls @c ios_base::imbue(loc), and if a stream buffer is associated
00404        *  with this stream, calls that buffer's @c pubimbue(loc).
00405        *
00406        *  Additional l10n notes are at
00407        *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
00408       */
00409       locale
00410       imbue(const locale& __loc);
00411 
00412       /**
00413        *  @brief  Squeezes characters.
00414        *  @param  __c  The character to narrow.
00415        *  @param  __dfault  The character to narrow.
00416        *  @return  The narrowed character.
00417        *
00418        *  Maps a character of @c char_type to a character of @c char,
00419        *  if possible.
00420        *
00421        *  Returns the result of
00422        *  @code
00423        *    std::use_facet<ctype<char_type> >(getloc()).narrow(c,dfault)
00424        *  @endcode
00425        *
00426        *  Additional l10n notes are at
00427        *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
00428       */
00429       char
00430       narrow(char_type __c, char __dfault) const
00431       { return __check_facet(_M_ctype).narrow(__c, __dfault); }
00432 
00433       /**
00434        *  @brief  Widens characters.
00435        *  @param  __c  The character to widen.
00436        *  @return  The widened character.
00437        *
00438        *  Maps a character of @c char to a character of @c char_type.
00439        *
00440        *  Returns the result of
00441        *  @code
00442        *    std::use_facet<ctype<char_type> >(getloc()).widen(c)
00443        *  @endcode
00444        *
00445        *  Additional l10n notes are at
00446        *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
00447       */
00448       char_type
00449       widen(char __c) const
00450       { return __check_facet(_M_ctype).widen(__c); }
00451 
00452     protected:
00453       // 27.4.5.1  basic_ios constructors
00454       /**
00455        *  @brief  Empty.
00456        *
00457        *  The default constructor does nothing and is not normally
00458        *  accessible to users.
00459       */
00460       basic_ios()
00461       : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), 
00462         _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0)
00463       { }
00464 
00465       /**
00466        *  @brief  All setup is performed here.
00467        *
00468        *  This is called from the public constructor.  It is not virtual and
00469        *  cannot be redefined.
00470       */
00471       void
00472       init(basic_streambuf<_CharT, _Traits>* __sb);
00473 
00474 #if __cplusplus >= 201103L
00475       basic_ios(const basic_ios&) = delete;
00476       basic_ios& operator=(const basic_ios&) = delete;
00477 
00478       void
00479       move(basic_ios& __rhs)
00480       {
00481         ios_base::_M_move(__rhs);
00482         _M_cache_locale(_M_ios_locale);
00483         this->tie(__rhs.tie(nullptr));
00484         _M_fill = __rhs._M_fill;
00485         _M_fill_init = __rhs._M_fill_init;
00486         _M_streambuf = nullptr;
00487       }
00488 
00489       void
00490       move(basic_ios&& __rhs)
00491       { this->move(__rhs); }
00492 
00493       void
00494       swap(basic_ios& __rhs) noexcept
00495       {
00496         ios_base::_M_swap(__rhs);
00497         _M_cache_locale(_M_ios_locale);
00498         __rhs._M_cache_locale(__rhs._M_ios_locale);
00499         std::swap(_M_tie, __rhs._M_tie);
00500         std::swap(_M_fill, __rhs._M_fill);
00501         std::swap(_M_fill_init, __rhs._M_fill_init);
00502       }
00503 
00504       void
00505       set_rdbuf(basic_streambuf<_CharT, _Traits>* __sb)
00506       { _M_streambuf = __sb; }
00507 #endif
00508 
00509       void
00510       _M_cache_locale(const locale& __loc);
00511     };
00512 
00513 _GLIBCXX_END_NAMESPACE_VERSION
00514 } // namespace
00515 
00516 #include <bits/basic_ios.tcc>
00517 
00518 #endif /* _BASIC_IOS_H */