Merged to 6.0 in r322659.
On Sun, Jan 7, 2018 at 5:45 PM, Dimitry Andric via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: dim > Date: Sun Jan 7 08:45:11 2018 > New Revision: 321963 > > URL: http://llvm.org/viewvc/llvm-project?rev=321963&view=rev > Log: > Add pre-C++11 is_constructible wrappers for 3 arguments > > Summary: > After rL319736 for D28253 (which fixes PR28929), gcc cannot compile > `<memory>` anymore in pre-C+11 modes, complaining: > > ``` > In file included from /usr/include/c++/v1/memory:648:0, > from test.cpp:1: > /usr/include/c++/v1/memory: In static member function 'static > std::__1::shared_ptr<_Tp> std::__1::shared_ptr<_Tp>::make_shared(_A0&, _A1&, > _A2&)': > /usr/include/c++/v1/memory:4365:5: error: wrong number of template arguments > (4, should be at least 1) > static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't > construct object in make_shared" ); > ^ > In file included from /usr/include/c++/v1/memory:649:0, > from test.cpp:1: > /usr/include/c++/v1/type_traits:3198:29: note: provided for 'template<class > _Tp, class _A0, class _A1> struct std::__1::is_constructible' > struct _LIBCPP_TEMPLATE_VIS is_constructible > ^~~~~~~~~~~~~~~~ > In file included from /usr/include/c++/v1/memory:648:0, > from test.cpp:1: > /usr/include/c++/v1/memory:4365:5: error: template argument 1 is invalid > static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't > construct object in make_shared" ); > ^ > /usr/include/c++/v1/memory: In static member function 'static > std::__1::shared_ptr<_Tp> std::__1::shared_ptr<_Tp>::allocate_shared(const > _Alloc&, _A0&, _A1&, _A2&)': > /usr/include/c++/v1/memory:4444:5: error: wrong number of template arguments > (4, should be at least 1) > static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't > construct object in allocate_shared" ); > ^ > In file included from /usr/include/c++/v1/memory:649:0, > from test.cpp:1: > /usr/include/c++/v1/type_traits:3198:29: note: provided for 'template<class > _Tp, class _A0, class _A1> struct std::__1::is_constructible' > struct _LIBCPP_TEMPLATE_VIS is_constructible > ^~~~~~~~~~~~~~~~ > In file included from /usr/include/c++/v1/memory:648:0, > from test.cpp:1: > /usr/include/c++/v1/memory:4444:5: error: template argument 1 is invalid > static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't > construct object in allocate_shared" ); > ^ > ``` > > This is also reported in https://bugs.freebsd.org/224946 (FreeBSD is > apparently one of the very few projects that regularly builds programs > against libc++ with gcc). > > The reason is that the static assertions are invoking `is_constructible` with > three arguments, while gcc does not have the built-in `is_constructible` > feature, and the pre-C++11 `is_constructible` wrappers in `<type_traits>` > only provide up to two arguments. > > I have added additional wrappers for three arguments, modified the > `is_constructible` entry point to take three arguments instead, and added a > simple test to is_constructible.pass.cpp. > > Reviewers: EricWF, mclow.lists > > Reviewed By: EricWF > > Subscribers: krytarowski, cfe-commits, emaste > > Differential Revision: https://reviews.llvm.org/D41805 > > Modified: > libcxx/trunk/include/type_traits > > libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp > > Modified: libcxx/trunk/include/type_traits > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=321963&r1=321962&r2=321963&view=diff > ============================================================================== > --- libcxx/trunk/include/type_traits (original) > +++ libcxx/trunk/include/type_traits Sun Jan 7 08:45:11 2018 > @@ -3172,6 +3172,14 @@ template <class _A0, class _A1> > false_type > __is_constructible2_test(__any, _A0&, _A1&); > > +template <class _Tp, class _A0, class _A1, class _A2> > +decltype((_Tp(_VSTD::declval<_A0>(), _VSTD::declval<_A1>(), > _VSTD::declval<_A2>()), true_type())) > +__is_constructible3_test(_Tp&, _A0&, _A1&, _A2&); > + > +template <class _A0, class _A1, class _A2> > +false_type > +__is_constructible3_test(__any, _A0&, _A1&, _A2&); > + > template <bool, class _Tp> > struct __is_constructible0_imp // false, _Tp is not a scalar > : public common_type > @@ -3196,6 +3204,14 @@ struct __is_constructible2_imp // false, > >::type > {}; > > +template <bool, class _Tp, class _A0, class _A1, class _A2> > +struct __is_constructible3_imp // false, _Tp is not a scalar > + : public common_type > + < > + decltype(__is_constructible3_test(declval<_Tp&>(), > declval<_A0>(), declval<_A1>(), declval<_A2>())) > + >::type > + {}; > + > // handle scalars and reference types > > // Scalars are default constructible, references are not > @@ -3215,6 +3231,11 @@ struct __is_constructible2_imp<true, _Tp > : public false_type > {}; > > +template <class _Tp, class _A0, class _A1, class _A2> > +struct __is_constructible3_imp<true, _Tp, _A0, _A1, _A2> > + : public false_type > + {}; > + > // Treat scalars and reference types separately > > template <bool, class _Tp> > @@ -3235,6 +3256,12 @@ struct __is_constructible2_void_check > _Tp, _A0, _A1> > {}; > > +template <bool, class _Tp, class _A0, class _A1, class _A2> > +struct __is_constructible3_void_check > + : public __is_constructible3_imp<is_scalar<_Tp>::value || > is_reference<_Tp>::value, > + _Tp, _A0, _A1, _A2> > + {}; > + > // If any of T or Args is void, is_constructible should be false > > template <class _Tp> > @@ -3252,17 +3279,24 @@ struct __is_constructible2_void_check<tr > : public false_type > {}; > > +template <class _Tp, class _A0, class _A1, class _A2> > +struct __is_constructible3_void_check<true, _Tp, _A0, _A1, _A2> > + : public false_type > + {}; > + > // is_constructible entry point > > template <class _Tp, class _A0 = __is_construct::__nat, > - class _A1 = __is_construct::__nat> > + class _A1 = __is_construct::__nat, > + class _A2 = __is_construct::__nat> > struct _LIBCPP_TEMPLATE_VIS is_constructible > - : public __is_constructible2_void_check<is_void<_Tp>::value > + : public __is_constructible3_void_check<is_void<_Tp>::value > || is_abstract<_Tp>::value > || is_function<_Tp>::value > || is_void<_A0>::value > - || is_void<_A1>::value, > - _Tp, _A0, _A1> > + || is_void<_A1>::value > + || is_void<_A2>::value, > + _Tp, _A0, _A1, _A2> > {}; > > template <class _Tp> > @@ -3282,6 +3316,16 @@ struct _LIBCPP_TEMPLATE_VIS is_construct > _Tp, _A0> > {}; > > +template <class _Tp, class _A0, class _A1> > +struct _LIBCPP_TEMPLATE_VIS is_constructible<_Tp, _A0, _A1, > __is_construct::__nat> > + : public __is_constructible2_void_check<is_void<_Tp>::value > + || is_abstract<_Tp>::value > + || is_function<_Tp>::value > + || is_void<_A0>::value > + || is_void<_A1>::value, > + _Tp, _A0, _A1> > + {}; > + > // Array types are default constructible if their element type > // is default constructible > > @@ -3300,6 +3344,11 @@ struct __is_constructible2_imp<false, _A > : public false_type > {}; > > +template <class _Ap, size_t _Np, class _A0, class _A1, class _A2> > +struct __is_constructible3_imp<false, _Ap[_Np], _A0, _A1, _A2> > + : public false_type > + {}; > + > // Incomplete array types are not constructible > > template <class _Ap> > @@ -3317,6 +3366,11 @@ struct __is_constructible2_imp<false, _A > : public false_type > {}; > > +template <class _Ap, class _A0, class _A1, class _A2> > +struct __is_constructible3_imp<false, _Ap[], _A0, _A1, _A2> > + : public false_type > + {}; > + > #endif // __has_feature(is_constructible) > > > > Modified: > libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp?rev=321963&r1=321962&r2=321963&view=diff > ============================================================================== > --- > libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp > (original) > +++ > libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp > Sun Jan 7 08:45:11 2018 > @@ -30,6 +30,7 @@ struct A > { > explicit A(int); > A(int, double); > + A(int, long, double); > #if TEST_STD_VER >= 11 > private: > #endif > @@ -106,6 +107,16 @@ void test_is_constructible() > #endif > } > > +template <class T, class A0, class A1, class A2> > +void test_is_constructible() > +{ > + static_assert(( std::is_constructible<T, A0, A1, A2>::value), ""); > + LIBCPP11_STATIC_ASSERT((std::__libcpp_is_constructible<T, A0, A1, > A2>::type::value), ""); > +#if TEST_STD_VER > 14 > + static_assert(( std::is_constructible_v<T, A0, A1, A2>), ""); > +#endif > +} > + > template <class T> > void test_is_not_constructible() > { > @@ -146,6 +157,7 @@ int main() > test_is_constructible<int, const int> (); > test_is_constructible<A, int> (); > test_is_constructible<A, int, double> (); > + test_is_constructible<A, int, long, double> (); > test_is_constructible<int&, int&> (); > > test_is_not_constructible<A> (); > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits