Home | History | Annotate | Download | only in bits
      1 // Stream iterators
      2 
      3 // Copyright (C) 2001, 2004, 2005, 2009, 2010 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file bits/stream_iterator.h
     26  *  This is an internal header file, included by other library headers.
     27  *  Do not attempt to use it directly. @headername{iterator}
     28  */
     29 
     30 #ifndef _STREAM_ITERATOR_H
     31 #define _STREAM_ITERATOR_H 1
     32 
     33 #pragma GCC system_header
     34 
     35 #include <debug/debug.h>
     36 
     37 namespace std _GLIBCXX_VISIBILITY(default)
     38 {
     39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     40 
     41   /**
     42    * @addtogroup iterators
     43    * @{
     44    */
     45 
     46   /// Provides input iterator semantics for streams.
     47   template<typename _Tp, typename _CharT = char,
     48            typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
     49     class istream_iterator
     50     : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
     51     {
     52     public:
     53       typedef _CharT                         char_type;
     54       typedef _Traits                        traits_type;
     55       typedef basic_istream<_CharT, _Traits> istream_type;
     56 
     57     private:
     58       istream_type*	_M_stream;
     59       _Tp		_M_value;
     60       bool		_M_ok;
     61 
     62     public:
     63       ///  Construct end of input stream iterator.
     64       _GLIBCXX_CONSTEXPR istream_iterator()
     65       : _M_stream(0), _M_value(), _M_ok(false) {}
     66 
     67       ///  Construct start of input stream iterator.
     68       istream_iterator(istream_type& __s)
     69       : _M_stream(&__s)
     70       { _M_read(); }
     71 
     72       istream_iterator(const istream_iterator& __obj)
     73       : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
     74         _M_ok(__obj._M_ok)
     75       { }
     76 
     77       const _Tp&
     78       operator*() const
     79       {
     80 	__glibcxx_requires_cond(_M_ok,
     81 				_M_message(__gnu_debug::__msg_deref_istream)
     82 				._M_iterator(*this));
     83 	return _M_value;
     84       }
     85 
     86       const _Tp*
     87       operator->() const { return &(operator*()); }
     88 
     89       istream_iterator&
     90       operator++()
     91       {
     92 	__glibcxx_requires_cond(_M_ok,
     93 				_M_message(__gnu_debug::__msg_inc_istream)
     94 				._M_iterator(*this));
     95 	_M_read();
     96 	return *this;
     97       }
     98 
     99       istream_iterator
    100       operator++(int)
    101       {
    102 	__glibcxx_requires_cond(_M_ok,
    103 				_M_message(__gnu_debug::__msg_inc_istream)
    104 				._M_iterator(*this));
    105 	istream_iterator __tmp = *this;
    106 	_M_read();
    107 	return __tmp;
    108       }
    109 
    110       bool
    111       _M_equal(const istream_iterator& __x) const
    112       { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); }
    113 
    114     private:
    115       void
    116       _M_read()
    117       {
    118 	_M_ok = (_M_stream && *_M_stream) ? true : false;
    119 	if (_M_ok)
    120 	  {
    121 	    *_M_stream >> _M_value;
    122 	    _M_ok = *_M_stream ? true : false;
    123 	  }
    124       }
    125     };
    126 
    127   ///  Return true if x and y are both end or not end, or x and y are the same.
    128   template<typename _Tp, typename _CharT, typename _Traits, typename _Dist>
    129     inline bool
    130     operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
    131 	       const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
    132     { return __x._M_equal(__y); }
    133 
    134   ///  Return false if x and y are both end or not end, or x and y are the same.
    135   template <class _Tp, class _CharT, class _Traits, class _Dist>
    136     inline bool
    137     operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
    138 	       const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
    139     { return !__x._M_equal(__y); }
    140 
    141   /**
    142    *  @brief  Provides output iterator semantics for streams.
    143    *
    144    *  This class provides an iterator to write to an ostream.  The type Tp is
    145    *  the only type written by this iterator and there must be an
    146    *  operator<<(Tp) defined.
    147    *
    148    *  @param  Tp  The type to write to the ostream.
    149    *  @param  CharT  The ostream char_type.
    150    *  @param  Traits  The ostream char_traits.
    151   */
    152   template<typename _Tp, typename _CharT = char,
    153            typename _Traits = char_traits<_CharT> >
    154     class ostream_iterator
    155     : public iterator<output_iterator_tag, void, void, void, void>
    156     {
    157     public:
    158       //@{
    159       /// Public typedef
    160       typedef _CharT                         char_type;
    161       typedef _Traits                        traits_type;
    162       typedef basic_ostream<_CharT, _Traits> ostream_type;
    163       //@}
    164 
    165     private:
    166       ostream_type*	_M_stream;
    167       const _CharT*	_M_string;
    168 
    169     public:
    170       /// Construct from an ostream.
    171       ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
    172 
    173       /**
    174        *  Construct from an ostream.
    175        *
    176        *  The delimiter string @a c is written to the stream after every Tp
    177        *  written to the stream.  The delimiter is not copied, and thus must
    178        *  not be destroyed while this iterator is in use.
    179        *
    180        *  @param  s  Underlying ostream to write to.
    181        *  @param  c  CharT delimiter string to insert.
    182       */
    183       ostream_iterator(ostream_type& __s, const _CharT* __c)
    184       : _M_stream(&__s), _M_string(__c)  { }
    185 
    186       /// Copy constructor.
    187       ostream_iterator(const ostream_iterator& __obj)
    188       : _M_stream(__obj._M_stream), _M_string(__obj._M_string)  { }
    189 
    190       /// Writes @a value to underlying ostream using operator<<.  If
    191       /// constructed with delimiter string, writes delimiter to ostream.
    192       ostream_iterator&
    193       operator=(const _Tp& __value)
    194       {
    195 	__glibcxx_requires_cond(_M_stream != 0,
    196 				_M_message(__gnu_debug::__msg_output_ostream)
    197 				._M_iterator(*this));
    198 	*_M_stream << __value;
    199 	if (_M_string) *_M_stream << _M_string;
    200 	return *this;
    201       }
    202 
    203       ostream_iterator&
    204       operator*()
    205       { return *this; }
    206 
    207       ostream_iterator&
    208       operator++()
    209       { return *this; }
    210 
    211       ostream_iterator&
    212       operator++(int)
    213       { return *this; }
    214     };
    215 
    216   // @} group iterators
    217 
    218 _GLIBCXX_END_NAMESPACE_VERSION
    219 } // namespace
    220 
    221 #endif
    222