Skip to content

Commit 26e4fa3

Browse files
change to __unchecked_get and visit value with hardened checks
1 parent 857897a commit 26e4fa3

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

libcxx/include/__ranges/concat_view.h

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,15 +349,19 @@ class concat_view<_Views...>::__iterator {
349349
__parent_(__i.parent_) {}
350350

351351
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const {
352-
return std::visit(
352+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
353+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
354+
return __variant_detail::__visitation::__variant::__visit_value(
353355
[](auto&& __it) -> __concat_reference_t<__maybe_const<_Const, _Views>...> { return *__it; }, __it_);
354356
}
355357

356358
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
359+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
360+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
357361
size_t __active_index = __it_.index();
358362
__apply_at_index<variant_size_v<decltype(__it_)>>(__active_index, [&](auto __index_constant) {
359363
constexpr size_t __i = __index_constant.value;
360-
++std::get<__i>(__it_);
364+
++std::__unchecked_get<__i>(__it_);
361365
__satisfy<__i>();
362366
});
363367
return *this;
@@ -376,6 +380,8 @@ class concat_view<_Views...>::__iterator {
376380
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
377381
requires __concat_is_bidirectional<_Const, _Views...>
378382
{
383+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
384+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
379385
size_t __active_index = __it_.index();
380386
__apply_at_index<variant_size_v<decltype(__it_)>>(__active_index, [&](auto __index_constant) {
381387
constexpr size_t __i = __index_constant.value;
@@ -395,6 +401,8 @@ class concat_view<_Views...>::__iterator {
395401
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
396402
requires(equality_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...)
397403
{
404+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
405+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
398406
return __x.__it_ == __y.__it_;
399407
}
400408

@@ -421,9 +429,11 @@ class concat_view<_Views...>::__iterator {
421429
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
422430
requires __concat_is_random_access<_Const, _Views...>
423431
{
432+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
433+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
424434
size_t __active_index = __it_.index();
425435
if (__n > 0) {
426-
std::visit(
436+
__variant_detail::__visitation::__variant::__visit_value(
427437
[&](auto& __active_it) {
428438
__apply_at_index<tuple_size_v<decltype(__parent_->__views_)>>(__active_index, [&](auto __index_constant) {
429439
constexpr size_t __i = __index_constant.value;
@@ -436,7 +446,7 @@ class concat_view<_Views...>::__iterator {
436446
}
437447

438448
else if (__n < 0) {
439-
std::visit(
449+
__variant_detail::__visitation::__variant::__visit_value(
440450
[&](auto& __active_it) {
441451
__apply_at_index<tuple_size_v<decltype(__parent_->__views_)>>(__active_index, [&](auto __index_constant) {
442452
constexpr size_t __i = __index_constant.value;
@@ -459,9 +469,12 @@ class concat_view<_Views...>::__iterator {
459469
}
460470

461471
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __it, default_sentinel_t) {
472+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
473+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
462474
constexpr auto __last_idx = sizeof...(_Views) - 1;
463475
return __it.__it_.index() == __last_idx &&
464-
std::get<__last_idx>(__it.__it_) == ranges::end(std::get<__last_idx>(__it.__parent_->__views_));
476+
std::__unchecked_get<__last_idx>(__it.__it_) ==
477+
ranges::end(std::__unchecked_get<__last_idx>(__it.__parent_->__views_));
465478
}
466479

467480
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
@@ -492,6 +505,8 @@ class concat_view<_Views...>::__iterator {
492505
requires((random_access_range<__maybe_const<_Const, _Views>> && ...) &&
493506
(three_way_comparable<__maybe_const<_Const, _Views>> && ...))
494507
{
508+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
509+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
495510
return __x.__it_ <=> __y.__it_;
496511
}
497512

@@ -536,11 +551,13 @@ class concat_view<_Views...>::__iterator {
536551
_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
537552
requires __concat_is_random_access<_Const, _Views...>
538553
{
554+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
555+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
539556
size_t __ix = __x.__it_.index();
540557
size_t __iy = __y.__it_.index();
541558

542559
if (__ix > __iy) {
543-
std::visit(
560+
__variant_detail::__visitation::__variant::__visit_value(
544561
[&](auto& __it_x, auto& __it_y) {
545562
__it_x.template __apply_at_index<tuple_size_v<decltype(__x.__parent_->__views_)>>(
546563
__ix, [&](auto __index_constant_x) {
@@ -565,7 +582,8 @@ class concat_view<_Views...>::__iterator {
565582
} else if (__ix < __iy) {
566583
return -(__y - __x);
567584
} else {
568-
std::visit([&](const auto& __it1, const auto& __it2) { return __it1 - __it2; }, __x.__it_, __y.__it_);
585+
__variant_detail::__visitation::__variant::__visit_value(
586+
[&](const auto& __it1, const auto& __it2) { return __it1 - __it2; }, __x.__it_, __y.__it_);
569587
}
570588
}
571589

@@ -582,8 +600,10 @@ class concat_view<_Views...>::__iterator {
582600
...) &&
583601
(__apply_drop_first<_Const, _Views...>::value)
584602
{
603+
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
604+
!__it_.valueless_by_exception(), "Trying to convert from a valueless iterator of concat_view.");
585605
size_t __ix = __x.__it_.index();
586-
std::visit(
606+
__variant_detail::__visitation::__variant::__visit_value(
587607
[&](auto& __it_x) {
588608
__it_x.template __apply_at_index<tuple_size_v<decltype(__x.__parent_->__views_)>>(
589609
__ix, [&](auto __index_constant) {

libcxx/test/std/ranges/range.adaptors/range.concat/iterator/ctor.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ constexpr bool test() {
9191

9292
{
9393
//valueless by exception test
94-
std::ranges::concat_view<ThrowOnCopyView> concatView;
94+
std::ranges::concat_view<ThrowOnCopyView> concatView_2;
9595
std::ranges::iterator_t<std::ranges::concat_view<ThrowOnCopyView>> it1;
9696
std::ranges::iterator_t<std::ranges::concat_view<ThrowOnCopyView>> it2;
9797
try {
98-
it1 = concatView.begin();
98+
it1 = concatView_2.begin();
9999
} catch (...) {
100100
TEST_LIBCPP_ASSERT_FAILURE(
101101
[&] {

0 commit comments

Comments
 (0)