1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H 11 #define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H 12 13 #include <__config> 14 #include <__fwd/istream.h> 15 #include <__fwd/streambuf.h> 16 #include <__iterator/default_sentinel.h> 17 #include <__iterator/iterator.h> 18 #include <__iterator/iterator_traits.h> 19 20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21 # pragma GCC system_header 22 #endif 23 24 _LIBCPP_BEGIN_NAMESPACE_STD 25 26 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 27 template <class _CharT, class _Traits> 28 class _LIBCPP_TEMPLATE_VIS istreambuf_iterator 29 #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) 30 : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, _CharT*, _CharT> 31 #endif 32 { 33 _LIBCPP_SUPPRESS_DEPRECATED_POP 34 35 public: 36 typedef input_iterator_tag iterator_category; 37 typedef _CharT value_type; 38 typedef typename _Traits::off_type difference_type; 39 typedef _CharT* pointer; 40 typedef _CharT reference; 41 typedef _CharT char_type; 42 typedef _Traits traits_type; 43 typedef typename _Traits::int_type int_type; 44 typedef basic_streambuf<_CharT, _Traits> streambuf_type; 45 typedef basic_istream<_CharT, _Traits> istream_type; 46 47 private: 48 mutable streambuf_type* __sbuf_; 49 50 class __proxy { 51 char_type __keep_; 52 streambuf_type* __sbuf_; 53 _LIBCPP_HIDE_FROM_ABI explicit __proxy(char_type __c, streambuf_type* __s) : __keep_(__c), __sbuf_(__s) {} 54 friend class istreambuf_iterator; 55 56 public: 57 _LIBCPP_HIDE_FROM_ABI char_type operator*() const { return __keep_; } 58 }; 59 60 _LIBCPP_HIDE_FROM_ABI bool __test_for_eof() const { 61 if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) 62 __sbuf_ = nullptr; 63 return __sbuf_ == nullptr; 64 } 65 66 public: 67 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} 68 #if _LIBCPP_STD_VER >= 20 69 _LIBCPP_HIDE_FROM_ABI constexpr istreambuf_iterator(default_sentinel_t) noexcept : istreambuf_iterator() {} 70 #endif // _LIBCPP_STD_VER >= 20 71 _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(istream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {} 72 _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(streambuf_type* __s) _NOEXCEPT : __sbuf_(__s) {} 73 _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(const __proxy& __p) _NOEXCEPT : __sbuf_(__p.__sbuf_) {} 74 75 _LIBCPP_HIDE_FROM_ABI char_type operator*() const { return static_cast<char_type>(__sbuf_->sgetc()); } 76 _LIBCPP_HIDE_FROM_ABI istreambuf_iterator& operator++() { 77 __sbuf_->sbumpc(); 78 return *this; 79 } 80 _LIBCPP_HIDE_FROM_ABI __proxy operator++(int) { return __proxy(__sbuf_->sbumpc(), __sbuf_); } 81 82 _LIBCPP_HIDE_FROM_ABI bool equal(const istreambuf_iterator& __b) const { 83 return __test_for_eof() == __b.__test_for_eof(); 84 } 85 86 #if _LIBCPP_STD_VER >= 20 87 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { 88 return __i.__test_for_eof(); 89 } 90 #endif // _LIBCPP_STD_VER >= 20 91 }; 92 93 template <class _CharT, class _Traits> 94 inline _LIBCPP_HIDE_FROM_ABI bool 95 operator==(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { 96 return __a.equal(__b); 97 } 98 99 #if _LIBCPP_STD_VER <= 17 100 template <class _CharT, class _Traits> 101 inline _LIBCPP_HIDE_FROM_ABI bool 102 operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { 103 return !__a.equal(__b); 104 } 105 #endif // _LIBCPP_STD_VER <= 17 106 107 _LIBCPP_END_NAMESPACE_STD 108 109 #endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H 110