VCCC  2024.05
VisualCamp Common C++ library
basic_istream_view.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2/3/24.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_BASIC_ISTREAM_VIEW_HPP
6 #define VCCC_RANGES_VIEWS_BASIC_ISTREAM_VIEW_HPP
7 
8 #include <cstddef>
9 #include <istream>
10 #include <string>
11 #include <type_traits>
12 
20 
21 namespace vccc {
22 namespace ranges {
23 namespace detail {
24 
25 template<typename Val, typename CharT, typename Traits, typename = void>
26 struct stream_extractable : std::false_type {};
27 
28 template<typename Val, typename CharT, typename Traits>
29 struct stream_extractable<Val, CharT, Traits,
30  void_t<decltype( std::declval<std::basic_istream<CharT, Traits>&>() >> std::declval<Val&>() )>>
31  : std::true_type {};
32 
33 } //namespace detail
34 
37 
38 template<typename Val, typename CharT, typename Traits = std::char_traits<CharT>>
39 class basic_istream_view : public view_interface<basic_istream_view<Val, CharT, Traits>> {
40  public:
41  static_assert(movable<Val>::value, "Constraints not satisfied");
42  static_assert(default_initializable<Val>::value, "Constraints not satisfied");
43  static_assert(detail::stream_extractable<Val, CharT, Traits>::value, "Constraints not satisfied");
44 
45  struct iterator {
47  using difference_type = std::ptrdiff_t;
48  using value_type = Val;
49 #if __cplusplus < 202002L
51  using pointer = void;
52  using reference = Val&;
53 #endif
54 
55  constexpr explicit iterator(basic_istream_view& parent)
56  : parent_(vccc::addressof(parent)) {}
57  iterator(const iterator&) = delete;
58  iterator(iterator&& other) noexcept
59  : parent_(other.parent_) {
60  other.parent_ = nullptr;
61  }
62 
63  iterator& operator=(const iterator&) = delete;
64  iterator& operator=(iterator&& other) noexcept {
65  if (this != vccc::addressof(other)) {
66  parent_ = other.parent_;
67  other.parent_ = nullptr;
68  }
69  return *this;
70  }
71 
73  parent_->read();
74  return *this;
75  }
76 
77  void operator++(int) {
78  parent_->read();
79  }
80 
81  Val& operator*() const {
82  return parent_->value_;
83  }
84 
85  friend bool operator==(const iterator& x, default_sentinel_t) {
86  return x.parent_ == nullptr || x.fail();
87  }
88 
89  friend bool operator!=(const iterator& x, default_sentinel_t) {
90  return !(x == default_sentinel);
91  }
92 
93  friend bool operator==(default_sentinel_t, const iterator& x) {
94  return x == default_sentinel;
95  }
96 
97  friend bool operator!=(default_sentinel_t, const iterator& x) {
98  return !(x == default_sentinel);
99  }
100 
101  private:
102  bool fail() const {
103  return parent_->stream_->fail();
104  }
105 
106  basic_istream_view* parent_;
107  };
108  friend struct iterator;
109 
110 
111  VCCC_ADDRESSOF_CONSTEXPR explicit basic_istream_view(std::basic_istream<CharT, Traits>& stream)
112  : stream_(std::addressof(stream)), value_() {}
113 
114  constexpr auto begin() {
115  read();
116  return iterator{*this};
117  }
118 
119  constexpr default_sentinel_t end() const noexcept {
120  return default_sentinel;
121  }
122 
123  private:
124  void read() {
125  *stream_ >> value_;
126  }
127 
128  std::basic_istream<CharT, Traits>* stream_;
129  Val value_;
130 };
131 
132 template<typename Val> using istream_view = basic_istream_view<Val, char>;
133 template<typename Val> using wistream_view = basic_istream_view<Val, wchar_t>;
134 
136 
137 } // namespace ranges
138 } // namespace vccc
139 
140 #endif // VCCC_RANGES_VIEWS_BASIC_ISTREAM_VIEW_HPP
#define VCCC_ADDRESSOF_CONSTEXPR
Definition: addressof.hpp:14
Definition: basic_istream_view.hpp:39
constexpr default_sentinel_t end() const noexcept
Definition: basic_istream_view.hpp:119
constexpr auto begin()
Definition: basic_istream_view.hpp:114
VCCC_ADDRESSOF_CONSTEXPR basic_istream_view(std::basic_istream< CharT, Traits > &stream)
Definition: basic_istream_view.hpp:111
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr VCCC_INLINE_OR_STATIC default_sentinel_t default_sentinel
Definition: default_sentinel_t.hpp:25
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
void void_t
Definition: void_t.hpp:19
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
specifies that an object of a type can be default constructed
Definition: default_initializable.hpp:62
Definition: default_sentinel_t.hpp:23
Definition: iterator_tag.hpp:28
specifies that an object of a type can be moved and swapped
Definition: movable.hpp:58
Definition: basic_istream_view.hpp:45
void pointer
Definition: basic_istream_view.hpp:51
iterator(iterator &&other) noexcept
Definition: basic_istream_view.hpp:58
void operator++(int)
Definition: basic_istream_view.hpp:77
input_iterator_tag iterator_concept
Definition: basic_istream_view.hpp:46
friend bool operator==(const iterator &x, default_sentinel_t)
Definition: basic_istream_view.hpp:85
iterator & operator=(const iterator &)=delete
friend bool operator==(default_sentinel_t, const iterator &x)
Definition: basic_istream_view.hpp:93
friend bool operator!=(const iterator &x, default_sentinel_t)
Definition: basic_istream_view.hpp:89
iterator & operator=(iterator &&other) noexcept
Definition: basic_istream_view.hpp:64
Val value_type
Definition: basic_istream_view.hpp:48
Val & reference
Definition: basic_istream_view.hpp:52
friend bool operator!=(default_sentinel_t, const iterator &x)
Definition: basic_istream_view.hpp:97
std::ptrdiff_t difference_type
Definition: basic_istream_view.hpp:47
constexpr iterator(basic_istream_view &parent)
Definition: basic_istream_view.hpp:55
Val & operator*() const
Definition: basic_istream_view.hpp:81
iterator & operator++()
Definition: basic_istream_view.hpp:72