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