You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.1 KiB
C++
166 lines
5.1 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// <utility>
|
|
|
|
// template <class T1, class T2> struct pair
|
|
|
|
// Test the SFINAE required by LWG Issue #2367.
|
|
// is_default_constructible<pair>
|
|
|
|
// UNSUPPORTED: c++98, c++03
|
|
|
|
#include <utility>
|
|
#include <type_traits>
|
|
#include <cassert>
|
|
|
|
#include "test_macros.h"
|
|
|
|
#if TEST_STD_VER > 11
|
|
#define CONSTEXPR_CXX14 constexpr
|
|
#define STATIC_ASSERT_CXX14(Pred) static_assert(Pred, "")
|
|
#else
|
|
#define CONSTEXPR_CXX14
|
|
#define STATIC_ASSERT_CXX14(Pred) assert(Pred)
|
|
#endif
|
|
|
|
struct DeletedDefault {
|
|
// A class with a deleted default constructor. Used to test the SFINAE
|
|
// on std::pair's default constructor.
|
|
constexpr explicit DeletedDefault(int x) : value(x) {}
|
|
constexpr DeletedDefault() = delete;
|
|
int value;
|
|
};
|
|
|
|
template <class Tp, bool>
|
|
struct DependantType: public Tp {};
|
|
|
|
template <class T, bool Val>
|
|
using DependantIsDefault = DependantType<std::is_default_constructible<T>, Val>;
|
|
|
|
template <class T>
|
|
struct DefaultSFINAES {
|
|
template <bool Dummy = false, class = typename std::enable_if<
|
|
DependantIsDefault<T, Dummy>::value
|
|
>::type
|
|
>
|
|
constexpr DefaultSFINAES() : value() {}
|
|
constexpr explicit DefaultSFINAES(T const& x) : value(x) {}
|
|
T value;
|
|
};
|
|
|
|
struct NoDefault {
|
|
constexpr NoDefault(int v) : value(v) {}
|
|
int value;
|
|
};
|
|
|
|
template <class Tp>
|
|
void test_not_is_default_constructible()
|
|
{
|
|
{
|
|
typedef std::pair<int, Tp> P;
|
|
static_assert(!std::is_default_constructible<P>::value, "");
|
|
static_assert(std::is_constructible<P, int, Tp>::value, "");
|
|
}
|
|
{
|
|
typedef std::pair<Tp, int> P;
|
|
static_assert(!std::is_default_constructible<P>::value, "");
|
|
static_assert(std::is_constructible<P, Tp, int>::value, "");
|
|
}
|
|
{
|
|
typedef std::pair<Tp, Tp> P;
|
|
static_assert(!std::is_default_constructible<P>::value, "");
|
|
static_assert(std::is_constructible<P, Tp, Tp>::value, "");
|
|
}
|
|
}
|
|
|
|
template <class Tp>
|
|
void test_is_default_constructible()
|
|
{
|
|
{
|
|
typedef std::pair<int, Tp> P;
|
|
static_assert(std::is_default_constructible<P>::value, "");
|
|
}
|
|
{
|
|
typedef std::pair<Tp, int> P;
|
|
static_assert(std::is_default_constructible<P>::value, "");
|
|
}
|
|
{
|
|
typedef std::pair<Tp, Tp> P;
|
|
static_assert(std::is_default_constructible<P>::value, "");
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
struct IllFormedDefaultImp {
|
|
constexpr explicit IllFormedDefaultImp(int v) : value(v) {}
|
|
constexpr IllFormedDefaultImp() : value(T::DoesNotExistAndShouldNotCompile) {}
|
|
int value;
|
|
};
|
|
|
|
typedef IllFormedDefaultImp<int> IllFormedDefault;
|
|
// A class which provides a constexpr default constructor with a valid
|
|
// signature but an ill-formed body. The A compile error will be emitted if
|
|
// the default constructor is instantiated.
|
|
|
|
|
|
// Check that the SFINAE on the default constructor is not evaluated when
|
|
// it isn't needed. If the default constructor of 'IllFormedDefault' is evaluated
|
|
// in C++11, even with is_default_constructible, then this test should fail to
|
|
// compile. In C++14 and greater evaluate each test is evaluated as a constant
|
|
// expression.
|
|
// See LWG issue #2367
|
|
void test_illformed_default()
|
|
{
|
|
{
|
|
typedef std::pair<IllFormedDefault, int> P;
|
|
static_assert((std::is_constructible<P, IllFormedDefault, int>::value), "");
|
|
CONSTEXPR_CXX14 P p(IllFormedDefault(42), -5);
|
|
STATIC_ASSERT_CXX14(p.first.value == 42 && p.second == -5);
|
|
}
|
|
{
|
|
typedef std::pair<int, IllFormedDefault> P;
|
|
static_assert((std::is_constructible<P, int, IllFormedDefault>::value), "");
|
|
CONSTEXPR_CXX14 IllFormedDefault dd(-5);
|
|
CONSTEXPR_CXX14 P p(42, dd);
|
|
STATIC_ASSERT_CXX14(p.first == 42 && p.second.value == -5);
|
|
}
|
|
{
|
|
typedef std::pair<IllFormedDefault, IllFormedDefault> P;
|
|
static_assert((std::is_constructible<P, IllFormedDefault, IllFormedDefault>::value), "");
|
|
CONSTEXPR_CXX14 P p(IllFormedDefault(42), IllFormedDefault(-5));
|
|
STATIC_ASSERT_CXX14(p.first.value == 42 && p.second.value == -5);
|
|
}
|
|
}
|
|
|
|
|
|
int main(int, char**)
|
|
{
|
|
{
|
|
// Check that pair<T, U> can still be used even if
|
|
// is_default_constructible<T> or is_default_constructible<U> cause
|
|
// a compilation error.
|
|
test_illformed_default();
|
|
}
|
|
{
|
|
// pair::pair() is only disable in C++11 and beyond.
|
|
test_not_is_default_constructible<NoDefault>();
|
|
test_not_is_default_constructible<DeletedDefault>();
|
|
test_not_is_default_constructible<DefaultSFINAES<int&>>();
|
|
test_not_is_default_constructible<DefaultSFINAES<int&&>>();
|
|
test_not_is_default_constructible<int&>();
|
|
test_not_is_default_constructible<int&&>();
|
|
}
|
|
{
|
|
test_is_default_constructible<int>();
|
|
test_is_default_constructible<DefaultSFINAES<int>>();
|
|
}
|
|
|
|
return 0;
|
|
}
|