xref: /freebsd-src/contrib/llvm-project/libcxx/include/__ranges/istream_view.h (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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