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 // <tuple>
     11 
     12 // template <class... Types> class tuple;
     13 
     14 // explicit tuple(const T&...);
     15 
     16 // UNSUPPORTED: c++98, c++03
     17 
     18 #include <tuple>
     19 #include <string>
     20 #include <cassert>
     21 
     22 
     23 template <class ...>
     24 struct never {
     25     enum { value = 0 };
     26 };
     27 
     28 struct NoValueCtor
     29 {
     30     NoValueCtor() : id(++count) {}
     31     NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
     32 
     33     // The constexpr is required to make is_constructible instantiate this template.
     34     // The explicit is needed to test-around a similar bug with is_convertible.
     35     template <class T>
     36     constexpr explicit NoValueCtor(T)
     37     { static_assert(never<T>::value, "This should not be instantiated"); }
     38 
     39     static int count;
     40     int id;
     41 };
     42 
     43 int NoValueCtor::count = 0;
     44 
     45 
     46 struct NoValueCtorEmpty
     47 {
     48     NoValueCtorEmpty() {}
     49     NoValueCtorEmpty(NoValueCtorEmpty const &) {}
     50 
     51     template <class T>
     52     constexpr explicit NoValueCtorEmpty(T)
     53     { static_assert(never<T>::value, "This should not be instantiated"); }
     54 };
     55 
     56 int main()
     57 {
     58     {
     59         std::tuple<int> t(2);
     60         assert(std::get<0>(t) == 2);
     61     }
     62 #if _LIBCPP_STD_VER > 11
     63     {
     64         constexpr std::tuple<int> t(2);
     65         static_assert(std::get<0>(t) == 2, "");
     66     }
     67     {
     68         constexpr std::tuple<int> t;
     69         static_assert(std::get<0>(t) == 0, "");
     70     }
     71 #endif
     72     {
     73         std::tuple<int, char*> t(2, 0);
     74         assert(std::get<0>(t) == 2);
     75         assert(std::get<1>(t) == nullptr);
     76     }
     77 #if _LIBCPP_STD_VER > 11
     78     {
     79         constexpr std::tuple<int, char*> t(2, nullptr);
     80         static_assert(std::get<0>(t) == 2, "");
     81         static_assert(std::get<1>(t) == nullptr, "");
     82     }
     83 #endif
     84     {
     85         std::tuple<int, char*> t(2, nullptr);
     86         assert(std::get<0>(t) == 2);
     87         assert(std::get<1>(t) == nullptr);
     88     }
     89     {
     90         std::tuple<int, char*, std::string> t(2, nullptr, "text");
     91         assert(std::get<0>(t) == 2);
     92         assert(std::get<1>(t) == nullptr);
     93         assert(std::get<2>(t) == "text");
     94     }
     95     // __tuple_leaf<T> uses is_constructible<T, U> to disable its explicit converting
     96     // constructor overload __tuple_leaf(U &&). Evaluating is_constructible can cause a compile error.
     97     // This overload is evaluated when __tuple_leafs copy or move ctor is called.
     98     // This checks that is_constructible is not evaluated when U == __tuple_leaf.
     99     {
    100         std::tuple<int, NoValueCtor, int, int> t(1, NoValueCtor(), 2, 3);
    101         assert(std::get<0>(t) == 1);
    102         assert(std::get<1>(t).id == 1);
    103         assert(std::get<2>(t) == 2);
    104         assert(std::get<3>(t) == 3);
    105     }
    106     {
    107         std::tuple<int, NoValueCtorEmpty, int, int> t(1, NoValueCtorEmpty(), 2, 3);
    108         assert(std::get<0>(t) == 1);
    109         assert(std::get<2>(t) == 2);
    110         assert(std::get<3>(t) == 3);
    111     }
    112     // extensions
    113     {
    114         std::tuple<int, char*, std::string> t(2);
    115         assert(std::get<0>(t) == 2);
    116         assert(std::get<1>(t) == nullptr);
    117         assert(std::get<2>(t) == "");
    118     }
    119     {
    120         std::tuple<int, char*, std::string> t(2, nullptr);
    121         assert(std::get<0>(t) == 2);
    122         assert(std::get<1>(t) == nullptr);
    123         assert(std::get<2>(t) == "");
    124     }
    125     {
    126         std::tuple<int, char*, std::string, double> t(2, nullptr, "text");
    127         assert(std::get<0>(t) == 2);
    128         assert(std::get<1>(t) == nullptr);
    129         assert(std::get<2>(t) == "text");
    130         assert(std::get<3>(t) == 0.0);
    131     }
    132 }
    133