stream_iterator.h revision 1.1.1.12
1// Stream iterators 2 3// Copyright (C) 2001-2022 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 37namespace std _GLIBCXX_VISIBILITY(default) 38{ 39_GLIBCXX_BEGIN_NAMESPACE_VERSION 40 41 /** 42 * @addtogroup iterators 43 * @{ 44 */ 45 46// Ignore warnings about std::iterator. 47#pragma GCC diagnostic push 48#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 49 50 /// Provides input iterator semantics for streams. 51 template<typename _Tp, typename _CharT = char, 52 typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t> 53 class istream_iterator 54 : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&> 55 { 56 public: 57 typedef _CharT char_type; 58 typedef _Traits traits_type; 59 typedef basic_istream<_CharT, _Traits> istream_type; 60 61 private: 62 istream_type* _M_stream; 63 _Tp _M_value; 64 // This bool becomes false at end-of-stream. It should be sufficient to 65 // check _M_stream != nullptr instead, but historically we did not set 66 // _M_stream to null when reaching the end, so we need to keep this flag. 67 bool _M_ok; 68 69 public: 70 /// Construct end of input stream iterator. 71 _GLIBCXX_CONSTEXPR istream_iterator() 72 _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Tp>::value) 73 : _M_stream(0), _M_value(), _M_ok(false) {} 74 75 /// Construct start of input stream iterator. 76 istream_iterator(istream_type& __s) 77 : _M_stream(std::__addressof(__s)), _M_ok(true) 78 { _M_read(); } 79 80 istream_iterator(const istream_iterator& __obj) 81 _GLIBCXX_NOEXCEPT_IF(is_nothrow_copy_constructible<_Tp>::value) 82 : _M_stream(__obj._M_stream), _M_value(__obj._M_value), 83 _M_ok(__obj._M_ok) 84 { } 85 86#if __cplusplus > 201703L && __cpp_lib_concepts 87 constexpr 88 istream_iterator(default_sentinel_t) 89 noexcept(is_nothrow_default_constructible_v<_Tp>) 90 : istream_iterator() { } 91#endif 92 93#if __cplusplus >= 201103L 94 istream_iterator& operator=(const istream_iterator&) = default; 95 ~istream_iterator() = default; 96#endif 97 98 _GLIBCXX_NODISCARD 99 const _Tp& 100 operator*() const _GLIBCXX_NOEXCEPT 101 { 102 __glibcxx_requires_cond(_M_ok, 103 _M_message(__gnu_debug::__msg_deref_istream) 104 ._M_iterator(*this)); 105 return _M_value; 106 } 107 108 _GLIBCXX_NODISCARD 109 const _Tp* 110 operator->() const _GLIBCXX_NOEXCEPT 111 { return std::__addressof((operator*())); } 112 113 istream_iterator& 114 operator++() 115 { 116 __glibcxx_requires_cond(_M_ok, 117 _M_message(__gnu_debug::__msg_inc_istream) 118 ._M_iterator(*this)); 119 _M_read(); 120 return *this; 121 } 122 123 istream_iterator 124 operator++(int) 125 { 126 __glibcxx_requires_cond(_M_ok, 127 _M_message(__gnu_debug::__msg_inc_istream) 128 ._M_iterator(*this)); 129 istream_iterator __tmp = *this; 130 _M_read(); 131 return __tmp; 132 } 133 134 private: 135 bool 136 _M_equal(const istream_iterator& __x) const _GLIBCXX_NOEXCEPT 137 { 138 // Ideally this would just return _M_stream == __x._M_stream, 139 // but code compiled with old versions never sets _M_stream to null. 140 return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); 141 } 142 143 void 144 _M_read() 145 { 146 if (_M_stream && !(*_M_stream >> _M_value)) 147 { 148 _M_stream = 0; 149 _M_ok = false; 150 } 151 } 152 153 /// Return true if the iterators refer to the same stream, 154 /// or are both at end-of-stream. 155 _GLIBCXX_NODISCARD 156 friend bool 157 operator==(const istream_iterator& __x, const istream_iterator& __y) 158 _GLIBCXX_NOEXCEPT 159 { return __x._M_equal(__y); } 160 161#if __cpp_impl_three_way_comparison < 201907L 162 /// Return true if the iterators refer to different streams, 163 /// or if one is at end-of-stream and the other is not. 164 _GLIBCXX_NODISCARD 165 friend bool 166 operator!=(const istream_iterator& __x, const istream_iterator& __y) 167 _GLIBCXX_NOEXCEPT 168 { return !__x._M_equal(__y); } 169#endif 170 171#if __cplusplus > 201703L && __cpp_lib_concepts 172 [[nodiscard]] 173 friend bool 174 operator==(const istream_iterator& __i, default_sentinel_t) noexcept 175 { return !__i._M_stream; } 176#endif 177 }; 178 179 /** 180 * @brief Provides output iterator semantics for streams. 181 * 182 * This class provides an iterator to write to an ostream. The type Tp is 183 * the only type written by this iterator and there must be an 184 * operator<<(Tp) defined. 185 * 186 * @tparam _Tp The type to write to the ostream. 187 * @tparam _CharT The ostream char_type. 188 * @tparam _Traits The ostream char_traits. 189 */ 190 template<typename _Tp, typename _CharT = char, 191 typename _Traits = char_traits<_CharT> > 192 class ostream_iterator 193 : public iterator<output_iterator_tag, void, void, void, void> 194 { 195 public: 196 ///@{ 197 /// Public typedef 198#if __cplusplus > 201703L 199 using difference_type = ptrdiff_t; 200#endif 201 typedef _CharT char_type; 202 typedef _Traits traits_type; 203 typedef basic_ostream<_CharT, _Traits> ostream_type; 204 ///@} 205 206 private: 207 ostream_type* _M_stream; 208 const _CharT* _M_string; 209 210 public: 211 /// Construct from an ostream. 212 ostream_iterator(ostream_type& __s) _GLIBCXX_NOEXCEPT 213 : _M_stream(std::__addressof(__s)), _M_string(0) {} 214 215 /** 216 * Construct from an ostream. 217 * 218 * The delimiter string @a c is written to the stream after every Tp 219 * written to the stream. The delimiter is not copied, and thus must 220 * not be destroyed while this iterator is in use. 221 * 222 * @param __s Underlying ostream to write to. 223 * @param __c CharT delimiter string to insert. 224 */ 225 ostream_iterator(ostream_type& __s, const _CharT* __c) _GLIBCXX_NOEXCEPT 226 : _M_stream(std::__addressof(__s)), _M_string(__c) { } 227 228 /// Copy constructor. 229 ostream_iterator(const ostream_iterator& __obj) _GLIBCXX_NOEXCEPT 230 : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } 231 232#if __cplusplus >= 201103L 233 ostream_iterator& operator=(const ostream_iterator&) = default; 234#endif 235 236 /// Writes @a value to underlying ostream using operator<<. If 237 /// constructed with delimiter string, writes delimiter to ostream. 238 ostream_iterator& 239 operator=(const _Tp& __value) 240 { 241 __glibcxx_requires_cond(_M_stream != 0, 242 _M_message(__gnu_debug::__msg_output_ostream) 243 ._M_iterator(*this)); 244 *_M_stream << __value; 245 if (_M_string) 246 *_M_stream << _M_string; 247 return *this; 248 } 249 250 _GLIBCXX_NODISCARD 251 ostream_iterator& 252 operator*() _GLIBCXX_NOEXCEPT 253 { return *this; } 254 255 ostream_iterator& 256 operator++() _GLIBCXX_NOEXCEPT 257 { return *this; } 258 259 ostream_iterator& 260 operator++(int) _GLIBCXX_NOEXCEPT 261 { return *this; } 262 }; 263#pragma GCC diagnostic pop 264 265 /// @} group iterators 266 267_GLIBCXX_END_NAMESPACE_VERSION 268} // namespace 269 270#endif 271