libstdc++
|
00001 // Stream iterators 00002 00003 // Copyright (C) 2001, 2004, 2005, 2009 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file stream_iterator.h 00026 * This is an internal header file, included by other library headers. 00027 * You should not attempt to use it directly. 00028 */ 00029 00030 #ifndef _STREAM_ITERATOR_H 00031 #define _STREAM_ITERATOR_H 1 00032 00033 #pragma GCC system_header 00034 00035 #include <debug/debug.h> 00036 00037 _GLIBCXX_BEGIN_NAMESPACE(std) 00038 00039 /// Provides input iterator semantics for streams. 00040 template<typename _Tp, typename _CharT = char, 00041 typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t> 00042 class istream_iterator 00043 : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&> 00044 { 00045 public: 00046 typedef _CharT char_type; 00047 typedef _Traits traits_type; 00048 typedef basic_istream<_CharT, _Traits> istream_type; 00049 00050 private: 00051 istream_type* _M_stream; 00052 _Tp _M_value; 00053 bool _M_ok; 00054 00055 public: 00056 /// Construct end of input stream iterator. 00057 istream_iterator() 00058 : _M_stream(0), _M_value(), _M_ok(false) {} 00059 00060 /// Construct start of input stream iterator. 00061 istream_iterator(istream_type& __s) 00062 : _M_stream(&__s) 00063 { _M_read(); } 00064 00065 istream_iterator(const istream_iterator& __obj) 00066 : _M_stream(__obj._M_stream), _M_value(__obj._M_value), 00067 _M_ok(__obj._M_ok) 00068 { } 00069 00070 const _Tp& 00071 operator*() const 00072 { 00073 __glibcxx_requires_cond(_M_ok, 00074 _M_message(__gnu_debug::__msg_deref_istream) 00075 ._M_iterator(*this)); 00076 return _M_value; 00077 } 00078 00079 const _Tp* 00080 operator->() const { return &(operator*()); } 00081 00082 istream_iterator& 00083 operator++() 00084 { 00085 __glibcxx_requires_cond(_M_ok, 00086 _M_message(__gnu_debug::__msg_inc_istream) 00087 ._M_iterator(*this)); 00088 _M_read(); 00089 return *this; 00090 } 00091 00092 istream_iterator 00093 operator++(int) 00094 { 00095 __glibcxx_requires_cond(_M_ok, 00096 _M_message(__gnu_debug::__msg_inc_istream) 00097 ._M_iterator(*this)); 00098 istream_iterator __tmp = *this; 00099 _M_read(); 00100 return __tmp; 00101 } 00102 00103 bool 00104 _M_equal(const istream_iterator& __x) const 00105 { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } 00106 00107 private: 00108 void 00109 _M_read() 00110 { 00111 _M_ok = (_M_stream && *_M_stream) ? true : false; 00112 if (_M_ok) 00113 { 00114 *_M_stream >> _M_value; 00115 _M_ok = *_M_stream ? true : false; 00116 } 00117 } 00118 }; 00119 00120 /// Return true if x and y are both end or not end, or x and y are the same. 00121 template<typename _Tp, typename _CharT, typename _Traits, typename _Dist> 00122 inline bool 00123 operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, 00124 const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) 00125 { return __x._M_equal(__y); } 00126 00127 /// Return false if x and y are both end or not end, or x and y are the same. 00128 template <class _Tp, class _CharT, class _Traits, class _Dist> 00129 inline bool 00130 operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, 00131 const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) 00132 { return !__x._M_equal(__y); } 00133 00134 /** 00135 * @brief Provides output iterator semantics for streams. 00136 * 00137 * This class provides an iterator to write to an ostream. The type Tp is 00138 * the only type written by this iterator and there must be an 00139 * operator<<(Tp) defined. 00140 * 00141 * @param Tp The type to write to the ostream. 00142 * @param CharT The ostream char_type. 00143 * @param Traits The ostream char_traits. 00144 */ 00145 template<typename _Tp, typename _CharT = char, 00146 typename _Traits = char_traits<_CharT> > 00147 class ostream_iterator 00148 : public iterator<output_iterator_tag, void, void, void, void> 00149 { 00150 public: 00151 //@{ 00152 /// Public typedef 00153 typedef _CharT char_type; 00154 typedef _Traits traits_type; 00155 typedef basic_ostream<_CharT, _Traits> ostream_type; 00156 //@} 00157 00158 private: 00159 ostream_type* _M_stream; 00160 const _CharT* _M_string; 00161 00162 public: 00163 /// Construct from an ostream. 00164 ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} 00165 00166 /** 00167 * Construct from an ostream. 00168 * 00169 * The delimiter string @a c is written to the stream after every Tp 00170 * written to the stream. The delimiter is not copied, and thus must 00171 * not be destroyed while this iterator is in use. 00172 * 00173 * @param s Underlying ostream to write to. 00174 * @param c CharT delimiter string to insert. 00175 */ 00176 ostream_iterator(ostream_type& __s, const _CharT* __c) 00177 : _M_stream(&__s), _M_string(__c) { } 00178 00179 /// Copy constructor. 00180 ostream_iterator(const ostream_iterator& __obj) 00181 : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } 00182 00183 /// Writes @a value to underlying ostream using operator<<. If 00184 /// constructed with delimiter string, writes delimiter to ostream. 00185 ostream_iterator& 00186 operator=(const _Tp& __value) 00187 { 00188 __glibcxx_requires_cond(_M_stream != 0, 00189 _M_message(__gnu_debug::__msg_output_ostream) 00190 ._M_iterator(*this)); 00191 *_M_stream << __value; 00192 if (_M_string) *_M_stream << _M_string; 00193 return *this; 00194 } 00195 00196 ostream_iterator& 00197 operator*() 00198 { return *this; } 00199 00200 ostream_iterator& 00201 operator++() 00202 { return *this; } 00203 00204 ostream_iterator& 00205 operator++(int) 00206 { return *this; } 00207 }; 00208 00209 _GLIBCXX_END_NAMESPACE 00210 00211 #endif