diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index a5a7898..dfcd357 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -141,13 +141,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template , - is_default_constructible<_U2>> + __is_implicitly_default_constructible<_U1>, + __is_implicitly_default_constructible<_U2>> ::value, bool>::type = true> #endif _GLIBCXX_CONSTEXPR pair() : first(), second() { } +#if __cplusplus >= 201103L + template , + is_default_constructible<_U2>, + __not_< + __and_<__is_implicitly_default_constructible<_U1>, + __is_implicitly_default_constructible<_U2>>>> + ::value, bool>::type = false> + explicit constexpr pair() + : first(), second() { } +#endif + /** Two objects may be passed to a @c pair constructor to be copied. */ #if __cplusplus < 201103L pair(const _T1& __a, const _T2& __b) diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 8af01f4..e6c32b3 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -551,16 +551,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __and_...>::value; } + static constexpr bool _ImplicitlyDefaultConstructibleTuple() + { + return __and_<__is_implicitly_default_constructible<_Elements>...> + ::value; + } }; public: template:: - _DefaultConstructibleTuple(), + _ImplicitlyDefaultConstructibleTuple(), bool>::type = true> constexpr tuple() : _Inherited() { } + template:: + _DefaultConstructibleTuple() + && + !_TC2<_Dummy>:: + _ImplicitlyDefaultConstructibleTuple(), + bool>::type = false> + explicit constexpr tuple() + : _Inherited() { } + // Shortcut for the cases where constructors taking _Elements... // need to be constrained. template using _TCC = @@ -837,13 +852,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template , - is_default_constructible<_U2>> + __is_implicitly_default_constructible<_U1>, + __is_implicitly_default_constructible<_U2>> ::value, bool>::type = true> constexpr tuple() : _Inherited() { } + template , + is_default_constructible<_U2>, + __not_< + __and_<__is_implicitly_default_constructible<_U1>, + __is_implicitly_default_constructible<_U2>>>> + ::value, bool>::type = false> + + explicit constexpr tuple() + : _Inherited() { } + // Shortcut for the cases where constructors taking _T1, _T2 // need to be constrained. template using _TCC = diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index e08131b..ccbae87 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -1337,6 +1337,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public is_trivially_constructible<_Tp>::type { }; + struct __do_is_implicitly_default_constructible_impl + { + template + static void __helper(const _Tp&); + + template + static true_type __test(const _Tp&, + decltype(__helper({}))* = 0); + + static false_type __test(...); + }; + + template + struct __is_implicitly_default_constructible_impl + : public __do_is_implicitly_default_constructible_impl + { + typedef decltype(__test(declval<_Tp>())) type; + }; + + template + struct __is_implicitly_default_constructible_safe + : public __is_implicitly_default_constructible_impl<_Tp>::type + { }; + + template + struct __is_implicitly_default_constructible + : public __and_, + __is_implicitly_default_constructible_safe<_Tp>> + { }; + /// is_trivially_copy_constructible template struct is_trivially_copy_constructible diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc index 2723e5c..4e7deda 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // . -// { dg-error "static assertion failed" "" { target *-*-* } 2209 } +// { dg-error "static assertion failed" "" { target *-*-* } 2239 } #include diff --git a/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/requirements/explicit_instantiation.cc new file mode 100644 index 0000000..acc9f37 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/requirements/explicit_instantiation.cc @@ -0,0 +1,27 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +namespace std +{ + typedef short test_type; + template struct std::__is_implicitly_default_constructible; +} diff --git a/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/requirements/typedefs.cc new file mode 100644 index 0000000..234b06c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/requirements/typedefs.cc @@ -0,0 +1,32 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + + +void test01() +{ + // Check for required typedefs + typedef std::__is_implicitly_default_constructible test_type; + typedef test_type::value_type value_type; + typedef test_type::type type; + typedef test_type::type::value_type type_value_type; + typedef test_type::type::type type_type; +} diff --git a/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/value.cc b/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/value.cc new file mode 100644 index 0000000..aff4955 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_implicitly_default_constructible/value.cc @@ -0,0 +1,44 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +struct ExplicitDefault +{ + explicit ExplicitDefault() {} +}; + +struct ExplicitDefaultDefault +{ + explicit ExplicitDefaultDefault() = default; +}; + +void test01() +{ + using std::__is_implicitly_default_constructible; + // Positive tests. + static_assert(__is_implicitly_default_constructible::value, ""); + // Negative tests. + static_assert(!__is_implicitly_default_constructible::value, ""); + static_assert(!__is_implicitly_default_constructible< + ExplicitDefault>::value, ""); + static_assert(!__is_implicitly_default_constructible< + ExplicitDefaultDefault>::value, ""); +} diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc index 507930d..8e5fe53 100644 --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc @@ -48,4 +48,4 @@ void test01() // { dg-error "required from here" "" { target *-*-* } 40 } // { dg-error "required from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1874 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1904 } diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc index 608fd1a..4cd0311 100644 --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc @@ -48,5 +48,5 @@ void test01() // { dg-error "required from here" "" { target *-*-* } 40 } // { dg-error "required from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1770 } -// { dg-error "declaration of" "" { target *-*-* } 1727 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1800 } +// { dg-error "declaration of" "" { target *-*-* } 1757 } diff --git a/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc b/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc index 50edda9..ac1dc7e 100644 --- a/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc +++ b/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc @@ -26,6 +26,16 @@ struct Explicit explicit Explicit(int) {} }; +struct ExplicitDefault +{ + explicit ExplicitDefault() {} +}; + +struct ExplicitDefaultDefault +{ + explicit ExplicitDefaultDefault() = default; +}; + std::pair f1() {return {1,2};} std::pair f2() {return {1,2};} // { dg-error "explicit" } @@ -72,6 +82,20 @@ void f6(std::pair) {} void f7(std::pair) {} +std::pair f8() +{ + return {}; // { dg-error "explicit" } +} + +std::pair f9() +{ + return {}; // { dg-error "explicit" } +} + +void f10(std::pair) {} + +void f11(std::pair) {} + void test_arg_passing() { f6(v0); // { dg-error "could not convert" } @@ -84,6 +108,10 @@ void test_arg_passing() f7({1,2}); f7(std::pair{}); f7(std::pair{}); + f10({}); // { dg-error "explicit" } + f11({}); // { dg-error "explicit" } + f10(std::pair{}); + f11(std::pair{}); } struct MoveOnly diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc index 114a490..4d97cfb 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc @@ -28,13 +28,26 @@ struct Explicit explicit Explicit(int) {} }; +struct ExplicitDefault +{ + explicit ExplicitDefault() {} +}; + +struct ExplicitDefaultDefault +{ + explicit ExplicitDefaultDefault() = default; +}; + std::tuple f1a() {return {1};} std::tuple f1b() {return {1,2};} std::tuple f1c() {return {1,2,3};} -std::tuple f2_a() {return {1};} // { dg-error "explicit" } -std::tuple f2_b() {return {1,2};} // { dg-error "explicit" } -std::tuple f2_c() {return {1,2,3};} // { dg-error "explicit" } +std::tuple f2_a() +{return {1};} // { dg-error "explicit" } +std::tuple f2_b() +{return {1,2};} // { dg-error "explicit" } +std::tuple f2_c() +{return {1,2,3};} // { dg-error "explicit" } std::tuple f3_a() {return std::tuple{1};} std::tuple f3_b() {return std::tuple{1,2};} @@ -57,6 +70,24 @@ std::tuple f5_a() {return {1};} std::tuple f5_b() {return {1,2};} std::tuple f5_c() {return {1,2,3};} +std::tuple f6_a() +{return {};} // { dg-error "explicit" } +std::tuple f6_b() +{return {};} // { dg-error "explicit" } +std::tuple f6_c() +{return {};} // { dg-error "explicit" } +std::tuple f6_d() +{return {};} // { dg-error "explicit" } + +std::tuple f7_a() +{return {};} // { dg-error "explicit" } +std::tuple f7_b() +{return {};} // { dg-error "explicit" } +std::tuple f7_c() +{return {};} // { dg-error "explicit" } + std::tuple fp1() {return std::pair{1,2}; } std::tuple fp2() {return std::pair{1,2}; } std::tuple fp3() @@ -163,7 +194,7 @@ std::tuple v31_c{std::allocator_arg, std::allocator{}, 1,2,3}; std::tuple v32_a - = {std::allocator_arg, std::allocator{}, 1}; // { dg-error "explicit" } + = {std::allocator_arg, std::allocator{ }, 1}; // { dg-error "explicit" } std::tuple v32_b = {std::allocator_arg, std::allocator{}, 1, 2}; // { dg-error "explicit" } std::tuple v32_c @@ -199,7 +230,19 @@ std::tuple v42 = {std::allocator_arg, std::allocator{}, v20}; std::tuple v43 = {std::allocator_arg, std::allocator{}, v20}; std::tuple v44 -= {std::allocator_arg, std::allocator{}, v20}; // { dg-error "explicit" } += {std::allocator_arg, std::allocator{ }, v20}; // { dg-error "explicit" } +std::tuple v45_a{}; +std::tuple v45_b{}; + +std::tuple v46_a = {}; // { dg-error "explicit" } +std::tuple v46_b = {}; // { dg-error "explicit" } + +std::tuple v47_a{}; +std::tuple v47_b{}; + +std::tuple v48_a = {}; // { dg-error "explicit" } +std::tuple v48_b = { }; // { dg-error "explicit" } + struct DeletedCopy { @@ -225,58 +268,73 @@ std::tuple v50(std::allocator_arg, std::allocator{}, 3, 4, {42}); -void f6_a(std::tuple) {} -void f6_b(std::tuple) {} -void f6_c(std::tuple) {} +void f8_a(std::tuple) {} +void f8_b(std::tuple) {} +void f8_c(std::tuple) {} + +void f9_a(std::tuple) {} +void f9_b(std::tuple) {} +void f9_c(std::tuple) {} + +void f10_a(std::tuple) {} +void f10_b(std::tuple) {} -void f7_a(std::tuple) {} -void f7_b(std::tuple) {} -void f7_c(std::tuple) {} +void f11_a(std::tuple) {} +void f11_b(std::tuple) {} void test_arg_passing() { - f6_a(v0_a); // { dg-error "could not convert" } - f6_b(v0_b); // { dg-error "could not convert" } - f6_c(v0_c); // { dg-error "could not convert" } - f6_b(v20); // { dg-error "could not convert" } - - f6_a(v1_a); - f6_b(v1_b); - f6_c(v1_c); - - f6_a({1}); // { dg-error "explicit" } - f6_b({1,2}); // { dg-error "explicit" } - f6_c({1,2,3}); // { dg-error "explicit" } - - f6_a(std::tuple{}); - f6_b(std::tuple{}); - f6_c(std::tuple{}); - - f6_a(std::tuple{}); // { dg-error "could not convert" } - f6_b(std::tuple{}); // { dg-error "could not convert" } - f6_c(std::tuple{}); // { dg-error "could not convert" } - f6_b(std::pair{}); // { dg-error "could not convert" } - - f7_a(v0_a); - f7_b(v0_b); - f7_c(v0_c); - f7_b(v20); - - f7_a(v6_a); - f7_b(v6_b); - f7_c(v6_c); - - f7_a({1}); - f7_b({1,2}); - f7_c({1,2,3}); - - f7_a(std::tuple{}); - f7_b(std::tuple{}); - f7_c(std::tuple{}); - f7_b(std::pair{}); - - - f7_a(std::tuple{}); - f7_b(std::tuple{}); - f7_c(std::tuple{}); + f8_a(v0_a); // { dg-error "could not convert" } + f8_b(v0_b); // { dg-error "could not convert" } + f8_c(v0_c); // { dg-error "could not convert" } + f8_b(v20); // { dg-error "could not convert" } + + f8_a(v1_a); + f8_b(v1_b); + f8_c(v1_c); + + f8_a({1}); // { dg-error "explicit" } + f8_b({1,2}); // { dg-error "explicit" } + f8_c({1,2,3}); // { dg-error "explicit" } + + f8_a(std::tuple{}); + f8_b(std::tuple{}); + f8_c(std::tuple{}); + + f8_a(std::tuple{}); // { dg-error "could not convert" } + f8_b(std::tuple{}); // { dg-error "could not convert" } + f8_c(std::tuple{}); // { dg-error "could not convert" } + f8_b(std::pair{}); // { dg-error "could not convert" } + + f9_a(v0_a); + f9_b(v0_b); + f9_c(v0_c); + f9_b(v20); + + f9_a(v6_a); + f9_b(v6_b); + f9_c(v6_c); + + f9_a({1}); + f9_b({1,2}); + f9_c({1,2,3}); + + f9_a(std::tuple{}); + f9_b(std::tuple{}); + f9_c(std::tuple{}); + f9_b(std::pair{}); + + f9_a(std::tuple{}); + f9_b(std::tuple{}); + f9_c(std::tuple{}); + + f10_a({}); // { dg-error "explicit" } + f10_b({}); // { dg-error "explicit" } + f11_a({}); // { dg-error "explicit" } + f11_b({}); // { dg-error "explicit" } + + f10_a(std::tuple{}); + f10_b(std::tuple{}); + f11_a(std::tuple{}); + f11_b(std::tuple{}); }