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