[libc++] Try and prevent evaluation of `is_default_constructible` on tuples default...
authorEric Fiselier <eric@efcs.ca>
Sat, 21 Feb 2015 02:30:41 +0000 (02:30 +0000)
committerEric Fiselier <eric@efcs.ca>
Sat, 21 Feb 2015 02:30:41 +0000 (02:30 +0000)
commit65500d4b29bdd03f6e3d14bd09550465bd9e16ed
treee56ee75938a9c33a4941b2a8d78758ce2f120f91
parentd2852b69ce15da37e62d98ca313febd3664c0f28
[libc++] Try and prevent evaluation of `is_default_constructible` on tuples default constructor if it is not needed.

Summary:
Currently parts of the SFINAE on tuples default constructor always gets evaluated even when the default constructor is never called or instantiated. This can cause a hard compile error when a tuple is created with types that do not have a default constructor. Below is a self contained example using a pair like class. This code will not compile but probably should.

```

#include <type_traits>

template <class T>
struct IllFormedDefaultImp {
    IllFormedDefaultImp(T x) : value(x) {}
    constexpr IllFormedDefaultImp() {}
    T value;
};

typedef IllFormedDefaultImp<int &> IllFormedDefault;

template <class T, class U>
struct pair
{
  template <bool Dummy = true,
    class = typename std::enable_if<
         std::is_default_constructible<T>::value
      && std::is_default_constructible<U>::value
      && Dummy>::type
    >
  constexpr pair() : first(), second() {}

  pair(T const & t, U const & u) : first(t), second(u) {}

  T first;
  U second;
};

int main()
{
  int x = 1;
  IllFormedDefault v(x);
  pair<IllFormedDefault, IllFormedDefault> p(v, v);
}
```

One way to fix this is to use `Dummy` in a more involved way in the constructor SFINAE. The following patch fixes these sorts of hard compile errors for tuple.

Reviewers: mclow.lists, rsmith, K-ballo, EricWF

Reviewed By: EricWF

Subscribers: ldionne, cfe-commits

Differential Revision: http://reviews.llvm.org/D7569

llvm-svn: 230120
libcxx/include/tuple
libcxx/include/type_traits
libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/default.pass.cpp