1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// UNSUPPORTED: c++98, c++03 11 12// <tuple> 13 14// template <class... Types> class tuple; 15 16// template <class Alloc> 17// tuple(allocator_arg_t, const Alloc& a); 18 19// NOTE: this constructor does not currently support tags derived from 20// allocator_arg_t because libc++ has to deduce the parameter as a template 21// argument. See PR27684 (https://bugs.llvm.org/show_bug.cgi?id=27684) 22 23#include <tuple> 24#include <cassert> 25 26#include "DefaultOnly.h" 27#include "allocators.h" 28#include "../alloc_first.h" 29#include "../alloc_last.h" 30 31template <class T = void> 32struct NonDefaultConstructible { 33 constexpr NonDefaultConstructible() { 34 static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); 35 } 36 37 explicit constexpr NonDefaultConstructible(int) {} 38}; 39 40 41struct DerivedFromAllocArgT : std::allocator_arg_t {}; 42 43int main() 44{ 45 { 46 std::tuple<> t(std::allocator_arg, A1<int>()); 47 } 48 { 49 std::tuple<int> t(std::allocator_arg, A1<int>()); 50 assert(std::get<0>(t) == 0); 51 } 52 { 53 std::tuple<DefaultOnly> t(std::allocator_arg, A1<int>()); 54 assert(std::get<0>(t) == DefaultOnly()); 55 } 56 { 57 assert(!alloc_first::allocator_constructed); 58 std::tuple<alloc_first> t(std::allocator_arg, A1<int>(5)); 59 assert(alloc_first::allocator_constructed); 60 assert(std::get<0>(t) == alloc_first()); 61 } 62 { 63 assert(!alloc_last::allocator_constructed); 64 std::tuple<alloc_last> t(std::allocator_arg, A1<int>(5)); 65 assert(alloc_last::allocator_constructed); 66 assert(std::get<0>(t) == alloc_last()); 67 } 68 { 69 alloc_first::allocator_constructed = false; 70 std::tuple<DefaultOnly, alloc_first> t(std::allocator_arg, A1<int>(5)); 71 assert(std::get<0>(t) == DefaultOnly()); 72 assert(alloc_first::allocator_constructed); 73 assert(std::get<1>(t) == alloc_first()); 74 } 75 { 76 alloc_first::allocator_constructed = false; 77 alloc_last::allocator_constructed = false; 78 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 79 A1<int>(5)); 80 assert(std::get<0>(t) == DefaultOnly()); 81 assert(alloc_first::allocator_constructed); 82 assert(std::get<1>(t) == alloc_first()); 83 assert(alloc_last::allocator_constructed); 84 assert(std::get<2>(t) == alloc_last()); 85 } 86 { 87 alloc_first::allocator_constructed = false; 88 alloc_last::allocator_constructed = false; 89 std::tuple<DefaultOnly, alloc_first, alloc_last> t(std::allocator_arg, 90 A2<int>(5)); 91 assert(std::get<0>(t) == DefaultOnly()); 92 assert(!alloc_first::allocator_constructed); 93 assert(std::get<1>(t) == alloc_first()); 94 assert(!alloc_last::allocator_constructed); 95 assert(std::get<2>(t) == alloc_last()); 96 } 97 { 98 // Test that the uses-allocator default constructor does not evaluate 99 // its SFINAE when it otherwise shouldn't be selected. Do this by 100 // using 'NonDefaultConstructible' which will cause a compile error 101 // if std::is_default_constructible is evaluated on it. 102 using T = NonDefaultConstructible<>; 103 T v(42); 104 std::tuple<T, T> t(v, v); 105 (void)t; 106 std::tuple<T, T> t2(42, 42); 107 (void)t2; 108 } 109} 110