1bdd1243dSDimitry Andric // -*- C++ -*-
2bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
3bdd1243dSDimitry Andric //
4bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7bdd1243dSDimitry Andric //
8bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
9bdd1243dSDimitry Andric
10bdd1243dSDimitry Andric #ifndef _LIBCPP___RANGES_ISTREAM_VIEW_H
11bdd1243dSDimitry Andric #define _LIBCPP___RANGES_ISTREAM_VIEW_H
12bdd1243dSDimitry Andric
13bdd1243dSDimitry Andric #include <__concepts/constructible.h>
14bdd1243dSDimitry Andric #include <__concepts/derived_from.h>
15bdd1243dSDimitry Andric #include <__concepts/movable.h>
16bdd1243dSDimitry Andric #include <__config>
175f757f3fSDimitry Andric #include <__fwd/istream.h>
185f757f3fSDimitry Andric #include <__fwd/string.h>
19bdd1243dSDimitry Andric #include <__iterator/default_sentinel.h>
20bdd1243dSDimitry Andric #include <__iterator/iterator_traits.h>
21bdd1243dSDimitry Andric #include <__memory/addressof.h>
22bdd1243dSDimitry Andric #include <__ranges/view_interface.h>
23bdd1243dSDimitry Andric #include <__type_traits/remove_cvref.h>
24bdd1243dSDimitry Andric #include <__utility/forward.h>
25bdd1243dSDimitry Andric #include <cstddef>
26bdd1243dSDimitry Andric
27bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
28bdd1243dSDimitry Andric # pragma GCC system_header
29bdd1243dSDimitry Andric #endif
30bdd1243dSDimitry Andric
31bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 20
32bdd1243dSDimitry Andric
33bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
34bdd1243dSDimitry Andric
35bdd1243dSDimitry Andric namespace ranges {
36bdd1243dSDimitry Andric
37bdd1243dSDimitry Andric template <class _Val, class _CharT, class _Traits>
requires(basic_istream<_CharT,_Traits> & __is,_Val & __t)38bdd1243dSDimitry Andric concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _Val& __t) { __is >> __t; };
39bdd1243dSDimitry Andric
40bdd1243dSDimitry Andric template <movable _Val, class _CharT, class _Traits = char_traits<_CharT>>
41bdd1243dSDimitry Andric requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
42bdd1243dSDimitry Andric class basic_istream_view : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> {
431ac55f4cSDimitry Andric class __iterator;
44bdd1243dSDimitry Andric
45bdd1243dSDimitry Andric public:
basic_istream_view(basic_istream<_CharT,_Traits> & __stream)46bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
47bdd1243dSDimitry Andric : __stream_(std::addressof(__stream)) {}
48bdd1243dSDimitry Andric
begin()49bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
50bdd1243dSDimitry Andric *__stream_ >> __value_;
51bdd1243dSDimitry Andric return __iterator{*this};
52bdd1243dSDimitry Andric }
53bdd1243dSDimitry Andric
end()54bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return default_sentinel; }
55bdd1243dSDimitry Andric
56bdd1243dSDimitry Andric private:
57bdd1243dSDimitry Andric basic_istream<_CharT, _Traits>* __stream_;
58bdd1243dSDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS _Val __value_ = _Val();
59bdd1243dSDimitry Andric };
60bdd1243dSDimitry Andric
61bdd1243dSDimitry Andric template <movable _Val, class _CharT, class _Traits>
62bdd1243dSDimitry Andric requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
631ac55f4cSDimitry Andric class basic_istream_view<_Val, _CharT, _Traits>::__iterator {
64bdd1243dSDimitry Andric public:
65bdd1243dSDimitry Andric using iterator_concept = input_iterator_tag;
66bdd1243dSDimitry Andric using difference_type = ptrdiff_t;
67bdd1243dSDimitry Andric using value_type = _Val;
68bdd1243dSDimitry Andric
__iterator(basic_istream_view<_Val,_CharT,_Traits> & __parent)69*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
70bdd1243dSDimitry Andric : __parent_(std::addressof(__parent)) {}
71bdd1243dSDimitry Andric
721ac55f4cSDimitry Andric __iterator(const __iterator&) = delete;
731ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default;
74bdd1243dSDimitry Andric
751ac55f4cSDimitry Andric __iterator& operator=(const __iterator&) = delete;
761ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iterator& operator=(__iterator&&) = default;
77bdd1243dSDimitry Andric
781ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iterator& operator++() {
79bdd1243dSDimitry Andric *__parent_->__stream_ >> __parent_->__value_;
80bdd1243dSDimitry Andric return *this;
81bdd1243dSDimitry Andric }
82bdd1243dSDimitry Andric
83bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void operator++(int) { ++*this; }
84bdd1243dSDimitry Andric
85bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Val& operator*() const { return __parent_->__value_; }
86bdd1243dSDimitry Andric
871ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __x, default_sentinel_t) {
88bdd1243dSDimitry Andric return !*__x.__get_parent_stream();
89bdd1243dSDimitry Andric }
90bdd1243dSDimitry Andric
91bdd1243dSDimitry Andric private:
92bdd1243dSDimitry Andric basic_istream_view<_Val, _CharT, _Traits>* __parent_;
93bdd1243dSDimitry Andric
__get_parent_stream()94bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr basic_istream<_CharT, _Traits>* __get_parent_stream() const {
95bdd1243dSDimitry Andric return __parent_->__stream_;
96bdd1243dSDimitry Andric }
97bdd1243dSDimitry Andric };
98bdd1243dSDimitry Andric
99bdd1243dSDimitry Andric template <class _Val>
100bdd1243dSDimitry Andric using istream_view = basic_istream_view<_Val, char>;
101bdd1243dSDimitry Andric
102bdd1243dSDimitry Andric # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
103bdd1243dSDimitry Andric template <class _Val>
104bdd1243dSDimitry Andric using wistream_view = basic_istream_view<_Val, wchar_t>;
105bdd1243dSDimitry Andric # endif
106bdd1243dSDimitry Andric
107bdd1243dSDimitry Andric namespace views {
108bdd1243dSDimitry Andric namespace __istream {
109bdd1243dSDimitry Andric
110bdd1243dSDimitry Andric // clang-format off
111bdd1243dSDimitry Andric template <class _Tp>
112bdd1243dSDimitry Andric struct __fn {
113bdd1243dSDimitry Andric template <class _Up, class _UnCVRef = remove_cvref_t<_Up>>
114bdd1243dSDimitry Andric requires derived_from<_UnCVRef, basic_istream<typename _UnCVRef::char_type,
115bdd1243dSDimitry Andric typename _UnCVRef::traits_type>>
116bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Up&& __u) const
117bdd1243dSDimitry Andric noexcept(noexcept(basic_istream_view<_Tp, typename _UnCVRef::char_type,
118bdd1243dSDimitry Andric typename _UnCVRef::traits_type>(std::forward<_Up>(__u))))
119bdd1243dSDimitry Andric -> decltype( basic_istream_view<_Tp, typename _UnCVRef::char_type,
120bdd1243dSDimitry Andric typename _UnCVRef::traits_type>(std::forward<_Up>(__u)))
121bdd1243dSDimitry Andric { return basic_istream_view<_Tp, typename _UnCVRef::char_type,
122bdd1243dSDimitry Andric typename _UnCVRef::traits_type>(std::forward<_Up>(__u));
123bdd1243dSDimitry Andric }
124bdd1243dSDimitry Andric };
125bdd1243dSDimitry Andric // clang-format on
126bdd1243dSDimitry Andric
127bdd1243dSDimitry Andric } // namespace __istream
128bdd1243dSDimitry Andric
129bdd1243dSDimitry Andric inline namespace __cpo {
130bdd1243dSDimitry Andric template <class _Tp>
131bdd1243dSDimitry Andric inline constexpr auto istream = __istream::__fn<_Tp>{};
132bdd1243dSDimitry Andric } // namespace __cpo
133bdd1243dSDimitry Andric } // namespace views
134bdd1243dSDimitry Andric
135bdd1243dSDimitry Andric } // namespace ranges
136bdd1243dSDimitry Andric
137bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
138bdd1243dSDimitry Andric
139bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 20
140bdd1243dSDimitry Andric
141bdd1243dSDimitry Andric #endif // _LIBCPP___RANGES_ISTREAM_VIEW_H
142