Skip to content

Commit

Permalink
Implement P2441R2 views::join_with (#2619)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Schellenberger Costa <[email protected]>
Co-authored-by: Stephan T. Lavavej <[email protected]>
Co-authored-by: Casey Carter <[email protected]>
  • Loading branch information
4 people authored Jun 20, 2022
1 parent 8e5d0aa commit 34c9a73
Show file tree
Hide file tree
Showing 12 changed files with 1,198 additions and 169 deletions.
5 changes: 0 additions & 5 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -909,11 +909,6 @@ _NODISCARD _CONSTEXPR20 bool is_permutation(_FwdIt1 _First1, _FwdIt1 _Last1, _Fw

#ifdef __cpp_lib_concepts
namespace ranges {
template <class _It, class _Se>
concept _Bidi_common = is_same_v<_It, _Se> && bidirectional_iterator<_It>;
template <class _Rng>
concept _Bidi_common_range = common_range<_Rng> && bidirectional_iterator<iterator_t<_Rng>>;

class _Is_permutation_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;
Expand Down
21 changes: 21 additions & 0 deletions stl/inc/exception
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,27 @@ template <class _Ty>
void rethrow_if_nested(const _Ty&) = delete; // requires /GR option
#endif // _CPPRTTI

class bad_variant_access
: public exception { // exception for visit of a valueless variant or get<I> on a variant with index() != I
public:
bad_variant_access() noexcept = default;

_NODISCARD const char* __CLR_OR_THIS_CALL what() const noexcept override {
return "bad variant access";
}

#if !_HAS_EXCEPTIONS
protected:
void _Doraise() const override { // perform class-specific exception handling
_RAISE(*this);
}
#endif // !_HAS_EXCEPTIONS
};

[[noreturn]] inline void _Throw_bad_variant_access() {
_THROW(bad_variant_access{});
}

_STD_END

#pragma pop_macro("new")
Expand Down
277 changes: 147 additions & 130 deletions stl/inc/iterator

Large diffs are not rendered by default.

476 changes: 475 additions & 1 deletion stl/inc/ranges

Large diffs are not rendered by default.

21 changes: 0 additions & 21 deletions stl/inc/variant
Original file line number Diff line number Diff line change
Expand Up @@ -392,27 +392,6 @@ struct variant_alternative<_Idx, variant<_Types...>> {

inline constexpr size_t variant_npos = _Meta_npos;

class bad_variant_access
: public exception { // exception for visit of a valueless variant or get<I> on a variant with index() != I
public:
bad_variant_access() noexcept = default;

_NODISCARD const char* __CLR_OR_THIS_CALL what() const noexcept override {
return "bad variant access";
}

#if !_HAS_EXCEPTIONS
protected:
void _Doraise() const override { // perform class-specific exception handling
_RAISE(*this);
}
#endif // !_HAS_EXCEPTIONS
};

[[noreturn]] inline void _Throw_bad_variant_access() {
_THROW(bad_variant_access{});
}

template <bool _TrivialDestruction, class... _Types>
class _Variant_storage_ {}; // empty storage (empty "_Types" case)

Expand Down
5 changes: 5 additions & 0 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -2688,6 +2688,11 @@ namespace ranges {
template <class _Rng>
concept common_range = range<_Rng> && same_as<iterator_t<_Rng>, sentinel_t<_Rng>>;

template <class _It, class _Se>
concept _Bidi_common = is_same_v<_It, _Se> && bidirectional_iterator<_It>;
template <class _Rng>
concept _Bidi_common_range = common_range<_Rng> && bidirectional_iterator<iterator_t<_Rng>>;

template <class _Ty>
concept _Can_empty = requires(_Ty __t) {
_RANGES empty(__t);
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
// P2321R2 zip
// (changes to pair, tuple, and vector<bool>::reference only)
// P2440R1 ranges::iota, ranges::shift_left, ranges::shift_right
// P2441R2 views::join_with
// P2442R1 Windowing Range Adaptors: views::chunk, views::slide
// P2443R1 views::chunk_by
// P2549R0 unexpected<E>::error()
Expand Down Expand Up @@ -1472,6 +1473,7 @@
#define __cpp_lib_ranges_chunk 202202L
#define __cpp_lib_ranges_chunk_by 202202L
#define __cpp_lib_ranges_iota 202202L
#define __cpp_lib_ranges_join_with 202202L
#define __cpp_lib_ranges_slide 202202L
#define __cpp_lib_ranges_starts_ends_with 202106L
#endif // __cpp_lib_concepts
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ tests\P2415R2_owning_view
tests\P2440R1_ranges_alg_shift_left
tests\P2440R1_ranges_alg_shift_right
tests\P2440R1_ranges_numeric_iota
tests\P2441R2_views_join_with
tests\P2442R1_views_chunk
tests\P2442R1_views_chunk_death
tests\P2442R1_views_slide
Expand Down
24 changes: 12 additions & 12 deletions tests/std/tests/P0896R4_common_iterator_death/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void test_case_operator_dereference_sentinel() {
}

void test_case_operator_dereference_valueless() {
CIT cit{_Common_iterator_construct_tag{}};
CIT cit{_Variantish_empty_tag{}};
(void) (*cit); // common_iterator can only be dereferenced if it holds an iterator
}

Expand All @@ -64,7 +64,7 @@ void test_case_operator_dereference_const_sentinel() {
}

void test_case_operator_dereference_const_valueless() {
const CIT cit{_Common_iterator_construct_tag{}};
const CIT cit{_Variantish_empty_tag{}};
(void) (*cit); // common_iterator can only be dereferenced if it holds an iterator
}

Expand All @@ -73,7 +73,7 @@ void test_case_operator_arrow_sentinel() {
(void) (cit.operator->()); // common_iterator can only be dereferenced if it holds an iterator
}
void test_case_operator_arrow_valueless() {
CIT cit{_Common_iterator_construct_tag{}};
CIT cit{_Variantish_empty_tag{}};
(void) (cit.operator->()); // common_iterator can only be dereferenced if it holds an iterator
}

Expand All @@ -83,7 +83,7 @@ void test_case_operator_preincrement_sentinel() {
}

void test_case_operator_preincrement_valueless() {
CIT cit{_Common_iterator_construct_tag{}};
CIT cit{_Variantish_empty_tag{}};
++cit; // common_iterator can only be preincremented if it holds an iterator
}

Expand All @@ -93,31 +93,31 @@ void test_case_operator_postincrement_sentinel() {
}

void test_case_operator_postincrement_valueless() {
CIT cit{_Common_iterator_construct_tag{}};
CIT cit{_Variantish_empty_tag{}};
cit++; // common_iterator can only be postincremented if it holds an iterator
}

void test_case_equality_left_valueless() {
CIT cit1{_Common_iterator_construct_tag{}};
CIT cit1{_Variantish_empty_tag{}};
CIT cit2{};
(void) (cit1 == cit2); // common_iterator can only be compared if it holds a value
}

void test_case_equality_right_valueless() {
CIT cit1{};
CIT cit2{_Common_iterator_construct_tag{}};
CIT cit2{_Variantish_empty_tag{}};
(void) (cit1 == cit2); // common_iterator can only be compared if it holds a value
}

void test_case_difference_left_valueless() {
CIT cit1{_Common_iterator_construct_tag{}};
CIT cit1{_Variantish_empty_tag{}};
CIT cit2{};
(void) (cit1 - cit2); // common_iterator can only be subtracted if it holds a value
}

void test_case_difference_right_valueless() {
CIT cit1{};
CIT cit2{_Common_iterator_construct_tag{}};
CIT cit2{_Variantish_empty_tag{}};
(void) (cit1 - cit2); // common_iterator can only be subtracted if it holds a value
}

Expand All @@ -127,7 +127,7 @@ void test_case_iter_move_sentinel() {
}

void test_case_iter_move_valueless() {
CIT cit{_Common_iterator_construct_tag{}};
CIT cit{_Variantish_empty_tag{}};
(void) ranges::iter_move(cit); // can only iter_move from common_iterator if it holds an iterator
}

Expand All @@ -138,7 +138,7 @@ void test_case_iter_swap_sentinel_left_sentinel() {
}

void test_case_iter_swap_sentinel_left_valueless() {
CIT cit1{_Common_iterator_construct_tag{}};
CIT cit1{_Variantish_empty_tag{}};
CIT cit2{};
(void) ranges::iter_swap(cit1, cit2); // can only iter_swap common_iterators if both hold iterators
}
Expand All @@ -151,7 +151,7 @@ void test_case_iter_swap_sentinel_right_sentinel() {

void test_case_iter_swap_sentinel_right_valueless() {
CIT cit1{};
CIT cit2{_Common_iterator_construct_tag{}};
CIT cit2{_Variantish_empty_tag{}};
(void) ranges::iter_swap(cit1, cit2); // can only iter_swap common_iterators if both hold iterators
}

Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P2441R2_views_join_with/env.lst
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_concepts_latest_matrix.lst
Loading

0 comments on commit 34c9a73

Please sign in to comment.