Home | History | Annotate | Download | only in bits
      1 // Stream iterators
      2 
      3 // Copyright (C) 2001, 2004, 2005, 2009 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 stream_iterator.h
     26  *  This is an internal header file, included by other library headers.
     27  *  You should not attempt to use it directly.
     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 _GLIBCXX_BEGIN_NAMESPACE(std)
     38 
     39   /// Provides input iterator semantics for streams.
     40   template<typename _Tp, typename _CharT = char,
     41            typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
     42     class istream_iterator
     43     : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
     44     {
     45     public:
     46       typedef _CharT                         char_type;
     47       typedef _Traits                        traits_type;
     48       typedef basic_istream<_CharT, _Traits> istream_type;
     49 
     50     private:
     51       istream_type*	_M_stream;
     52       _Tp		_M_value;
     53       bool		_M_ok;
     54 
     55     public:
     56       ///  Construct end of input stream iterator.
     57       istream_iterator()
     58       : _M_stream(0), _M_value(), _M_ok(false) {}
     59 
     60       ///  Construct start of input stream iterator.
     61       istream_iterator(istream_type& __s)
     62       : _M_stream(&__s)
     63       { _M_read(); }
     64 
     65       istream_iterator(const istream_iterator& __obj)
     66       : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
     67         _M_ok(__obj._M_ok)
     68       { }
     69 
     70       const _Tp&
     71       operator*() const
     72       {
     73 	__glibcxx_requires_cond(_M_ok,
     74 				_M_message(__gnu_debug::__msg_deref_istream)
     75 				._M_iterator(*this));
     76 	return _M_value;
     77       }
     78 
     79       const _Tp*
     80       operator->() const { return &(operator*()); }
     81 
     82       istream_iterator&
     83       operator++()
     84       {
     85 	__glibcxx_requires_cond(_M_ok,
     86 				_M_message(__gnu_debug::__msg_inc_istream)
     87 				._M_iterator(*this));
     88 	_M_read();
     89 	return *this;
     90       }
     91 
     92       istream_iterator
     93       operator++(int)
     94       {
     95 	__glibcxx_requires_cond(_M_ok,
     96 				_M_message(__gnu_debug::__msg_inc_istream)
     97 				._M_iterator(*this));
     98 	istream_iterator __tmp = *this;
     99 	_M_read();
    100 	return __tmp;
    101       }
    102 
    103       bool
    104       _M_equal(const istream_iterator& __x) const
    105       { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); }
    106 
    107     private:
    108       void
    109       _M_read()
    110       {
    111 	_M_ok = (_M_stream && *_M_stream) ? true : false;
    112 	if (_M_ok)
    113 	  {
    114 	    *_M_stream >> _M_value;
    115 	    _M_ok = *_M_stream ? true : false;
    116 	  }
    117       }
    118     };
    119 
    120   ///  Return true if x and y are both end or not end, or x and y are the same.
    121   template<typename _Tp, typename _CharT, typename _Traits, typename _Dist>
    122     inline bool
    123     operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
    124 	       const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
    125     { return __x._M_equal(__y); }
    126 
    127   ///  Return false if x and y are both end or not end, or x and y are the same.
    128   template <class _Tp, class _CharT, class _Traits, class _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   /**
    135    *  @brief  Provides output iterator semantics for streams.
    136    *
    137    *  This class provides an iterator to write to an ostream.  The type Tp is
    138    *  the only type written by this iterator and there must be an
    139    *  operator<<(Tp) defined.
    140    *
    141    *  @param  Tp  The type to write to the ostream.
    142    *  @param  CharT  The ostream char_type.
    143    *  @param  Traits  The ostream char_traits.
    144   */
    145   template<typename _Tp, typename _CharT = char,
    146            typename _Traits = char_traits<_CharT> >
    147     class ostream_iterator
    148     : public iterator<output_iterator_tag, void, void, void, void>
    149     {
    150     public:
    151       //@{
    152       /// Public typedef
    153       typedef _CharT                         char_type;
    154       typedef _Traits                        traits_type;
    155       typedef basic_ostream<_CharT, _Traits> ostream_type;
    156       //@}
    157 
    158     private:
    159       ostream_type*	_M_stream;
    160       const _CharT*	_M_string;
    161 
    162     public:
    163       /// Construct from an ostream.
    164       ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
    165 
    166       /**
    167        *  Construct from an ostream.
    168        *
    169        *  The delimiter string @a c is written to the stream after every Tp
    170        *  written to the stream.  The delimiter is not copied, and thus must
    171        *  not be destroyed while this iterator is in use.
    172        *
    173        *  @param  s  Underlying ostream to write to.
    174        *  @param  c  CharT delimiter string to insert.
    175       */
    176       ostream_iterator(ostream_type& __s, const _CharT* __c)
    177       : _M_stream(&__s), _M_string(__c)  { }
    178 
    179       /// Copy constructor.
    180       ostream_iterator(const ostream_iterator& __obj)
    181       : _M_stream(__obj._M_stream), _M_string(__obj._M_string)  { }
    182 
    183       /// Writes @a value to underlying ostream using operator<<.  If
    184       /// constructed with delimiter string, writes delimiter to ostream.
    185       ostream_iterator&
    186       operator=(const _Tp& __value)
    187       {
    188 	__glibcxx_requires_cond(_M_stream != 0,
    189 				_M_message(__gnu_debug::__msg_output_ostream)
    190 				._M_iterator(*this));
    191 	*_M_stream << __value;
    192 	if (_M_string) *_M_stream << _M_string;
    193 	return *this;
    194       }
    195 
    196       ostream_iterator&
    197       operator*()
    198       { return *this; }
    199 
    200       ostream_iterator&
    201       operator++()
    202       { return *this; }
    203 
    204       ostream_iterator&
    205       operator++(int)
    206       { return *this; }
    207     };
    208 
    209 _GLIBCXX_END_NAMESPACE
    210 
    211 #endif
    212