1 // Stream iterators 2 3 // Copyright (C) 2001-2014 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 * @tparam _Tp The type to write to the ostream. 149 * @tparam _CharT The ostream char_type. 150 * @tparam _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