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

<type_traits>: Workaround for common_reference #2592

Merged
Merged
Show file tree
Hide file tree
Changes from 10 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
32 changes: 28 additions & 4 deletions stl/inc/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -1179,10 +1179,6 @@ struct basic_common_reference {};
template <class _Ty>
_Ty _Returns_exactly() noexcept; // not defined

template <class _Ty1, class _Ty2>
using _Cond_res = // N4810 [meta.trans.other]/2.4
decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>());

template <class _From>
struct _Copy_cv_impl {
template <class _To>
Expand Down Expand Up @@ -1223,6 +1219,34 @@ struct _Add_qualifiers<_Ty1&&> {
using _Apply = add_rvalue_reference_t<_Copy_cv<_Ty1, _Ty2>>;
};

#if !defined(__EDG__) && !defined(__clang__) // TRANSITION, DevCom-876860
template <class _Ty1, class _Ty2>
using _Cond_res_if_right = // N4810 [meta.trans.other]/2.4
decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>());

template <class _Ty>
using _Is_scalar_or_array = disjunction<is_scalar<_Ty>, is_array<_Ty>>;

template <class _Ty1, class _Ty2, class = void>
struct _Cond_res_workaround {};

template <class _Ty1, class _Ty2>
struct _Cond_res_workaround<_Ty1, _Ty2, void_t<_Cond_res_if_right<_Ty1, _Ty2>>> {
using _Uty = remove_cvref_t<_Ty1>;
using type = conditional_t<conjunction_v<is_same<_Uty, remove_cvref_t<_Ty2>>, _Is_scalar_or_array<_Uty>,
disjunction<conjunction<is_lvalue_reference<_Ty1>, is_rvalue_reference<_Ty2>>,
conjunction<is_rvalue_reference<_Ty1>, is_lvalue_reference<_Ty2>>>>,
decay_t<_Copy_cv<remove_reference_t<_Ty1>, remove_reference_t<_Ty2>>>, _Cond_res_if_right<_Ty1, _Ty2>>;
};

template <class _Ty1, class _Ty2>
using _Cond_res = typename _Cond_res_workaround<_Ty1, _Ty2>::type;
#else // ^^^ workaround / no workaround vvv
template <class _Ty1, class _Ty2>
using _Cond_res = // N4810 [meta.trans.other]/2.4
decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>());
#endif
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved

template <class...>
struct common_reference;

Expand Down
11 changes: 0 additions & 11 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,17 +256,6 @@ std/atomics/atomics.types.generic/copy_semantics_traits.pass.cpp FAIL
# DevCom-409222 "Constructing rvalue reference from non-reference-related lvalue reference"
std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp:0 FAIL

# DevCom-876860 "conditional operator errors" blocks readable<volatile int*>.
std/concepts/concepts.lang/concept.common/common_with.compile.pass.cpp:0 FAIL
std/concepts/concepts.lang/concept.commonref/common_reference.compile.pass.cpp:0 FAIL
std/containers/views/span.cons/iterator_sentinel.pass.cpp:0 FAIL
std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/bidirectional_iterator.compile.pass.cpp:0 FAIL
std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp:0 FAIL
std/iterators/iterator.requirements/iterator.concepts/iterator.concept.readable/indirectly_readable.compile.pass.cpp:0 FAIL
std/iterators/iterator.requirements/iterator.concepts/iterator.concept.forward/forward_iterator.compile.pass.cpp:0 FAIL
std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp:0 FAIL
std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp:0 FAIL

# VSO-1271673 "static analyzer doesn't know about short-circuiting"
std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort.pass.cpp:0 FAIL
std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp:0 FAIL
Expand Down
11 changes: 0 additions & 11 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,17 +256,6 @@ atomics\atomics.types.generic\copy_semantics_traits.pass.cpp
# DevCom-409222 "Constructing rvalue reference from non-reference-related lvalue reference"
utilities\meta\meta.unary\meta.unary.prop\is_constructible.pass.cpp

# DevCom-876860 "conditional operator errors" blocks readable<volatile int*>.
concepts\concepts.lang\concept.common\common_with.compile.pass.cpp
concepts\concepts.lang\concept.commonref\common_reference.compile.pass.cpp
containers\views\span.cons\iterator_sentinel.pass.cpp
iterators\iterator.requirements\iterator.concepts\iterator.concept.bidir\bidirectional_iterator.compile.pass.cpp
iterators\iterator.requirements\iterator.concepts\iterator.concept.random.access\contiguous_iterator.compile.pass.cpp
iterators\iterator.requirements\iterator.concepts\iterator.concept.readable\indirectly_readable.compile.pass.cpp
iterators\iterator.requirements\iterator.concepts\iterator.concept.forward\forward_iterator.compile.pass.cpp
iterators\iterator.requirements\iterator.concepts\iterator.concept.input\input_iterator.compile.pass.cpp
iterators\iterator.requirements\iterator.concepts\iterator.concept.random.access\random_access_iterator.compile.pass.cpp

# VSO-1271673 "static analyzer doesn't know about short-circuiting"
algorithms\alg.sorting\alg.sort\partial.sort\partial_sort.pass.cpp
algorithms\alg.sorting\alg.sort\partial.sort\partial_sort_comp.pass.cpp
Expand Down
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_20_matrix.lst
42 changes: 42 additions & 0 deletions tests/std/tests/GH_002581_common_reference_workaround/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <cstddef>
frederick-vs-ja marked this conversation as resolved.
Show resolved Hide resolved
#include <iterator>

using namespace std;

struct Test {};
enum Unscoped {};
enum class Scoped {};

// Tests for raw pointers
static_assert(contiguous_iterator<volatile int*>);
static_assert(contiguous_iterator<const volatile int*>);
static_assert(contiguous_iterator<volatile double*>);
static_assert(contiguous_iterator<const volatile double*>);
static_assert(contiguous_iterator<volatile nullptr_t*>);
static_assert(contiguous_iterator<const volatile nullptr_t*>);
static_assert(contiguous_iterator<volatile Unscoped*>);
static_assert(contiguous_iterator<const volatile Unscoped*>);
static_assert(contiguous_iterator<volatile Scoped*>);
static_assert(contiguous_iterator<const volatile Scoped*>);
static_assert(contiguous_iterator<Test* volatile*>);
static_assert(contiguous_iterator<Test* const volatile*>);
static_assert(contiguous_iterator<int Test::*volatile*>);
static_assert(contiguous_iterator<int Test::*const volatile*>);

// Tests for move_iterator specializations
static_assert(input_iterator<move_iterator<volatile int*>>);
static_assert(input_iterator<move_iterator<const volatile int*>>);
static_assert(input_iterator<move_iterator<volatile double*>>);
static_assert(input_iterator<move_iterator<const volatile double*>>);
static_assert(input_iterator<move_iterator<volatile nullptr_t*>>);
static_assert(input_iterator<move_iterator<const volatile nullptr_t*>>);
static_assert(input_iterator<move_iterator<volatile Unscoped*>>);
static_assert(input_iterator<move_iterator<const volatile Unscoped*>>);
static_assert(input_iterator<move_iterator<volatile Scoped*>>);
static_assert(input_iterator<move_iterator<const volatile Scoped*>>);
static_assert(input_iterator<move_iterator<Test* volatile*>>);
static_assert(input_iterator<move_iterator<Test* const volatile*>>);
static_assert(input_iterator<move_iterator<int Test::*volatile*>>);
static_assert(input_iterator<move_iterator<int Test::*const volatile*>>);

int main() {} // COMPILE-ONLY
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved