mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-24 20:29:39 +08:00
Test changes for P0504R0 "Revisiting in-place tag types for any/optional/variant". Patch from Casey Carter
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@287249 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -40,7 +40,7 @@ void test_in_place_type() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a(std::in_place<Type>);
|
any a(std::in_place_type<Type>);
|
||||||
|
|
||||||
assert(Type::count == 1);
|
assert(Type::count == 1);
|
||||||
assert(Type::copied == 0);
|
assert(Type::copied == 0);
|
||||||
@@ -50,7 +50,7 @@ void test_in_place_type() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
{ // Test that the in_place argument is properly decayed
|
{ // Test that the in_place argument is properly decayed
|
||||||
any a(std::in_place<Type&>);
|
any a(std::in_place_type<Type&>);
|
||||||
|
|
||||||
assert(Type::count == 1);
|
assert(Type::count == 1);
|
||||||
assert(Type::copied == 0);
|
assert(Type::copied == 0);
|
||||||
@@ -60,7 +60,7 @@ void test_in_place_type() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a(std::in_place<Type>, 101);
|
any a(std::in_place_type<Type>, 101);
|
||||||
|
|
||||||
assert(Type::count == 1);
|
assert(Type::count == 1);
|
||||||
assert(Type::copied == 0);
|
assert(Type::copied == 0);
|
||||||
@@ -70,7 +70,7 @@ void test_in_place_type() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a(std::in_place<Type>, -1, 42, -1);
|
any a(std::in_place_type<Type>, -1, 42, -1);
|
||||||
|
|
||||||
assert(Type::count == 1);
|
assert(Type::count == 1);
|
||||||
assert(Type::copied == 0);
|
assert(Type::copied == 0);
|
||||||
@@ -86,21 +86,21 @@ void test_in_place_type_tracked() {
|
|||||||
// constructing from a small type should perform no allocations.
|
// constructing from a small type should perform no allocations.
|
||||||
DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
|
DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
|
||||||
{
|
{
|
||||||
any a(std::in_place<Type>);
|
any a(std::in_place_type<Type>);
|
||||||
assertArgsMatch<Type>(a);
|
assertArgsMatch<Type>(a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
any a(std::in_place<Type>, -1, 42, -1);
|
any a(std::in_place_type<Type>, -1, 42, -1);
|
||||||
assertArgsMatch<Type, int, int, int>(a);
|
assertArgsMatch<Type, int, int, int>(a);
|
||||||
}
|
}
|
||||||
// initializer_list constructor tests
|
// initializer_list constructor tests
|
||||||
{
|
{
|
||||||
any a(std::in_place<Type>, {-1, 42, -1});
|
any a(std::in_place_type<Type>, {-1, 42, -1});
|
||||||
assertArgsMatch<Type, std::initializer_list<int>>(a);
|
assertArgsMatch<Type, std::initializer_list<int>>(a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int x = 42;
|
int x = 42;
|
||||||
any a(std::in_place<Type&>, {-1, 42, -1}, x);
|
any a(std::in_place_type<Type&>, {-1, 42, -1}, x);
|
||||||
assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
|
assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ void test_in_place_type_decayed() {
|
|||||||
{
|
{
|
||||||
using Type = decltype(test_func);
|
using Type = decltype(test_func);
|
||||||
using DecayT = void(*)();
|
using DecayT = void(*)();
|
||||||
any a(std::in_place<Type>, test_func);
|
any a(std::in_place_type<Type>, test_func);
|
||||||
assert(containsType<DecayT>(a));
|
assert(containsType<DecayT>(a));
|
||||||
assert(any_cast<DecayT>(a) == test_func);
|
assert(any_cast<DecayT>(a) == test_func);
|
||||||
}
|
}
|
||||||
@@ -119,14 +119,14 @@ void test_in_place_type_decayed() {
|
|||||||
int my_arr[5];
|
int my_arr[5];
|
||||||
using Type = int(&)[5];
|
using Type = int(&)[5];
|
||||||
using DecayT = int*;
|
using DecayT = int*;
|
||||||
any a(std::in_place<Type>, my_arr);
|
any a(std::in_place_type<Type>, my_arr);
|
||||||
assert(containsType<DecayT>(a));
|
assert(containsType<DecayT>(a));
|
||||||
assert(any_cast<DecayT>(a) == my_arr);
|
assert(any_cast<DecayT>(a) == my_arr);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
using Type = int[5];
|
using Type = int[5];
|
||||||
using DecayT = int*;
|
using DecayT = int*;
|
||||||
any a(std::in_place<Type>);
|
any a(std::in_place_type<Type>);
|
||||||
assert(containsType<DecayT>(a));
|
assert(containsType<DecayT>(a));
|
||||||
assert(any_cast<DecayT>(a) == nullptr);
|
assert(any_cast<DecayT>(a) == nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,13 +106,12 @@ void test_copy_move_value() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that any(ValueType&&) is *never* selected for a std::in_place type.
|
// Test that any(ValueType&&) is *never* selected for a std::in_place_type_t specialization.
|
||||||
void test_sfinae_constraints() {
|
void test_sfinae_constraints() {
|
||||||
using BadTag = std::in_place_type_t<int>;
|
using BadTag = std::in_place_type_t<int>;
|
||||||
using OKTag = std::in_place_t;
|
using OKTag = std::in_place_t;
|
||||||
using OKDecay = std::decay_t<OKTag>;
|
|
||||||
// Test that the tag type is properly handled in SFINAE
|
// Test that the tag type is properly handled in SFINAE
|
||||||
BadTag t = std::in_place;
|
BadTag t = std::in_place_type<int>;
|
||||||
OKTag ot = std::in_place;
|
OKTag ot = std::in_place;
|
||||||
{
|
{
|
||||||
std::any a(t);
|
std::any a(t);
|
||||||
@@ -124,12 +123,7 @@ void test_sfinae_constraints() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::any a(ot);
|
std::any a(ot);
|
||||||
assertContains<OKDecay>(a, ot);
|
assert(containsType<OKTag>(a));
|
||||||
}
|
|
||||||
{
|
|
||||||
OKDecay d = ot;
|
|
||||||
std::any a(d);
|
|
||||||
assertContains<OKDecay>(a, ot);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
struct Dummy { Dummy() = delete; };
|
struct Dummy { Dummy() = delete; };
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ void test_emplace_type() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a(std::in_place<Tracked>);
|
any a(std::in_place_type<Tracked>);
|
||||||
assert(Tracked::count == 1);
|
assert(Tracked::count == 1);
|
||||||
|
|
||||||
a.emplace<Type>();
|
a.emplace<Type>();
|
||||||
@@ -53,7 +53,7 @@ void test_emplace_type() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a(std::in_place<Tracked>);
|
any a(std::in_place_type<Tracked>);
|
||||||
assert(Tracked::count == 1);
|
assert(Tracked::count == 1);
|
||||||
|
|
||||||
a.emplace<Type>(101);
|
a.emplace<Type>(101);
|
||||||
@@ -67,7 +67,7 @@ void test_emplace_type() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a(std::in_place<Tracked>);
|
any a(std::in_place_type<Tracked>);
|
||||||
assert(Tracked::count == 1);
|
assert(Tracked::count == 1);
|
||||||
|
|
||||||
a.emplace<Type>(-1, 42, -1);
|
a.emplace<Type>(-1, 42, -1);
|
||||||
@@ -87,14 +87,14 @@ void test_emplace_type_tracked() {
|
|||||||
// constructing from a small type should perform no allocations.
|
// constructing from a small type should perform no allocations.
|
||||||
DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
|
DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
|
||||||
{
|
{
|
||||||
any a(std::in_place<Tracked>);
|
any a(std::in_place_type<Tracked>);
|
||||||
assert(Tracked::count == 1);
|
assert(Tracked::count == 1);
|
||||||
a.emplace<Type>();
|
a.emplace<Type>();
|
||||||
assert(Tracked::count == 0);
|
assert(Tracked::count == 0);
|
||||||
assertArgsMatch<Type>(a);
|
assertArgsMatch<Type>(a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
any a(std::in_place<Tracked>);
|
any a(std::in_place_type<Tracked>);
|
||||||
assert(Tracked::count == 1);
|
assert(Tracked::count == 1);
|
||||||
a.emplace<Type>(-1, 42, -1);
|
a.emplace<Type>(-1, 42, -1);
|
||||||
assert(Tracked::count == 0);
|
assert(Tracked::count == 0);
|
||||||
@@ -102,7 +102,7 @@ void test_emplace_type_tracked() {
|
|||||||
}
|
}
|
||||||
// initializer_list constructor tests
|
// initializer_list constructor tests
|
||||||
{
|
{
|
||||||
any a(std::in_place<Tracked>);
|
any a(std::in_place_type<Tracked>);
|
||||||
assert(Tracked::count == 1);
|
assert(Tracked::count == 1);
|
||||||
a.emplace<Type>({-1, 42, -1});
|
a.emplace<Type>({-1, 42, -1});
|
||||||
assert(Tracked::count == 0);
|
assert(Tracked::count == 0);
|
||||||
@@ -110,7 +110,7 @@ void test_emplace_type_tracked() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
int x = 42;
|
int x = 42;
|
||||||
any a(std::in_place<Tracked>);
|
any a(std::in_place_type<Tracked>);
|
||||||
assert(Tracked::count == 1);
|
assert(Tracked::count == 1);
|
||||||
a.emplace<Type>({-1, 42, -1}, x);
|
a.emplace<Type>({-1, 42, -1}, x);
|
||||||
assert(Tracked::count == 0);
|
assert(Tracked::count == 0);
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ void test_cast_to_value() {
|
|||||||
Type::reset();
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a((Type(42)));
|
any a((Type(42)));
|
||||||
any const& ca = a;
|
|
||||||
assert(Type::count == 1);
|
assert(Type::count == 1);
|
||||||
assert(Type::copied == 0);
|
assert(Type::copied == 0);
|
||||||
assert(Type::moved == 1);
|
assert(Type::moved == 1);
|
||||||
|
|||||||
@@ -11,21 +11,24 @@
|
|||||||
|
|
||||||
// <utility>
|
// <utility>
|
||||||
|
|
||||||
// struct in_place_tag { in_place_tag() = delete; };
|
// struct in_place_t {
|
||||||
//
|
// explicit in_place_t() = default;
|
||||||
// using in_place_t = in_place_tag(&)(unspecified);
|
// };
|
||||||
|
// inline constexpr in_place_t in_place{};
|
||||||
|
|
||||||
// template <class T>
|
// template <class T>
|
||||||
// using in_place_type_t = in_place_tag(&)(unspecified<T>);
|
// struct in_place_type_t {
|
||||||
// template <size_t N>
|
// explicit in_place_type_t() = default;
|
||||||
// using in_place_index_t = in_place_tag(&)(unspecified<N>);
|
// };
|
||||||
//
|
// template <class T>
|
||||||
// in_place_tag in_place(unspecified);
|
// inline constexpr in_place_type_t<T> in_place_type{};
|
||||||
//
|
|
||||||
// template <class T>;
|
// template <size_t I>
|
||||||
// in_place_tag in_place(unspecified<T>);
|
// struct in_place_index_t {
|
||||||
//
|
// explicit in_place_index_t() = default;
|
||||||
// template <size_t N>
|
// };
|
||||||
// in_place_tag in_place(unspecified<N>);
|
// template <size_t I>
|
||||||
|
// inline constexpr in_place_index_t<I> in_place_index{};
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -34,66 +37,38 @@
|
|||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
#include "type_id.h"
|
#include "type_id.h"
|
||||||
|
|
||||||
template <class Tp>
|
template <class Tp, class Up>
|
||||||
struct CheckRet : std::false_type {};
|
constexpr bool check_tag(Up) {
|
||||||
template <class Arg>
|
return std::is_same<Tp, std::decay_t<Tp>>::value
|
||||||
struct CheckRet<std::in_place_tag(Arg)> : std::true_type {};
|
&& std::is_same<Tp, Up>::value;
|
||||||
|
|
||||||
TypeID const* test_fn(std::in_place_t) { return &makeTypeID<std::in_place_t>(); }
|
|
||||||
template <class T>
|
|
||||||
TypeID const* test_fn(std::in_place_type_t<T>)
|
|
||||||
{ return &makeTypeID<std::in_place_type_t<T>>(); }
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
TypeID const* test_fn(std::in_place_index_t<I>)
|
|
||||||
{ return &makeTypeID<std::in_place_index_t<I>>(); }
|
|
||||||
|
|
||||||
// Concrete test overloads that don't have to be deduced.
|
|
||||||
template <class Tag>
|
|
||||||
TypeID const* concrete_test_fn(Tag) { return &makeTypeID<Tag>(); }
|
|
||||||
|
|
||||||
template <class Tp>
|
|
||||||
bool check_tag_basic() {
|
|
||||||
using RawTp = typename std::remove_reference<Tp>::type;
|
|
||||||
static_assert(std::is_lvalue_reference<Tp>::value, "");
|
|
||||||
static_assert(std::is_function<RawTp>::value, "");
|
|
||||||
static_assert(CheckRet<RawTp>::value, "");
|
|
||||||
auto concrete_fn = concrete_test_fn<Tp>;
|
|
||||||
return test_fn((Tp)std::in_place) == &makeTypeID<Tp>()
|
|
||||||
&& concrete_fn(std::in_place) == &makeTypeID<Tp>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// test in_place_tag
|
|
||||||
{
|
|
||||||
static_assert(!std::is_default_constructible<std::in_place_tag>::value, "");
|
|
||||||
}
|
|
||||||
// test in_place_t
|
// test in_place_t
|
||||||
{
|
{
|
||||||
using T = std::in_place_t;
|
using T = std::in_place_t;
|
||||||
assert(check_tag_basic<std::in_place_t>());
|
static_assert(check_tag<T>(std::in_place));
|
||||||
assert(test_fn((T)std::in_place) == &makeTypeID<T>());
|
|
||||||
}
|
}
|
||||||
// test in_place_type_t
|
// test in_place_type_t
|
||||||
{
|
{
|
||||||
using T1 = std::in_place_type_t<void>;
|
using T1 = std::in_place_type_t<void>;
|
||||||
using T2 = std::in_place_type_t<int>;
|
using T2 = std::in_place_type_t<int>;
|
||||||
using T3 = std::in_place_type_t<const int>;
|
using T3 = std::in_place_type_t<const int>;
|
||||||
assert(check_tag_basic<T1>());
|
static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value);
|
||||||
assert(check_tag_basic<T2>());
|
static_assert(!std::is_same<T2, T3>::value);
|
||||||
assert(check_tag_basic<T3>());
|
static_assert(check_tag<T1>(std::in_place_type<void>));
|
||||||
static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value, "");
|
static_assert(check_tag<T2>(std::in_place_type<int>));
|
||||||
static_assert(!std::is_same<T2, T3>::value, "");
|
static_assert(check_tag<T3>(std::in_place_type<const int>));
|
||||||
}
|
}
|
||||||
// test in_place_index_t
|
// test in_place_index_t
|
||||||
{
|
{
|
||||||
using T1 = std::in_place_index_t<0>;
|
using T1 = std::in_place_index_t<0>;
|
||||||
using T2 = std::in_place_index_t<1>;
|
using T2 = std::in_place_index_t<1>;
|
||||||
using T3 = std::in_place_index_t<static_cast<size_t>(-1)>;
|
using T3 = std::in_place_index_t<static_cast<size_t>(-1)>;
|
||||||
assert(check_tag_basic<T1>());
|
static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value);
|
||||||
assert(check_tag_basic<T2>());
|
static_assert(!std::is_same<T2, T3>::value);
|
||||||
assert(check_tag_basic<T3>());
|
static_assert(check_tag<T1>(std::in_place_index<0>));
|
||||||
static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value, "");
|
static_assert(check_tag<T2>(std::in_place_index<1>));
|
||||||
static_assert(!std::is_same<T2, T3>::value, "");
|
static_assert(check_tag<T3>(std::in_place_index<static_cast<size_t>(-1)>));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user