#include <cassert>
#include <tuple>
#include <utility>
#include "copy_move_types.h"
static_assert(std::is_constructible_v<std::tuple<MutableCopy, int>, std::pair<MutableCopy, int>&>);
static_assert(!std::is_constructible_v<std::tuple<MutableCopy>, std::pair<MutableCopy, int>&>);
static_assert(!std::is_constructible_v<std::tuple<MutableCopy, int, int>, std::pair<MutableCopy, int>&>);
static_assert(std::is_constructible_v<std::tuple<int, int>, std::pair<int, int>&>);
static_assert(!std::is_constructible_v<std::tuple<NoConstructorFromInt, int>, std::pair<int, int>&>);
static_assert(!std::is_constructible_v<std::tuple<int, NoConstructorFromInt>, std::pair<int, int>&>);
static_assert(!std::is_constructible_v< std::tuple<NoConstructorFromInt, NoConstructorFromInt>, std::pair<int, int>&>);
static_assert(std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&,
std::tuple<ConvertibleFrom<MutableCopy>, ConvertibleFrom<MutableCopy>>>);
static_assert(!std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&,
std::tuple<ExplicitConstructibleFrom<MutableCopy>, ConvertibleFrom<MutableCopy>>>);
static_assert(!std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&,
std::tuple<ConvertibleFrom<MutableCopy>, ExplicitConstructibleFrom<MutableCopy>>>);
constexpr bool test() {
{
std::pair<MutableCopy, int> p{1, 2};
std::tuple<ConvertibleFrom<MutableCopy>, ConvertibleFrom<int>> t = p;
assert(std::get<0>(t).v.val == 1);
assert(std::get<1>(t).v == 2);
}
{
std::pair<MutableCopy, int> p{1, 2};
std::tuple<ExplicitConstructibleFrom<MutableCopy>, ExplicitConstructibleFrom<int>> t{p};
assert(std::get<0>(t).v.val == 1);
assert(std::get<1>(t).v == 2);
}
{
std::pair<TracedCopyMove, TracedCopyMove> p;
std::tuple<ConvertibleFrom<TracedCopyMove>, TracedCopyMove> t = p;
assert(nonConstCopyCtrCalled(std::get<0>(t).v));
assert(nonConstCopyCtrCalled(std::get<1>(t)));
}
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}