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

Implement LWG-3121: tuple constructor constraints for UTypes&&... overloads #2640

Merged
merged 9 commits into from
Apr 16, 2022
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
13 changes: 11 additions & 2 deletions stl/inc/tuple
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,17 @@ template <class _Myself, class _This2, class... _Rest2>
struct _Tuple_perfect_val : true_type {};

template <class _Myself, class _This2>
struct _Tuple_perfect_val<_Myself, _This2>
: bool_constant<!is_same_v<_Myself, remove_const_t<remove_reference_t<_This2>>>> {};
struct _Tuple_perfect_val<_Myself, _This2> : bool_constant<!is_same_v<_Myself, _Remove_cvref_t<_This2>>> {};

template <class _Ty0, class _Ty1, class _Uty0, class _Uty1>
struct _Tuple_perfect_val<tuple<_Ty0, _Ty1>, _Uty0, _Uty1>
: bool_constant<disjunction_v<negation<is_same<_Remove_cvref_t<_Uty0>, allocator_arg_t>>,
is_same<_Remove_cvref_t<_Ty0>, allocator_arg_t>>> {};

template <class _Ty0, class _Ty1, class _Ty2, class _Uty0, class _Uty1, class _Uty2>
struct _Tuple_perfect_val<tuple<_Ty0, _Ty1, _Ty2>, _Uty0, _Uty1, _Uty2>
: bool_constant<disjunction_v<negation<is_same<_Remove_cvref_t<_Uty0>, allocator_arg_t>>,
is_same<_Remove_cvref_t<_Ty0>, allocator_arg_t>>> {};

struct _Ignore { // struct that ignores assignments
template <class _Ty>
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ tests\GH_002488_promise_not_default_constructible_types
tests\GH_002581_common_reference_workaround
tests\LWG2597_complex_branch_cut
tests\LWG3018_shared_ptr_function
tests\LWG3121_constrained_tuple_forwarding_ctor
tests\LWG3146_excessive_unwrapping_ref_cref
tests\LWG3422_seed_seq_ctors
tests\LWG3480_directory_iterator_range
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 ..\usual_matrix.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cassert>
#include <memory>
#include <tuple>
#include <type_traits>

#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

#if _HAS_CXX20
#define CONSTEXPR_VAR_20 constexpr
#else
#define CONSTEXPR_VAR_20 const
#endif

using namespace std;

class pseudo_any {
private:
bool has_value_ = false;

public:
pseudo_any() = default;
template <class ValT,
enable_if_t<conjunction_v<negation<is_same<decay_t<ValT>, pseudo_any>>, is_copy_constructible<decay_t<ValT>>>,
int> = 0>
constexpr pseudo_any(ValT&&) noexcept : has_value_{true} {}

constexpr bool has_value() const noexcept {
return has_value_;
}
};

STATIC_ASSERT(is_copy_constructible_v<tuple<pseudo_any>>);

using TA2 = tuple<pseudo_any, pseudo_any>;
using TA3 = tuple<pseudo_any, pseudo_any, pseudo_any>;

CONSTEXPR_VAR_20 TA2 t2{allocator_arg, allocator<int>{}};
CONSTEXPR_VAR_20 TA3 t3{allocator_arg, allocator<int>{}, tuple<pseudo_any, pseudo_any, int>{}};

#if _HAS_CXX20
static_assert(!get<0>(t2).has_value());
static_assert(!get<1>(t2).has_value());
static_assert(!get<0>(t3).has_value());
static_assert(!get<1>(t3).has_value());
static_assert(get<2>(t3).has_value());
#endif // _HAS_CXX20

int main() {
assert(!get<0>(t2).has_value());
assert(!get<1>(t2).has_value());
assert(!get<0>(t3).has_value());
assert(!get<1>(t3).has_value());
assert(get<2>(t3).has_value());
}