Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -305,6 +305,10 @@ #define _LIBCPP_UNUSED __attribute__((__unused__)) +#if !(__has_feature(cxx_default_function_template_args)) +#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS +#endif + #if !(__has_feature(cxx_defaulted_functions)) #define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS #endif // !(__has_feature(cxx_defaulted_functions)) @@ -474,6 +478,7 @@ #define _LIBCPP_HAS_NO_ADVANCED_SFINAE #define _LIBCPP_HAS_NO_DECLTYPE +#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS #define _LIBCPP_HAS_NO_NULLPTR @@ -487,13 +492,12 @@ #else // __GXX_EXPERIMENTAL_CXX0X__ #if _GNUC_VER < 403 +#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #define _LIBCPP_HAS_NO_RVALUE_REFERENCES -#endif - -#if _GNUC_VER < 403 #define _LIBCPP_HAS_NO_STATIC_ASSERT #endif + #if _GNUC_VER < 404 #define _LIBCPP_HAS_NO_DECLTYPE #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS @@ -565,6 +569,7 @@ #define _LIBCPP_NORETURN __attribute__((noreturn)) #define _LIBCPP_UNUSED +#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES #define _LIBCPP_HAS_NO_ADVANCED_SFINAE #define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS Index: include/utility =================================================================== --- include/utility +++ include/utility @@ -288,6 +288,12 @@ // pair(const pair&) = default; // pair(pair&&) = default; +#ifndef _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS + template , _Dummy>::value && + __dependent_type, _Dummy>::value + >::type> +#endif _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() : first(), second() {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 Index: test/std/utilities/utility/pairs/pairs.pair/default-sfinae.pass.cpp =================================================================== --- /dev/null +++ test/std/utilities/utility/pairs/pairs.pair/default-sfinae.pass.cpp @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template struct pair + +// Test the SFINAE required by LWG Issue #2367. +// is_default_constructible + +// UNSUPPORTED: c++98, c++03 + +#include +#include +#include + +#include "test_macros.h" + +#if TEST_STD_VER > 11 +#define CONSTEXPR_CXX14 constexpr +#define STATIC_ASSERT_CXX14(Pred) static_assert(Pred, "") +#else +#define CONSTEXPR_CXX14 +#define STATIC_ASSERT_CXX14(Pred) assert(Pred) +#endif + +struct DeletedDefault { + // A class with a deleted default constructor. Used to test the SFINAE + // on std::pairs default constructor. + constexpr explicit DeletedDefault(int x) : value(x) {} + constexpr DeletedDefault() = delete; + int value; +}; + +template +struct DependantType: public Tp {}; + +template +using DependantIsDefault = DependantType, Val>; + +template +struct DefaultSFINAES { + template ::value + >::type + > + constexpr DefaultSFINAES() : value() {} + constexpr explicit DefaultSFINAES(T const& x) : value(x) {} + T value; +}; + +struct NoDefault { + constexpr NoDefault(int v) : value(v) {} + int value; +}; + +template +void test_not_is_default_constructible() +{ + { + typedef std::pair P; + static_assert(!std::is_default_constructible

::value, ""); + static_assert(std::is_constructible::value, ""); + } + { + typedef std::pair P; + static_assert(!std::is_default_constructible

::value, ""); + static_assert(std::is_constructible::value, ""); + } + { + typedef std::pair P; + static_assert(!std::is_default_constructible

::value, ""); + static_assert(std::is_constructible::value, ""); + } +} + +template +void test_is_default_constructible() +{ + { + typedef std::pair P; + static_assert(std::is_default_constructible

::value, ""); + } + { + typedef std::pair P; + static_assert(std::is_default_constructible

::value, ""); + } + { + typedef std::pair P; + static_assert(std::is_default_constructible

::value, ""); + } +} + +template +struct IllFormedDefaultImp { + constexpr explicit IllFormedDefaultImp(int v) : value(v) {} + constexpr IllFormedDefaultImp() : value(T::DoesNotExistAndShouldNotCompile) {} + int value; +}; + +typedef IllFormedDefaultImp IllFormedDefault; + // A class which provides a constexpr default constructor with a valid + // signature but an ill-formed body. The A compile error will be emitted if + // the default constructor is instantiated. + + +// Check that the SFINAE on the default constructor is not evaluated when +// it isn't needed. If the default constructor of 'IllFormedDefault' is evaluated +// in C++11, even with is_default_constructible, then this test should fail to +// compile. In C++14 and greater evaluate each test is evaluated as a constant +// expression. +// See LWG issue #2367 +void test_illformed_default() +{ + { + typedef std::pair P; + static_assert((std::is_constructible::value), ""); + CONSTEXPR_CXX14 P p(IllFormedDefault(42), -5); + STATIC_ASSERT_CXX14(p.first.value == 42 && p.second == -5); + } + { + typedef std::pair P; + static_assert((std::is_constructible::value), ""); + CONSTEXPR_CXX14 IllFormedDefault dd(-5); + CONSTEXPR_CXX14 P p(42, dd); + STATIC_ASSERT_CXX14(p.first == 42 && p.second.value == -5); + } + { + typedef std::pair P; + static_assert((std::is_constructible::value), ""); + CONSTEXPR_CXX14 P p(IllFormedDefault(42), IllFormedDefault(-5)); + STATIC_ASSERT_CXX14(p.first.value == 42 && p.second.value == -5); + } +} + + +int main() +{ + { + // Check that pair can still be used even if + // is_default_constructible or is_default_constructible cause + // a compilation error. + test_illformed_default(); + } + { + // pair::pair() is only disable in C++11 and beyond. + test_not_is_default_constructible(); + test_not_is_default_constructible(); + test_not_is_default_constructible>(); + test_not_is_default_constructible>(); + test_not_is_default_constructible(); + test_not_is_default_constructible(); + } + { + test_is_default_constructible(); + test_is_default_constructible>(); + } +} Index: test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp =================================================================== --- test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp +++ test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp @@ -13,9 +13,15 @@ // constexpr pair(); +// NOTE: The SFINAE on the default constructor is tested in +// default-sfinae.pass.cpp + #include +#include #include +#include "test_macros.h" + int main() { { @@ -24,13 +30,12 @@ assert(p.first == 0.0f); assert(p.second == nullptr); } - -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER >= 11 { - typedef std::pair P; - constexpr P p; - static_assert(p.first == 0.0f, ""); - static_assert(p.second == nullptr, ""); + typedef std::pair P; + constexpr P p; + static_assert(p.first == 0.0f, ""); + static_assert(p.second == nullptr, ""); } #endif }