libstdc++: Add [range.istream]
This patch adds ranges::basic_istream_view and ranges::istream_view. This seems to be the last missing part of the ranges header. libstdc++-v3/ChangeLog: * include/std/ranges (ranges::__detail::__stream_extractable, ranges::basic_istream_view, ranges::istream_view): Define. * testsuite/std/ranges/istream_view: New test.
This commit is contained in:
parent
55d4cbcba8
commit
b7903d9f5b
@ -1,5 +1,9 @@
|
||||
2020-02-07 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
* include/std/ranges (ranges::__detail::__stream_extractable,
|
||||
ranges::basic_istream_view, ranges::istream_view): Define.
|
||||
* testsuite/std/ranges/istream_view: New test.
|
||||
|
||||
Implement C++20 range adaptors
|
||||
* include/std/ranges: Include <bits/refwrap.h> and <tuple>.
|
||||
(subrange::_S_store_size): Mark as const instead of constexpr to
|
||||
|
@ -951,6 +951,100 @@ namespace views
|
||||
inline constexpr _Iota iota{};
|
||||
} // namespace views
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
template<typename _Val, typename _CharT, typename _Traits>
|
||||
concept __stream_extractable
|
||||
= requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
|
||||
} // namespace __detail
|
||||
|
||||
template<movable _Val, typename _CharT, typename _Traits>
|
||||
requires default_initializable<_Val>
|
||||
&& __detail::__stream_extractable<_Val, _CharT, _Traits>
|
||||
class basic_istream_view
|
||||
: public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
|
||||
{
|
||||
public:
|
||||
basic_istream_view() = default;
|
||||
|
||||
constexpr explicit
|
||||
basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
|
||||
: _M_stream(std::__addressof(__stream))
|
||||
{ }
|
||||
|
||||
constexpr auto
|
||||
begin()
|
||||
{
|
||||
if (_M_stream != nullptr)
|
||||
*_M_stream >> _M_object;
|
||||
return _Iterator{*this};
|
||||
}
|
||||
|
||||
constexpr default_sentinel_t
|
||||
end() const noexcept
|
||||
{ return default_sentinel; }
|
||||
|
||||
private:
|
||||
basic_istream<_CharT, _Traits>* _M_stream = nullptr;
|
||||
_Val _M_object = _Val();
|
||||
|
||||
struct _Iterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = input_iterator_tag;
|
||||
using difference_type = ptrdiff_t;
|
||||
using value_type = _Val;
|
||||
|
||||
_Iterator() = default;
|
||||
|
||||
constexpr explicit
|
||||
_Iterator(basic_istream_view& __parent) noexcept
|
||||
: _M_parent(std::__addressof(__parent))
|
||||
{ }
|
||||
|
||||
_Iterator(const _Iterator&) = delete;
|
||||
_Iterator(_Iterator&&) = default;
|
||||
_Iterator& operator=(const _Iterator&) = delete;
|
||||
_Iterator& operator=(_Iterator&&) = default;
|
||||
|
||||
_Iterator&
|
||||
operator++()
|
||||
{
|
||||
__glibcxx_assert(_M_parent->_M_stream != nullptr);
|
||||
*_M_parent->_M_stream >> _M_parent->_M_object;
|
||||
}
|
||||
|
||||
void
|
||||
operator++(int)
|
||||
{ ++*this; }
|
||||
|
||||
_Val&
|
||||
operator*() const
|
||||
{
|
||||
__glibcxx_assert(_M_parent->_M_stream != nullptr);
|
||||
return _M_parent->_M_object;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator==(const _Iterator& __x, default_sentinel_t)
|
||||
{ return __x._M_at_end(); }
|
||||
|
||||
private:
|
||||
basic_istream_view* _M_parent = nullptr;
|
||||
|
||||
bool
|
||||
_M_at_end() const
|
||||
{ return _M_parent == nullptr || !*_M_parent->_M_stream; }
|
||||
};
|
||||
|
||||
friend _Iterator;
|
||||
};
|
||||
|
||||
template<typename _Val, typename _CharT, typename _Traits>
|
||||
basic_istream_view<_Val, _CharT, _Traits>
|
||||
istream_view(basic_istream<_CharT, _Traits>& __s)
|
||||
{ return basic_istream_view<_Val, _CharT, _Traits>{__s}; }
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
struct _Empty { };
|
||||
|
77
libstdc++-v3/testsuite/std/ranges/istream_view.cc
Normal file
77
libstdc++-v3/testsuite/std/ranges/istream_view.cc
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do run { target c++2a } }
|
||||
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_iterators.h>
|
||||
#include <testsuite_rvalref.h>
|
||||
|
||||
namespace ranges = std::ranges;
|
||||
namespace views = std::views;
|
||||
|
||||
struct X : __gnu_test::rvalstruct
|
||||
{
|
||||
char c;
|
||||
|
||||
friend std::istream&
|
||||
operator>>(std::istream& is, X& m)
|
||||
{
|
||||
is >> m.c;
|
||||
return is;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
std::string s = "0123456789";
|
||||
auto ss = std::istringstream{s};
|
||||
auto v = ranges::istream_view<X>(ss);
|
||||
VERIFY( ranges::equal(v, s, {}, &X::c) );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
auto ints = std::istringstream{"0 1 2 3 4"};
|
||||
int x[5];
|
||||
ranges::copy(ranges::istream_view<int>(ints), x);
|
||||
VERIFY( ranges::equal(x, (int[]){0,1,2,3,4}) );
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
auto input = std::istringstream{"0 1 2 3 4 5 6 7 8 9"};
|
||||
auto small = [](const auto x) noexcept { return x < 5; };
|
||||
auto v = ranges::istream_view<int>(input) | views::take_while(small);
|
||||
VERIFY( ranges::equal(v, (int[]){0,1,2,3,4}) );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
}
|
Loading…
Reference in New Issue
Block a user