Home | History | Annotate | Download | only in tuple.cnstr
      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, c++11, c++14
     11 // UNSUPPORTED: libcpp-no-deduction-guides
     12 
     13 // GCC's implementation of class template deduction is still immature and runs
     14 // into issues with libc++. However GCC accepts this code when compiling
     15 // against libstdc++.
     16 // XFAIL: gcc
     17 
     18 // <tuple>
     19 
     20 // Test that the constructors offered by std::tuple are formulated
     21 // so they're compatible with implicit deduction guides, or if that's not
     22 // possible that they provide explicit guides to make it work.
     23 
     24 #include <tuple>
     25 #include <memory>
     26 #include <cassert>
     27 
     28 #include "test_macros.h"
     29 #include "archetypes.hpp"
     30 
     31 
     32 // Overloads
     33 //  using A = Allocator
     34 //  using AT = std::allocator_arg_t
     35 // ---------------
     36 // (1)  tuple(const Types&...) -> tuple<Types...>
     37 // (2)  explicit tuple(const Types&...) -> tuple<Types...>
     38 // (3)  tuple(AT, A const&, Types const&...) -> tuple<Types...>
     39 // (4)  explicit tuple(AT, A const&, Types const&...) -> tuple<Types...>
     40 // (5)  tuple(tuple const& t) -> decltype(t)
     41 // (6)  tuple(tuple&& t) -> decltype(t)
     42 // (7)  tuple(AT, A const&, tuple const& t) -> decltype(t)
     43 // (8)  tuple(AT, A const&, tuple&& t) -> decltype(t)
     44 void test_primary_template()
     45 {
     46   const std::allocator<int> A;
     47   const auto AT = std::allocator_arg;
     48   { // Testing (1)
     49     int x = 101;
     50     std::tuple t1(42);
     51     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
     52     std::tuple t2(x, 0.0, nullptr);
     53     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, decltype(nullptr)>);
     54   }
     55   { // Testing (2)
     56     using T = ExplicitTestTypes::TestType;
     57     static_assert(!std::is_convertible<T const&, T>::value, "");
     58 
     59     std::tuple t1(T{});
     60     ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
     61 
     62     const T v{};
     63     std::tuple t2(T{}, 101l, v);
     64     ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
     65   }
     66   { // Testing (3)
     67     int x = 101;
     68     std::tuple t1(AT, A, 42);
     69     ASSERT_SAME_TYPE(decltype(t1), std::tuple<int>);
     70 
     71     std::tuple t2(AT, A, 42, 0.0, x);
     72     ASSERT_SAME_TYPE(decltype(t2), std::tuple<int, double, int>);
     73   }
     74   { // Testing (4)
     75     using T = ExplicitTestTypes::TestType;
     76     static_assert(!std::is_convertible<T const&, T>::value, "");
     77 
     78     std::tuple t1(AT, A, T{});
     79     ASSERT_SAME_TYPE(decltype(t1), std::tuple<T>);
     80 
     81     const T v{};
     82     std::tuple t2(AT, A, T{}, 101l, v);
     83     ASSERT_SAME_TYPE(decltype(t2), std::tuple<T, long, T>);
     84   }
     85   { // Testing (5)
     86     using Tup = std::tuple<int, decltype(nullptr)>;
     87     const Tup t(42, nullptr);
     88 
     89     std::tuple t1(t);
     90     ASSERT_SAME_TYPE(decltype(t1), Tup);
     91   }
     92   { // Testing (6)
     93     using Tup = std::tuple<void*, unsigned, char>;
     94     std::tuple t1(Tup(nullptr, 42, 'a'));
     95     ASSERT_SAME_TYPE(decltype(t1), Tup);
     96   }
     97   { // Testing (7)
     98     using Tup = std::tuple<int, decltype(nullptr)>;
     99     const Tup t(42, nullptr);
    100 
    101     std::tuple t1(AT, A, t);
    102     ASSERT_SAME_TYPE(decltype(t1), Tup);
    103   }
    104   { // Testing (8)
    105     using Tup = std::tuple<void*, unsigned, char>;
    106     std::tuple t1(AT, A, Tup(nullptr, 42, 'a'));
    107     ASSERT_SAME_TYPE(decltype(t1), Tup);
    108   }
    109 }
    110 
    111 // Overloads
    112 //  using A = Allocator
    113 //  using AT = std::allocator_arg_t
    114 // ---------------
    115 // (1)  tuple() -> tuple<>
    116 // (2)  tuple(AT, A const&) -> tuple<>
    117 // (3)  tuple(tuple const&) -> tuple<>
    118 // (4)  tuple(tuple&&) -> tuple<>
    119 // (5)  tuple(AT, A const&, tuple const&) -> tuple<>
    120 // (6)  tuple(AT, A const&, tuple&&) -> tuple<>
    121 void test_empty_specialization()
    122 {
    123   std::allocator<int> A;
    124   const auto AT = std::allocator_arg;
    125   { // Testing (1)
    126     std::tuple t1{};
    127     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
    128   }
    129   { // Testing (2)
    130     std::tuple t1{AT, A};
    131     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
    132   }
    133   { // Testing (3)
    134     const std::tuple<> t{};
    135     std::tuple t1(t);
    136     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
    137   }
    138   { // Testing (4)
    139     std::tuple t1(std::tuple<>{});
    140     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
    141   }
    142   { // Testing (5)
    143     const std::tuple<> t{};
    144     std::tuple t1(AT, A, t);
    145     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
    146   }
    147   { // Testing (6)
    148     std::tuple t1(AT, A, std::tuple<>{});
    149     ASSERT_SAME_TYPE(decltype(t1), std::tuple<>);
    150   }
    151 }
    152 
    153 int main() {
    154   test_primary_template();
    155   test_empty_specialization();
    156 }
    157