blob: ef06df1c53fa966dadfd2a57ea27a2be59f5e796 [file]
// Verify P2165R4 enhancements to std::pair.
// { dg-do run { target c++23 } }
#include <array>
#include <tuple>
#include <utility>
#include <testsuite_hooks.h>
using std::array;
using std::pair;
using std::tuple;
struct A { };
template<template<typename> class pair_like_t>
constexpr bool
test01()
{
struct B {
int m;
constexpr B(A&) : m(0) { }
constexpr B(A&&) : m(1) { }
constexpr B(const A&) : m(2) { }
constexpr B(const A&&) : m(3) { }
};
// template<pair-like UPair>
// constexpr explicit(false) pair(UPair&&);
pair_like_t<A> pair_like;
[&] {
pair<B, B> p2b = pair_like;
VERIFY( p2b.first.m == 0 && p2b.second.m == 0 );
}();
[&] {
pair<B, B> p2b = std::move(pair_like);
VERIFY( p2b.first.m == 1 && p2b.second.m == 1 );
}();
[&] {
pair<B, B> p2b = std::as_const(pair_like);
VERIFY( p2b.first.m == 2 && p2b.second.m == 2 );
}();
[&] {
pair<B, B> p2b = std::move(std::as_const(pair_like));
VERIFY( p2b.first.m == 3 && p2b.second.m == 3 );
}();
// Verify dangling checks.
static_assert( !std::is_constructible_v<pair<const int&, int>, pair_like_t<long>> );
static_assert( !std::is_constructible_v<pair<int, const int&>, pair_like_t<long>> );
return true;
}
template<template<typename> class pair_like_t>
constexpr bool
test02()
{
struct B {
int m;
constexpr explicit B(A&) : m(0) { }
constexpr explicit B(A&&) : m(1) { }
constexpr explicit B(const A&) : m(2) { }
constexpr explicit B(const A&&) : m(3) { }
};
// template<pair-like UPair>
// constexpr explicit(true) pair(UPair&&);
static_assert( !std::is_convertible_v<pair_like_t<A>, pair<B, B>> );
pair_like_t<A> pair_like;
[&] {
pair<B, B> p2b{pair_like};
VERIFY( p2b.first.m == 0 && p2b.second.m == 0 );
}();
[&] {
pair<B, B> p2b{std::move(pair_like)};
VERIFY( p2b.first.m == 1 && p2b.second.m == 1 );
}();
[&] {
pair<B, B> p2b{std::as_const(pair_like)};
VERIFY( p2b.first.m == 2 && p2b.second.m == 2 );
}();
[&] {
pair<B, B> p2b{std::move(std::as_const(pair_like))};
VERIFY( p2b.first.m == 3 && p2b.second.m == 3 );
}();
return true;
}
template<template<typename> class pair_like_t>
constexpr bool
test03()
{
struct B {
int m;
constexpr B& operator=(A&) { m = 0; return *this; }
constexpr B& operator=(A&&) { m = 1; return *this; }
constexpr B& operator=(const A&) { m = 2; return *this; }
constexpr B& operator=(const A&&) { m = 3; return *this; }
};
// template<pair-like UPair>
// constexpr pair& operator=(UPair&&);
pair_like_t<A> pair_like;
pair<B, B> p2b;
p2b = pair_like;
VERIFY( p2b.first.m == 0 && p2b.second.m == 0 );
p2b = std::move(pair_like);
VERIFY( p2b.first.m == 1 && p2b.second.m == 1 );
p2b = std::as_const(pair_like);
VERIFY( p2b.first.m == 2 && p2b.second.m == 2 );
p2b = std::move(std::as_const(pair_like));
VERIFY( p2b.first.m == 3 && p2b.second.m == 3 );
return true;
}
template<template<typename> class pair_like_t>
constexpr bool
test04()
{
struct B {
mutable int m;
constexpr const B& operator=(A&) const { m = 0; return *this; }
constexpr const B& operator=(A&&) const { m = 1; return *this; }
constexpr const B& operator=(const A&) const { m = 2; return *this; }
constexpr const B& operator=(const A&&) const { m = 3; return *this; }
};
// template<pair-like UPair>
// constexpr const pair& operator=(UPair&&) const;
pair_like_t<A> pair_like;
const pair<B, B> p2b;
p2b = pair_like;
VERIFY( p2b.first.m == 0 && p2b.second.m == 0 );
p2b = std::move(pair_like);
VERIFY( p2b.first.m == 1 && p2b.second.m == 1 );
p2b = std::as_const(pair_like);
VERIFY( p2b.first.m == 2 && p2b.second.m == 2 );
p2b = std::move(std::as_const(pair_like));
VERIFY( p2b.first.m == 3 && p2b.second.m == 3 );
return true;
}
template<typename T>
using pair_like_array = array<T, 2>;
template<typename T>
using pair_like_tuple = tuple<T, T>;
int
main()
{
static_assert( test01<pair_like_array>() );
static_assert( test02<pair_like_array>() );
static_assert( test03<pair_like_array>() );
static_assert( test04<pair_like_array>() );
static_assert( test01<pair_like_tuple>() );
static_assert( test02<pair_like_tuple>() );
static_assert( test03<pair_like_tuple>() );
static_assert( test04<pair_like_tuple>() );
}