Skip to content
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

Implement P2325R3 Views Should Not Be Required To Be Default Constructible #2012

Merged
merged 9 commits into from
Jun 29, 2021

Conversation

CaseyCarter
Copy link
Member

@CaseyCarter CaseyCarter commented Jun 15, 2021

Major changes:

  1. view does not refine default_initializable. This means that even span<int, 42> - which is not default constructible - is a view. Replace _Semiregular_box with _Copyable_box which need not be default constructible when the wrapped type is not.

  2. weakly_incrementable does not refine default_initializable; consequently neither do input_or_output_iterator, input_iterator, nor output_iterator. forward_iterator refines incrementable refines regular, and so is still default_initalizable. This proposal reverts the changes from P0896R4 that made {back_,front_,}insert_iterator and ostream{buf,}_iterator default_initializable.

  3. The proposal leaves join_view broken for ranges of ranges with iterators that aren't default constructible - that defect is fixed here. This will be (but is not yet) the proposed resolution of an LWG issue.

  4. The proposal also leaves basic_stream_view in a dangerous state by removing the DMI for the stored value: copying the view before the first call to begin could result in undefined behavior. This will be (but is not yet) the proposed resolution of an LWG issue.

  5. This change makes test::iterator not default constructible when not modeling forward_iterator, and makes test::range not default constructible when the range is immovable or move-only. This gives us some good test coverage for non-default-constructible types.

Collateral damage:

  • Repurpose _Semiregular_box into the working draft's new copyable-box, which no longer adds default construction behavior. Add a new optional-like _Defaultabox that augments a movable type with default construction behavior for deferred initialization of views and iterators which the working draft depicts as being stored in an optional.
  • Remove all test cases that were using span<T, N> as an exemplar non-view borrowed_range.
  • It's possible for drop_while_view and take_while_view to have no predicate even when not default-initialized; fixup error message and test cases.

Drive-by: Implement missed insert_iterator changes that use ranges::iterator_t<Container> instead of typename Container::iterator.

Fixes #1984.

…ctible"

Major changes:
1. `view` does not refine `default_initializable`. This means that even `span<int, 42>` - which is not default constructible - is a `view`. Replace `_Semiregular_box` with `_Copyable_box` which need not be default constructible when the wrapped type is not.

2. `weakly_incrementable` does not refine `default_initializable`; consequently neither do `input_or_output_iterator`, `input_iterator`, nor `output_iterator`. `forward_iterator` refines `incrementable` refines `regular`, and so is still `default_initalizable`. This proposal reverts the changes from P0896R4 that made `{back_,front_,}insert_iterator` and `ostream{buf,}_iterator` `default_initializable`.

3. The proposal leaves `join_view` broken for ranges of ranges with iterators that aren't default constructible - that defect is fixed here. This will be (but is not yet) the proposed resolution of an LWG issue.

Collateral damage:
* Repurpose `_Semiregular_box` into the working draft's new _`copyable-box`_, which no longer adds default construction behavior. Add a new `optional`-like `_Defaultabox` that augments a `movable` type with default construction behavior for deferred initialization of `view`s and `iterator`s which the working draft depicts as being stored in an `optional`.
* Remove all test cases that were using `span<T, N>` as an exemplar non-`view` `borrowed_range`.
* It's possible for `drop_while_view` and `take_while_view` to have no predicate even when not default-initialized; fixup error message and test cases.

Drive-by: Implement missed `insert_iterator` changes that use `ranges::iterator_t<Container>` instead of `typename Container::iterator`.
@CaseyCarter CaseyCarter added cxx20 C++20 feature high priority Important! ranges C++20/23 ranges labels Jun 15, 2021
@CaseyCarter CaseyCarter requested a review from a team as a code owner June 15, 2021 04:29
stl/inc/ranges Outdated Show resolved Hide resolved
stl/inc/ranges Show resolved Hide resolved
stl/inc/ranges Show resolved Hide resolved
stl/inc/ranges Outdated Show resolved Hide resolved
stl/inc/ranges Outdated Show resolved Hide resolved
stl/inc/ranges Outdated Show resolved Hide resolved
@StephanTLavavej StephanTLavavej self-assigned this Jun 16, 2021
stl/inc/iterator Outdated Show resolved Hide resolved
stl/inc/iterator Outdated
insert_iterator() = default;
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
_CONSTEXPR20 insert_iterator(_Container& _Cont, ranges::iterator_t<_Container> _Where)
: container(_STD addressof(_Cont)), iter(_STD move(_Where)) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N4885 [insert.iter.ops]/1 says "Effects: Initializes container with addressof(x) and iter with i." Are we allowed to move here? Should this be restricted to the concepts implementation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, the intent is that we're allowed to move instead of copy everywhere the standard depicts making a copy of an object that meets the Cpp17CopyConstructible / Cpp17CopyAssignable requirements. Cpp17CopyConstructible / Cpp17CopyAssignable incorporate Cpp17MoveConstructible / Cpp17MoveAssignable, so the move operations are required to be valid and produce "equivalent" results.

That said, the difference is observable. Would you like me to submit an LWG issue to add blanket wording permitting an implementation to weaken copies to moves?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think an LWG issue would be great, thanks. It would need to be carefully phrased since implementations shouldn't be allowed to move from an object multiple times.

In any event, I'm ok with this code as-is.

stl/inc/iterator Outdated Show resolved Hide resolved
stl/inc/iterator Outdated Show resolved Hide resolved
stl/inc/ranges Outdated Show resolved Hide resolved
stl/inc/ranges Outdated Show resolved Hide resolved
stl/inc/ranges Outdated Show resolved Hide resolved
stl/inc/ranges Outdated Show resolved Hide resolved
tests/std/tests/P0896R4_ranges_alg_binary_search/test.cpp Outdated Show resolved Hide resolved
@StephanTLavavej StephanTLavavej removed their assignment Jun 19, 2021
stl/inc/ranges Outdated Show resolved Hide resolved
@StephanTLavavej StephanTLavavej changed the title Implement P2325R3 "Views Should Not Be Required To Be Default Constructible Implement P2325R3 Views Should Not Be Required To Be Default Constructible Jun 24, 2021
Copy link
Member

@barcharcraz barcharcraz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only strongly requested change is the ifdef in the test code that may be the wrong direction.

stl/inc/iterator Show resolved Hide resolved
stl/inc/iterator Show resolved Hide resolved
stl/inc/iterator Show resolved Hide resolved
stl/inc/ranges Show resolved Hide resolved
@@ -1279,7 +1280,7 @@
#define __cpp_lib_polymorphic_allocator 201902L

#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 and GH-1814
#define __cpp_lib_ranges 201911L
#define __cpp_lib_ranges 202106L
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is tentative right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp Outdated Show resolved Hide resolved
tests/std/tests/P0896R4_views_filter/test.cpp Show resolved Hide resolved
tests/std/tests/P0896R4_views_join/test.cpp Outdated Show resolved Hide resolved
@StephanTLavavej StephanTLavavej merged commit a4983af into microsoft:main Jun 29, 2021
@StephanTLavavej
Copy link
Member

Thanks for implementing this major C++20 Defect Report - change the past to save the future! 😸

@CaseyCarter CaseyCarter deleted the p2325 branch June 29, 2021 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cxx20 C++20 feature high priority Important! ranges C++20/23 ranges
Projects
None yet
Development

Successfully merging this pull request may close these issues.

P2325R3 Views Should Not Be Required To Be Default Constructible
4 participants