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