I think I've solved issues with is_assignable and references to incomplete
types. The updated patch adds tests for this case.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@276603 91177308-0d34-0410-b5e6-96231b3b80d8
This is a breaking change. The SFINAE required is instantiated the second
the class is instantiated, and this can cause hard SFINAE errors
when applied to references to incomplete types. Ex.
struct IncompleteType;
extern IncompleteType it;
std::tuple<IncompleteType&> t(it); // SFINAE will blow up.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@276598 91177308-0d34-0410-b5e6-96231b3b80d8
Libc++ provides static assertions to detect reference binding issues inside
tuple. This patch adds tests for those diagnostics.
It should be noted that these static assertions technically violate the
standard since it allows these illegal bindings to occur.
Also see https://llvm.org/bugs/show_bug.cgi?id=20855
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@276078 91177308-0d34-0410-b5e6-96231b3b80d8
This patch upgrades <tuple> to be C++17 compliant by implementing:
* tuple_size_v: This was forgotten when implementing the other _v traits.
* std::apply: This was added via LFTS v1 in p0220r1.
* std::make_from_tuple: This was added in p0209r2.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@275745 91177308-0d34-0410-b5e6-96231b3b80d8
This patch is the last in a series that replaces recursive meta-programming
in std::tuple with non-recursive implementations.
Previously std::tuple could only be instantiated with 126 elements before
it blew the max template instantiation depth. Now the size of std::tuple is
essentially unbounded (I've tested with over 5000 elements).
One unfortunate side-effect of this change is that tuple_constructible
and similar no longer short circuit after the first failure. Instead they
evaluate the conditions for all elements. This could be potentially breaking.
I plan to look into this further.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@274331 91177308-0d34-0410-b5e6-96231b3b80d8
Libc++ has to deduce the 'allocator_arg_t' parameter as 'AllocArgT' for the
following constructor:
template <class Alloc> tuple(allocator_arg_t, Alloc const&)
Previously libc++ has tried to support tags derived from 'allocator_arg_t' by
using 'is_base_of<AllocArgT, allocator_arg_t>'. However this breaks whenever a
2-tuple contains a reference to an incomplete type as its first parameter.
See https://llvm.org/bugs/show_bug.cgi?id=27684
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@273334 91177308-0d34-0410-b5e6-96231b3b80d8
There are two main fixes in this patch.
First the constructor SFINAE was changed so that it's evaluated in two stages
where the first stage evaluates the "safe" SFINAE conditions and the second
evaluates the "dangerous" ones. The key is that the second stage is lazily
evaluated only if the first stage passes. This helps fix PR23256
(https://llvm.org/bugs/show_bug.cgi?id=23256).
The second fix is for PR22806 and LWG issue 2549. This fix applies
the suggested resolution to the LWG issue in order to prevent the construction
of dangling references. The SFINAE for this check is contained within
the _PreferTupleLikeConstructor alias template. The tuple-like constructors
are disabled whenever that trait returns false.
(https://llvm.org/bugs/show_bug.cgi?id=22806)
(http://cplusplus.github.io/LWG/lwg-active.html#2549)
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@266461 91177308-0d34-0410-b5e6-96231b3b80d8
Summary: Currently we only enable the use of __is_final(...) with Clang. GCC also provides __is_final(...) since 4.7 in all standard modes. This patch creates the macro _LIBCPP_HAS_IS_FINAL to note the availability of `__is_final`.
Reviewers: danalbert, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D8795
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@239664 91177308-0d34-0410-b5e6-96231b3b80d8
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
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@230120 91177308-0d34-0410-b5e6-96231b3b80d8