enable_reduced_arity_initialization_extension.pass.cpp (3732B)
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 // <tuple> 11 12 // template <class... Types> class tuple; 13 14 // template <class... UTypes> 15 // explicit tuple(UTypes&&... u); 16 17 // UNSUPPORTED: c++98, c++03 18 19 // MODULES_DEFINES: _LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION 20 #define _LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION 21 #include <tuple> 22 #include <cassert> 23 #include <type_traits> 24 #include <string> 25 #include <system_error> 26 27 #include "test_macros.h" 28 #include "test_convertible.hpp" 29 #include "MoveOnly.h" 30 31 32 struct NoDefault { NoDefault() = delete; }; 33 34 35 // Make sure the _Up... constructor SFINAEs out when the types that 36 // are not explicitly initialized are not all default constructible. 37 // Otherwise, std::is_constructible would return true but instantiating 38 // the constructor would fail. 39 void test_default_constructible_extension_sfinae() 40 { 41 typedef MoveOnly MO; 42 typedef NoDefault ND; 43 { 44 typedef std::tuple<MO, ND> Tuple; 45 static_assert(!std::is_constructible<Tuple, MO>::value, ""); 46 static_assert(std::is_constructible<Tuple, MO, ND>::value, ""); 47 static_assert(test_convertible<Tuple, MO, ND>(), ""); 48 } 49 { 50 typedef std::tuple<MO, MO, ND> Tuple; 51 static_assert(!std::is_constructible<Tuple, MO, MO>::value, ""); 52 static_assert(std::is_constructible<Tuple, MO, MO, ND>::value, ""); 53 static_assert(test_convertible<Tuple, MO, MO, ND>(), ""); 54 } 55 { 56 // Same idea as above but with a nested tuple type. 57 typedef std::tuple<MO, ND> Tuple; 58 typedef std::tuple<MO, Tuple, MO, MO> NestedTuple; 59 60 static_assert(!std::is_constructible< 61 NestedTuple, MO, MO, MO, MO>::value, ""); 62 static_assert(std::is_constructible< 63 NestedTuple, MO, Tuple, MO, MO>::value, ""); 64 } 65 { 66 typedef std::tuple<MO, int> Tuple; 67 typedef std::tuple<MO, Tuple, MO, MO> NestedTuple; 68 69 static_assert(std::is_constructible< 70 NestedTuple, MO, MO, MO, MO>::value, ""); 71 static_assert(test_convertible< 72 NestedTuple, MO, MO, MO, MO>(), ""); 73 74 static_assert(std::is_constructible< 75 NestedTuple, MO, Tuple, MO, MO>::value, ""); 76 static_assert(test_convertible< 77 NestedTuple, MO, Tuple, MO, MO>(), ""); 78 } 79 } 80 81 std::tuple<std::string, int, std::error_code> doc_example() { 82 return {"hello world", 42}; 83 } 84 85 // Test that the example given in UsingLibcxx.rst actually works. 86 void test_example_from_docs() { 87 auto tup = doc_example(); 88 assert(std::get<0>(tup) == "hello world"); 89 assert(std::get<1>(tup) == 42); 90 assert(std::get<2>(tup) == std::error_code{}); 91 } 92 93 int main() 94 { 95 96 { 97 using E = MoveOnly; 98 using Tup = std::tuple<E, E, E>; 99 static_assert(test_convertible<Tup, E, E, E>(), ""); 100 101 Tup t = {E(0), E(1)}; 102 static_assert(test_convertible<Tup, E, E>(), ""); 103 assert(std::get<0>(t) == 0); 104 assert(std::get<1>(t) == 1); 105 assert(std::get<2>(t) == MoveOnly()); 106 107 Tup t2 = {E(0)}; 108 static_assert(test_convertible<Tup, E>(), ""); 109 assert(std::get<0>(t) == 0); 110 assert(std::get<1>(t) == E()); 111 assert(std::get<2>(t) == E()); 112 } 113 // Check that SFINAE is properly applied with the default reduced arity 114 // constructor extensions. 115 test_default_constructible_extension_sfinae(); 116 test_example_from_docs(); 117 }