forked from OSchip/llvm-project
implement `std::views::istream`
implement `std::ranges::basic_istream_view` and `std::views::istream`. Although the view itself is constexpr, the constructor argument is a base class std::istream where its ctor/dtor are not constexpr. So no tests are performed in constexpr Differential Revision: https://reviews.llvm.org/D133317
This commit is contained in:
parent
6e7df70e5a
commit
96a509bca2
|
@ -296,6 +296,6 @@
|
|||
"`3393 <https://wg21.link/LWG3393>`__","Missing/incorrect feature test macro for coroutines","Prague","|Complete|","14.0"
|
||||
"`3395 <https://wg21.link/LWG3395>`__","Definition for three-way comparison needs to be updated (US 152)","Prague","","","|spaceship|"
|
||||
"`3396 <https://wg21.link/LWG3396>`__","Clarify point of reference for ``source_location::current()``\ (DE 169)","Prague","",""
|
||||
"`3397 <https://wg21.link/LWG3397>`__","``ranges::basic_istream_view::iterator``\ should not provide ``iterator_category``\ ","Prague","","","|ranges|"
|
||||
"`3397 <https://wg21.link/LWG3397>`__","``ranges::basic_istream_view::iterator``\ should not provide ``iterator_category``\ ","Prague","|Complete|","16.0","|ranges|"
|
||||
"`3398 <https://wg21.link/LWG3398>`__","``tuple_element_t``\ is also wrong for ``const subrange``\ ","Prague","|Complete|","14.0","|ranges|"
|
||||
"`3446 <https://wg21.link/LWG3446>`__","``indirectly_readable_traits``\ ambiguity for types with both ``value_type``\ and ``element_type``\ ","November virtual meeting","|Complete|","13.0"
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -108,7 +108,7 @@
|
|||
"`P0784R7 <https://wg21.link/P0784R7>`__","CWG","More constexpr containers","Cologne","|Complete|","12.0"
|
||||
"`P0980R1 <https://wg21.link/P0980R1>`__","LWG","Making std::string constexpr","Cologne","|Complete|","15.0"
|
||||
"`P1004R2 <https://wg21.link/P1004R2>`__","LWG","Making std::vector constexpr","Cologne","|Complete|","15.0"
|
||||
"`P1035R7 <https://wg21.link/P1035R7>`__","LWG","Input Range Adaptors","Cologne","",""
|
||||
"`P1035R7 <https://wg21.link/P1035R7>`__","LWG","Input Range Adaptors","Cologne","|In Progress|",""
|
||||
"`P1065R2 <https://wg21.link/P1065R2>`__","LWG","Constexpr INVOKE","Cologne","|Complete|","12.0"
|
||||
"`P1135R6 <https://wg21.link/P1135R6>`__","LWG","The C++20 Synchronization Library","Cologne","|Complete|","11.0"
|
||||
"`P1207R4 <https://wg21.link/P1207R4>`__","LWG","Movability of Single-pass Iterators","Cologne","|Complete|","15.0"
|
||||
|
@ -124,7 +124,7 @@
|
|||
"`P1523R1 <https://wg21.link/P1523R1>`__","LWG","Views and Size Types","Cologne","|Complete|","15.0"
|
||||
"`P1612R1 <https://wg21.link/P1612R1>`__","LWG","Relocate Endian's Specification","Cologne","|Complete|","10.0"
|
||||
"`P1614R2 <https://wg21.link/P1614R2>`__","LWG","The Mothership has Landed","Cologne","|In Progress|",""
|
||||
"`P1638R1 <https://wg21.link/P1638R1>`__","LWG","basic_istream_view::iterator should not be copyable","Cologne","",""
|
||||
"`P1638R1 <https://wg21.link/P1638R1>`__","LWG","basic_istream_view::iterator should not be copyable","Cologne","|Complete|","16.0"
|
||||
"`P1643R1 <https://wg21.link/P1643R1>`__","LWG","Add wait/notify to atomic_ref","Cologne","",""
|
||||
"`P1644R0 <https://wg21.link/P1644R0>`__","LWG","Add wait/notify to atomic<shared_ptr>","Cologne","",""
|
||||
"`P1650R0 <https://wg21.link/P1650R0>`__","LWG","Output std::chrono::days with 'd' suffix","Cologne","",""
|
||||
|
@ -204,4 +204,4 @@
|
|||
"`P2372R3 <https://wg21.link/P2372R3>`__","LWG","Fixing locale handling in chrono formatters","October 2021","",""
|
||||
"`P2415R2 <https://wg21.link/P2415R2>`__","LWG","What is a ``view``","October 2021","|Complete|","14.0"
|
||||
"`P2418R2 <https://wg21.link/P2418R2>`__","LWG","Add support for ``std::generator``-like types to ``std::format``","October 2021","|Complete|","15.0"
|
||||
"`P2432R1 <https://wg21.link/P2432R1>`__","LWG","Fix ``istream_view``","October 2021","",""
|
||||
"`P2432R1 <https://wg21.link/P2432R1>`__","LWG","Fix ``istream_view``","October 2021","|Complete|","16.0"
|
||||
|
|
|
|
@ -121,7 +121,7 @@
|
|||
`3563 <https://wg21.link/LWG3563>`__,"``keys_view`` example is broken","October 2021","","","|ranges|"
|
||||
`3566 <https://wg21.link/LWG3566>`__,"Constraint recursion for ``operator<=>(optional<T>, U)``","October 2021","","","|spaceship|"
|
||||
`3567 <https://wg21.link/LWG3567>`__,"Formatting move-only iterators take two","October 2021","","","|format|"
|
||||
`3568 <https://wg21.link/LWG3568>`__,"``basic_istream_view`` needs to initialize ``value_``","October 2021","","","|ranges|"
|
||||
`3568 <https://wg21.link/LWG3568>`__,"``basic_istream_view`` needs to initialize ``value_``","October 2021","|Complete|","16.0","|ranges|"
|
||||
`3570 <https://wg21.link/LWG3570>`__,"``basic_osyncstream::emit`` should be an unformatted output function","October 2021","",""
|
||||
`3571 <https://wg21.link/LWG3571>`__,"``flush_emit`` should set ``badbit`` if the ``emit`` call fails","October 2021","",""
|
||||
`3572 <https://wg21.link/LWG3572>`__,"``copyable-box`` should be fully ``constexpr``","October 2021","|Complete|","14.0","|ranges|"
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -481,6 +481,7 @@ set(files
|
|||
__ranges/enable_view.h
|
||||
__ranges/filter_view.h
|
||||
__ranges/iota_view.h
|
||||
__ranges/istream_view.h
|
||||
__ranges/join_view.h
|
||||
__ranges/lazy_split_view.h
|
||||
__ranges/non_propagating_cache.h
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef _LIBCPP___RANGES_ISTREAM_VIEW_H
|
||||
#define _LIBCPP___RANGES_ISTREAM_VIEW_H
|
||||
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__concepts/derived_from.h>
|
||||
#include <__concepts/movable.h>
|
||||
#include <__config>
|
||||
#include <__iterator/default_sentinel.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Val, class _CharT, class _Traits>
|
||||
concept __stream_extractable = requires(basic_istream<_CharT, _Traits>& __is, _Val& __t) { __is >> __t; };
|
||||
|
||||
template <movable _Val, class _CharT, class _Traits = char_traits<_CharT>>
|
||||
requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
|
||||
class basic_istream_view : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> {
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
|
||||
: __stream_(std::addressof(__stream)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
|
||||
*__stream_ >> __value_;
|
||||
return __iterator{*this};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return default_sentinel; }
|
||||
|
||||
private:
|
||||
class __iterator;
|
||||
|
||||
basic_istream<_CharT, _Traits>* __stream_;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Val __value_ = _Val();
|
||||
};
|
||||
|
||||
template <movable _Val, class _CharT, class _Traits>
|
||||
requires default_initializable<_Val> && __stream_extractable<_Val, _CharT, _Traits>
|
||||
class basic_istream_view<_Val, _CharT, _Traits>::__iterator {
|
||||
public:
|
||||
using iterator_concept = input_iterator_tag;
|
||||
using difference_type = ptrdiff_t;
|
||||
using value_type = _Val;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view& __parent) noexcept
|
||||
: __parent_(std::addressof(__parent)) {}
|
||||
|
||||
__iterator(const __iterator&) = delete;
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator(__iterator&&) = default;
|
||||
|
||||
__iterator& operator=(const __iterator&) = delete;
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator& operator=(__iterator&&) = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator& operator++() {
|
||||
*__parent_->__stream_ >> __parent_->__value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void operator++(int) { ++*this; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Val& operator*() const { return __parent_->__value_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __x, default_sentinel_t) {
|
||||
return !*__x.__get_parent_stream();
|
||||
}
|
||||
|
||||
private:
|
||||
basic_istream_view* __parent_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr basic_istream<_CharT, _Traits>* __get_parent_stream() const {
|
||||
return __parent_->__stream_;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Val>
|
||||
using istream_view = basic_istream_view<_Val, char>;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class _Val>
|
||||
using wistream_view = basic_istream_view<_Val, wchar_t>;
|
||||
#endif
|
||||
|
||||
namespace views {
|
||||
namespace __istream {
|
||||
|
||||
// clang-format off
|
||||
template <class _Tp>
|
||||
struct __fn {
|
||||
template <class _Up, class _UnCVRef = remove_cvref_t<_Up>>
|
||||
requires derived_from<_UnCVRef, basic_istream<typename _UnCVRef::char_type,
|
||||
typename _UnCVRef::traits_type>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Up&& __u) const
|
||||
noexcept(noexcept(basic_istream_view<_Tp, typename _UnCVRef::char_type,
|
||||
typename _UnCVRef::traits_type>(std::forward<_Up>(__u))))
|
||||
-> decltype( basic_istream_view<_Tp, typename _UnCVRef::char_type,
|
||||
typename _UnCVRef::traits_type>(std::forward<_Up>(__u)))
|
||||
{ return basic_istream_view<_Tp, typename _UnCVRef::char_type,
|
||||
typename _UnCVRef::traits_type>(std::forward<_Up>(__u));
|
||||
}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
} // namespace __istream
|
||||
|
||||
inline namespace __cpo {
|
||||
template <class _Tp>
|
||||
inline constexpr auto istream = __istream::__fn<_Tp>{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
#endif // _LIBCPP___RANGES_ISTREAM_VIEW_H
|
|
@ -1014,6 +1014,10 @@ module std [system] {
|
|||
module enable_view { private header "__ranges/enable_view.h" }
|
||||
module filter_view { private header "__ranges/filter_view.h" }
|
||||
module iota_view { private header "__ranges/iota_view.h" }
|
||||
module istream_view {
|
||||
@requires_LIBCXX_ENABLE_LOCALIZATION@
|
||||
private header "__ranges/istream_view.h"
|
||||
}
|
||||
module join_view { private header "__ranges/join_view.h" }
|
||||
module lazy_split_view { private header "__ranges/lazy_split_view.h" }
|
||||
module non_propagating_cache { private header "__ranges/non_propagating_cache.h" }
|
||||
|
|
|
@ -228,6 +228,19 @@ namespace std::ranges {
|
|||
inline constexpr unspecified lazy_split = unspecified;
|
||||
}
|
||||
|
||||
// [range.istream], istream view
|
||||
template<movable Val, class CharT, class Traits = char_traits<CharT>>
|
||||
requires see below
|
||||
class basic_istream_view;
|
||||
|
||||
template<class Val>
|
||||
using istream_view = basic_istream_view<Val, char>;
|
||||
|
||||
template<class Val>
|
||||
using wistream_view = basic_istream_view<Val, wchar_t>;
|
||||
|
||||
namespace views { template<class T> inline constexpr unspecified istream = unspecified; }
|
||||
|
||||
// [range.zip], zip view
|
||||
template<input_range... Views>
|
||||
requires (view<Views> && ...) && (sizeof...(Views) > 0)
|
||||
|
@ -305,6 +318,10 @@ namespace std {
|
|||
#include <type_traits>
|
||||
#include <version>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
|
||||
#include <__ranges/istream_view.h>
|
||||
#endif
|
||||
|
||||
// standard-mandated includes
|
||||
|
||||
// [ranges.syn]
|
||||
|
|
|
@ -512,6 +512,7 @@ END-SCRIPT
|
|||
#include <__ranges/enable_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/enable_view.h'}}
|
||||
#include <__ranges/filter_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/filter_view.h'}}
|
||||
#include <__ranges/iota_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/iota_view.h'}}
|
||||
#include <__ranges/istream_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/istream_view.h'}}
|
||||
#include <__ranges/join_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/join_view.h'}}
|
||||
#include <__ranges/lazy_split_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/lazy_split_view.h'}}
|
||||
#include <__ranges/non_propagating_cache.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/non_propagating_cache.h'}}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// clang-cl and cl currently don't support [[no_unique_address]]
|
||||
// XFAIL: msvc
|
||||
|
||||
// Test the libc++ extension that the value stored in `std::ranges::istream_view` has been marked
|
||||
// as _LIBCPP_NO_UNIQUE_ADDRESS
|
||||
|
||||
#include <istream>
|
||||
#include <ranges>
|
||||
|
||||
struct Empty {
|
||||
friend std::istream& operator>>(std::istream& i, Empty const&) { return i; }
|
||||
};
|
||||
|
||||
static_assert(sizeof(std::ranges::istream_view<Empty>) == sizeof(void*));
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// constexpr auto begin();
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "utils.h"
|
||||
|
||||
template <class T>
|
||||
concept HasBegin = requires(T t) { t.begin(); };
|
||||
|
||||
static_assert(HasBegin<std::ranges::istream_view<int>>);
|
||||
static_assert(!HasBegin<const std::ranges::istream_view<int>>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(HasBegin<std::ranges::wistream_view<int>>);
|
||||
static_assert(!HasBegin<const std::ranges::wistream_view<int>>);
|
||||
#endif
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
// begin should read the first element
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("12 3");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(*it == 12);
|
||||
}
|
||||
|
||||
// empty stream
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(it == isv.end());
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// std::views::istream<T>
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "utils.h"
|
||||
|
||||
static_assert(!std::is_invocable_v<decltype((std::views::istream<int>))>);
|
||||
static_assert(std::is_invocable_v<decltype((std::views::istream<int>)), std::istream&>);
|
||||
static_assert(!std::is_invocable_v<decltype((std::views::istream<int>)), const std::istream&>);
|
||||
static_assert(!std::is_invocable_v<decltype((std::views::istream<int>)), int>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(std::is_invocable_v<decltype((std::views::istream<int>)), std::wistream&>);
|
||||
static_assert(!std::is_invocable_v<decltype((std::views::istream<int>)), const std::wistream&>);
|
||||
#endif
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
auto iss = make_string_stream<CharT>("12 3");
|
||||
auto isv = std::views::istream<int>(iss);
|
||||
auto it = isv.begin();
|
||||
assert(*it == 12);
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// constexpr explicit basic_istream_view(basic_istream<CharT, Traits>& stream);
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "utils.h"
|
||||
|
||||
// test that the constructor is explicit
|
||||
static_assert(std::constructible_from<std::ranges::istream_view<int>, std::istream&>);
|
||||
static_assert(!std::convertible_to<std::istream&, std::ranges::istream_view<int>>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(std::constructible_from<std::ranges::wistream_view<int>, std::wistream&>);
|
||||
static_assert(!std::convertible_to<std::wistream&, std::ranges::wistream_view<int>>);
|
||||
#endif
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
// test constructor init the stream pointer to the passed one
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("123");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(*it == 123);
|
||||
}
|
||||
|
||||
// LWG 3568. basic_istream_view needs to initialize value_
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("123");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
using Iter = std::ranges::iterator_t<decltype(isv)>;
|
||||
Iter iter{isv};
|
||||
assert(*iter == 0);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// constexpr default_sentinel_t end() const noexcept;
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "utils.h"
|
||||
|
||||
template <class T>
|
||||
concept NoexceptEnd =
|
||||
requires(T t) {
|
||||
{ t.end() } noexcept;
|
||||
};
|
||||
|
||||
static_assert(NoexceptEnd<std::ranges::istream_view<int>>);
|
||||
static_assert(NoexceptEnd<const std::ranges::istream_view<int>>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(NoexceptEnd<std::ranges::wistream_view<int>>);
|
||||
static_assert(NoexceptEnd<const std::ranges::wistream_view<int>>);
|
||||
#endif
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
auto iss = make_string_stream<CharT>("12");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
[[maybe_unused]] std::same_as<std::default_sentinel_t> auto sent = isv.end();
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// Some basic examples of how istream_view might be used in the wild. This is a general
|
||||
// collection of sample algorithms and functions that try to mock general usage of
|
||||
// this view.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "utils.h"
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
auto ints = make_string_stream<CharT>("0 1 2 3 4");
|
||||
auto oss = std::basic_ostringstream<CharT>{};
|
||||
auto delimiter = make_string<CharT>("-");
|
||||
std::ranges::copy(
|
||||
std::ranges::basic_istream_view<int, CharT>(ints), std::ostream_iterator<int, CharT>{oss, delimiter.c_str()});
|
||||
auto expected = make_string<CharT>("0-1-2-3-4-");
|
||||
assert(oss.str() == expected);
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// friend bool operator==(const iterator& x, default_sentinel_t);
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "../utils.h"
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
// fail to read
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("a123 4");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(it == std::default_sentinel);
|
||||
}
|
||||
|
||||
// iterate through the end
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("123 ");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(it != std::default_sentinel);
|
||||
++it;
|
||||
assert(it == std::default_sentinel);
|
||||
}
|
||||
|
||||
// empty stream
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(it == std::default_sentinel);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// constexpr explicit iterator(basic_istream_view& parent) noexcept;
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "../utils.h"
|
||||
|
||||
// test that the constructor is explicit
|
||||
template <class CharT>
|
||||
using IstreamView = std::ranges::basic_istream_view<int, CharT>;
|
||||
template <class CharT>
|
||||
using Iter = std::ranges::iterator_t<IstreamView<CharT>>;
|
||||
|
||||
static_assert(std::constructible_from<Iter<char>, IstreamView<char>&>);
|
||||
static_assert(!std::convertible_to<IstreamView<char>&, Iter<char>>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(std::constructible_from<Iter<wchar_t>, IstreamView<wchar_t>&>);
|
||||
static_assert(!std::convertible_to<IstreamView<wchar_t>&, Iter<wchar_t>>);
|
||||
#endif
|
||||
|
||||
// test that the constructor is noexcept
|
||||
static_assert(std::is_nothrow_constructible_v<Iter<char>, IstreamView<char>&>);
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(std::is_nothrow_constructible_v<Iter<wchar_t>, IstreamView<wchar_t>&>);
|
||||
#endif
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
auto iss = make_string_stream<CharT>("123");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
Iter<CharT> it{isv};
|
||||
++it;
|
||||
assert(*it == 123);
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// Val& operator*() const;
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "../utils.h"
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
// operator* should return correct value
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("1 2 345 ");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
std::same_as<int&> decltype(auto) v1 = *it;
|
||||
assert(v1 == 1);
|
||||
}
|
||||
|
||||
// operator* should return the same reference to the value stored in the view
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("1 2 345 ");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
using Iter = std::ranges::iterator_t<decltype(isv)>;
|
||||
|
||||
Iter it1{isv};
|
||||
Iter it2{isv};
|
||||
assert(&*it1 == &*it2);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// iterator& operator++();
|
||||
// void operator++(int);
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "../utils.h"
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
// operator ++()
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("1 2 345 ");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(*it == 1);
|
||||
|
||||
std::same_as<decltype(it)&> decltype(auto) it2 = ++it;
|
||||
assert(&it2 == &it);
|
||||
assert(*it2 == 2);
|
||||
|
||||
++it2;
|
||||
assert(*it2 == 345);
|
||||
|
||||
++it2;
|
||||
assert(it2 == isv.end());
|
||||
}
|
||||
|
||||
// operator ++(int)
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("1 2 345 ");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
assert(*it == 1);
|
||||
|
||||
static_assert(std::same_as<decltype(it++), void>);
|
||||
it++;
|
||||
assert(*it == 2);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// Member typedefs in istream_view<T>::<iterator>.
|
||||
|
||||
#include <istream>
|
||||
#include <ranges>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
template <class T>
|
||||
concept HasIterCategory = requires { typename T::iterator_category; };
|
||||
|
||||
struct MemberIteratorCategory {
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
};
|
||||
static_assert(HasIterCategory<MemberIteratorCategory>);
|
||||
|
||||
template <class Val, class CharT>
|
||||
void test() {
|
||||
using Iter = std::ranges::iterator_t<std::ranges::basic_istream_view<Val, CharT>>;
|
||||
static_assert(std::is_same_v<typename Iter::iterator_concept, std::input_iterator_tag>);
|
||||
static_assert(std::is_same_v<typename Iter::difference_type, std::ptrdiff_t>);
|
||||
static_assert(std::is_same_v<typename Iter::value_type, Val>);
|
||||
static_assert(!HasIterCategory<Iter>);
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
void testOne() {
|
||||
test<int, CharT>();
|
||||
test<long, CharT>();
|
||||
test<double, CharT>();
|
||||
test<CharT, CharT>();
|
||||
}
|
||||
|
||||
void test() {
|
||||
testOne<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
testOne<wchar_t>();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// iterator(const iterator&) = delete;
|
||||
// iterator(iterator&&) = default;
|
||||
// iterator& operator=(const iterator&) = delete;
|
||||
// iterator& operator=(iterator&&) = default;
|
||||
|
||||
#include <cassert>
|
||||
#include <ranges>
|
||||
#include <sstream>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "../utils.h"
|
||||
|
||||
template <class CharT>
|
||||
using Iter = std::ranges::iterator_t<std::ranges::basic_istream_view<int, CharT>>;
|
||||
static_assert(!std::copy_constructible<Iter<char>>);
|
||||
static_assert(!std::is_copy_assignable_v<Iter<char>>);
|
||||
static_assert(std::move_constructible<Iter<char>>);
|
||||
static_assert(std::is_move_assignable_v<Iter<char>>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(!std::copy_constructible<Iter<wchar_t>>);
|
||||
static_assert(!std::is_copy_assignable_v<Iter<wchar_t>>);
|
||||
static_assert(std::move_constructible<Iter<wchar_t>>);
|
||||
static_assert(std::is_move_assignable_v<Iter<wchar_t>>);
|
||||
#endif
|
||||
|
||||
template <class CharT>
|
||||
void test() {
|
||||
// test move constructor
|
||||
{
|
||||
auto iss = make_string_stream<CharT>("12 3");
|
||||
std::ranges::basic_istream_view<int, CharT> isv{iss};
|
||||
auto it = isv.begin();
|
||||
auto it2 = std::move(it);
|
||||
assert(*it2 == 12);
|
||||
}
|
||||
|
||||
// test move assignment
|
||||
{
|
||||
auto iss1 = make_string_stream<CharT>("12 3");
|
||||
std::ranges::basic_istream_view<int, CharT> isv1{iss1};
|
||||
auto iss2 = make_string_stream<CharT>("45 6");
|
||||
std::ranges::basic_istream_view<int, CharT> isv2{iss2};
|
||||
|
||||
auto it1 = isv1.begin();
|
||||
assert(*it1 == 12);
|
||||
it1 = isv2.begin();
|
||||
assert(*it1 == 45);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test<wchar_t>();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-localization
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// concept checking istream_view
|
||||
|
||||
#include <istream>
|
||||
#include <ranges>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
template <class Val, class CharT, class Traits = std::char_traits<CharT>>
|
||||
concept HasIstreamView = requires { typename std::ranges::basic_istream_view<Val, CharT, Traits>; };
|
||||
|
||||
static_assert(HasIstreamView<int, char>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(HasIstreamView<int, wchar_t>);
|
||||
#endif
|
||||
|
||||
// Unmovable Val
|
||||
struct Unmovable {
|
||||
Unmovable() = default;
|
||||
Unmovable(Unmovable&&) = delete;
|
||||
template <class CharT>
|
||||
friend std::basic_istream<CharT>& operator>>(std::basic_istream<CharT>& x, const Unmovable&) {
|
||||
return x;
|
||||
}
|
||||
};
|
||||
static_assert(!HasIstreamView<Unmovable, char>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(!HasIstreamView<Unmovable, wchar_t>);
|
||||
#endif
|
||||
|
||||
// !default_initializable<Val>
|
||||
struct NoDefaultCtor {
|
||||
NoDefaultCtor(int) {}
|
||||
friend std::istream& operator>>(std::istream& x, const NoDefaultCtor&) { return x; }
|
||||
};
|
||||
static_assert(!HasIstreamView<NoDefaultCtor, char>);
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(!HasIstreamView<NoDefaultCtor, wchar_t>);
|
||||
#endif
|
||||
|
||||
// !stream-extractable<Val, CharT, Traits>
|
||||
struct Foo {};
|
||||
static_assert(!HasIstreamView<Foo, char>);
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(!HasIstreamView<Foo, wchar_t>);
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
concept OnlyInputRange = std::ranges::input_range<T> && !std::ranges::forward_range<T>;
|
||||
|
||||
static_assert(OnlyInputRange<std::ranges::istream_view<int>>);
|
||||
static_assert(OnlyInputRange<std::ranges::istream_view<long>>);
|
||||
static_assert(OnlyInputRange<std::ranges::istream_view<double>>);
|
||||
static_assert(OnlyInputRange<std::ranges::istream_view<char>>);
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
static_assert(OnlyInputRange<std::ranges::wistream_view<int>>);
|
||||
static_assert(OnlyInputRange<std::ranges::wistream_view<long>>);
|
||||
static_assert(OnlyInputRange<std::ranges::wistream_view<double>>);
|
||||
static_assert(OnlyInputRange<std::ranges::wistream_view<wchar_t>>);
|
||||
#endif
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef TEST_STD_RANGES_RANGE_FACTORIES_RANGE_ISTREAM_UTILS_H
|
||||
#define TEST_STD_RANGES_RANGE_FACTORIES_RANGE_ISTREAM_UTILS_H
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
template <class CharT, std::size_t N>
|
||||
auto make_string(const char (&in)[N]) {
|
||||
std::basic_string<CharT> r(N - 1, static_cast<CharT>(0));
|
||||
for (std::size_t i = 0; i < N - 1; ++i) {
|
||||
r[i] = static_cast<CharT>(in[i]);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class CharT, std::size_t N>
|
||||
auto make_string_stream(const char (&in)[N]) {
|
||||
return std::basic_istringstream<CharT>(make_string<CharT>(in));
|
||||
}
|
||||
|
||||
#endif //TEST_STD_RANGES_RANGE_FACTORIES_RANGE_ISTREAM_UTILS_H
|
Loading…
Reference in New Issue