Skip to content
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
35 changes: 31 additions & 4 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -866,8 +866,36 @@ namespace ranges {
template <class _Ty>
concept _Can_deref = requires(_Ty&& __t) { *static_cast<_Ty&&>(__t); };

struct _Must_have_ADL_found_iter_move_or_be_dereferenceable {};

class _Cpo {
private:
template <class _Ty>
_NODISCARD static auto _Choose_return_type() {
if constexpr (_Has_ADL<_Ty>) {
return type_identity<decltype(iter_move(_STD declval<_Ty>()))>{}; // intentional ADL
} else if constexpr (_Can_deref<_Ty>) {
using _Ref = decltype(*_STD declval<_Ty>());
#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-1008447, VSO-2066340
if constexpr (is_function_v<remove_reference_t<_Ref>>) {
return type_identity<_Ref&>{};
} else
#endif // ^^^ workaround ^^^
{
if constexpr (is_lvalue_reference_v<_Ref>) {
return type_identity<remove_reference_t<_Ref>&&>{};
} else {
return type_identity<_Ref>{};
}
}
} else {
return _Must_have_ADL_found_iter_move_or_be_dereferenceable{};
}
}

template <class _Ty>
using _Return_type = decltype(_Choose_return_type<_Ty>())::type;

enum class _St { _None, _Custom, _Fallback };

template <class _Ty>
Expand All @@ -886,8 +914,7 @@ namespace ranges {

public:
template <class _Ty>
requires (_Choice<_Ty>._Strategy != _St::_None)
_NODISCARD _STATIC_CALL_OPERATOR constexpr decltype(auto) operator()(_Ty&& _Val) _CONST_CALL_OPERATOR
_NODISCARD _STATIC_CALL_OPERATOR constexpr _Return_type<_Ty> operator()(_Ty&& _Val) _CONST_CALL_OPERATOR
noexcept(_Choice<_Ty>._No_throw) {
constexpr _St _Strat = _Choice<_Ty>._Strategy;

Expand Down Expand Up @@ -1121,8 +1148,8 @@ struct _Projected_impl {

using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>;
[[noreturn]] indirect_result_t<_Proj&, _It> operator*() const {
_STL_REPORT_ERROR("std::projected::operator*() can't be called (N5008 [projected]/1)");
_STL_UNREACHABLE; // no return value available for "continue on error"
static_assert(
false, "std::projected::operator*() can't be instantiated (N5008 [projected] as modified by LWG-4270)");
}
};
};
Expand Down
9 changes: 0 additions & 9 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1164,12 +1164,6 @@ std/containers/sequences/vector.bool/vector_bool.pass.cpp FAIL
# Not analyzed. Inspecting shift operators for quoted().
std/input.output/iostream.format/quoted.manip/quoted_traits.compile.pass.cpp FAIL

# Not analyzed.
# MSVC warning C5046: 'test_undefined_internal::A::operator *': Symbol involving type with internal linkage not defined
# Clang error: function 'test_undefined_internal()::A::operator*' has internal linkage but is not defined [-Werror,-Wundefined-internal]
std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp FAIL
std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.comp/op_spaceship.pass.cpp FAIL

# Not analyzed. Failing assert(arr[0].moves() == 1 && arr[1].moves() == 3).
std/iterators/iterator.requirements/iterator.cust/iterator.cust.swap/iter_swap.pass.cpp FAIL

Expand Down Expand Up @@ -1518,9 +1512,6 @@ std/algorithms/alg.sorting/alg.set.operations/set.intersection/set_intersection_
# Clang assertion: std::hermite(n, +inf) == inf
std/numerics/c.math/hermite.pass.cpp FAIL

# Not analyzed. Test coverage for LLVM-104496 uses span<Incomplete>.
std/containers/views/views.span/span.cons/copy.pass.cpp FAIL

# Not analyzed. These tests disable or limit allocations, which interferes with our proxy objects.
std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp FAIL
std/containers/sequences/vector/vector.capacity/shrink_to_fit_exceptions.pass.cpp FAIL
Expand Down
4 changes: 0 additions & 4 deletions tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1073,9 +1073,7 @@ namespace iterator_cust_move_test {
static_assert(noexcept(ranges::iter_move(static_cast<int const*>(&some_ints[2]))));

static_assert(same_as<iter_rvalue_reference_t<int[]>, int&&>);
#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-1008447, VSO-2066340
static_assert(same_as<iter_rvalue_reference_t<int(int)>, int (&)(int)>);
#endif // ^^^ no workaround ^^^

static_assert(same_as<iter_rvalue_reference_t<int[4]>, int&&>);
static_assert(ranges::iter_move(some_ints) == 0);
Expand All @@ -1084,9 +1082,7 @@ namespace iterator_cust_move_test {
constexpr int f(int i) noexcept {
return i + 1;
}
#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-1008447
static_assert(same_as<iter_rvalue_reference_t<int (*)(int)>, int (&)(int)>);
#endif // ^^^ no workaround ^^^
static_assert(ranges::iter_move(&f)(42) == 43);
static_assert(noexcept(ranges::iter_move(&f)));

Expand Down