//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14 // // template any(in_place_type_t, Args&&...); // template // any(in_place_type_t, initializer_list, Args&&...); // Test construction from a value. // Concerns: // --------- // 1. The value is properly move/copied depending on the value category. // 2. Both small and large values are properly handled. #include #include #include "any_helpers.h" #include "count_new.hpp" #include "test_macros.h" #include "test_convertible.hpp" using std::any; using std::any_cast; template void test_in_place_type() { // constructing from a small type should perform no allocations. DisableAllocationGuard g(isSmallType()); ((void)g); assert(Type::count == 0); Type::reset(); { any a(std::in_place_type); assert(Type::count == 1); assert(Type::copied == 0); assert(Type::moved == 0); assertContains(a, 0); } assert(Type::count == 0); Type::reset(); { // Test that the in_place argument is properly decayed any a(std::in_place_type); assert(Type::count == 1); assert(Type::copied == 0); assert(Type::moved == 0); assertContains(a, 0); } assert(Type::count == 0); Type::reset(); { any a(std::in_place_type, 101); assert(Type::count == 1); assert(Type::copied == 0); assert(Type::moved == 0); assertContains(a, 101); } assert(Type::count == 0); Type::reset(); { any a(std::in_place_type, -1, 42, -1); assert(Type::count == 1); assert(Type::copied == 0); assert(Type::moved == 0); assertContains(a, 42); } assert(Type::count == 0); Type::reset(); } template void test_in_place_type_tracked() { // constructing from a small type should perform no allocations. DisableAllocationGuard g(isSmallType()); ((void)g); { any a(std::in_place_type); assertArgsMatch(a); } { any a(std::in_place_type, -1, 42, -1); assertArgsMatch(a); } // initializer_list constructor tests { any a(std::in_place_type, {-1, 42, -1}); assertArgsMatch>(a); } { int x = 42; any a(std::in_place_type, {-1, 42, -1}, x); assertArgsMatch, int&>(a); } } void test_func() {} void test_in_place_type_decayed() { { using Type = decltype(test_func); using DecayT = void(*)(); any a(std::in_place_type, test_func); assert(containsType(a)); assert(any_cast(a) == test_func); } { int my_arr[5]; using Type = int(&)[5]; using DecayT = int*; any a(std::in_place_type, my_arr); assert(containsType(a)); assert(any_cast(a) == my_arr); } { using Type = int[5]; using DecayT = int*; any a(std::in_place_type); assert(containsType(a)); assert(any_cast(a) == nullptr); } } void test_ctor_sfinae() { { // Test that the init-list ctor SFINAE's away properly when // construction would be ill-formed. using IL = std::initializer_list; static_assert(!std::is_constructible, IL>::value, ""); static_assert(std::is_constructible, IL>::value, ""); } { // Test that the tagged dispatch constructor SFINAE's away when the // argument is non-copyable struct NoCopy { NoCopy() = default; NoCopy(NoCopy const&) = delete; NoCopy(int) {} NoCopy(std::initializer_list, int) {} }; using Tag = std::in_place_type_t; using RefTag = std::in_place_type_t; using IL = std::initializer_list; static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); } } struct Implicit { Implicit(int) {} Implicit(int, int, int) {} Implicit(std::initializer_list, int) {} }; void test_constructor_explicit() { using I = Implicit; using IT = std::in_place_type_t; static_assert(!test_convertible(), ""); static_assert(std::is_constructible::value, ""); static_assert(!test_convertible(), ""); static_assert(std::is_constructible::value, ""); static_assert(!test_convertible&, int>(), ""); static_assert(std::is_constructible&, int>::value, ""); } int main() { test_in_place_type(); test_in_place_type(); test_in_place_type(); test_in_place_type(); test_in_place_type(); test_in_place_type_tracked(); test_in_place_type_tracked(); test_in_place_type_decayed(); test_ctor_sfinae(); test_constructor_explicit(); }