Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
726e509
libc++ takes `(void)iter_swap(x, y)` too seriously
CaseyCarter Dec 28, 2021
fca8c58
views::counted can fail with move-only iterator lvalues
CaseyCarter Dec 28, 2021
9d50b8f
Give raw_storage_iterator a proper difference type in C++20
CaseyCarter Dec 28, 2021
d36407c
<ranges>: iota_view::iterator's difference is broken
CaseyCarter Dec 29, 2021
a6b4f1c
<format>: `L` is valid (and ignored) for integral types charT and `char`
CaseyCarter Dec 29, 2021
eeee5af
Per [format.string.std]/7, width must be positive
CaseyCarter Dec 29, 2021
337512e
Missed Ranges update to std::inserter
CaseyCarter Dec 29, 2021
227e638
un-nest requirement not depicted as nested in the Working Draft
CaseyCarter Dec 29, 2021
e46b952
Implement final P/R of LWG-3150
CaseyCarter Dec 29, 2021
d05dad9
Don't use defaults to implement _Ioterator comparisons
CaseyCarter Jan 2, 2022
76c887a
Abandon aggregate _Iotinel
CaseyCarter Jan 2, 2022
072c836
Add concept test cases
CaseyCarter Jan 3, 2022
62ad0b2
Update implementation of LWG-3569 to reflect the current PR
CaseyCarter Jan 4, 2022
f3de685
Workaround LLVM-48173 in `weakly_incrementable`
CaseyCarter Jan 4, 2022
93cb0ae
Implement _Defaultabox converting constructor templates
CaseyCarter Jan 5, 2022
c47a8cf
Fix iterator_traits<common_iterator>
CaseyCarter Jan 6, 2022
efd4f44
_Define_ default constructor of basic_format_args
CaseyCarter Jan 8, 2022
f769d45
Workaround DevCom-1632113 in `to_address`
CaseyCarter Jan 8, 2022
0c932a4
Oops - bug in ranges::uninitialized_copy_n
CaseyCarter Jan 13, 2022
413cdd7
Update skips and magic_comments; bump LLVM reference
CaseyCarter Jan 19, 2022
8a72a06
Update skips to allow for ARM/ARM64 variations
CaseyCarter Jan 22, 2022
6aa149a
Two more skips
CaseyCarter Jan 22, 2022
743dd63
Update tests.py for C++23
CaseyCarter Jan 23, 2022
3854b91
Merge: views::counted tweak
CaseyCarter Jan 23, 2022
25c87dd
Replace duplicate LLVM bug
CaseyCarter Jan 30, 2022
f9bd522
Merge branch 'main' into llvm
CaseyCarter Feb 9, 2022
876bf51
Update skips after merging main
CaseyCarter Feb 10, 2022
2857309
Restore _Iotinel's aggregateness
CaseyCarter Feb 10, 2022
e2ab01d
More review comments
CaseyCarter Feb 10, 2022
b76b4fb
More review comments
CaseyCarter Feb 11, 2022
d182686
Merge branch 'main' into llvm
CaseyCarter Feb 12, 2022
4cb99ac
Charlie's comments
CaseyCarter Feb 17, 2022
1494fb1
Revert warning suppression
CaseyCarter Feb 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm-project
4 changes: 1 addition & 3 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -4773,9 +4773,7 @@ concept uniform_random_bit_generator = invocable<_Ty&>
&& requires {
{ (_Ty::min)() } -> same_as<invoke_result_t<_Ty&>>;
{ (_Ty::max)() } -> same_as<invoke_result_t<_Ty&>>;
typename _Require_constant<(_Ty::min)()>;
typename _Require_constant<(_Ty::max)()>;
requires (_Ty::min)() < (_Ty::max)();
requires bool_constant<(_Ty::min)() < (_Ty::max)()>::value;
};
// clang-format on

Expand Down
4 changes: 3 additions & 1 deletion stl/inc/concepts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ concept common_with =
requires {
typename common_type_t<_Ty1, _Ty2>;
typename common_type_t<_Ty2, _Ty1>;
requires same_as<common_type_t<_Ty1, _Ty2>, common_type_t<_Ty2, _Ty1>>;
}
&& same_as<common_type_t<_Ty1, _Ty2>, common_type_t<_Ty2, _Ty1>>
&& requires {
static_cast<common_type_t<_Ty1, _Ty2>>(_STD declval<_Ty1>());
static_cast<common_type_t<_Ty1, _Ty2>>(_STD declval<_Ty2>());
}
Expand Down
22 changes: 13 additions & 9 deletions stl/inc/format
Original file line number Diff line number Diff line change
Expand Up @@ -1129,10 +1129,15 @@ public:
template <class _Ty>
_NODISCARD constexpr unsigned long long operator()(const _Ty _Value) const {
if constexpr (is_integral_v<_Ty>) {
if constexpr (is_signed_v<_Ty>) {
if (_Value < 0) {
_THROW(format_error("Negative width."));
}
bool _Positive;
if constexpr (same_as<_Ty, bool>) { // avoid "bool > 0", which triggers C4804
_Positive = _Value != 0;
} else {
_Positive = _Value > 0;
}

if (!_Positive) {
_THROW(format_error("width is not positive."));
}
return static_cast<unsigned long long>(_Value);
} else {
Expand Down Expand Up @@ -1603,8 +1608,10 @@ class _Format_arg_store<_Context> {};
template <class _Context>
class basic_format_args {
public:
basic_format_args() noexcept;
basic_format_args() noexcept = default;

basic_format_args(const _Format_arg_store<_Context>&) noexcept {}

template <class... _Args>
basic_format_args(const _Format_arg_store<_Context, _Args...>& _Store) noexcept
: _Num_args(sizeof...(_Args)), _Index_array(_Store._Index_array) {}
Expand Down Expand Up @@ -2394,8 +2401,6 @@ _NODISCARD _OutputIt _Fmt_write(

_STL_INTERNAL_CHECK(_Specs._Precision == -1);

// Clear the type so that the string_view writer doesn't fail on 'c'.
_Specs._Type = '\0';
return _Fmt_write(_STD move(_Out), basic_string_view<_CharT>{&_Value, 1}, _Specs, _Locale);
}

Expand Down Expand Up @@ -2698,11 +2703,10 @@ _NODISCARD const _CharT* _Measure_string_prefix(const basic_string_view<_CharT>
template <class _CharT, class _OutputIt>
_NODISCARD _OutputIt _Fmt_write(
_OutputIt _Out, const basic_string_view<_CharT> _Value, const _Basic_format_specs<_CharT>& _Specs, _Lazy_locale) {
_STL_INTERNAL_CHECK(_Specs._Type == '\0' || _Specs._Type == 's');
_STL_INTERNAL_CHECK(_Specs._Type == '\0' || _Specs._Type == 'c' || _Specs._Type == 's');
_STL_INTERNAL_CHECK(_Specs._Sgn == _Fmt_sign::_None);
_STL_INTERNAL_CHECK(!_Specs._Alt);
_STL_INTERNAL_CHECK(!_Specs._Leading_zero);
_STL_INTERNAL_CHECK(!_Specs._Localized);

if (_Specs._Precision < 0 && _Specs._Width <= 0) {
return _Fmt_write(_STD move(_Out), _Value);
Expand Down
9 changes: 7 additions & 2 deletions stl/inc/iterator
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,17 @@ protected:
_Wrapped_iter iter;
};

#ifndef __cpp_lib_concepts
template <class _Container>
_NODISCARD _CONSTEXPR20 insert_iterator<_Container> inserter(_Container& _Cont, typename _Container::iterator _Where) {
return insert_iterator<_Container>(_Cont, _Where);
}
#else // ^^^ No Ranges / Ranges vvv
template <class _Container>
_NODISCARD constexpr insert_iterator<_Container> inserter(_Container& _Cont, _RANGES iterator_t<_Container> _Where) {
return insert_iterator<_Container>(_Cont, _Where);
}

#ifdef __cpp_lib_concepts
template <semiregular _Se>
class move_sentinel {
public:
Expand Down Expand Up @@ -1044,7 +1049,7 @@ struct _Common_iterator_pointer_type {

// clang-format off
template <class _Iter, class _Se>
requires _Has_member_arrow<const common_iterator<_Iter, _Se>&> //
requires _Has_member_arrow<const common_iterator<_Iter, _Se>&>
struct _Common_iterator_pointer_type<_Iter, _Se> {
// clang-format on
using pointer = decltype(_STD declval<const common_iterator<_Iter, _Se>&>().operator->());
Expand Down
12 changes: 8 additions & 4 deletions stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ namespace ranges {
} else {
_Uninitialized_backout _Backout{_STD move(_OFirst)};

for (; _Count > 0 && _OFirst != _OLast; --_Count, (void) ++_IFirst) {
for (; _Count > 0 && _Backout._Last != _OLast; --_Count, (void) ++_IFirst) {
_Backout._Emplace_back(*_IFirst);
}

Expand Down Expand Up @@ -880,9 +880,13 @@ class _CXX17_DEPRECATE_RAW_STORAGE_ITERATOR raw_storage_iterator { // wrap store
public:
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = void;
using pointer = void;
using reference = void;
#ifdef __cpp_lib_concepts
using difference_type = ptrdiff_t;
#else
using difference_type = void;
#endif // __cpp_lib_concepts
using pointer = void;
using reference = void;

explicit raw_storage_iterator(_OutIt _First) : _Next(_First) {}

Expand Down
107 changes: 78 additions & 29 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,22 @@ namespace ranges {
}
}

template <_Not_same_as<_Ty> _Uty>
requires convertible_to<const _Uty&, _Ty>
constexpr _Defaultabox(const _Defaultabox<_Uty>& _That) : _Engaged{_That} {
if (_That) {
_Construct_in_place(_Val, *_That);
}
}

template <_Not_same_as<_Ty> _Uty>
requires convertible_to<_Uty, _Ty>
constexpr _Defaultabox(_Defaultabox<_Uty>&& _That) : _Engaged{_That} {
if (_That) {
_Construct_in_place(_Val, _STD move(*_That));
}
}

// clang-format off
_Defaultabox& operator=(const _Defaultabox&) noexcept
requires copyable<_Ty> && is_trivially_copy_assignable_v<_Ty> = default;
Expand Down Expand Up @@ -627,6 +643,24 @@ namespace ranges {
class _Defaultabox<_Ty> { // provide the same API more efficiently for default-constructible types
// clang-format on
public:
_Defaultabox() = default;

template <_Not_same_as<_Ty> _Uty>
requires convertible_to<const _Uty&, _Ty>
constexpr _Defaultabox(const _Defaultabox<_Uty>& _That) {
if (_That) {
_Value = static_cast<_Ty>(*_That);
}
}

template <_Not_same_as<_Ty> _Uty>
requires convertible_to<_Uty, _Ty>
constexpr _Defaultabox(_Defaultabox<_Uty>&& _That) {
if (_That) {
_Value = static_cast<_Ty>(_STD move(*_That));
}
}

constexpr _Defaultabox& operator=(const _Ty& _Right) noexcept(
is_nothrow_copy_assignable_v<_Ty>) requires copyable<_Ty> {
_Value = _Right;
Expand Down Expand Up @@ -978,23 +1012,17 @@ namespace ranges {
// clang-format on

template <class _Wi>
struct _Ioterator_category_base {
_NODISCARD auto operator<=>(const _Ioterator_category_base&) const = default;
};
struct _Ioterator_category_base {};

template <incrementable _Wi>
requires integral<_Iota_diff_t<_Wi>> // TRANSITION, LWG-3670
struct _Ioterator_category_base<_Wi> {
using iterator_category = input_iterator_tag;

_NODISCARD auto operator<=>(const _Ioterator_category_base&) const = default;
};

// clang-format off
template <weakly_incrementable _Wi>
requires copyable<_Wi>
struct _Ioterator : _Ioterator_category_base<_Wi> {
// clang-format on
/* [[no_unique_address]] */ _Wi _Current{};

using iterator_concept = conditional_t<_Advanceable<_Wi>, random_access_iterator_tag,
Expand Down Expand Up @@ -1115,10 +1143,10 @@ namespace ranges {
}
}

// clang-format off
_NODISCARD friend constexpr bool operator==(
const _Ioterator&, const _Ioterator&) requires equality_comparable<_Wi> = default;
// clang-format on
_NODISCARD friend constexpr bool operator==(const _Ioterator& _Left, const _Ioterator& _Right) noexcept(
noexcept(_Left._Current == _Right._Current)) requires equality_comparable<_Wi> {
return _Left._Current == _Right._Current;
}

_NODISCARD friend constexpr bool operator<(const _Ioterator& _Left, const _Ioterator& _Right) noexcept(
noexcept(_Left._Current < _Right._Current)) /* strengthened */ requires totally_ordered<_Wi> {
Expand All @@ -1137,10 +1165,10 @@ namespace ranges {
return !(_Left._Current < _Right._Current);
}

// clang-format off
_NODISCARD friend constexpr auto operator<=>(const _Ioterator& _Left, const _Ioterator& _Right)
requires totally_ordered<_Wi> && three_way_comparable<_Wi> = default;
// clang-format on
_NODISCARD friend constexpr auto operator<=>(const _Ioterator& _Left, const _Ioterator& _Right) noexcept(
noexcept(_Left._Current <=> _Right._Current)) requires totally_ordered<_Wi> && three_way_comparable<_Wi> {
return _Left._Current <=> _Right._Current;
}

_NODISCARD friend constexpr _Ioterator operator+(_Ioterator _It, const difference_type _Off) noexcept(
is_nothrow_move_constructible_v<_Ioterator>&& noexcept(
Expand All @@ -1153,16 +1181,30 @@ namespace ranges {
static_cast<_Wi>(_It._Current + _Off))) /* strengthened */ requires _Advanceable<_Wi> {
return _Ioterator{static_cast<_Wi>(_It._Current + _Off)};
}

_NODISCARD friend constexpr _Ioterator operator-(_Ioterator _It, const difference_type _Off) noexcept(
is_nothrow_move_constructible_v<_Ioterator>&& noexcept(
_It -= _Off)) /* strengthened */ requires _Advanceable<_Wi> {
_It -= _Off;
return _It;
}

_NODISCARD friend constexpr difference_type
operator-(const _Ioterator& _Left, const _Ioterator& _Right) noexcept(
noexcept(_Left._Current - _Right._Current)) /* strengthened */ requires _Advanceable<_Wi> {
return static_cast<difference_type>(_Left._Current - _Right._Current);
if constexpr (_Integer_like<_Wi>) {
if constexpr (_Signed_integer_like<_Wi>) {
return static_cast<difference_type>(
static_cast<difference_type>(_Left._Current) - static_cast<difference_type>(_Right._Current));
} else if (_Right._Current > _Left._Current) {
return static_cast<difference_type>(
-static_cast<difference_type>(_Right._Current - _Left._Current));
} else {
return static_cast<difference_type>(_Left._Current - _Right._Current);
}
} else {
return static_cast<difference_type>(_Left._Current - _Right._Current);
}
}
};

Expand Down Expand Up @@ -3132,7 +3174,7 @@ namespace ranges {
constexpr void _Check_dereference() const noexcept {
_STL_VERIFY(_Parent != nullptr, "cannot dereference value-initialized join_view iterator");
_STL_VERIFY(_Outer != _RANGES end(_Parent->_Range), "cannot dereference join_view end iterator");
sentinel_t<_InnerRng<false>> _Last;
sentinel_t<_InnerRng<_Const>> _Last;
if constexpr (_Deref_is_glvalue) {
_Last = _RANGES end(*_Outer);
} else {
Expand All @@ -3158,7 +3200,7 @@ namespace ranges {
using difference_type = common_type_t<range_difference_t<_Base>, range_difference_t<_InnerRng<_Const>>>;

// clang-format off
_Iterator() requires default_initializable<_OuterIter> && default_initializable<_InnerIter> = default;
_Iterator() requires default_initializable<_OuterIter> = default; // per LWG-3569
// clang-format on

constexpr _Iterator(_Parent_t& _Parent_, _OuterIter _Outer_)
Expand Down Expand Up @@ -3408,6 +3450,9 @@ namespace ranges {
inline constexpr _Join_fn join;
} // namespace views

template <auto> // _Require_constant<E> is a valid template-id iff E is a constant expression of structural type
struct _Require_constant;

// clang-format off
template <class _Ty>
concept _Tiny_range = sized_range<_Ty>
Expand Down Expand Up @@ -4029,20 +4074,24 @@ namespace ranges {

class _Counted_fn {
private:
enum class _St { _Span, _Subrange, _Subrange_counted };
enum class _St { _None, _Span, _Subrange, _Subrange_counted };

template <class _It>
_NODISCARD static _CONSTEVAL _Choice_t<_St> _Choose() noexcept {
_STL_INTERNAL_STATIC_ASSERT(input_or_output_iterator<_It>);
if constexpr (contiguous_iterator<_It>) {
return {_St::_Span, noexcept(span(_STD to_address(_STD declval<_It>()), iter_difference_t<_It>{}))};
} else if constexpr (random_access_iterator<_It>) {
using _Decayed = decay_t<_It>;
_STL_INTERNAL_STATIC_ASSERT(input_or_output_iterator<_Decayed>);
if constexpr (contiguous_iterator<_Decayed>) {
return {_St::_Span,
noexcept(span(_STD to_address(_STD declval<_It>()), iter_difference_t<_Decayed>{}))};
} else if constexpr (random_access_iterator<_Decayed>) {
return {_St::_Subrange,
noexcept(subrange(_STD declval<_It>(), _STD declval<_It>() + iter_difference_t<_It>{}))};
} else {
noexcept(subrange(_STD declval<_It>(), _STD declval<_It>() + iter_difference_t<_Decayed>{}))};
} else if constexpr (constructible_from<_Decayed, _It>) {
return {_St::_Subrange_counted,
noexcept(subrange(
counted_iterator(_STD declval<_It>(), iter_difference_t<_It>{}), default_sentinel))};
counted_iterator(_STD declval<_It>(), iter_difference_t<_Decayed>{}), default_sentinel))};
} else {
return {_St::_None};
}
}

Expand All @@ -4052,12 +4101,12 @@ namespace ranges {
public:
// clang-format off
template <class _It>
requires input_or_output_iterator<decay_t<_It>>
requires (input_or_output_iterator<decay_t<_It>> && _Choice<_It>._Strategy != _St::_None)
_NODISCARD constexpr auto operator()(_It&& _First, const iter_difference_t<decay_t<_It>> _Count) const
noexcept(_Choice<decay_t<_It>>._No_throw) {
noexcept(_Choice<_It>._No_throw) {
// clang-format on
_STL_ASSERT(_Count >= 0, "The size passed to views::counted must be non-negative");
constexpr _St _Strat = _Choice<decay_t<_It>>._Strategy;
constexpr _St _Strat = _Choice<_It>._Strategy;

if constexpr (_Strat == _St::_Span) {
return span(_STD to_address(_STD forward<_It>(_First)), static_cast<size_t>(_Count));
Expand Down
Loading