1*38fd1498Szrj // Stream iterators
2*38fd1498Szrj
3*38fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj
25*38fd1498Szrj /** @file bits/stream_iterator.h
26*38fd1498Szrj * This is an internal header file, included by other library headers.
27*38fd1498Szrj * Do not attempt to use it directly. @headername{iterator}
28*38fd1498Szrj */
29*38fd1498Szrj
30*38fd1498Szrj #ifndef _STREAM_ITERATOR_H
31*38fd1498Szrj #define _STREAM_ITERATOR_H 1
32*38fd1498Szrj
33*38fd1498Szrj #pragma GCC system_header
34*38fd1498Szrj
35*38fd1498Szrj #include <debug/debug.h>
36*38fd1498Szrj
_GLIBCXX_VISIBILITY(default)37*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
38*38fd1498Szrj {
39*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
40*38fd1498Szrj
41*38fd1498Szrj /**
42*38fd1498Szrj * @addtogroup iterators
43*38fd1498Szrj * @{
44*38fd1498Szrj */
45*38fd1498Szrj
46*38fd1498Szrj /// Provides input iterator semantics for streams.
47*38fd1498Szrj template<typename _Tp, typename _CharT = char,
48*38fd1498Szrj typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
49*38fd1498Szrj class istream_iterator
50*38fd1498Szrj : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
51*38fd1498Szrj {
52*38fd1498Szrj public:
53*38fd1498Szrj typedef _CharT char_type;
54*38fd1498Szrj typedef _Traits traits_type;
55*38fd1498Szrj typedef basic_istream<_CharT, _Traits> istream_type;
56*38fd1498Szrj
57*38fd1498Szrj private:
58*38fd1498Szrj istream_type* _M_stream;
59*38fd1498Szrj _Tp _M_value;
60*38fd1498Szrj bool _M_ok;
61*38fd1498Szrj
62*38fd1498Szrj public:
63*38fd1498Szrj /// Construct end of input stream iterator.
64*38fd1498Szrj _GLIBCXX_CONSTEXPR istream_iterator()
65*38fd1498Szrj : _M_stream(0), _M_value(), _M_ok(false) {}
66*38fd1498Szrj
67*38fd1498Szrj /// Construct start of input stream iterator.
68*38fd1498Szrj istream_iterator(istream_type& __s)
69*38fd1498Szrj : _M_stream(std::__addressof(__s))
70*38fd1498Szrj { _M_read(); }
71*38fd1498Szrj
72*38fd1498Szrj istream_iterator(const istream_iterator& __obj)
73*38fd1498Szrj : _M_stream(__obj._M_stream), _M_value(__obj._M_value),
74*38fd1498Szrj _M_ok(__obj._M_ok)
75*38fd1498Szrj { }
76*38fd1498Szrj
77*38fd1498Szrj const _Tp&
78*38fd1498Szrj operator*() const
79*38fd1498Szrj {
80*38fd1498Szrj __glibcxx_requires_cond(_M_ok,
81*38fd1498Szrj _M_message(__gnu_debug::__msg_deref_istream)
82*38fd1498Szrj ._M_iterator(*this));
83*38fd1498Szrj return _M_value;
84*38fd1498Szrj }
85*38fd1498Szrj
86*38fd1498Szrj const _Tp*
87*38fd1498Szrj operator->() const { return std::__addressof((operator*())); }
88*38fd1498Szrj
89*38fd1498Szrj istream_iterator&
90*38fd1498Szrj operator++()
91*38fd1498Szrj {
92*38fd1498Szrj __glibcxx_requires_cond(_M_ok,
93*38fd1498Szrj _M_message(__gnu_debug::__msg_inc_istream)
94*38fd1498Szrj ._M_iterator(*this));
95*38fd1498Szrj _M_read();
96*38fd1498Szrj return *this;
97*38fd1498Szrj }
98*38fd1498Szrj
99*38fd1498Szrj istream_iterator
100*38fd1498Szrj operator++(int)
101*38fd1498Szrj {
102*38fd1498Szrj __glibcxx_requires_cond(_M_ok,
103*38fd1498Szrj _M_message(__gnu_debug::__msg_inc_istream)
104*38fd1498Szrj ._M_iterator(*this));
105*38fd1498Szrj istream_iterator __tmp = *this;
106*38fd1498Szrj _M_read();
107*38fd1498Szrj return __tmp;
108*38fd1498Szrj }
109*38fd1498Szrj
110*38fd1498Szrj bool
111*38fd1498Szrj _M_equal(const istream_iterator& __x) const
112*38fd1498Szrj { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); }
113*38fd1498Szrj
114*38fd1498Szrj private:
115*38fd1498Szrj void
116*38fd1498Szrj _M_read()
117*38fd1498Szrj {
118*38fd1498Szrj _M_ok = (_M_stream && *_M_stream) ? true : false;
119*38fd1498Szrj if (_M_ok)
120*38fd1498Szrj {
121*38fd1498Szrj *_M_stream >> _M_value;
122*38fd1498Szrj _M_ok = *_M_stream ? true : false;
123*38fd1498Szrj }
124*38fd1498Szrj }
125*38fd1498Szrj };
126*38fd1498Szrj
127*38fd1498Szrj /// Return true if x and y are both end or not end, or x and y are the same.
128*38fd1498Szrj template<typename _Tp, typename _CharT, typename _Traits, typename _Dist>
129*38fd1498Szrj inline bool
130*38fd1498Szrj operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
131*38fd1498Szrj const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
132*38fd1498Szrj { return __x._M_equal(__y); }
133*38fd1498Szrj
134*38fd1498Szrj /// Return false if x and y are both end or not end, or x and y are the same.
135*38fd1498Szrj template <class _Tp, class _CharT, class _Traits, class _Dist>
136*38fd1498Szrj inline bool
137*38fd1498Szrj operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
138*38fd1498Szrj const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
139*38fd1498Szrj { return !__x._M_equal(__y); }
140*38fd1498Szrj
141*38fd1498Szrj /**
142*38fd1498Szrj * @brief Provides output iterator semantics for streams.
143*38fd1498Szrj *
144*38fd1498Szrj * This class provides an iterator to write to an ostream. The type Tp is
145*38fd1498Szrj * the only type written by this iterator and there must be an
146*38fd1498Szrj * operator<<(Tp) defined.
147*38fd1498Szrj *
148*38fd1498Szrj * @tparam _Tp The type to write to the ostream.
149*38fd1498Szrj * @tparam _CharT The ostream char_type.
150*38fd1498Szrj * @tparam _Traits The ostream char_traits.
151*38fd1498Szrj */
152*38fd1498Szrj template<typename _Tp, typename _CharT = char,
153*38fd1498Szrj typename _Traits = char_traits<_CharT> >
154*38fd1498Szrj class ostream_iterator
155*38fd1498Szrj : public iterator<output_iterator_tag, void, void, void, void>
156*38fd1498Szrj {
157*38fd1498Szrj public:
158*38fd1498Szrj //@{
159*38fd1498Szrj /// Public typedef
160*38fd1498Szrj typedef _CharT char_type;
161*38fd1498Szrj typedef _Traits traits_type;
162*38fd1498Szrj typedef basic_ostream<_CharT, _Traits> ostream_type;
163*38fd1498Szrj //@}
164*38fd1498Szrj
165*38fd1498Szrj private:
166*38fd1498Szrj ostream_type* _M_stream;
167*38fd1498Szrj const _CharT* _M_string;
168*38fd1498Szrj
169*38fd1498Szrj public:
170*38fd1498Szrj /// Construct from an ostream.
171*38fd1498Szrj ostream_iterator(ostream_type& __s)
172*38fd1498Szrj : _M_stream(std::__addressof(__s)), _M_string(0) {}
173*38fd1498Szrj
174*38fd1498Szrj /**
175*38fd1498Szrj * Construct from an ostream.
176*38fd1498Szrj *
177*38fd1498Szrj * The delimiter string @a c is written to the stream after every Tp
178*38fd1498Szrj * written to the stream. The delimiter is not copied, and thus must
179*38fd1498Szrj * not be destroyed while this iterator is in use.
180*38fd1498Szrj *
181*38fd1498Szrj * @param __s Underlying ostream to write to.
182*38fd1498Szrj * @param __c CharT delimiter string to insert.
183*38fd1498Szrj */
184*38fd1498Szrj ostream_iterator(ostream_type& __s, const _CharT* __c)
185*38fd1498Szrj : _M_stream(&__s), _M_string(__c) { }
186*38fd1498Szrj
187*38fd1498Szrj /// Copy constructor.
188*38fd1498Szrj ostream_iterator(const ostream_iterator& __obj)
189*38fd1498Szrj : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { }
190*38fd1498Szrj
191*38fd1498Szrj /// Writes @a value to underlying ostream using operator<<. If
192*38fd1498Szrj /// constructed with delimiter string, writes delimiter to ostream.
193*38fd1498Szrj ostream_iterator&
194*38fd1498Szrj operator=(const _Tp& __value)
195*38fd1498Szrj {
196*38fd1498Szrj __glibcxx_requires_cond(_M_stream != 0,
197*38fd1498Szrj _M_message(__gnu_debug::__msg_output_ostream)
198*38fd1498Szrj ._M_iterator(*this));
199*38fd1498Szrj *_M_stream << __value;
200*38fd1498Szrj if (_M_string) *_M_stream << _M_string;
201*38fd1498Szrj return *this;
202*38fd1498Szrj }
203*38fd1498Szrj
204*38fd1498Szrj ostream_iterator&
205*38fd1498Szrj operator*()
206*38fd1498Szrj { return *this; }
207*38fd1498Szrj
208*38fd1498Szrj ostream_iterator&
209*38fd1498Szrj operator++()
210*38fd1498Szrj { return *this; }
211*38fd1498Szrj
212*38fd1498Szrj ostream_iterator&
213*38fd1498Szrj operator++(int)
214*38fd1498Szrj { return *this; }
215*38fd1498Szrj };
216*38fd1498Szrj
217*38fd1498Szrj // @} group iterators
218*38fd1498Szrj
219*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
220*38fd1498Szrj } // namespace
221*38fd1498Szrj
222*38fd1498Szrj #endif
223