-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Implement ranges::istream_view #1334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b8d3ca3
d2554d1
769bb06
7257687
a978ef8
fe4b53c
c617e60
c550d44
ff85a89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Copyright (c) Microsoft Corporation. | ||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| RUNALL_INCLUDE ..\concepts_matrix.lst |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| #include <algorithm> | ||
| #include <cassert> | ||
| #include <cstddef> | ||
| #include <iostream> | ||
| #include <ranges> | ||
| #include <sstream> | ||
StephanTLavavej marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #include <type_traits> | ||
|
|
||
| #include <range_algorithm_support.hpp> | ||
|
|
||
| using namespace std; | ||
|
|
||
| constexpr int expected_empty[] = {-1, -1, -1, -1, -1}; | ||
| constexpr int expected[] = {0, 1, 2, 3, -1}; | ||
|
|
||
| struct streamable { | ||
| streamable() = default; | ||
| streamable(const int input) : _val(input) {} | ||
|
|
||
| friend istream& operator>>(istream& is, streamable& right) noexcept { | ||
| is >> right._val; | ||
| return is; | ||
| } | ||
|
|
||
| friend bool operator==(const streamable& left, const streamable& right) noexcept = default; | ||
|
|
||
| int _val = 0; | ||
| }; | ||
|
|
||
| template <class T> | ||
| void test_one_type() { | ||
| using ranges::basic_istream_view; | ||
|
|
||
| // validate type properties | ||
| using R = basic_istream_view<T, char>; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I observe that this doesn't test character types other than
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the thought was that every wild character type would actually only implement the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm mostly concerned about typos where we should have said |
||
| static_assert(ranges::view<R>); | ||
| static_assert(ranges::input_range<R>); | ||
| static_assert(!ranges::forward_range<R>); | ||
|
|
||
| static_assert(!ranges::sized_range<R>); | ||
| static_assert(!ranges::common_range<R>); | ||
|
|
||
| // validate constructors | ||
| istringstream nonempty_stream{"0"}; | ||
| istringstream empty_intstream{}; | ||
| R default_constructed{}; | ||
| R empty_constructed{empty_intstream}; | ||
| R non_empty_constructed{nonempty_stream}; | ||
|
|
||
| static_assert(is_nothrow_constructible_v<R> == is_nothrow_default_constructible_v<T>); | ||
| static_assert(is_nothrow_constructible_v<R, istream&> == is_nothrow_default_constructible_v<T>); | ||
|
|
||
| // validate member begin | ||
| // NOTE: begin() consumes the first token | ||
| (void) default_constructed.begin(); // default-constructed basic_istream_view doesn't model range. | ||
| assert(empty_constructed.begin() == default_sentinel); | ||
| assert(non_empty_constructed.begin() != default_sentinel); | ||
|
|
||
| // validate default constructed istream::iterator | ||
| { | ||
| const ranges::iterator_t<R> default_constructed_it; | ||
| assert(default_constructed_it == default_sentinel); | ||
| static_assert(noexcept(default_constructed_it == default_sentinel)); | ||
| } | ||
|
|
||
| // validate member end | ||
| static_assert(same_as<decltype(default_constructed.end()), default_sentinel_t>); | ||
| static_assert(noexcept(default_constructed.end())); | ||
| static_assert(noexcept(ranges::end(default_constructed))); | ||
|
|
||
| // Non existing member functions | ||
| static_assert(!CanMemberSize<R>); | ||
| static_assert(!CanMemberData<R>); | ||
| static_assert(!CanMemberEmpty<R>); | ||
| static_assert(!CanMemberFront<R>); | ||
| static_assert(!CanMemberBack<R>); | ||
|
|
||
| // Some basic tests | ||
| T input_empty[] = {-1, -1, -1, -1, -1}; | ||
| ranges::copy(empty_constructed, input_empty); | ||
| assert(ranges::equal(input_empty, expected_empty)); | ||
|
|
||
| istringstream intstream{"0 1 2 3"}; | ||
| T input_value[] = {-1, -1, -1, -1, -1}; | ||
| ranges::copy(basic_istream_view<T, char>{intstream}, input_value); | ||
| assert(ranges::equal(input_value, expected)); | ||
|
|
||
| istringstream intstream_view{"0 1 2 3"}; | ||
| T input_value_view[] = {-1, -1, -1, -1, -1}; | ||
| ranges::copy(ranges::istream_view<T>(intstream_view), input_value_view); | ||
| static_assert(noexcept(ranges::istream_view<T>(intstream_view))); | ||
| assert(ranges::equal(input_value_view, expected)); | ||
| } | ||
|
|
||
| istringstream some_stream{"42"}; | ||
| constexpr bool test_constexpr() { | ||
| // Default constructor is constexpr | ||
| ranges::basic_istream_view<int, char> empty{}; | ||
|
|
||
| // begin is constexpr??!? | ||
| (void) empty.begin(); | ||
|
|
||
| // stream constructor is constexpr | ||
| ranges::basic_istream_view<int, char> meow{some_stream}; | ||
|
|
||
| // end is constexpr | ||
| (void) meow.end(); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| int main() { | ||
| test_one_type<int>(); | ||
| test_one_type<streamable>(); | ||
|
|
||
| static_assert(test_constexpr()); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Copyright (c) Microsoft Corporation. | ||
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| RUNALL_INCLUDE ..\strict_winsdk_concepts_matrix.lst |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| #define _CONTAINER_DEBUG_LEVEL 1 | ||
|
|
||
| #include <cassert> | ||
| #include <cstddef> | ||
| #include <ranges> | ||
| #include <sstream> | ||
|
|
||
| #include <test_death.hpp> | ||
| using namespace std; | ||
|
|
||
| using iview = ranges::basic_istream_view<int, char>; | ||
|
|
||
| void test_preincrement_default_initialized() { | ||
| ranges::iterator_t<iview> it; | ||
| (void) ++it; | ||
| } | ||
|
|
||
| void test_postincrement_default_initialized() { | ||
| ranges::iterator_t<iview> it; | ||
| (void) it++; | ||
| } | ||
|
|
||
| void test_dereference_default_initialized() { | ||
| ranges::iterator_t<iview> it; | ||
| (void) *it; | ||
| } | ||
|
|
||
| void test_preincrement_no_stream() { | ||
| iview v; | ||
| auto it = v.begin(); | ||
| (void) ++it; | ||
| } | ||
|
|
||
| void test_postincrement_no_stream() { | ||
| iview v; | ||
| auto it = v.begin(); | ||
| (void) it++; | ||
| } | ||
|
|
||
| void test_dereference_no_stream() { | ||
| iview v; | ||
| auto it = v.begin(); | ||
| (void) *it; | ||
| } | ||
|
|
||
| void test_compare_no_stream() { | ||
| iview v; | ||
| auto it = v.begin(); | ||
| auto se = v.end(); | ||
| (void) (it == se); | ||
| } | ||
|
|
||
| void test_preincrement_end_of_stream() { | ||
| istringstream stream; | ||
| iview view{stream}; | ||
| auto it = view.begin(); | ||
| (void) ++it; | ||
| } | ||
|
|
||
| void test_postincrement_end_of_stream() { | ||
| istringstream stream; | ||
| iview view{stream}; | ||
| auto it = view.begin(); | ||
| (void) it++; | ||
| } | ||
|
|
||
| void test_dereference_end_of_stream() { | ||
| istringstream stream; | ||
| iview view{stream}; | ||
| auto it = view.begin(); | ||
| (void) *it; | ||
| } | ||
|
|
||
| int main(int argc, char* argv[]) { | ||
| std_testing::death_test_executive exec; | ||
|
|
||
| #if _ITERATOR_DEBUG_LEVEL != 0 | ||
| exec.add_death_tests({ | ||
| test_preincrement_default_initialized, | ||
| test_postincrement_default_initialized, | ||
| test_dereference_default_initialized, | ||
| test_preincrement_no_stream, | ||
| test_postincrement_no_stream, | ||
| test_dereference_no_stream, | ||
| test_compare_no_stream, | ||
| test_preincrement_end_of_stream, | ||
| test_postincrement_end_of_stream, | ||
| test_dereference_end_of_stream, | ||
| }); | ||
| #endif // _ITERATOR_DEBUG_LEVEL != 0 | ||
|
|
||
| return exec.run(argc, argv); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.