xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/stream_iterator.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // Stream iterators
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2001-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /** @file bits/stream_iterator.h
261debfc3dSmrg  *  This is an internal header file, included by other library headers.
271debfc3dSmrg  *  Do not attempt to use it directly. @headername{iterator}
281debfc3dSmrg  */
291debfc3dSmrg 
301debfc3dSmrg #ifndef _STREAM_ITERATOR_H
311debfc3dSmrg #define _STREAM_ITERATOR_H 1
321debfc3dSmrg 
331debfc3dSmrg #pragma GCC system_header
341debfc3dSmrg 
351debfc3dSmrg #include <debug/debug.h>
361debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)371debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
381debfc3dSmrg {
391debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
401debfc3dSmrg 
411debfc3dSmrg   /**
421debfc3dSmrg    * @addtogroup iterators
431debfc3dSmrg    * @{
441debfc3dSmrg    */
451debfc3dSmrg 
461debfc3dSmrg   /// Provides input iterator semantics for streams.
471debfc3dSmrg   template<typename _Tp, typename _CharT = char,
481debfc3dSmrg            typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
491debfc3dSmrg     class istream_iterator
501debfc3dSmrg     : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
511debfc3dSmrg     {
521debfc3dSmrg     public:
531debfc3dSmrg       typedef _CharT                         char_type;
541debfc3dSmrg       typedef _Traits                        traits_type;
551debfc3dSmrg       typedef basic_istream<_CharT, _Traits> istream_type;
561debfc3dSmrg 
571debfc3dSmrg     private:
581debfc3dSmrg       istream_type*	_M_stream;
591debfc3dSmrg       _Tp		_M_value;
60*8feb0f0bSmrg       // This bool becomes false at end-of-stream. It should be sufficient to
61*8feb0f0bSmrg       // check _M_stream != nullptr instead, but historically we did not set
62*8feb0f0bSmrg       // _M_stream to null when reaching the end, so we need to keep this flag.
631debfc3dSmrg       bool		_M_ok;
641debfc3dSmrg 
651debfc3dSmrg     public:
661debfc3dSmrg       ///  Construct end of input stream iterator.
671debfc3dSmrg       _GLIBCXX_CONSTEXPR istream_iterator()
681debfc3dSmrg       : _M_stream(0), _M_value(), _M_ok(false) {}
691debfc3dSmrg 
701debfc3dSmrg       ///  Construct start of input stream iterator.
711debfc3dSmrg       istream_iterator(istream_type& __s)
72*8feb0f0bSmrg       : _M_stream(std::__addressof(__s)), _M_ok(true)
731debfc3dSmrg       { _M_read(); }
741debfc3dSmrg 
751debfc3dSmrg       istream_iterator(const istream_iterator& __obj)
761debfc3dSmrg       : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
771debfc3dSmrg         _M_ok(__obj._M_ok)
781debfc3dSmrg       { }
791debfc3dSmrg 
80*8feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
81*8feb0f0bSmrg       constexpr
82*8feb0f0bSmrg       istream_iterator(default_sentinel_t)
83*8feb0f0bSmrg       noexcept(is_nothrow_default_constructible_v<_Tp>)
84*8feb0f0bSmrg       : istream_iterator() { }
85*8feb0f0bSmrg #endif
86*8feb0f0bSmrg 
87c0a68be4Smrg #if __cplusplus >= 201103L
88c0a68be4Smrg       istream_iterator& operator=(const istream_iterator&) = default;
89*8feb0f0bSmrg       ~istream_iterator() = default;
90c0a68be4Smrg #endif
91c0a68be4Smrg 
921debfc3dSmrg       const _Tp&
931debfc3dSmrg       operator*() const
941debfc3dSmrg       {
951debfc3dSmrg 	__glibcxx_requires_cond(_M_ok,
961debfc3dSmrg 				_M_message(__gnu_debug::__msg_deref_istream)
971debfc3dSmrg 				._M_iterator(*this));
981debfc3dSmrg 	return _M_value;
991debfc3dSmrg       }
1001debfc3dSmrg 
1011debfc3dSmrg       const _Tp*
1021debfc3dSmrg       operator->() const { return std::__addressof((operator*())); }
1031debfc3dSmrg 
1041debfc3dSmrg       istream_iterator&
1051debfc3dSmrg       operator++()
1061debfc3dSmrg       {
1071debfc3dSmrg 	__glibcxx_requires_cond(_M_ok,
1081debfc3dSmrg 				_M_message(__gnu_debug::__msg_inc_istream)
1091debfc3dSmrg 				._M_iterator(*this));
1101debfc3dSmrg 	_M_read();
1111debfc3dSmrg 	return *this;
1121debfc3dSmrg       }
1131debfc3dSmrg 
1141debfc3dSmrg       istream_iterator
1151debfc3dSmrg       operator++(int)
1161debfc3dSmrg       {
1171debfc3dSmrg 	__glibcxx_requires_cond(_M_ok,
1181debfc3dSmrg 				_M_message(__gnu_debug::__msg_inc_istream)
1191debfc3dSmrg 				._M_iterator(*this));
1201debfc3dSmrg 	istream_iterator __tmp = *this;
1211debfc3dSmrg 	_M_read();
1221debfc3dSmrg 	return __tmp;
1231debfc3dSmrg       }
1241debfc3dSmrg 
125*8feb0f0bSmrg     private:
1261debfc3dSmrg       bool
1271debfc3dSmrg       _M_equal(const istream_iterator& __x) const
128*8feb0f0bSmrg       {
129*8feb0f0bSmrg 	// Ideally this would just return _M_stream == __x._M_stream,
130*8feb0f0bSmrg 	// but code compiled with old versions never sets _M_stream to null.
131*8feb0f0bSmrg 	return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream);
132*8feb0f0bSmrg       }
1331debfc3dSmrg 
1341debfc3dSmrg       void
1351debfc3dSmrg       _M_read()
1361debfc3dSmrg       {
137*8feb0f0bSmrg         if (_M_stream && !(*_M_stream >> _M_value))
1381debfc3dSmrg           {
139*8feb0f0bSmrg             _M_stream = 0;
140*8feb0f0bSmrg             _M_ok = false;
1411debfc3dSmrg           }
1421debfc3dSmrg       }
1431debfc3dSmrg 
144*8feb0f0bSmrg       /// Return true if the iterators refer to the same stream,
145*8feb0f0bSmrg       /// or are both at end-of-stream.
146*8feb0f0bSmrg       friend bool
147*8feb0f0bSmrg       operator==(const istream_iterator& __x, const istream_iterator& __y)
1481debfc3dSmrg       { return __x._M_equal(__y); }
1491debfc3dSmrg 
150*8feb0f0bSmrg       /// Return true if the iterators refer to different streams,
151*8feb0f0bSmrg       /// or if one is at end-of-stream and the other is not.
152*8feb0f0bSmrg       friend bool
153*8feb0f0bSmrg       operator!=(const istream_iterator& __x, const istream_iterator& __y)
1541debfc3dSmrg       { return !__x._M_equal(__y); }
1551debfc3dSmrg 
156*8feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
157*8feb0f0bSmrg       friend bool
158*8feb0f0bSmrg       operator==(const istream_iterator& __i, default_sentinel_t)
159*8feb0f0bSmrg       { return !__i._M_stream; }
160*8feb0f0bSmrg #endif
161*8feb0f0bSmrg     };
162*8feb0f0bSmrg 
1631debfc3dSmrg   /**
1641debfc3dSmrg    *  @brief  Provides output iterator semantics for streams.
1651debfc3dSmrg    *
1661debfc3dSmrg    *  This class provides an iterator to write to an ostream.  The type Tp is
1671debfc3dSmrg    *  the only type written by this iterator and there must be an
1681debfc3dSmrg    *  operator<<(Tp) defined.
1691debfc3dSmrg    *
1701debfc3dSmrg    *  @tparam  _Tp  The type to write to the ostream.
1711debfc3dSmrg    *  @tparam  _CharT  The ostream char_type.
1721debfc3dSmrg    *  @tparam  _Traits  The ostream char_traits.
1731debfc3dSmrg   */
1741debfc3dSmrg   template<typename _Tp, typename _CharT = char,
1751debfc3dSmrg            typename _Traits = char_traits<_CharT> >
1761debfc3dSmrg     class ostream_iterator
1771debfc3dSmrg     : public iterator<output_iterator_tag, void, void, void, void>
1781debfc3dSmrg     {
1791debfc3dSmrg     public:
180*8feb0f0bSmrg       ///@{
1811debfc3dSmrg       /// Public typedef
182*8feb0f0bSmrg #if __cplusplus > 201703L
183*8feb0f0bSmrg       using difference_type = ptrdiff_t;
184*8feb0f0bSmrg #endif
1851debfc3dSmrg       typedef _CharT                         char_type;
1861debfc3dSmrg       typedef _Traits                        traits_type;
1871debfc3dSmrg       typedef basic_ostream<_CharT, _Traits> ostream_type;
188*8feb0f0bSmrg       ///@}
1891debfc3dSmrg 
1901debfc3dSmrg     private:
1911debfc3dSmrg       ostream_type*	_M_stream;
1921debfc3dSmrg       const _CharT*	_M_string;
1931debfc3dSmrg 
1941debfc3dSmrg     public:
195*8feb0f0bSmrg #if __cplusplus > 201703L
196*8feb0f0bSmrg       constexpr ostream_iterator() noexcept
197*8feb0f0bSmrg       : _M_stream(nullptr), _M_string(nullptr) { }
198*8feb0f0bSmrg #endif
199*8feb0f0bSmrg 
2001debfc3dSmrg       /// Construct from an ostream.
2011debfc3dSmrg       ostream_iterator(ostream_type& __s)
2021debfc3dSmrg       : _M_stream(std::__addressof(__s)), _M_string(0) {}
2031debfc3dSmrg 
2041debfc3dSmrg       /**
2051debfc3dSmrg        *  Construct from an ostream.
2061debfc3dSmrg        *
2071debfc3dSmrg        *  The delimiter string @a c is written to the stream after every Tp
2081debfc3dSmrg        *  written to the stream.  The delimiter is not copied, and thus must
2091debfc3dSmrg        *  not be destroyed while this iterator is in use.
2101debfc3dSmrg        *
2111debfc3dSmrg        *  @param  __s  Underlying ostream to write to.
2121debfc3dSmrg        *  @param  __c  CharT delimiter string to insert.
2131debfc3dSmrg       */
2141debfc3dSmrg       ostream_iterator(ostream_type& __s, const _CharT* __c)
215*8feb0f0bSmrg       : _M_stream(std::__addressof(__s)), _M_string(__c)  { }
2161debfc3dSmrg 
2171debfc3dSmrg       /// Copy constructor.
2181debfc3dSmrg       ostream_iterator(const ostream_iterator& __obj)
2191debfc3dSmrg       : _M_stream(__obj._M_stream), _M_string(__obj._M_string)  { }
2201debfc3dSmrg 
221c0a68be4Smrg #if __cplusplus >= 201103L
222c0a68be4Smrg       ostream_iterator& operator=(const ostream_iterator&) = default;
223c0a68be4Smrg #endif
224c0a68be4Smrg 
2251debfc3dSmrg       /// Writes @a value to underlying ostream using operator<<.  If
2261debfc3dSmrg       /// constructed with delimiter string, writes delimiter to ostream.
2271debfc3dSmrg       ostream_iterator&
2281debfc3dSmrg       operator=(const _Tp& __value)
2291debfc3dSmrg       {
2301debfc3dSmrg 	__glibcxx_requires_cond(_M_stream != 0,
2311debfc3dSmrg 				_M_message(__gnu_debug::__msg_output_ostream)
2321debfc3dSmrg 				._M_iterator(*this));
2331debfc3dSmrg 	*_M_stream << __value;
234*8feb0f0bSmrg 	if (_M_string)
235*8feb0f0bSmrg           *_M_stream << _M_string;
2361debfc3dSmrg 	return *this;
2371debfc3dSmrg       }
2381debfc3dSmrg 
2391debfc3dSmrg       ostream_iterator&
2401debfc3dSmrg       operator*()
2411debfc3dSmrg       { return *this; }
2421debfc3dSmrg 
2431debfc3dSmrg       ostream_iterator&
2441debfc3dSmrg       operator++()
2451debfc3dSmrg       { return *this; }
2461debfc3dSmrg 
2471debfc3dSmrg       ostream_iterator&
2481debfc3dSmrg       operator++(int)
2491debfc3dSmrg       { return *this; }
2501debfc3dSmrg     };
2511debfc3dSmrg 
252*8feb0f0bSmrg   /// @} group iterators
2531debfc3dSmrg 
2541debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
2551debfc3dSmrg } // namespace
2561debfc3dSmrg 
2571debfc3dSmrg #endif
258