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

Workaround some Clang-16-rc2 regressions #3483

Merged
merged 2 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 10 additions & 8 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -7570,6 +7570,12 @@ namespace ranges {
&& (convertible_to<sentinel_t<_ViewTypes>, sentinel_t<const _ViewTypes>> && ...);
#endif // ^^^ workaround ^^^

template <class _Func, class... _Views>
concept _Zip_transform_constraints = move_constructible<_Func> && is_object_v<_Func> && (sizeof...(_Views) > 0)
&& (input_range<_Views> && ...) && (view<_Views> && ...)
&& regular_invocable<_Func&, range_reference_t<_Views>...>
&& _Can_reference<invoke_result_t<_Func&, range_reference_t<_Views>...>>;

_EXPORT_STD template <input_range... _ViewTypes>
requires (view<_ViewTypes> && ...) && (sizeof...(_ViewTypes) > 0)
class zip_view : public view_interface<zip_view<_ViewTypes...>> {
Expand All @@ -7590,10 +7596,8 @@ namespace ranges {
private:
friend zip_view;

template <move_constructible _Func, input_range... _OtherViews>
requires ((view<_OtherViews> && ...) && (sizeof...(_OtherViews) > 0)
&& is_object_v<_Func> && regular_invocable<_Func&, range_reference_t<_OtherViews>...>
&& _Can_reference<invoke_result_t<_Func&, range_reference_t<_OtherViews>...>>)
template <class _Func, class... _OtherViews>
requires _Zip_transform_constraints<_Func, _OtherViews...>
friend class zip_transform_view;

using _My_tuple = tuple<iterator_t<_Maybe_const<_IsConst, _ViewTypes>>...>;
Expand Down Expand Up @@ -7988,10 +7992,8 @@ namespace ranges {
_EXPORT_STD inline constexpr _Zip_fn zip{};
} // namespace views

_EXPORT_STD template <move_constructible _Func, input_range... _ViewTypes>
requires ((view<_ViewTypes> && ...) && (sizeof...(_ViewTypes) > 0)
&& is_object_v<_Func> && regular_invocable<_Func&, range_reference_t<_ViewTypes>...>
&& _Can_reference<invoke_result_t<_Func&, range_reference_t<_ViewTypes>...>>)
_EXPORT_STD template <class _Func, class... _ViewTypes>
requires _Zip_transform_constraints<_Func, _ViewTypes...>
class zip_transform_view : public view_interface<zip_transform_view<_Func, _ViewTypes...>> {
private:
using _Inner_view = zip_view<_ViewTypes...>;
Expand Down
118 changes: 59 additions & 59 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -3599,99 +3599,99 @@ _EXPORT_STD template <size_t _Index, class... _Types>
_NODISCARD constexpr const tuple_element_t<_Index, tuple<_Types...>>&& get(const tuple<_Types...>&& _Tuple) noexcept;

namespace ranges {
// clang-format off
template <class _From, class _To>
concept _Uses_nonqualification_pointer_conversion =
is_pointer_v<_From> && is_pointer_v<_To>
&& !convertible_to<remove_pointer_t<_From>(*)[], remove_pointer_t<_To>(*)[]>;
&& (!convertible_to<remove_pointer_t<_From> (*)[], remove_pointer_t<_To> (*)[]>);

template <class _From, class _To>
concept _Convertible_to_non_slicing = convertible_to<_From, _To>
&& !_Uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>;
&& (!_Uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>);

template <class _Ty>
concept _Pair_like = !is_reference_v<_Ty> && requires(_Ty __t) {
typename tuple_size<_Ty>::type;
requires derived_from<tuple_size<_Ty>, integral_constant<size_t, 2>>;
typename tuple_element_t<0, remove_const_t<_Ty>>;
typename tuple_element_t<1, remove_const_t<_Ty>>;
{ _STD get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Ty>&>;
{ _STD get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Ty>&>;
};
concept _Pair_like =
(!is_reference_v<_Ty>) && requires(_Ty __t) {
typename tuple_size<_Ty>::type;
requires derived_from<tuple_size<_Ty>, integral_constant<size_t, 2>>;
typename tuple_element_t<0, remove_const_t<_Ty>>;
typename tuple_element_t<1, remove_const_t<_Ty>>;
{ _STD get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Ty>&>;
{ _STD get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Ty>&>;
};

template <class _Ty, class _First, class _Second>
concept _Pair_like_convertible_from = !range<_Ty> && _Pair_like<_Ty>
&& constructible_from<_Ty, _First, _Second>
&& _Convertible_to_non_slicing<_First, tuple_element_t<0, _Ty>>
&& convertible_to<_Second, tuple_element_t<1, _Ty>>;
// clang-format on
concept _Pair_like_convertible_from = (!range<_Ty>) && _Pair_like<_Ty> && constructible_from<_Ty, _First, _Second>
&& _Convertible_to_non_slicing<_First, tuple_element_t<0, _Ty>>
&& convertible_to<_Second, tuple_element_t<1, _Ty>>;

template <class _It, class _Se, subrange_kind _Ki,
bool _Store = _Ki == subrange_kind::sized && !sized_sentinel_for<_Se, _It>>
class _Subrange_base : public view_interface<subrange<_It, _Se, _Ki>> { // TRANSITION, [[no_unique_address]]
protected:
using _Size_type = _Make_unsigned_like_t<iter_difference_t<_It>>;
static constexpr bool _Store_size = true;
template <class _It, class _Se, subrange_kind _Ki>
concept _Store_size = (_Ki == subrange_kind::sized) && (!sized_sentinel_for<_Se, _It>);

_Size_type _Size = 0;
template <class _It, class _Se, subrange_kind _Ki>
class _Subrange_base : public view_interface<subrange<_It, _Se, _Ki>> {
protected:
using _Size_type = _Make_unsigned_like_t<iter_difference_t<_It>>;

public:
_Subrange_base() = default;
constexpr explicit _Subrange_base(const _Size_type& _Size_) noexcept : _Size(_Size_) {}
constexpr explicit _Subrange_base(const _Size_type&) noexcept {}
};

template <class _It, class _Se, subrange_kind _Ki>
class _Subrange_base<_It, _Se, _Ki, false> : public view_interface<subrange<_It, _Se, _Ki>> {
requires _Store_size<_It, _Se, _Ki>
class _Subrange_base<_It, _Se, _Ki> : public view_interface<subrange<_It, _Se, _Ki>> {
protected:
using _Size_type = _Make_unsigned_like_t<iter_difference_t<_It>>;
static constexpr bool _Store_size = false;
using _Size_type = _Make_unsigned_like_t<iter_difference_t<_It>>;

_Size_type _Size = 0;

public:
_Subrange_base() = default;
constexpr explicit _Subrange_base(const _Size_type&) noexcept {}
constexpr explicit _Subrange_base(const _Size_type& _Size_) noexcept : _Size(_Size_) {}
};

#if 1 // TRANSITION, VSO-1695918 - Warning C4324 incorrectly firing in the presence of `pragma pack`
#pragma warning(push)
#pragma warning(disable : 4324) // structure was padded due to alignment specifier
#endif // TRANSITION, VSO-1695918 - Warning C4324 incorrectly firing in the presence of `pragma pack`
#endif // ^^^ workaround ^^^
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
_EXPORT_STD template <input_or_output_iterator _It, sentinel_for<_It> _Se, subrange_kind _Ki>
requires (_Ki == subrange_kind::sized || !sized_sentinel_for<_Se, _It>)
class subrange : public _Subrange_base<_It, _Se, _Ki> {
private:
using _Mybase = _Subrange_base<_It, _Se, _Ki>;
using _Mybase::_Store_size;
using typename _Mybase::_Size_type;
using _Size_type = _Make_unsigned_like_t<iter_difference_t<_It>>;

// TRANSITION, [[no_unique_address]]:
/* [[no_unique_address]] */ _It _First{};
/* [[no_unique_address]] */ _Se _Last{};
// [[no_unique_address]] conditional_t<_Store_size, _Size_type, _Nil> _Size{};
// [[no_unique_address]] conditional_t<_Store_size<_It, _Se, _Ki>, _Size_type, _Nil> _Size{};

template <class _Rng>
constexpr subrange(true_type, _Rng&& _Val)
: subrange(_STD forward<_Rng>(_Val), static_cast<_Size_type>(_RANGES size(_Val))) {
// delegation target for subrange(_Rng&&) when we must store the range size
_STL_INTERNAL_STATIC_ASSERT(_Store_size);
_STL_INTERNAL_STATIC_ASSERT(_Store_size<_It, _Se, _Ki>);
}

template <class _Rng>
constexpr subrange(false_type, _Rng&& _Val) : subrange(_RANGES begin(_Val), _RANGES end(_Val)) {
// delegation target for subrange(_Rng&&) when we need not store the range size
_STL_INTERNAL_STATIC_ASSERT(!_Store_size);
_STL_INTERNAL_STATIC_ASSERT(!_Store_size<_It, _Se, _Ki>);
}

public:
// clang-format off
subrange() requires default_initializable<_It> = default;
// clang-format on

template <_Convertible_to_non_slicing<_It> _It2>
constexpr subrange(_It2 _First_, _Se _Last_) requires (!_Store_size)
constexpr subrange(_It2 _First_, _Se _Last_)
requires (!_Store_size<_It, _Se, _Ki>)
: _First(_STD move(_First_)), _Last(_STD move(_Last_)) {}

template <_Convertible_to_non_slicing<_It> _It2>
constexpr subrange(_It2 _First_, _Se _Last_, const _Size_type _Size_) requires (_Ki == subrange_kind::sized)
: _Mybase(_Size_), _First(_STD move(_First_)), _Last(_STD move(_Last_)) {
constexpr subrange(_It2 _First_, _Se _Last_, const _Size_type _Size_)
requires (_Ki == subrange_kind::sized)
: _Subrange_base<_It, _Se, _Ki>(_Size_), _First(_STD move(_First_)), _Last(_STD move(_Last_)) {
if constexpr (sized_sentinel_for<_Se, _It>) {
_STL_ASSERT(_Size_ == static_cast<_Size_type>(_Last - _First),
"This constructor's third argument should be equal to the distance "
Expand All @@ -3700,17 +3700,17 @@ namespace ranges {
}

template <_Different_from<subrange> _Rng>
requires borrowed_range<_Rng>
&& _Convertible_to_non_slicing<iterator_t<_Rng>, _It>
&& convertible_to<sentinel_t<_Rng>, _Se>
constexpr subrange(_Rng&& _Val) requires (!_Store_size || sized_range<_Rng>)
: subrange{bool_constant<_Store_size>{}, _STD forward<_Rng>(_Val)} {}
requires (borrowed_range<_Rng> && _Convertible_to_non_slicing<iterator_t<_Rng>, _It>
&& convertible_to<sentinel_t<_Rng>, _Se>)
constexpr subrange(_Rng&& _Val)
requires (!_Store_size<_It, _Se, _Ki> || sized_range<_Rng>)
: subrange{bool_constant<_Store_size<_It, _Se, _Ki>>{}, _STD forward<_Rng>(_Val)} {}

template <borrowed_range _Rng>
requires _Convertible_to_non_slicing<iterator_t<_Rng>, _It> && convertible_to<sentinel_t<_Rng>, _Se>
constexpr subrange(_Rng&& _Val, const _Size_type _Count) requires (_Ki == subrange_kind::sized)
requires (_Convertible_to_non_slicing<iterator_t<_Rng>, _It> && convertible_to<sentinel_t<_Rng>, _Se>)
constexpr subrange(_Rng&& _Val, const _Size_type _Count)
requires (_Ki == subrange_kind::sized)
: subrange{_RANGES begin(_Val), _RANGES end(_Val), _Count} {}
// clang-format on

template <_Different_from<subrange> _Pair_like>
requires _Pair_like_convertible_from<_Pair_like, const _It&, const _Se&>
Expand All @@ -3723,9 +3723,9 @@ namespace ranges {
{
return _First;
}
// clang-format off
_NODISCARD constexpr _It begin() requires (!copyable<_It>) {
// clang-format on
_NODISCARD constexpr _It begin()
requires (!copyable<_It>)
{
return _STD move(_First);
}

Expand All @@ -3737,10 +3737,10 @@ namespace ranges {
return _First == _Last;
}

// clang-format off
_NODISCARD constexpr _Size_type size() const requires (_Ki == subrange_kind::sized) {
// clang-format on
if constexpr (_Store_size) {
_NODISCARD constexpr _Size_type size() const
requires (_Ki == subrange_kind::sized)
{
if constexpr (_Store_size<_It, _Se, _Ki>) {
return this->_Size;
} else {
return static_cast<_Size_type>(_Last - _First);
Expand All @@ -3753,7 +3753,7 @@ namespace ranges {
auto _Tmp = *this;
if (_Tmp._First != _Tmp._Last) {
++_Tmp._First;
if constexpr (_Store_size) {
if constexpr (_Store_size<_It, _Se, _Ki>) {
--_Tmp._Size;
}
}
Expand All @@ -3770,7 +3770,7 @@ namespace ranges {
_NODISCARD constexpr subrange next() && {
if (_First != _Last) {
++_First;
if constexpr (_Store_size) {
if constexpr (_Store_size<_It, _Se, _Ki>) {
--this->_Size;
}
}
Expand All @@ -3786,7 +3786,7 @@ namespace ranges {
{
auto _Tmp = *this;
--_Tmp._First;
if constexpr (_Store_size) {
if constexpr (_Store_size<_It, _Se, _Ki>) {
++_Tmp._Size;
}
return _Tmp;
Expand All @@ -3803,23 +3803,23 @@ namespace ranges {
if constexpr (bidirectional_iterator<_It>) {
if (_Count < 0) {
_RANGES advance(_First, _Count);
if constexpr (_Store_size) {
if constexpr (_Store_size<_It, _Se, _Ki>) {
this->_Size += static_cast<_Size_type>(-_Count);
}
return *this;
}
}

const auto _Remainder = _RANGES advance(_First, _Count, _Last);
if constexpr (_Store_size) {
if constexpr (_Store_size<_It, _Se, _Ki>) {
this->_Size -= static_cast<_Size_type>(_Count - _Remainder);
}
return *this;
}
};
#if 1 // TRANSITION, VSO-1695918 - Warning C4324 incorrectly firing in the presence of `pragma pack`
#pragma warning(pop)
#endif // TRANSITION, VSO-1695918 - Warning C4324 incorrectly firing in the presence of `pragma pack`
#endif // ^^^ workaround ^^^

template <input_or_output_iterator _It, sentinel_for<_It> _Se>
subrange(_It, _Se) -> subrange<_It, _Se>;
Expand Down
2 changes: 1 addition & 1 deletion tests/std/tests/P0323R12_expected/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ namespace test_expected {

struct payload_default_constructor {
constexpr payload_default_constructor()
requires (should_be_defaultable)
requires (IsYes(defaultConstructible))
: _val(42) {}

[[nodiscard]] constexpr bool operator==(const int val) const noexcept {
Expand Down