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