diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:47:26 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:47:26 +0000 |
commit | 51072bd6bf79ef2bc6a922079bff57c31c1effbc (patch) | |
tree | 91a2effbc9e6f80bdbbf9eb70e06c51ad0867ea0 /test/std/utilities | |
parent | bb5e33f003797b67974a8893f7f2930fc51b8210 (diff) |
Notes
Diffstat (limited to 'test/std/utilities')
300 files changed, 5606 insertions, 2200 deletions
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp index e165d9836db00..81c366e0668f4 100644 --- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp +++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp @@ -11,7 +11,9 @@ #include <memory> #include <cassert> -#if __cplusplus >= 201103L +#include "test_macros.h" + +#if TEST_STD_VER >= 11 // #include <memory> // // template <class Alloc> @@ -20,7 +22,7 @@ // typedef Alloc allocator_type; // typedef typename allocator_type::value_type // value_type; -// +// // typedef Alloc::pointer | value_type* pointer; // typedef Alloc::const_pointer // | pointer_traits<pointer>::rebind<const value_type> @@ -37,7 +39,10 @@ void test_pointer() { typename std::allocator_traits<Alloc>::pointer vp; typename std::allocator_traits<Alloc>::const_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -71,7 +76,10 @@ void test_void_pointer() { typename std::allocator_traits<Alloc>::void_pointer vp; typename std::allocator_traits<Alloc>::const_void_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -110,7 +118,7 @@ int main() test_void_pointer<std::scoped_allocator_adaptor<std::allocator<char>>> (); test_void_pointer<std::scoped_allocator_adaptor<std::allocator<int>>> (); - test_void_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> (); + test_void_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> (); } #else int main() {} diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp index e19e731f6cf2b..90fe944125b5f 100644 --- a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp +++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp @@ -32,7 +32,7 @@ int main() static_assert( (std::is_same< std::allocator_traits<min_allocator<int>>::is_always_equal, std::true_type>::value ), "" ); - + // wrapping one allocator static_assert( (std::is_same< @@ -51,14 +51,14 @@ int main() static_assert(( std::scoped_allocator_adaptor<A1<int>, A2<int>>::is_always_equal::value == ( std::allocator_traits<A1<int>>::is_always_equal::value && - std::allocator_traits<A2<int>>::is_always_equal::value) + std::allocator_traits<A2<int>>::is_always_equal::value) ), ""); // wrapping two allocators (check the values instead of the types) static_assert(( std::scoped_allocator_adaptor<A1<int>, min_allocator<int>>::is_always_equal::value == ( std::allocator_traits<A1<int>>::is_always_equal::value && - std::allocator_traits<min_allocator<int>>::is_always_equal::value) + std::allocator_traits<min_allocator<int>>::is_always_equal::value) ), ""); @@ -66,8 +66,8 @@ int main() static_assert(( std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::is_always_equal::value == ( std::allocator_traits<A1<int>>::is_always_equal::value && - std::allocator_traits<A2<int>>::is_always_equal::value && - std::allocator_traits<A3<int>>::is_always_equal::value) + std::allocator_traits<A2<int>>::is_always_equal::value && + std::allocator_traits<A3<int>>::is_always_equal::value) ), ""); diff --git a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp index 8d4cb6abe84a0..51dd67f9ffdc9 100644 --- a/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp +++ b/test/std/utilities/allocator.adaptor/scoped.adaptor.operators/eq.pass.cpp @@ -16,7 +16,7 @@ // bool // operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, // const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b); -// +// // template <class OuterA1, class OuterA2, class... InnerAllocs> // bool // operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, diff --git a/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp index 3c093fc093c32..ce544c78b6768 100644 --- a/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp +++ b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp @@ -29,7 +29,7 @@ int main() assert(f2(3,2) == 5); assert(f2(3.0, 2) == 5); assert(f2(3, 2.5) == 5.5); - + constexpr int foo = std::plus<int> () (3, 2); static_assert ( foo == 5, "" ); diff --git a/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp index 72b4b4a0a1fe7..b85f439ba7a02 100644 --- a/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp +++ b/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -22,9 +23,8 @@ public: }; -int main () { -#if _LIBCPP_STD_VER > 11 - +int main () +{ static_assert ( !is_transparent<std::plus<int>>::value, "" ); static_assert ( !is_transparent<std::plus<std::string>>::value, "" ); static_assert ( is_transparent<std::plus<void>>::value, "" ); @@ -54,8 +54,6 @@ int main () { static_assert ( !is_transparent<std::negate<std::string>>::value, "" ); static_assert ( is_transparent<std::negate<void>>::value, "" ); static_assert ( is_transparent<std::negate<>>::value, "" ); - -#endif return 0; - } +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/PR23141_invoke_not_constexpr.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/PR23141_invoke_not_constexpr.pass.cpp new file mode 100644 index 0000000000000..5e347c4c57156 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/PR23141_invoke_not_constexpr.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); + +// https://llvm.org/bugs/show_bug.cgi?id=23141 +#include <functional> +#include <type_traits> + +struct Fun +{ + template<typename T, typename U> + void operator()(T &&, U &&) const + { + static_assert(std::is_same<U, int &>::value, ""); + } +}; + +int main() +{ + std::bind(Fun{}, std::placeholders::_1, 42)("hello"); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp new file mode 100644 index 0000000000000..63d3c9b0de923 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +// unspecified bind(Fn, Types...); + +// Check that the call operators have the proper return type and that they +// only SFINAE away when too few arguments are provided. Otherwise they should +// be well formed and should ignore any additional arguments. + +#include <functional> +#include <type_traits> +#include <cassert> + +int dummy = 42; + +int return_value(int) { return dummy; } +int& return_lvalue(int) { return dummy; } +const int& return_const_lvalue(int) { return dummy; } +int&& return_rvalue(int) { return std::move(dummy); } +const int&& return_const_rvalue(int) { return std::move(dummy); } + +template <class Bind, class ...Args> +auto CheckCallImp(int) + -> decltype((std::declval<Bind>()(std::declval<Args>()...)), std::true_type{}); + +template <class Bind, class ...> +auto CheckCallImp(long) -> std::false_type; + +template <class ...Args> +constexpr bool CheckCall() { + return decltype(CheckCallImp<Args...>(0))::value; +} + +template <class Expect, class Fn> +void do_test(Fn* func) { + using namespace std::placeholders; + auto ret = std::bind(func, _1); + auto ret_r = std::bind<Expect>(func, _1); + using Bind = decltype(ret); + using BindR = decltype(ret_r); + + using Ret = decltype(ret(42)); + using Ret2 = decltype(ret(42, 43)); // Test that the extra argument is discarded. + using RetR = decltype(ret_r(42)); + using RetR2 = decltype(ret_r(42, 43)); + + static_assert(std::is_same<Ret, Expect>::value, ""); + static_assert(std::is_same<Ret2, Expect>::value, ""); + static_assert(std::is_same<RetR, Expect>::value, ""); + static_assert(std::is_same<RetR2, Expect>::value, ""); + + Expect exp = ret(100); // the input value is ignored. dummy is returned. + Expect exp2 = ret(101, 102); + Expect exp_r = ret_r(100); + Expect exp_r2 = ret_r(101, 102); + + assert(exp == 42); + assert(exp2 == 42); + assert(exp_r == 42); + assert(exp_r2 == 42); + + if ((std::is_reference<Expect>::value)) { + assert(&exp == &dummy); + assert(&exp2 == &dummy); + assert(&exp_r == &dummy); + assert(&exp_r2 == &dummy); + } + // Check that the call operator SFINAE's away when too few arguments + // are provided but is well-formed otherwise. + { + static_assert(!CheckCall<Bind>(), ""); + static_assert(CheckCall<Bind, int>(), ""); + static_assert(CheckCall<Bind, int, int>(), ""); + static_assert(!CheckCall<BindR>(), ""); + static_assert(CheckCall<BindR, int>(), ""); + static_assert(CheckCall<BindR, int, int>(), ""); + } +} + + +// Test but with an explicit return type which differs from the real one. +template <class Expect, class Fn> +void do_test_r(Fn* func) { + using namespace std::placeholders; + auto ret = std::bind<Expect>(func, _1); + using Bind = decltype(ret); + using Ret = decltype(ret(42)); + using Ret2 = decltype(ret(42, 43)); // Test that the extra argument is discarded. + static_assert(std::is_same<Ret, Expect>::value, ""); + static_assert(std::is_same<Ret2, Expect>::value, ""); + Expect exp = ret(100); // the input value is ignored + Expect exp2 = ret(101, 102); + assert(exp == 42); + assert(exp2 == 42); + // Check that the call operator SFINAE's away when too few arguments + // are provided but is well-formed otherwise. + { + static_assert(!CheckCall<Bind>(), ""); + static_assert(CheckCall<Bind, int>(), ""); + static_assert(CheckCall<Bind, int, int>(), ""); + } +} + +int main() +{ + do_test<int>(return_value); + do_test<int&>(return_lvalue); + do_test<const int&>(return_const_lvalue); + do_test<int&&>(return_rvalue); + do_test<const int&&>(return_const_rvalue); + + do_test_r<long>(return_value); + do_test_r<long>(return_lvalue); + do_test_r<long>(return_const_lvalue); + do_test_r<long>(return_rvalue); + do_test_r<long>(return_const_rvalue); + +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp index 4577d0bf4d54d..a0c686de77ba4 100644 --- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp @@ -23,7 +23,7 @@ struct DummyUnaryFunction { template <typename S> - int operator()(S const & s) const { return 0; } + int operator()(S const &) const { return 0; } }; struct BadUnaryFunction @@ -39,7 +39,7 @@ struct BadUnaryFunction } }; -int main(int argc, char* argv[]) +int main() { // Check that BadUnaryFunction::operator()(S const &) is not // instantiated when checking if BadUnaryFunction is a nested bind diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp index f69afbf576673..dbbd184c7833a 100644 --- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp @@ -286,4 +286,5 @@ int main() test_void_1(); test_int_1(); test_void_2(); + test3(); } diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp index 246186040c56e..68986ac1aeb34 100644 --- a/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp @@ -10,10 +10,14 @@ // <functional> // placeholders +// The placeholders are constexpr in C++17 and beyond. +// libc++ provides constexpr placeholders in C++11 and beyond. #include <functional> #include <type_traits> +#include "test_macros.h" + template <class T> void test(const T& t) @@ -28,6 +32,30 @@ test(const T& t) static_assert(std::is_nothrow_move_constructible<T>::value, ""); } +#if TEST_STD_VER >= 11 +constexpr decltype(std::placeholders::_1) default1{}; +constexpr decltype(std::placeholders::_2) default2{}; +constexpr decltype(std::placeholders::_3) default3{}; +constexpr decltype(std::placeholders::_4) default4{}; +constexpr decltype(std::placeholders::_5) default5{}; +constexpr decltype(std::placeholders::_6) default6{}; +constexpr decltype(std::placeholders::_7) default7{}; +constexpr decltype(std::placeholders::_8) default8{}; +constexpr decltype(std::placeholders::_9) default9{}; +constexpr decltype(std::placeholders::_10) default10{}; + +constexpr decltype(std::placeholders::_1) cp1 = std::placeholders::_1; +constexpr decltype(std::placeholders::_2) cp2 = std::placeholders::_2; +constexpr decltype(std::placeholders::_3) cp3 = std::placeholders::_3; +constexpr decltype(std::placeholders::_4) cp4 = std::placeholders::_4; +constexpr decltype(std::placeholders::_5) cp5 = std::placeholders::_5; +constexpr decltype(std::placeholders::_6) cp6 = std::placeholders::_6; +constexpr decltype(std::placeholders::_7) cp7 = std::placeholders::_7; +constexpr decltype(std::placeholders::_8) cp8 = std::placeholders::_8; +constexpr decltype(std::placeholders::_9) cp9 = std::placeholders::_9; +constexpr decltype(std::placeholders::_10) cp10 = std::placeholders::_10; +#endif // TEST_STD_VER >= 11 + int main() { test(std::placeholders::_1); diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp index 48800a366a81c..d5788986dd25b 100644 --- a/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp +++ b/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <functional> // bit_not @@ -17,7 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::bit_not<int> F; const F f = F(); static_assert((std::is_same<F::argument_type, int>::value), "" ); @@ -43,5 +43,4 @@ int main() constexpr int bar = std::bit_not<> () (0xEA95) & 0xFFFF; static_assert ( bar == 0x156A, "" ); -#endif } diff --git a/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp index 9f8e15dd55fe0..db7168c44f8be 100644 --- a/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp +++ b/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -23,8 +24,6 @@ public: int main () { -#if _LIBCPP_STD_VER > 11 - static_assert ( !is_transparent<std::bit_and<int>>::value, "" ); static_assert ( !is_transparent<std::bit_and<std::string>>::value, "" ); static_assert ( is_transparent<std::bit_and<void>>::value, "" ); @@ -44,8 +43,6 @@ int main () { static_assert ( !is_transparent<std::bit_not<std::string>>::value, "" ); static_assert ( is_transparent<std::bit_not<void>>::value, "" ); static_assert ( is_transparent<std::bit_not<>>::value, "" ); - -#endif return 0; - } +} diff --git a/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp b/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp index 60415ec75d60f..d4d99756fecc2 100644 --- a/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp @@ -15,6 +15,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int main() { typedef std::equal_to<int> F; @@ -24,7 +26,7 @@ int main() static_assert((std::is_same<bool, F::result_type>::value), "" ); assert(f(36, 36)); assert(!f(36, 6)); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 typedef std::equal_to<> F2; const F2 f2 = F2(); assert(f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/greater.pass.cpp b/test/std/utilities/function.objects/comparisons/greater.pass.cpp index 164f09aa605cc..50bdcceee1c98 100644 --- a/test/std/utilities/function.objects/comparisons/greater.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/greater.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::greater<int> F; @@ -25,7 +28,12 @@ int main() assert(!f(36, 36)); assert(f(36, 6)); assert(!f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for greater<int*> and + // greater<void>. + do_pointer_comparison_test<int, std::greater>(); + } +#if TEST_STD_VER > 11 typedef std::greater<> F2; const F2 f2 = F2(); assert(!f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp b/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp index e89c14e246259..0aacb81e9cb47 100644 --- a/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::greater_equal<int> F; @@ -25,7 +28,12 @@ int main() assert(f(36, 36)); assert(f(36, 6)); assert(!f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for greater_equal<int*> and + // greater_equal<void>. + do_pointer_comparison_test<int, std::greater_equal>(); + } +#if TEST_STD_VER > 11 typedef std::greater_equal<> F2; const F2 f2 = F2(); assert(f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/less.pass.cpp b/test/std/utilities/function.objects/comparisons/less.pass.cpp index 74fe166a0cd96..191d58d6e544c 100644 --- a/test/std/utilities/function.objects/comparisons/less.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/less.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::less<int> F; @@ -25,7 +28,11 @@ int main() assert(!f(36, 36)); assert(!f(36, 6)); assert(f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for less<int*> and less<void>. + do_pointer_comparison_test<int, std::less>(); + } +#if TEST_STD_VER > 11 typedef std::less<> F2; const F2 f2 = F2(); assert(!f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp b/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp index e6ba1f7f8a212..a6aca5d195697 100644 --- a/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp @@ -15,6 +15,9 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" +#include "pointer_comparison_test_helper.hpp" + int main() { typedef std::less_equal<int> F; @@ -25,7 +28,12 @@ int main() assert(f(36, 36)); assert(!f(36, 6)); assert(f(6, 36)); -#if _LIBCPP_STD_VER > 11 + { + // test total ordering of int* for less_equal<int*> and + // less_equal<void>. + do_pointer_comparison_test<int, std::less_equal>(); + } +#if TEST_STD_VER > 11 typedef std::less_equal<> F2; const F2 f2 = F2(); assert( f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp b/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp index 3e710b3e0c70b..777c25d520a99 100644 --- a/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp @@ -15,6 +15,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int main() { typedef std::not_equal_to<int> F; @@ -24,7 +26,7 @@ int main() static_assert((std::is_same<bool, F::result_type>::value), "" ); assert(!f(36, 36)); assert(f(36, 6)); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 typedef std::not_equal_to<> F2; const F2 f2 = F2(); assert(!f2(36, 36)); diff --git a/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp b/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp new file mode 100644 index 0000000000000..66d783a6e3577 --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp @@ -0,0 +1,39 @@ +#ifndef POINTER_COMPARISON_TEST_HELPER_HPP +#define POINTER_COMPARISON_TEST_HELPER_HPP + +#include <vector> +#include <memory> +#include <cstdint> +#include <cassert> + +#include "test_macros.h" + +template <class T, template<class> class CompareTemplate> +void do_pointer_comparison_test() { + typedef CompareTemplate<T*> Compare; + typedef CompareTemplate<std::uintptr_t> UIntCompare; +#if TEST_STD_VER > 11 + typedef CompareTemplate<void> VoidCompare; +#else + typedef Compare VoidCompare; +#endif + std::vector<std::shared_ptr<T> > pointers; + const std::size_t test_size = 100; + for (int i=0; i < test_size; ++i) + pointers.push_back(std::shared_ptr<T>(new T())); + Compare comp; + UIntCompare ucomp; + VoidCompare vcomp; + for (int i=0; i < test_size; ++i) { + for (int j=0; j < test_size; ++j) { + T* lhs = pointers[i].get(); + T* rhs = pointers[j].get(); + std::uintptr_t lhs_uint = reinterpret_cast<std::uintptr_t>(lhs); + std::uintptr_t rhs_uint = reinterpret_cast<std::uintptr_t>(rhs); + assert(comp(lhs, rhs) == ucomp(lhs_uint, rhs_uint)); + assert(vcomp(lhs, rhs) == ucomp(lhs_uint, rhs_uint)); + } + } +} + +#endif // POINTER_COMPARISON_TEST_HELPER_HPP diff --git a/test/std/utilities/function.objects/comparisons/transparent.pass.cpp b/test/std/utilities/function.objects/comparisons/transparent.pass.cpp index 41ce4bcae65fd..f353fe7a72a6a 100644 --- a/test/std/utilities/function.objects/comparisons/transparent.pass.cpp +++ b/test/std/utilities/function.objects/comparisons/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -22,9 +23,8 @@ public: }; -int main () { -#if _LIBCPP_STD_VER > 11 - +int main () +{ static_assert ( !is_transparent<std::less<int>>::value, "" ); static_assert ( !is_transparent<std::less<std::string>>::value, "" ); static_assert ( is_transparent<std::less<void>>::value, "" ); @@ -55,7 +55,5 @@ int main () { static_assert ( is_transparent<std::greater_equal<void>>::value, "" ); static_assert ( is_transparent<std::greater_equal<>>::value, "" ); -#endif - return 0; - } +} diff --git a/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp index 97b0b4d158a0c..d1ae6b7809ce8 100644 --- a/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp +++ b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp @@ -174,6 +174,32 @@ void bullet_one_two_tests() { } { TestClass cl_obj(42); + std::reference_wrapper<TestClass> cl(cl_obj); + test_b12<int&(NonCopyable&&) &, int&>(cl); + test_b12<int const&(NonCopyable&&) const &, int const&>(cl); + test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); + test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); + + test_b12<int&(NonCopyable&&) &, int&>(std::move(cl)); + test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl)); + test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl)); + test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl)); + } + { + DerivedFromTestClass cl_obj(42); + std::reference_wrapper<DerivedFromTestClass> cl(cl_obj); + test_b12<int&(NonCopyable&&) &, int&>(cl); + test_b12<int const&(NonCopyable&&) const &, int const&>(cl); + test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); + test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); + + test_b12<int&(NonCopyable&&) &, int&>(std::move(cl)); + test_b12<int const&(NonCopyable&&) const &, int const&>(std::move(cl)); + test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(std::move(cl)); + test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(std::move(cl)); + } + { + TestClass cl_obj(42); TestClass *cl = &cl_obj; test_b12<int&(NonCopyable&&) &, int&>(cl); test_b12<int const&(NonCopyable&&) const &, int const&>(cl); @@ -219,6 +245,22 @@ void bullet_three_four_tests() { } { typedef TestClass Fn; + Fn cl(42); + test_b34<int&>(std::reference_wrapper<Fn>(cl)); + test_b34<int const&>(std::reference_wrapper<Fn const>(cl)); + test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl)); + test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl)); + } + { + typedef DerivedFromTestClass Fn; + Fn cl(42); + test_b34<int&>(std::reference_wrapper<Fn>(cl)); + test_b34<int const&>(std::reference_wrapper<Fn const>(cl)); + test_b34<int volatile&>(std::reference_wrapper<Fn volatile>(cl)); + test_b34<int const volatile&>(std::reference_wrapper<Fn const volatile>(cl)); + } + { + typedef TestClass Fn; Fn cl_obj(42); Fn* cl = &cl_obj; test_b34<int&>(cl); @@ -262,8 +304,46 @@ void bullet_five_tests() { } } +struct CopyThrows { + CopyThrows() {} + CopyThrows(CopyThrows const&) {} + CopyThrows(CopyThrows&&) noexcept {} +}; + +struct NoThrowCallable { + void operator()() noexcept {} + void operator()(CopyThrows) noexcept {} +}; + +struct ThrowsCallable { + void operator()() {} +}; + +struct MemberObj { + int x; +}; + +void noexcept_test() { + { + NoThrowCallable obj; ((void)obj); // suppress unused warning + CopyThrows arg; ((void)arg); // suppress unused warning + static_assert(noexcept(std::invoke(obj)), ""); + static_assert(!noexcept(std::invoke(obj, arg)), ""); + static_assert(noexcept(std::invoke(obj, std::move(arg))), ""); + } + { + ThrowsCallable obj; ((void)obj); // suppress unused warning + static_assert(!noexcept(std::invoke(obj)), ""); + } + { + MemberObj obj{42}; ((void)obj); // suppress unused warning. + static_assert(noexcept(std::invoke(&MemberObj::x, obj)), ""); + } +} + int main() { bullet_one_two_tests(); bullet_three_four_tests(); bullet_five_tests(); + noexcept_test(); } diff --git a/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp b/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp index f371223ee84c7..465e001c3debc 100644 --- a/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp +++ b/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp @@ -15,6 +15,8 @@ #include <functional> #include <cassert> +#include "test_macros.h" + struct A { char test0() {return 'a';} @@ -69,7 +71,7 @@ int main() test0(std::mem_fn(&A::test0)); test1(std::mem_fn(&A::test1)); test2(std::mem_fn(&A::test2)); -#if __has_feature(cxx_noexcept) +#if TEST_STD_VER >= 11 static_assert((noexcept(std::mem_fn(&A::test0))), ""); // LWG#2489 #endif } diff --git a/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp b/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp new file mode 100644 index 0000000000000..c12fa7920974c --- /dev/null +++ b/test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp @@ -0,0 +1,589 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// template <class F> unspecified not_fn(F&& f); + +#include <functional> +#include <type_traits> +#include <string> +#include <cassert> + +#include "test_macros.h" +#include "type_id.h" + + +/////////////////////////////////////////////////////////////////////////////// +// CALLABLE TEST TYPES +/////////////////////////////////////////////////////////////////////////////// + +bool returns_true() { return true; } + +template <class Ret = bool> +struct MoveOnlyCallable { + MoveOnlyCallable(MoveOnlyCallable const&) = delete; + MoveOnlyCallable(MoveOnlyCallable&& other) + : value(other.value) + { other.value = !other.value; } + + template <class ...Args> + Ret operator()(Args&&...) { return Ret{value}; } + + explicit MoveOnlyCallable(bool x) : value(x) {} + Ret value; +}; + +template <class Ret = bool> +struct CopyCallable { + CopyCallable(CopyCallable const& other) + : value(other.value) {} + + CopyCallable(CopyCallable&& other) + : value(other.value) { other.value = !other.value; } + + template <class ...Args> + Ret operator()(Args&&...) { return Ret{value}; } + + explicit CopyCallable(bool x) : value(x) {} + Ret value; +}; + + +template <class Ret = bool> +struct ConstCallable { + ConstCallable(ConstCallable const& other) + : value(other.value) {} + + ConstCallable(ConstCallable&& other) + : value(other.value) { other.value = !other.value; } + + template <class ...Args> + Ret operator()(Args&&...) const { return Ret{value}; } + + explicit ConstCallable(bool x) : value(x) {} + Ret value; +}; + + + +template <class Ret = bool> +struct NoExceptCallable { + NoExceptCallable(NoExceptCallable const& other) + : value(other.value) {} + + template <class ...Args> + Ret operator()(Args&&...) noexcept { return Ret{value}; } + + template <class ...Args> + Ret operator()(Args&&...) const noexcept { return Ret{value}; } + + explicit NoExceptCallable(bool x) : value(x) {} + Ret value; +}; + +struct CopyAssignableWrapper { + CopyAssignableWrapper(CopyAssignableWrapper const&) = default; + CopyAssignableWrapper(CopyAssignableWrapper&&) = default; + CopyAssignableWrapper& operator=(CopyAssignableWrapper const&) = default; + CopyAssignableWrapper& operator=(CopyAssignableWrapper &&) = default; + + template <class ...Args> + bool operator()(Args&&...) { return value; } + + explicit CopyAssignableWrapper(bool x) : value(x) {} + bool value; +}; + + +struct MoveAssignableWrapper { + MoveAssignableWrapper(MoveAssignableWrapper const&) = delete; + MoveAssignableWrapper(MoveAssignableWrapper&&) = default; + MoveAssignableWrapper& operator=(MoveAssignableWrapper const&) = delete; + MoveAssignableWrapper& operator=(MoveAssignableWrapper &&) = default; + + template <class ...Args> + bool operator()(Args&&...) { return value; } + + explicit MoveAssignableWrapper(bool x) : value(x) {} + bool value; +}; + +struct MemFunCallable { + explicit MemFunCallable(bool x) : value(x) {} + + bool return_value() const { return value; } + bool return_value_nc() { return value; } + bool value; +}; + +enum CallType : unsigned { + CT_None, + CT_NonConst = 1, + CT_Const = 2, + CT_LValue = 4, + CT_RValue = 8 +}; + +inline constexpr CallType operator|(CallType LHS, CallType RHS) { + return static_cast<CallType>(static_cast<unsigned>(LHS) | static_cast<unsigned>(RHS)); +} + +struct ForwardingCallObject { + + template <class ...Args> + bool operator()(Args&&... args) & { + set_call<Args&&...>(CT_NonConst | CT_LValue); + return true; + } + + template <class ...Args> + bool operator()(Args&&... args) const & { + set_call<Args&&...>(CT_Const | CT_LValue); + return true; + } + + // Don't allow the call operator to be invoked as an rvalue. + template <class ...Args> + bool operator()(Args&&... args) && { + set_call<Args&&...>(CT_NonConst | CT_RValue); + return true; + } + + template <class ...Args> + bool operator()(Args&&... args) const && { + set_call<Args&&...>(CT_Const | CT_RValue); + return true; + } + + template <class ...Args> + static void set_call(CallType type) { + assert(last_call_type == CT_None); + assert(last_call_args == nullptr); + last_call_type = type; + last_call_args = &makeArgumentID<Args...>(); + } + + template <class ...Args> + static bool check_call(CallType type) { + bool result = + last_call_type == type + && last_call_args + && *last_call_args == makeArgumentID<Args...>(); + last_call_type = CT_None; + last_call_args = nullptr; + return result; + } + + static CallType last_call_type; + static TypeID const* last_call_args; +}; + +CallType ForwardingCallObject::last_call_type = CT_None; +TypeID const* ForwardingCallObject::last_call_args = nullptr; + + + +/////////////////////////////////////////////////////////////////////////////// +// BOOL TEST TYPES +/////////////////////////////////////////////////////////////////////////////// + +struct EvilBool { + static int bang_called; + + EvilBool(EvilBool const&) = default; + EvilBool(EvilBool&&) = default; + + friend EvilBool operator!(EvilBool const& other) { + ++bang_called; + return EvilBool{!other.value}; + } + +private: + friend struct MoveOnlyCallable<EvilBool>; + friend struct CopyCallable<EvilBool>; + friend struct NoExceptCallable<EvilBool>; + + explicit EvilBool(bool x) : value(x) {} + EvilBool& operator=(EvilBool const& other) = default; + +public: + bool value; +}; + +int EvilBool::bang_called = 0; + +struct ExplicitBool { + ExplicitBool(ExplicitBool const&) = default; + ExplicitBool(ExplicitBool&&) = default; + + explicit operator bool() const { return value; } + +private: + friend struct MoveOnlyCallable<ExplicitBool>; + friend struct CopyCallable<ExplicitBool>; + + explicit ExplicitBool(bool x) : value(x) {} + ExplicitBool& operator=(bool x) { + value = x; + return *this; + } + + bool value; +}; + + +struct NoExceptEvilBool { + NoExceptEvilBool(NoExceptEvilBool const&) = default; + NoExceptEvilBool(NoExceptEvilBool&&) = default; + NoExceptEvilBool& operator=(NoExceptEvilBool const& other) = default; + + explicit NoExceptEvilBool(bool x) : value(x) {} + + friend NoExceptEvilBool operator!(NoExceptEvilBool const& other) noexcept { + return NoExceptEvilBool{!other.value}; + } + + bool value; +}; + + + +void constructor_tests() +{ + { + using T = MoveOnlyCallable<bool>; + T value(true); + using RetT = decltype(std::not_fn(std::move(value))); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(!std::is_copy_constructible<RetT>::value, ""); + static_assert(!std::is_move_assignable<RetT>::value, ""); + static_assert(!std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(std::move(value)); + // test it was moved from + assert(value.value == false); + // test that ret() negates the original value 'true' + assert(ret() == false); + assert(ret(0, 0.0, "blah") == false); + // Move ret and test that it was moved from and that ret2 got the + // original value. + auto ret2 = std::move(ret); + assert(ret() == true); + assert(ret2() == false); + assert(ret2(42) == false); + } + { + using T = CopyCallable<bool>; + T value(false); + using RetT = decltype(std::not_fn(value)); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(std::is_copy_constructible<RetT>::value, ""); + static_assert(!std::is_move_assignable<RetT>::value, ""); + static_assert(!std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(value); + // test that value is unchanged (copied not moved) + assert(value.value == false); + // test 'ret' has the original value + assert(ret() == true); + assert(ret(42, 100) == true); + // move from 'ret' and check that 'ret2' has the original value. + auto ret2 = std::move(ret); + assert(ret() == false); + assert(ret2() == true); + assert(ret2("abc") == true); + } + { + using T = CopyAssignableWrapper; + T value(true); + T value2(false); + using RetT = decltype(std::not_fn(value)); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(std::is_copy_constructible<RetT>::value, ""); + static_assert(std::is_move_assignable<RetT>::value, ""); + static_assert(std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(value); + assert(ret() == false); + auto ret2 = std::not_fn(value2); + assert(ret2() == true); + ret = ret2; + assert(ret() == true); + assert(ret2() == true); + } + { + using T = MoveAssignableWrapper; + T value(true); + T value2(false); + using RetT = decltype(std::not_fn(std::move(value))); + static_assert(std::is_move_constructible<RetT>::value, ""); + static_assert(!std::is_copy_constructible<RetT>::value, ""); + static_assert(std::is_move_assignable<RetT>::value, ""); + static_assert(!std::is_copy_assignable<RetT>::value, ""); + auto ret = std::not_fn(std::move(value)); + assert(ret() == false); + auto ret2 = std::not_fn(std::move(value2)); + assert(ret2() == true); + ret = std::move(ret2); + assert(ret() == true); + } +} + +void return_type_tests() +{ + using std::is_same; + { + using T = CopyCallable<bool>; + auto ret = std::not_fn(T{false}); + static_assert(is_same<decltype(ret()), bool>::value, ""); + static_assert(is_same<decltype(ret("abc")), bool>::value, ""); + assert(ret() == true); + } + { + using T = CopyCallable<ExplicitBool>; + auto ret = std::not_fn(T{true}); + static_assert(is_same<decltype(ret()), bool>::value, ""); + static_assert(is_same<decltype(ret(std::string("abc"))), bool>::value, ""); + assert(ret() == false); + } + { + using T = CopyCallable<EvilBool>; + auto ret = std::not_fn(T{false}); + static_assert(is_same<decltype(ret()), EvilBool>::value, ""); + EvilBool::bang_called = 0; + auto value_ret = ret(); + assert(EvilBool::bang_called == 1); + assert(value_ret.value == true); + ret(); + assert(EvilBool::bang_called == 2); + } +} + +// Other tests only test using objects with call operators. Test various +// other callable types here. +void other_callable_types_test() +{ + { // test with function pointer + auto ret = std::not_fn(returns_true); + assert(ret() == false); + } + { // test with lambda + auto returns_value = [](bool value) { return value; }; + auto ret = std::not_fn(returns_value); + assert(ret(true) == false); + assert(ret(false) == true); + } + { // test with pointer to member function + MemFunCallable mt(true); + const MemFunCallable mf(false); + auto ret = std::not_fn(&MemFunCallable::return_value); + assert(ret(mt) == false); + assert(ret(mf) == true); + assert(ret(&mt) == false); + assert(ret(&mf) == true); + } + { // test with pointer to member function + MemFunCallable mt(true); + MemFunCallable mf(false); + auto ret = std::not_fn(&MemFunCallable::return_value_nc); + assert(ret(mt) == false); + assert(ret(mf) == true); + assert(ret(&mt) == false); + assert(ret(&mf) == true); + } + { // test with pointer to member data + MemFunCallable mt(true); + const MemFunCallable mf(false); + auto ret = std::not_fn(&MemFunCallable::value); + assert(ret(mt) == false); + assert(ret(mf) == true); + assert(ret(&mt) == false); + assert(ret(&mf) == true); + } +} + +void throws_in_constructor_test() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + struct ThrowsOnCopy { + ThrowsOnCopy(ThrowsOnCopy const&) { + throw 42; + } + ThrowsOnCopy() = default; + bool operator()() const { assert(false); } + }; + { + ThrowsOnCopy cp; + try { + std::not_fn(cp); + assert(false); + } catch (int const& value) { + assert(value == 42); + } + } +#endif +} + +void call_operator_sfinae_test() { + { // wrong number of arguments + using T = decltype(std::not_fn(returns_true)); + static_assert(std::is_callable<T()>::value, ""); // callable only with no args + static_assert(!std::is_callable<T(bool)>::value, ""); + } + { // violates const correctness (member function pointer) + using T = decltype(std::not_fn(&MemFunCallable::return_value_nc)); + static_assert(std::is_callable<T(MemFunCallable&)>::value, ""); + static_assert(!std::is_callable<T(const MemFunCallable&)>::value, ""); + } + { // violates const correctness (call object) + using Obj = CopyCallable<bool>; + using NCT = decltype(std::not_fn(Obj{true})); + using CT = const NCT; + static_assert(std::is_callable<NCT()>::value, ""); + static_assert(!std::is_callable<CT()>::value, ""); + } + { // returns bad type with no operator! + auto fn = [](auto x) { return x; }; + using T = decltype(std::not_fn(fn)); + static_assert(std::is_callable<T(bool)>::value, ""); + static_assert(!std::is_callable<T(std::string)>::value, ""); + } +} + +void call_operator_forwarding_test() +{ + using Fn = ForwardingCallObject; + auto obj = std::not_fn(Fn{}); + const auto& c_obj = obj; + { // test zero args + obj(); + assert(Fn::check_call<>(CT_NonConst | CT_LValue)); + std::move(obj)(); + assert(Fn::check_call<>(CT_NonConst | CT_RValue)); + c_obj(); + assert(Fn::check_call<>(CT_Const | CT_LValue)); + std::move(c_obj)(); + assert(Fn::check_call<>(CT_Const | CT_RValue)); + } + { // test value categories + int x = 42; + const int cx = 42; + obj(x); + assert(Fn::check_call<int&>(CT_NonConst | CT_LValue)); + obj(cx); + assert(Fn::check_call<const int&>(CT_NonConst | CT_LValue)); + obj(std::move(x)); + assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); + obj(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_NonConst | CT_LValue)); + obj(42); + assert(Fn::check_call<int&&>(CT_NonConst | CT_LValue)); + } + { // test value categories - rvalue + int x = 42; + const int cx = 42; + std::move(obj)(x); + assert(Fn::check_call<int&>(CT_NonConst | CT_RValue)); + std::move(obj)(cx); + assert(Fn::check_call<const int&>(CT_NonConst | CT_RValue)); + std::move(obj)(std::move(x)); + assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); + std::move(obj)(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_NonConst | CT_RValue)); + std::move(obj)(42); + assert(Fn::check_call<int&&>(CT_NonConst | CT_RValue)); + } + { // test value categories - const call + int x = 42; + const int cx = 42; + c_obj(x); + assert(Fn::check_call<int&>(CT_Const | CT_LValue)); + c_obj(cx); + assert(Fn::check_call<const int&>(CT_Const | CT_LValue)); + c_obj(std::move(x)); + assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); + c_obj(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_Const | CT_LValue)); + c_obj(42); + assert(Fn::check_call<int&&>(CT_Const | CT_LValue)); + } + { // test value categories - const call rvalue + int x = 42; + const int cx = 42; + std::move(c_obj)(x); + assert(Fn::check_call<int&>(CT_Const | CT_RValue)); + std::move(c_obj)(cx); + assert(Fn::check_call<const int&>(CT_Const | CT_RValue)); + std::move(c_obj)(std::move(x)); + assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); + std::move(c_obj)(std::move(cx)); + assert(Fn::check_call<const int&&>(CT_Const | CT_RValue)); + std::move(c_obj)(42); + assert(Fn::check_call<int&&>(CT_Const | CT_RValue)); + } + { // test multi arg + int x = 42; + const double y = 3.14; + std::string s = "abc"; + obj(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_LValue); + std::move(obj)(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_NonConst | CT_RValue); + c_obj(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_LValue); + std::move(c_obj)(42, std::move(y), s, std::string{"foo"}); + Fn::check_call<int&&, const double&&, std::string&, std::string&&>(CT_Const | CT_RValue); + } +} + +void call_operator_noexcept_test() +{ + { + using T = ConstCallable<bool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(!noexcept(ret()), "call should not be noexcept"); + auto const& cret = ret; + static_assert(!noexcept(cret()), "call should not be noexcept"); + } + { + using T = NoExceptCallable<bool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(noexcept(!_VSTD::__invoke(value)), ""); + static_assert(noexcept(ret()), "call should be noexcept"); + auto const& cret = ret; + static_assert(noexcept(cret()), "call should be noexcept"); + } + { + using T = NoExceptCallable<NoExceptEvilBool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(noexcept(ret()), "call should not be noexcept"); + auto const& cret = ret; + static_assert(noexcept(cret()), "call should not be noexcept"); + } + { + using T = NoExceptCallable<EvilBool>; + T value(true); + auto ret = std::not_fn(value); + static_assert(!noexcept(ret()), "call should not be noexcept"); + auto const& cret = ret; + static_assert(!noexcept(cret()), "call should not be noexcept"); + } +} + +int main() +{ + constructor_tests(); + return_type_tests(); + other_callable_types_test(); + throws_in_constructor_test(); + call_operator_sfinae_test(); // somewhat of an extension + call_operator_forwarding_test(); + call_operator_noexcept_test(); +} diff --git a/test/std/utilities/function.objects/version.pass.cpp b/test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp index 99d731a74543c..d61c3773e5396 100644 --- a/test/std/utilities/function.objects/version.pass.cpp +++ b/test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp @@ -7,14 +7,10 @@ // //===----------------------------------------------------------------------===// -// <functional> +// INVOKE (f, t1, t2, ..., tN) -#include <functional> +// The tests for INVOKE (f, t1, t2, ..., tN) live in the "test/libcxx" tree +// since they require calling the implementation specific "__invoke" and +// "__invoke_constexpr" functions. -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} +int main() {} diff --git a/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp b/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp deleted file mode 100644 index e579f207a33f2..0000000000000 --- a/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp +++ /dev/null @@ -1,318 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <functional> - -// INVOKE (f, t1, t2, ..., tN) - -//------------------------------------------------------------------------------ -// TESTING INVOKE(f, t1, t2, ..., tN) -// - Bullet 1 -- (t1.*f)(t2, ..., tN) -// - Bullet 2 -- ((*t1).*f)(t2, ..., tN) -// -// Overview: -// Bullets 1 and 2 handle the case where 'f' is a pointer to member function. -// Bullet 1 only handles the cases where t1 is an object of type T or a -// type derived from 'T'. Bullet 2 handles all other cases. -// -// Concerns: -// 1) cv-qualified member function signatures are accepted. -// 2) reference qualified member function signatures are accepted. -// 3) member functions with varargs at the end are accepted. -// 4) The arguments are perfect forwarded to the member function call. -// 5) Classes that are publicly derived from 'T' are accepted as the call object -// 6) All types that dereference to T or a type derived from T can be used -// as the call object. -// 7) Pointers to T or a type derived from T can be used as the call object. -// 8) Reference return types are properly deduced. -// -// -// Plan: -// 1) Create a class that contains a set, 'S', of non-static functions. -// 'S' should include functions that cover every single combination -// of qualifiers and varargs for arities of 0, 1 and 2 (C-1,2,3). -// The argument types used in the functions should be non-copyable (C-4). -// The functions should return 'MethodID::setUncheckedCall()'. -// -// 2) Create a set of supported call object, 'Objs', of different types -// and behaviors. (C-5,6,7) -// -// 3) Attempt to call each function, 'f', in 'S' with each call object, 'c', -// in 'Objs'. After every attempted call to 'f' check that 'f' was -// actually called using 'MethodID::checkCalled(<return-value>)' -// -// 3b) If 'f' is reference qualified call 'f' with the properly qualified -// call object. Otherwise call 'f' with lvalue call objects. -// -// 3a) If 'f' is const, volatile, or cv qualified then call it with call -// objects that are equally or less cv-qualified. - -#include <functional> -#include <type_traits> -#include <cassert> - -#include "test_macros.h" -#include "invoke_helpers.h" - -//============================================================================== -// MemFun03 - C++03 compatible set of test member functions. -struct MemFun03 { - typedef void*& R; -#define F(...) \ - R f(__VA_ARGS__) { return MethodID<R(MemFun03::*)(__VA_ARGS__)>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const { return MethodID<R(MemFun03::*)(__VA_ARGS__) const>::setUncheckedCall(); } \ - R f(__VA_ARGS__) volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) volatile>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) const volatile>::setUncheckedCall(); } -# - F() - F(...) - F(ArgType&) - F(ArgType&, ...) - F(ArgType&, ArgType&) - F(ArgType&, ArgType&, ...) - F(ArgType&, ArgType&, ArgType&) - F(ArgType&, ArgType&, ArgType&, ...) -#undef F -public: - MemFun03() {} -private: - MemFun03(MemFun03 const&); - MemFun03& operator=(MemFun03 const&); -}; - - -#if TEST_STD_VER >= 11 - -//============================================================================== -// MemFun11 - C++11 reference qualified test member functions. -struct MemFun11 { - typedef void*& R; - typedef MemFun11 C; -#define F(...) \ - R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \ - R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \ - R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \ - R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); } -# - F() - F(...) - F(ArgType&&) - F(ArgType&&, ...) - F(ArgType&&, ArgType&&) - F(ArgType&&, ArgType&&, ...) - F(ArgType&&, ArgType&&, ArgType&&) - F(ArgType&&, ArgType&&, ArgType&&, ...) -#undef F -public: - MemFun11() {} -private: - MemFun11(MemFun11 const&); - MemFun11& operator=(MemFun11 const&); -}; - -#endif // TEST_STD_VER >= 11 - - -//============================================================================== -// TestCase - A test case for a single member function. -// ClassType - The type of the class being tested. -// CallSig - The function signature of the method being tested. -// Arity - the arity of 'CallSig' -// CV - the cv qualifiers of 'CallSig' represented as a type tag. -// RValue - The method is RValue qualified. -// ArgRValue - Call the method with RValue arguments. -template <class ClassType, class CallSig, int Arity, class CV, - bool RValue = false, bool ArgRValue = false> -struct TestCaseImp { -public: - - static void run() { TestCaseImp().doTest(); } - -private: - //========================================================================== - // TEST DISPATCH - void doTest() { - // (Plan-2) Create test call objects. - typedef ClassType T; - typedef DerivedFromType<T> D; - T obj; - T* obj_ptr = &obj; - D der; - D* der_ptr = &der; - DerefToType<T> dref; - DerefPropType<T> dref2; - - // (Plan-3) Dispatch based on the CV tags. - CV tag; - Bool<!RValue> NotRValue; - runTestDispatch(tag, obj); - runTestDispatch(tag, der); - runTestDispatch(tag, dref2); - runTestDispatchIf(NotRValue, tag, dref); - runTestDispatchIf(NotRValue, tag, obj_ptr); - runTestDispatchIf(NotRValue, tag, der_ptr); - } - - template <class QT, class Tp> - void runTestDispatchIf(Bool<true>, QT q, Tp& v) { - runTestDispatch(q, v); - } - - template <class QT, class Tp> - void runTestDispatchIf(Bool<false>, QT, Tp&) { - } - - template <class Tp> - void runTestDispatch(Q_None, Tp& v) { - runTest(v); - } - - template <class Tp> - void runTestDispatch(Q_Const, Tp& v) { - Tp const& cv = v; - runTest(v); - runTest(cv); - } - - template <class Tp> - void runTestDispatch(Q_Volatile, Tp& v) { - Tp volatile& vv = v; - runTest(v); - runTest(vv); - } - - template <class Tp> - void runTestDispatch(Q_CV, Tp& v) { - Tp const& cv = v; - Tp volatile& vv = v; - Tp const volatile& cvv = v; - runTest(v); - runTest(cv); - runTest(vv); - runTest(cvv); - } - - template <class Obj> - void runTest(Obj& obj) { - typedef Caster<Q_None, RValue> SCast; - typedef Caster<Q_None, ArgRValue> ACast; - typedef CallSig (ClassType::*MemPtr); - // Delegate test to logic in invoke_helpers.h - BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b; - b.runTest( (MemPtr)&ClassType::f, obj); - } -}; - -template <class Sig, int Arity, class CV> -struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {}; - -#if TEST_STD_VER >= 11 -template <class Sig, int Arity, class CV, bool RValue = false> -struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {}; -#endif - -int main() { - typedef void*& R; - typedef ArgType A; - TestCase<R(), 0, Q_None>::run(); - TestCase<R() const, 0, Q_Const>::run(); - TestCase<R() volatile, 0, Q_Volatile>::run(); - TestCase<R() const volatile, 0, Q_CV>::run(); - TestCase<R(...), 0, Q_None>::run(); - TestCase<R(...) const, 0, Q_Const>::run(); - TestCase<R(...) volatile, 0, Q_Volatile>::run(); - TestCase<R(...) const volatile, 0, Q_CV>::run(); - TestCase<R(A&), 1, Q_None>::run(); - TestCase<R(A&) const, 1, Q_Const>::run(); - TestCase<R(A&) volatile, 1, Q_Volatile>::run(); - TestCase<R(A&) const volatile, 1, Q_CV>::run(); - TestCase<R(A&, ...), 1, Q_None>::run(); - TestCase<R(A&, ...) const, 1, Q_Const>::run(); - TestCase<R(A&, ...) volatile, 1, Q_Volatile>::run(); - TestCase<R(A&, ...) const volatile, 1, Q_CV>::run(); - TestCase<R(A&, A&), 2, Q_None>::run(); - TestCase<R(A&, A&) const, 2, Q_Const>::run(); - TestCase<R(A&, A&) volatile, 2, Q_Volatile>::run(); - TestCase<R(A&, A&) const volatile, 2, Q_CV>::run(); - TestCase<R(A&, A&, ...), 2, Q_None>::run(); - TestCase<R(A&, A&, ...) const, 2, Q_Const>::run(); - TestCase<R(A&, A&, ...) volatile, 2, Q_Volatile>::run(); - TestCase<R(A&, A&, ...) const volatile, 2, Q_CV>::run(); - TestCase<R(A&, A&, A&), 3, Q_None>::run(); - TestCase<R(A&, A&, A&) const, 3, Q_Const>::run(); - TestCase<R(A&, A&, A&) volatile, 3, Q_Volatile>::run(); - TestCase<R(A&, A&, A&) const volatile, 3, Q_CV>::run(); - TestCase<R(A&, A&, A&, ...), 3, Q_None>::run(); - TestCase<R(A&, A&, A&, ...) const, 3, Q_Const>::run(); - TestCase<R(A&, A&, A&, ...) volatile, 3, Q_Volatile>::run(); - TestCase<R(A&, A&, A&, ...) const volatile, 3, Q_CV>::run(); - -#if TEST_STD_VER >= 11 - TestCase11<R() &, 0, Q_None>::run(); - TestCase11<R() const &, 0, Q_Const>::run(); - TestCase11<R() volatile &, 0, Q_Volatile>::run(); - TestCase11<R() const volatile &, 0, Q_CV>::run(); - TestCase11<R(...) &, 0, Q_None>::run(); - TestCase11<R(...) const &, 0, Q_Const>::run(); - TestCase11<R(...) volatile &, 0, Q_Volatile>::run(); - TestCase11<R(...) const volatile &, 0, Q_CV>::run(); - TestCase11<R(A&&) &, 1, Q_None>::run(); - TestCase11<R(A&&) const &, 1, Q_Const>::run(); - TestCase11<R(A&&) volatile &, 1, Q_Volatile>::run(); - TestCase11<R(A&&) const volatile &, 1, Q_CV>::run(); - TestCase11<R(A&&, ...) &, 1, Q_None>::run(); - TestCase11<R(A&&, ...) const &, 1, Q_Const>::run(); - TestCase11<R(A&&, ...) volatile &, 1, Q_Volatile>::run(); - TestCase11<R(A&&, ...) const volatile &, 1, Q_CV>::run(); - TestCase11<R(A&&, A&&) &, 2, Q_None>::run(); - TestCase11<R(A&&, A&&) const &, 2, Q_Const>::run(); - TestCase11<R(A&&, A&&) volatile &, 2, Q_Volatile>::run(); - TestCase11<R(A&&, A&&) const volatile &, 2, Q_CV>::run(); - TestCase11<R(A&&, A&&, ...) &, 2, Q_None>::run(); - TestCase11<R(A&&, A&&, ...) const &, 2, Q_Const>::run(); - TestCase11<R(A&&, A&&, ...) volatile &, 2, Q_Volatile>::run(); - TestCase11<R(A&&, A&&, ...) const volatile &, 2, Q_CV>::run(); - TestCase11<R() &&, 0, Q_None, /* RValue */ true>::run(); - TestCase11<R() const &&, 0, Q_Const, /* RValue */ true>::run(); - TestCase11<R() volatile &&, 0, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R() const volatile &&, 0, Q_CV, /* RValue */ true>::run(); - TestCase11<R(...) &&, 0, Q_None, /* RValue */ true>::run(); - TestCase11<R(...) const &&, 0, Q_Const, /* RValue */ true>::run(); - TestCase11<R(...) volatile &&, 0, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(...) const volatile &&, 0, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&) &&, 1, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&) const &&, 1, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&) volatile &&, 1, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&) const volatile &&, 1, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) &&, 1, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) const &&, 1, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) volatile &&, 1, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, ...) const volatile &&, 1, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) &&, 2, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) const &&, 2, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) volatile &&, 2, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&) const volatile &&, 2, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) &&, 2, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) const &&, 2, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) volatile &&, 2, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, ...) const volatile &&, 2, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) &&, 3, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) const &&, 3, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) volatile &&, 3, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&) const volatile &&, 3, Q_CV, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) &&, 3, Q_None, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) const &&, 3, Q_Const, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) volatile &&, 3, Q_Volatile, /* RValue */ true>::run(); - TestCase11<R(A&&, A&&, A&&, ...) const volatile &&, 3, Q_CV, /* RValue */ true>::run(); -#endif -}
\ No newline at end of file diff --git a/test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp b/test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp deleted file mode 100644 index b6fe190bd2a77..0000000000000 --- a/test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp +++ /dev/null @@ -1,164 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <functional> - -// INVOKE (f, t1, t2, ..., tN) - -//------------------------------------------------------------------------------ -// TESTING INVOKE(f, t1, t2, ..., tN) -// - Bullet 3 -- t1.*f -// - Bullet 4 -- (*t1).*f -// -// Overview: -// Bullets 3 and 4 handle the case where 'f' is a pointer to member object. -// Bullet 3 only handles the cases where t1 is an object of type T or a -// type derived from 'T'. Bullet 4 handles all other cases. -// -// Concerns: -// 1) The return type is always an lvalue reference. -// 2) The return type is not less cv-qualified that the object that contains it. -// 3) The return type is not less cv-qualified than object type. -// 4) The call object is perfectly forwarded. -// 5) Classes that are publicly derived from 'T' are accepted as the call object -// 6) All types that dereference to T or a type derived from T can be used -// as the call object. -// 7) Pointers to T or a type derived from T can be used as the call object. - -#include <functional> -#include <type_traits> -#include <cassert> - -#include "test_macros.h" -#include "invoke_helpers.h" - -template <class Tp> -struct TestMemberObject { - TestMemberObject() : object() {} - Tp object; -private: - TestMemberObject(TestMemberObject const&); - TestMemberObject& operator=(TestMemberObject const&); -}; - -template <class ObjectType> -struct TestCase { - public: - - static void run() { TestCase().doTest(); } - -private: - typedef TestMemberObject<ObjectType> TestType; - - //========================================================================== - // TEST DISPATCH - void doTest() { - typedef DerivedFromType<TestType> Derived; - TestType obj; - TestType* obj_ptr = &obj; - Derived der; - Derived* der_ptr = &der; - DerefToType<TestType> dref; - DerefPropType<TestType> dref2; - - { - typedef ObjectType (TestType::*MemPtr); - typedef ObjectType E; - MemPtr M = &TestType::object; - runTestDispatch<E>(M, obj, &obj.object); - runTestDispatch<E>(M, der, &der.object); - runTestDispatch<E>(M, dref2, &dref2.object.object); - runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object); - runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object); - runTestPointerDispatch<E>(M, dref, &dref.object.object); - } - { - typedef ObjectType const (TestType::*CMemPtr); - typedef ObjectType const E; - CMemPtr M = &TestType::object; - runTestDispatch<E>(M, obj, &obj.object); - runTestDispatch<E>(M, der, &der.object); - runTestDispatch<E>(M, dref2, &dref2.object.object); - runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object); - runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object); - runTestPointerDispatch<E>(M, dref, &dref.object.object); - } - { - typedef ObjectType volatile (TestType::*VMemPtr); - typedef ObjectType volatile E; - VMemPtr M = &TestType::object; - runTestDispatch<E>(M, obj, &obj.object); - runTestDispatch<E>(M, der, &der.object); - runTestDispatch<E>(M, dref2, &dref2.object.object); - runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object); - runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object); - runTestPointerDispatch<E>(M, dref, &dref.object.object); - } - { - typedef ObjectType const volatile (TestType::*CVMemPtr); - typedef ObjectType const volatile E; - CVMemPtr M = &TestType::object; - runTestDispatch<E>(M, obj, &obj.object); - runTestDispatch<E>(M, der, &der.object); - runTestDispatch<E>(M, dref2, &dref2.object.object); - runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object); - runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object); - runTestPointerDispatch<E>(M, dref, &dref.object.object); - } - } - - template <class Expect, class Fn, class T> - void runTestDispatch(Fn M, T& obj, ObjectType* expect) { - runTest<Expect &> (M, C_<T&>(obj), expect); - runTest<Expect const&> (M, C_<T const&>(obj), expect); - runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect); - runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect); -#if TEST_STD_VER >= 11 - runTest<Expect&&> (M, C_<T&&>(obj), expect); - runTest<Expect const&&> (M, C_<T const&&>(obj), expect); - runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect); - runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect); -#endif - } - - template <class Expect, class Fn, class T> - void runTestPointerDispatch(Fn M, T& obj, ObjectType* expect) { - runTest<Expect&>(M, C_<T &>(obj), expect); - runTest<Expect&>(M, C_<T const&>(obj), expect); - runTest<Expect&>(M, C_<T volatile&>(obj), expect); - runTest<Expect&>(M, C_<T const volatile&>(obj), expect); -#if TEST_STD_VER >= 11 - runTest<Expect&>(M, C_<T&&>(obj), expect); - runTest<Expect&>(M, C_<T const&&>(obj), expect); - runTest<Expect&>(M, C_<T volatile&&>(obj), expect); - runTest<Expect&>(M, C_<T const volatile&&>(obj), expect); -#endif - } - - template <class Expect, class Fn, class T> -#if TEST_STD_VER >= 11 - void runTest(Fn M, T&& obj, ObjectType* expect) { -#else - void runTest(Fn M, T& obj, ObjectType* expect ) { -#endif - static_assert((std::is_same< - decltype(std::__invoke(M, std::forward<T>(obj))), Expect - >::value), ""); - Expect e = std::__invoke(M, std::forward<T>(obj)); - assert(&e == expect); - } -}; - -int main() { - TestCase<ArgType>::run(); - TestCase<ArgType const>::run(); - TestCase<ArgType volatile>::run(); - TestCase<ArgType const volatile>::run(); - TestCase<ArgType*>::run(); -}
\ No newline at end of file diff --git a/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp b/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp deleted file mode 100644 index 3f3c96a9b9bda..0000000000000 --- a/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp +++ /dev/null @@ -1,327 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <functional> - -// INVOKE (f, t1, t2, ..., tN) - -//------------------------------------------------------------------------------ -// TESTING INVOKE(f, t1, t2, ..., tN) -// - Bullet 5 -- f(t2, ..., tN) -// -// Overview: -// Bullet 5 handles the cases where the first argument is not a member -// function. -// -// Concerns: -// 1) Different types of callable objects are supported. Including -// 1a) Free Function pointers and references. -// 1b) Classes which provide a call operator -// 1c) lambdas -// 2) The callable objects are perfect forwarded. -// 3) The arguments are perfect forwarded. -// 4) Signatures which include varargs are supported. -// 5) In C++03 3 extra arguments should be allowed. -// -// Plan: -// 1) Define a set of free functions, 'SF', and class types with call -// operators, 'SC', that address concerns 4 and 5. The free functions should -// return 'FunctionID::setUncheckedCall()' and the call operators should -// return 'MethodID::setUncheckedCall()'. -// -// 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f' -// using the correct number of arguments and cv-ref qualifiers. Check that -// 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free -// function and 'MethodID::checkCall()' otherwise. - - - -#include <functional> -#include <type_traits> -#include <cassert> - -#include "test_macros.h" -#include "invoke_helpers.h" - - -//============================================================================== -// freeFunction03 - A C++03 free function. -void*& freeFunction03() { - return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall(); -} - -void*& freeFunction03(...) { - return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall(); -} - -template <class A0> -void*& freeFunction03(A0&) { - return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall(); -} - - -template <class A0> -void*& freeFunction03(A0&, ...) { - return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall(); -} - -template <class A0, class A1> -void*& freeFunction03(A0&, A1&) { - return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall(); -} - - -template <class A0, class A1> -void*& freeFunction03(A0&, A1&, ...) { - return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall(); -} - -template <class A0, class A1, class A2> -void*& freeFunction03(A0&, A1&, A2&) { - return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall(); -} - -template <class A0, class A1, class A2> -void*& freeFunction03(A0&, A1&, A2&, ...) { - return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall(); -} - -//============================================================================== -// Functor03 - C++03 compatible functor object -struct Functor03 { - typedef void*& R; - typedef Functor03 C; -#define F(Args, ...) \ - __VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \ - __VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \ - __VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \ - __VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); } -# - F(()) - F((A0&), template <class A0>) - F((A0&, A1&), template <class A0, class A1>) - F((A0&, A1&, A2&), template <class A0, class A1, class A2>) -#undef F -public: - Functor03() {} -private: - Functor03(Functor03 const&); - Functor03& operator=(Functor03 const&); -}; - - -#if TEST_STD_VER >= 11 - -//============================================================================== -// freeFunction11 - A C++11 free function. -template <class ...Args> -void*& freeFunction11(Args&&...) { - return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall(); -} - -template <class ...Args> -void*& freeFunction11(Args&&...,...) { - return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall(); -} - -//============================================================================== -// Functor11 - C++11 reference qualified test member functions. -struct Functor11 { - typedef void*& R; - typedef Functor11 C; - -#define F(CV) \ - template <class ...Args> \ - R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); } -# - F(&) - F(const &) - F(volatile &) - F(const volatile &) - F(&&) - F(const &&) - F(volatile &&) - F(const volatile &&) -#undef F -public: - Functor11() {} -private: - Functor11(Functor11 const&); - Functor11& operator=(Functor11 const&); -}; - -#endif // TEST_STD_VER >= 11 - - -//============================================================================== -// TestCaseFunctorImp - A test case for an operator() class method. -// ClassType - The type of the call object. -// CallSig - The function signature of the call operator being tested. -// Arity - the arity of 'CallSig' -// ObjCaster - Transformation function applied to call object. -// ArgCaster - Transformation function applied to the extra arguments. -template <class ClassType, class CallSig, int Arity, - class ObjCaster, class ArgCaster = LValueCaster> -struct TestCaseFunctorImp { -public: - static void run() { - typedef MethodID<CallSig ClassType::*> MID; - BasicTest<MID, Arity, ObjCaster, ArgCaster> t; - typedef ClassType T; - typedef DerivedFromType<T> D; - T obj; - D der; - t.runTest(obj); - t.runTest(der); - } -}; - -//============================================================================== -// TestCaseFreeFunction - A test case for a free function. -// CallSig - The function signature of the free function being tested. -// FnPtr - The function being tested. -// Arity - the arity of 'CallSig' -// ArgCaster - Transformation function to be applied to the extra arguments. -template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster> -struct TestCaseFreeFunction { -public: - static void run() { - typedef FunctionPtrID<CallSig, FnPtr> FID; - BasicTest<FID, Arity, LValueCaster, ArgCaster> t; - - DerefToType<CallSig*> deref_to(FnPtr); - DerefToType<CallSig&> deref_to_ref(*FnPtr); - - t.runTest(FnPtr); - t.runTest(*FnPtr); - t.runTest(deref_to); - t.runTest(deref_to_ref); - } -}; - -//============================================================================== -// runTest Helpers -//============================================================================== -#if TEST_STD_VER >= 11 -template <class Sig, int Arity, class ArgCaster> -void runFunctionTestCase11() { - TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>(); -} -#endif - -template <class Sig, int Arity, class ArgCaster> -void runFunctionTestCase() { - TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>(); -#if TEST_STD_VER >= 11 - runFunctionTestCase11<Sig, Arity, ArgCaster>(); -#endif -} - -template <class Sig, int Arity, class ObjCaster, class ArgCaster> -void runFunctorTestCase() { - TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run(); -} - -template <class Sig, int Arity, class ObjCaster> -void runFunctorTestCase() { - TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run(); -} - -#if TEST_STD_VER >= 11 -// runTestCase - Run a test case for C++11 class functor types -template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster> -void runFunctorTestCase11() { - TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run(); -} -#endif - -// runTestCase - Run a test case for both function and functor types. -template <class Sig, int Arity, class ArgCaster> -void runTestCase() { - runFunctionTestCase<Sig, Arity, ArgCaster>(); - runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>(); -}; - -int main() { - typedef void*& R; - typedef ArgType A; - typedef A const CA; - - runTestCase< R(), 0, LValueCaster >(); - runTestCase< R(A&), 1, LValueCaster >(); - runTestCase< R(A&, A&), 2, LValueCaster >(); - runTestCase< R(A&, A&, A&), 3, LValueCaster >(); - runTestCase< R(CA&), 1, ConstCaster >(); - runTestCase< R(CA&, CA&), 2, ConstCaster >(); - runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >(); - - runFunctionTestCase<R(...), 0, LValueCaster >(); - runFunctionTestCase<R(A&, ...), 1, LValueCaster >(); - runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >(); - runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >(); - -#if TEST_STD_VER >= 11 - runFunctionTestCase11<R(A&&), 1, MoveCaster >(); - runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >(); -#endif - - runFunctorTestCase<R(), 0, LValueCaster >(); - runFunctorTestCase<R() const, 0, ConstCaster >(); - runFunctorTestCase<R() volatile, 0, VolatileCaster >(); - runFunctorTestCase<R() const volatile, 0, CVCaster >(); - runFunctorTestCase<R(A&), 1, LValueCaster >(); - runFunctorTestCase<R(A&) const, 1, ConstCaster >(); - runFunctorTestCase<R(A&) volatile, 1, VolatileCaster >(); - runFunctorTestCase<R(A&) const volatile, 1, CVCaster >(); - runFunctorTestCase<R(A&, A&), 2, LValueCaster >(); - runFunctorTestCase<R(A&, A&) const, 2, ConstCaster >(); - runFunctorTestCase<R(A&, A&) volatile, 2, VolatileCaster >(); - runFunctorTestCase<R(A&, A&) const volatile, 2, CVCaster >(); - runFunctorTestCase<R(A&, A&, A&), 3, LValueCaster >(); - runFunctorTestCase<R(A&, A&, A&) const, 3, ConstCaster >(); - runFunctorTestCase<R(A&, A&, A&) volatile, 3, VolatileCaster >(); - runFunctorTestCase<R(A&, A&, A&) const volatile, 3, CVCaster >(); - { - typedef ConstCaster CC; - runFunctorTestCase<R(CA&), 1, LValueCaster, CC>(); - runFunctorTestCase<R(CA&) const, 1, ConstCaster, CC>(); - runFunctorTestCase<R(CA&) volatile, 1, VolatileCaster, CC>(); - runFunctorTestCase<R(CA&) const volatile, 1, CVCaster, CC>(); - runFunctorTestCase<R(CA&, CA&), 2, LValueCaster, CC>(); - runFunctorTestCase<R(CA&, CA&) const, 2, ConstCaster, CC>(); - runFunctorTestCase<R(CA&, CA&) volatile, 2, VolatileCaster, CC>(); - runFunctorTestCase<R(CA&, CA&) const volatile, 2, CVCaster, CC>(); - runFunctorTestCase<R(CA&, CA&, CA&), 3, LValueCaster, CC>(); - runFunctorTestCase<R(CA&, CA&, CA&) const, 3, ConstCaster, CC>(); - runFunctorTestCase<R(CA&, CA&, CA&) volatile, 3, VolatileCaster, CC>(); - runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>(); - } - -#if TEST_STD_VER >= 11 - runFunctorTestCase11<R() &, 0, LValueCaster >(); - runFunctorTestCase11<R() const &, 0, ConstCaster >(); - runFunctorTestCase11<R() volatile &, 0, VolatileCaster >(); - runFunctorTestCase11<R() const volatile &, 0, CVCaster >(); - runFunctorTestCase11<R() &&, 0, MoveCaster >(); - runFunctorTestCase11<R() const &&, 0, MoveConstCaster >(); - runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >(); - runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >(); - { - typedef MoveCaster MC; - runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>(); - runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>(); - runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>(); - runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>(); - runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>(); - runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>(); - runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>(); - runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>(); - } -#endif -} diff --git a/test/std/utilities/function.objects/func.require/invoke.pass.cpp b/test/std/utilities/function.objects/func.require/invoke.pass.cpp deleted file mode 100644 index 25681630a80c3..0000000000000 --- a/test/std/utilities/function.objects/func.require/invoke.pass.cpp +++ /dev/null @@ -1,50 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// [func.require] - -// INVOKE -#if __cplusplus < 201103L -int main () {} // no __invoke in C++03 -#else - -#include <type_traits> - -template <typename T, int N> -struct Array -{ - typedef T type[N]; -}; - -struct Type -{ - Array<char, 1>::type& f1(); - Array<char, 2>::type& f2() const; - - Array<char, 1>::type& g1() &; - Array<char, 2>::type& g2() const &; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - Array<char, 3>::type& g3() &&; - Array<char, 4>::type& g4() const &&; -#endif -}; - -int main() -{ - static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, ""); - static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, ""); - - static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, ""); - static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, ""); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, ""); - static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, ""); -#endif -} -#endif diff --git a/test/std/utilities/function.objects/func.require/invoke_helpers.h b/test/std/utilities/function.objects/func.require/invoke_helpers.h deleted file mode 100644 index a85b39f371758..0000000000000 --- a/test/std/utilities/function.objects/func.require/invoke_helpers.h +++ /dev/null @@ -1,326 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#ifndef INVOKE_HELPERS_H -#define INVOKE_HELPERS_H - -#include <type_traits> -#include <cassert> -#include <functional> - -#include "test_macros.h" - -template <int I> -struct Int : public std::integral_constant<int, I> {}; - -template <bool P> -struct Bool : public std::integral_constant<bool, P> {}; - -struct Q_None { - template <class T> - struct apply { typedef T type; }; -}; - -struct Q_Const { - template <class T> - struct apply { typedef T const type; }; -}; - -struct Q_Volatile { - template <class T> - struct apply { typedef T volatile type; }; -}; - -struct Q_CV { - template <class T> - struct apply { typedef T const volatile type; }; -}; - -// Caster - A functor object that performs cv-qualifier and value category -// conversions. -// QualTag - A metafunction type that applies cv-qualifiers to its argument. -// RValue - True if the resulting object should be an RValue reference. -// False otherwise. -template <class QualTag, bool RValue = false> -struct Caster { - template <class T> - struct apply { - typedef typename std::remove_reference<T>::type RawType; - typedef typename QualTag::template apply<RawType>::type CVType; -#if TEST_STD_VER >= 11 - typedef typename std::conditional<RValue, - CVType&&, CVType& - >::type type; -#else - typedef CVType& type; -#endif - }; - - template <class T> - typename apply<T>::type - operator()(T& obj) const { - typedef typename apply<T>::type OutType; - return static_cast<OutType>(obj); - } -}; - -typedef Caster<Q_None> LValueCaster; -typedef Caster<Q_Const> ConstCaster; -typedef Caster<Q_Volatile> VolatileCaster; -typedef Caster<Q_CV> CVCaster; -typedef Caster<Q_None, true> MoveCaster; -typedef Caster<Q_Const, true> MoveConstCaster; -typedef Caster<Q_Volatile, true> MoveVolatileCaster; -typedef Caster<Q_CV, true> MoveCVCaster; - -// A shorter name for 'static_cast' -template <class QualType, class Tp> -QualType C_(Tp& v) { return static_cast<QualType>(v); }; - -//============================================================================== -// ArgType - A non-copyable type intended to be used as a dummy argument type -// to test functions. -struct ArgType { - int value; - explicit ArgType(int val = 0) : value(val) {} -private: - ArgType(ArgType const&); - ArgType& operator=(ArgType const&); -}; - -//============================================================================== -// DerivedFromBase - A type that derives from it's template argument 'Base' -template <class Base> -struct DerivedFromType : public Base { - DerivedFromType() : Base() {} - template <class Tp> - explicit DerivedFromType(Tp const& t) : Base(t) {} -}; - -//============================================================================== -// DerefToType - A type that dereferences to it's template argument 'To'. -// The cv-ref qualifiers of the 'DerefToType' object do not propagate -// to the resulting 'To' object. -template <class To> -struct DerefToType { - To object; - - DerefToType() {} - - template <class Up> - explicit DerefToType(Up const& val) : object(val) {} - - To& operator*() const volatile { return const_cast<To&>(object); } -}; - -//============================================================================== -// DerefPropToType - A type that dereferences to it's template argument 'To'. -// The cv-ref qualifiers of the 'DerefPropToType' object propagate -// to the resulting 'To' object. -template <class To> -struct DerefPropType { - To object; - - DerefPropType() {} - - template <class Up> - explicit DerefPropType(Up const& val) : object(val) {} - -#if TEST_STD_VER < 11 - To& operator*() { return object; } - To const& operator*() const { return object; } - To volatile& operator*() volatile { return object; } - To const volatile& operator*() const volatile { return object; } -#else - To& operator*() & { return object; } - To const& operator*() const & { return object; } - To volatile& operator*() volatile & { return object; } - To const volatile& operator*() const volatile & { return object; } - To&& operator*() && { return static_cast<To &&>(object); } - To const&& operator*() const && { return static_cast<To const&&>(object); } - To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); } - To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); } -#endif -}; - -//============================================================================== -// MethodID - A type that uniquely identifies a member function for a class. -// This type is used to communicate between the member functions being tested -// and the tests invoking them. -// - Test methods should call 'setUncheckedCall()' whenever they are invoked. -// - Tests consume the unchecked call using checkCall(<return-value>)` to assert -// that the method has been called and that the return value of `__invoke` -// matches what the method actually returned. -template <class T> -struct MethodID { - typedef void* IDType; - - static int dummy; // A dummy memory location. - static void* id; // The "ID" is the value of this pointer. - static bool unchecked_call; // Has a call happened that has not been checked. - - static void*& setUncheckedCall() { - assert(unchecked_call == false); - unchecked_call = true; - return id; - } - - static bool checkCalled(void*& return_value) { - bool old = unchecked_call; - unchecked_call = false; - return old && id == return_value && &id == &return_value; - } -}; - -template <class T> int MethodID<T>::dummy = 0; -template <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy; -template <class T> bool MethodID<T>::unchecked_call = false; - - -//============================================================================== -// FunctionPtrID - Like MethodID but for free function pointers. -template <class T, T*> -struct FunctionPtrID { - static int dummy; // A dummy memory location. - static void* id; // The "ID" is the value of this pointer. - static bool unchecked_call; // Has a call happened that has not been checked. - - static void*& setUncheckedCall() { - assert(unchecked_call == false); - unchecked_call = true; - return id; - } - - static bool checkCalled(void*& return_value) { - bool old = unchecked_call; - unchecked_call = false; - return old && id == return_value && &id == &return_value; - } -}; - -template <class T, T* Ptr> int FunctionPtrID<T, Ptr>::dummy = 0; -template <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy; -template <class T, T* Ptr> bool FunctionPtrID<T, Ptr>::unchecked_call = false; - -//============================================================================== -// BasicTest - The basic test structure for everything except -// member object pointers. -// ID - The "Function Identifier" type used either MethodID or FunctionPtrID. -// Arity - The Arity of the call signature. -// ObjectCaster - The object transformation functor type. -// ArgCaster - The extra argument transformation functor type. -template <class ID, int Arity, class ObjectCaster = LValueCaster, - class ArgCaster = LValueCaster> -struct BasicTest { - template <class ObjectT> - void runTest(ObjectT& object) { - Int<Arity> A; - runTestImp(A, object); - } - - template <class MethodPtr, class ObjectT> - void runTest(MethodPtr ptr, ObjectT& object) { - Int<Arity> A; - runTestImp(A, ptr, object); - } - -private: - typedef void*& CallRet; - ObjectCaster object_cast; - ArgCaster arg_cast; - ArgType a0, a1, a2; - - //========================================================================== - // BULLET 1 AND 2 TEST METHODS - //========================================================================== - template <class MethodPtr, class ObjectT> - void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(ptr, object_cast(object))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(ptr, object_cast(object)); - assert(ID::checkCalled(ret)); - } - - template <class MethodPtr, class ObjectT> - void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0)); - assert(ID::checkCalled(ret)); - } - - template <class MethodPtr, class ObjectT> - void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)); - assert(ID::checkCalled(ret)); - } - - template <class MethodPtr, class ObjectT> - void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); - assert(ID::checkCalled(ret)); - } - - //========================================================================== - // BULLET 5 TEST METHODS - //========================================================================== - template <class ObjectT> - void runTestImp(Int<0>, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(object_cast(object))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(object_cast(object)); - assert(ID::checkCalled(ret)); - } - - template <class ObjectT> - void runTestImp(Int<1>, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(object_cast(object), arg_cast(a0))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(object_cast(object), arg_cast(a0)); - assert(ID::checkCalled(ret)); - } - - template <class ObjectT> - void runTestImp(Int<2>, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)); - assert(ID::checkCalled(ret)); - } - - template <class ObjectT> - void runTestImp(Int<3>, ObjectT& object) { - static_assert((std::is_same< - decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); - assert(ID::checkCalled(ret)); - } -}; - -#endif // INVOKE_HELPERS_H diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp index aa6b743b5236b..403d646f4216e 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <functional> // class function<R(ArgTypes...)> @@ -14,8 +16,10 @@ // template<class A> function(allocator_arg_t, const A&, function&&); #include <functional> +#include <memory> #include <cassert> +#include "test_macros.h" #include "min_allocator.h" #include "count_new.hpp" @@ -46,23 +50,57 @@ public: int A::count = 0; +int g(int) { return 0; } + int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES assert(globalMemCounter.checkOutstandingNewEq(0)); { - std::function<int(int)> f = A(); - assert(A::count == 1); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(f.target<A>()); - assert(f.target<int(*)(int)>() == 0); - std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), std::move(f)); - assert(A::count == 1); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(f2.target<A>()); - assert(f2.target<int(*)(int)>() == 0); - assert(f.target<A>() == 0); - assert(f.target<int(*)(int)>() == 0); + std::function<int(int)> f = A(); + assert(A::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(f.target<A>()); + assert(f.target<int(*)(int)>() == 0); + std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), std::move(f)); + assert(A::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(f2.target<A>()); + assert(f2.target<int(*)(int)>() == 0); + assert(f.target<A>() == 0); + assert(f.target<int(*)(int)>() == 0); + } + assert(globalMemCounter.checkOutstandingNewEq(0)); + { + // Test that moving a function constructed from a reference wrapper + // is done without allocating. + DisableAllocationGuard g; + using Ref = std::reference_wrapper<A>; + A a; + Ref aref(a); + std::function<int(int)> f(aref); + assert(A::count == 1); + assert(f.target<A>() == nullptr); + assert(f.target<Ref>()); + std::function<int(int)> f2(std::allocator_arg, std::allocator<void>{}, + std::move(f)); + assert(A::count == 1); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ref>()); + assert(f.target<Ref>()); // f is unchanged because the target is small + } + { + // Test that moving a function constructed from a function pointer + // is done without allocating + DisableAllocationGuard guard; + using Ptr = int(*)(int); + Ptr p = g; + std::function<int(int)> f(p); + assert(f.target<A>() == nullptr); + assert(f.target<Ptr>()); + std::function<int(int)> f2(std::allocator_arg, std::allocator<void>(), + std::move(f)); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ptr>()); + assert(f.target<Ptr>()); // f is unchanged because the target is small } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp index f603da9dd1319..387b371a93311 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp @@ -14,9 +14,11 @@ // function(const function& f); #include <functional> +#include <memory> #include <cstdlib> #include <cassert> +#include "test_macros.h" #include "count_new.hpp" class A @@ -98,21 +100,53 @@ int main() assert(g.target<A>() == 0); assert(!g); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 + assert(globalMemCounter.checkOutstandingNewEq(0)); + { // Test rvalue references + std::function<int(int)> f = A(); + assert(A::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(f.target<A>()); + assert(f.target<int(*)(int)>() == 0); + std::function<int(int)> f2 = std::move(f); + assert(A::count == 1); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(f2.target<A>()); + assert(f2.target<int(*)(int)>() == 0); + assert(f.target<A>() == 0); + assert(f.target<int(*)(int)>() == 0); + } assert(globalMemCounter.checkOutstandingNewEq(0)); { - std::function<int(int)> f = A(); - assert(A::count == 1); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(f.target<A>()); - assert(f.target<int(*)(int)>() == 0); - std::function<int(int)> f2 = std::move(f); - assert(A::count == 1); - assert(globalMemCounter.checkOutstandingNewEq(1)); - assert(f2.target<A>()); - assert(f2.target<int(*)(int)>() == 0); - assert(f.target<A>() == 0); - assert(f.target<int(*)(int)>() == 0); + // Test that moving a function constructed from a reference wrapper + // is done without allocating. + DisableAllocationGuard g; + using Ref = std::reference_wrapper<A>; + A a; + Ref aref(a); + std::function<int(int)> f(aref); + assert(A::count == 1); + assert(f.target<A>() == nullptr); + assert(f.target<Ref>()); + std::function<int(int)> f2(std::move(f)); + assert(A::count == 1); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ref>()); + assert(f.target<Ref>()); // f is unchanged because the target is small + } + { + // Test that moving a function constructed from a function pointer + // is done without allocating + DisableAllocationGuard guard; + using Ptr = int(*)(int); + Ptr p = g; + std::function<int(int)> f(p); + assert(f.target<A>() == nullptr); + assert(f.target<Ptr>()); + std::function<int(int)> f2(std::move(f)); + assert(f2.target<A>() == nullptr); + assert(f2.target<Ptr>()); + assert(f.target<Ptr>()); // f is unchanged because the target is small } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // TEST_STD_VER >= 11 } diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp index e9ecfa5539ce5..cb45b30a9fd4e 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp @@ -12,10 +12,12 @@ // class function<R(ArgTypes...)> // template<class F, class A> void assign(F&&, const A&); +// This call was removed post-C++14 #include <functional> #include <cassert> +#include "test_macros.h" #include "test_allocator.h" class A @@ -49,6 +51,7 @@ int A::count = 0; int main() { +#if TEST_STD_VER <= 14 { std::function<int(int)> f; f.assign(A(), test_allocator<A>()); @@ -57,4 +60,5 @@ int main() assert(f.target<int(*)(int)>() == 0); } assert(A::count == 0); +#endif } diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp index eb4eac65cd2cb..e48b8f986916e 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp @@ -14,7 +14,7 @@ // public: // typedef R result_type; // typedef T1 argument_type; // iff sizeof...(ArgTypes) == 1 and -// // the type in ArgTypes is T1 +// // the type in ArgTypes is T1 // typedef T1 first_argument_type; // iff sizeof...(ArgTypes) == 2 and // // ArgTypes contains T1 and T2 // typedef T2 second_argument_type; // iff sizeof...(ArgTypes) == 2 and diff --git a/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp b/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp index 6e3b7a2eee246..00e513ec546f9 100644 --- a/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp +++ b/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <functional> #include <string> @@ -22,9 +23,8 @@ public: }; -int main () { -#if _LIBCPP_STD_VER > 11 - +int main () +{ static_assert ( !is_transparent<std::logical_and<int>>::value, "" ); static_assert ( !is_transparent<std::logical_and<std::string>>::value, "" ); static_assert ( is_transparent<std::logical_and<void>>::value, "" ); @@ -39,8 +39,6 @@ int main () { static_assert ( !is_transparent<std::logical_not<std::string>>::value, "" ); static_assert ( is_transparent<std::logical_not<void>>::value, "" ); static_assert ( is_transparent<std::logical_not<>>::value, "" ); - -#endif return 0; - } +} diff --git a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp index 61e0bfa162d89..3c00bd20ac648 100644 --- a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp +++ b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp @@ -14,6 +14,9 @@ // Test that reference wrapper meets the requirements of TriviallyCopyable, // CopyConstructible and CopyAssignable. +// Test fails due to use of is_trivially_* trait. +// XFAIL: gcc-4.9 + #include <functional> #include <type_traits> #include <string> @@ -51,8 +54,8 @@ int main() { test<int>(); test<double>(); - test<std::string>(); + test<std::string>(); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - test<MoveOnly>(); + test<MoveOnly>(); #endif } diff --git a/test/std/utilities/function.objects/unord.hash/enum.pass.cpp b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp index bd92a4ac4d2e1..8aa2c1df89358 100644 --- a/test/std/utilities/function.objects/unord.hash/enum.pass.cpp +++ b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp @@ -12,7 +12,9 @@ // make sure that we can hash enumeration values // Not very portable -#if __cplusplus >= 201402L +#include "test_macros.h" + +#if TEST_STD_VER >= 14 #include <functional> #include <cassert> @@ -35,7 +37,7 @@ test() static_assert((std::is_same<typename H::argument_type, T>::value), "" ); static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); typedef typename std::underlying_type<T>::type under_type; - + H h1; std::hash<under_type> h2; for (int i = 0; i <= 5; ++i) diff --git a/test/std/utilities/function.objects/unord.hash/floating.pass.cpp b/test/std/utilities/function.objects/unord.hash/floating.pass.cpp index f1f198f235996..643e2d8c5d860 100644 --- a/test/std/utilities/function.objects/unord.hash/floating.pass.cpp +++ b/test/std/utilities/function.objects/unord.hash/floating.pass.cpp @@ -35,7 +35,7 @@ test() std::size_t t0 = h(0.); std::size_t tn0 = h(-0.); - std::size_t tp1 = h(0.1); + std::size_t tp1 = h(static_cast<T>(0.1)); std::size_t t1 = h(1); std::size_t tn1 = h(-1); std::size_t pinf = h(INFINITY); diff --git a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp index c20f31ff2c996..8954f4f3664b7 100644 --- a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp +++ b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp @@ -16,14 +16,14 @@ // size_t operator()(T val) const; // }; -// Not very portable - #include <functional> #include <cassert> #include <type_traits> #include <cstddef> #include <limits> +#include "test_macros.h" + template <class T> void test() @@ -37,7 +37,11 @@ test() { T t(i); if (sizeof(T) <= sizeof(std::size_t)) - assert(h(t) == t); + { + const std::size_t result = h(t); + LIBCPP_ASSERT(result == t); + ((void)result); // Prevent unused warning + } } } @@ -67,7 +71,7 @@ int main() test<int16_t>(); test<int32_t>(); test<int64_t>(); - + test<int_fast8_t>(); test<int_fast16_t>(); test<int_fast32_t>(); @@ -80,12 +84,12 @@ int main() test<intmax_t>(); test<intptr_t>(); - + test<uint8_t>(); test<uint16_t>(); test<uint32_t>(); test<uint64_t>(); - + test<uint_fast8_t>(); test<uint_fast16_t>(); test<uint_fast32_t>(); @@ -98,4 +102,9 @@ int main() test<uintmax_t>(); test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + test<__int128_t>(); + test<__uint128_t>(); +#endif } diff --git a/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp b/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp index 8ca5a96a4fac7..653fbc43d3017 100644 --- a/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp +++ b/test/std/utilities/intseq/intseq.general/integer_seq.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <utility> // class make_integer_sequence @@ -16,19 +17,13 @@ #include <type_traits> #include <cassert> -#if _LIBCPP_STD_VER > 11 - template <typename AtContainer, typename T, T... I> -auto extract ( const AtContainer &t, const std::integer_sequence<T, I...> idx ) +auto extract ( const AtContainer &t, const std::integer_sequence<T, I...> ) -> decltype ( std::make_tuple ( std::get<I>(t)... )) { return std::make_tuple ( std::get<I>(t)... ); } -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 - // Make a couple of sequences using int3 = std::make_integer_sequence<int, 3>; // generates int: 0,1,2 using size7 = std::make_integer_sequence<size_t, 7>; // generates size_t: 0,1,2,3,4,5,6 @@ -36,20 +31,20 @@ int main() using size2 = std::index_sequence_for<int, size_t>; // generates size_t: 0,1 using intmix = std::integer_sequence<int, 9, 8, 7, 2>; // generates int: 9,8,7,2 using sizemix = std::index_sequence<1, 1, 2, 3, 5>; // generates size_t: 1,1,2,3,5 - + // Make sure they're what we expect static_assert ( std::is_same<int3::value_type, int>::value, "int3 type wrong" ); static_assert ( int3::size () == 3, "int3 size wrong" ); - + static_assert ( std::is_same<size7::value_type, size_t>::value, "size7 type wrong" ); static_assert ( size7::size () == 7, "size7 size wrong" ); - + static_assert ( std::is_same<size4::value_type, size_t>::value, "size4 type wrong" ); static_assert ( size4::size () == 4, "size4 size wrong" ); - + static_assert ( std::is_same<size2::value_type, size_t>::value, "size2 type wrong" ); static_assert ( size2::size () == 2, "size2 size wrong" ); - + static_assert ( std::is_same<intmix::value_type, int>::value, "intmix type wrong" ); static_assert ( intmix::size () == 4, "intmix size wrong" ); @@ -57,7 +52,7 @@ int main() static_assert ( sizemix::size () == 5, "sizemix size wrong" ); auto tup = std::make_tuple ( 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ); - + // Use them auto t3 = extract ( tup, int3() ); static_assert ( std::tuple_size<decltype(t3)>::value == int3::size (), "t3 size wrong"); @@ -82,5 +77,4 @@ int main() auto tsizemix = extract ( tup, sizemix ()); static_assert ( std::tuple_size<decltype(tsizemix)>::value == sizemix::size (), "tsizemix size wrong"); assert ( tsizemix == std::make_tuple ( 11, 11, 12, 13, 15 )); -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp b/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp index 4b2d1acb5e6b4..b689160babaac 100644 --- a/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp +++ b/test/std/utilities/intseq/intseq.intseq/integer_seq.fail.cpp @@ -13,7 +13,7 @@ // struct integer_sequence // { // typedef T type; -// +// // static constexpr size_t size() noexcept; // }; diff --git a/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp b/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp index 5c789f5db2741..841a234334b78 100644 --- a/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp +++ b/test/std/utilities/intseq/intseq.intseq/integer_seq.pass.cpp @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <utility> // template<class T, T... I> // struct integer_sequence // { // typedef T type; -// +// // static constexpr size_t size() noexcept; // }; @@ -24,26 +25,22 @@ int main() { -#if _LIBCPP_STD_VER > 11 - // Make a few of sequences using int3 = std::integer_sequence<int, 3, 2, 1>; using size1 = std::integer_sequence<std::size_t, 7>; using ushort2 = std::integer_sequence<unsigned short, 4, 6>; using bool0 = std::integer_sequence<bool>; - + // Make sure they're what we expect static_assert ( std::is_same<int3::value_type, int>::value, "int3 type wrong" ); static_assert ( int3::size() == 3, "int3 size wrong" ); - + static_assert ( std::is_same<size1::value_type, std::size_t>::value, "size1 type wrong" ); static_assert ( size1::size() == 1, "size1 size wrong" ); - + static_assert ( std::is_same<ushort2::value_type, unsigned short>::value, "ushort2 type wrong" ); static_assert ( ushort2::size() == 2, "ushort2 size wrong" ); - + static_assert ( std::is_same<bool0::value_type, bool>::value, "bool0 type wrong" ); static_assert ( bool0::size() == 0, "bool0 size wrong" ); - -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp index 352c7c8d0cafd..bbc6b470174d0 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp @@ -21,6 +21,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + template <class T> struct A { @@ -61,7 +63,7 @@ int main() const B<int> b = {}; assert(std::allocator_traits<B<int> >::max_size(b) == 100); } -#if __cplusplus >= 201103 +#if TEST_STD_VER >= 11 { std::allocator<int> a; static_assert(noexcept(std::allocator_traits<std::allocator<int>>::max_size(a)) == true, ""); diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp index 20348d20c10cd..10fbfe141ae55 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_pointer.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct Ptr {}; @@ -47,9 +49,19 @@ struct C typedef CPtr<const T> const_pointer; }; +template <class T> +struct D { + typedef T value_type; +private: + typedef void const_pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::const_pointer, Ptr<const char> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::const_pointer, const char*>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::const_pointer, CPtr<const char> >::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::const_pointer, const char*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp index 4b4045a51bae0..8365d22613ee0 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/const_void_pointer.pass.cpp @@ -21,6 +21,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct Ptr {}; @@ -47,9 +49,21 @@ struct C typedef CPtr<const void> const_void_pointer; }; + +template <class T> +struct D +{ + typedef T value_type; +private: + typedef int const_void_pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::const_void_pointer, Ptr<const void> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::const_void_pointer, const void*>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::const_void_pointer, CPtr<const void> >::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::const_void_pointer, const void*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp index 085c911b07035..c728909477b52 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/difference_type.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -43,13 +45,24 @@ struct C struct const_void_pointer {}; }; + +template <class T> +struct D +{ + typedef T value_type; +private: + typedef void difference_type; +}; + namespace std { template <> struct pointer_traits<C<char>::pointer> { - typedef signed char difference_type; + typedef C<char>::pointer pointer; + typedef char element_type; + typedef signed char difference_type; }; } @@ -59,4 +72,7 @@ int main() static_assert((std::is_same<std::allocator_traits<A<char> >::difference_type, short>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::difference_type, signed char>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::difference_type, std::ptrdiff_t>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp index 60ba094993428..ff1ae2c051b65 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/pointer.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct Ptr {}; @@ -35,8 +37,18 @@ struct B typedef T value_type; }; +template <class T> +struct C { + typedef T value_type; +private: + typedef void pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::pointer, Ptr<char> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::pointer, char*>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::pointer, char*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp index 604e890efaaee..0112ab371a836 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_copy_assignment.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -33,8 +35,20 @@ struct B typedef T value_type; }; + +template <class T> +struct C +{ + typedef T value_type; +private: + typedef std::true_type propagate_on_container_copy_assignment; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::propagate_on_container_copy_assignment, std::true_type>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::propagate_on_container_copy_assignment, std::false_type>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::propagate_on_container_copy_assignment, std::false_type>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp index 1d2b18686d0f1..64de15c2cd484 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_move_assignment.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -33,8 +35,21 @@ struct B typedef T value_type; }; + +template <class T> +struct C +{ + typedef T value_type; +private: + typedef std::true_type propagate_on_container_move_assignment; +}; + + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::propagate_on_container_move_assignment, std::true_type>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::propagate_on_container_move_assignment, std::false_type>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::propagate_on_container_move_assignment, std::false_type>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp index 6730d1ae261a6..a62336fa6cb05 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/propagate_on_container_swap.pass.cpp @@ -20,6 +20,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -33,8 +35,19 @@ struct B typedef T value_type; }; +template <class T> +struct C +{ + typedef T value_type; +private: + typedef std::true_type propagate_on_container_swap; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::propagate_on_container_swap, std::true_type>::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::propagate_on_container_swap, std::false_type>::value), ""); + #if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<C<char> >::propagate_on_container_swap, std::false_type>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp index 50611b99da9a8..8097a66fc9d62 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/rebind_alloc.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct ReboundA {}; @@ -61,19 +63,39 @@ struct E template <class U> struct rebind {typedef ReboundA<U> otter;}; }; +template <class T> +struct F { + typedef T value_type; +private: + template <class> + struct rebind { typedef void other; }; +}; + +template <class T> +struct G { + typedef T value_type; + template <class> + struct rebind { + private: + typedef void other; + }; +}; + int main() { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 static_assert((std::is_same<std::allocator_traits<A<char> >::rebind_alloc<double>, ReboundA<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<int, char> >::rebind_alloc<double>, ReboundB<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::rebind_alloc<double>, C<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<D<int, char> >::rebind_alloc<double>, D<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<E<char> >::rebind_alloc<double>, E<double> >::value), ""); -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES + static_assert((std::is_same<std::allocator_traits<F<char> >::rebind_alloc<double>, F<double> >::value), ""); + static_assert((std::is_same<std::allocator_traits<G<char> >::rebind_alloc<double>, G<double> >::value), ""); +#else static_assert((std::is_same<std::allocator_traits<A<char> >::rebind_alloc<double>::other, ReboundA<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<int, char> >::rebind_alloc<double>::other, ReboundB<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::rebind_alloc<double>::other, C<double> >::value), ""); static_assert((std::is_same<std::allocator_traits<D<int, char> >::rebind_alloc<double>::other, D<double, char> >::value), ""); static_assert((std::is_same<std::allocator_traits<E<char> >::rebind_alloc<double>::other, E<double> >::value), ""); -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp index e9c175fe86a54..00ed50727c983 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/size_type.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -42,6 +44,14 @@ struct C struct const_void_pointer {}; }; +template <class T> +struct D { + typedef T value_type; + typedef short difference_type; +private: + typedef void size_type; +}; + namespace std { @@ -60,4 +70,7 @@ int main() std::make_unsigned<std::ptrdiff_t>::type>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::size_type, unsigned char>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::size_type, unsigned short>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp index 74cd3475f6645..2c3623793db60 100644 --- a/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp +++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/void_pointer.pass.cpp @@ -20,6 +20,7 @@ #include <memory> #include <type_traits> +#include "test_macros.h" template <class T> struct Ptr {}; @@ -47,9 +48,21 @@ struct C typedef CPtr<void> void_pointer; }; + +template <class T> +struct D +{ + typedef T value_type; +private: + typedef void void_pointer; +}; + int main() { static_assert((std::is_same<std::allocator_traits<A<char> >::void_pointer, Ptr<void> >::value), ""); static_assert((std::is_same<std::allocator_traits<B<char> >::void_pointer, void*>::value), ""); static_assert((std::is_same<std::allocator_traits<C<char> >::void_pointer, CPtr<void> >::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::allocator_traits<D<char> >::void_pointer, void*>::value), ""); +#endif } diff --git a/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp b/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp index 0477d9912e6ec..bd32bc34e7a0f 100644 --- a/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp +++ b/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp @@ -14,6 +14,8 @@ #include <memory> #include <vector> +#include "test_macros.h" + struct A { }; @@ -23,6 +25,19 @@ struct B typedef int allocator_type; }; +struct C { + static int allocator_type; +}; + +struct D { + static int allocator_type() { return 0; } +}; + +struct E { +private: + typedef int allocator_type; +}; + int main() { static_assert((!std::uses_allocator<int, std::allocator<int> >::value), ""); @@ -30,4 +45,9 @@ int main() static_assert((!std::uses_allocator<A, std::allocator<int> >::value), ""); static_assert((!std::uses_allocator<B, std::allocator<int> >::value), ""); static_assert(( std::uses_allocator<B, double>::value), ""); + static_assert((!std::uses_allocator<C, decltype(C::allocator_type)>::value), ""); + static_assert((!std::uses_allocator<D, decltype(D::allocator_type)>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((!std::uses_allocator<E, int>::value), ""); +#endif } diff --git a/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp b/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp new file mode 100644 index 0000000000000..dc0bdd047c61a --- /dev/null +++ b/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// XFAIL: libcpp-no-exceptions +// <memory> + +// allocator: +// pointer allocate(size_type n, allocator<void>::const_pointer hint=0); + +#include <memory> +#include <cassert> + +template <typename T> +void test_max(size_t count) +{ + std::allocator<T> a; + try { + a.allocate(count); + assert(false); + } catch (const std::exception &) { + } +} + +int main() +{ + { // Bug 26812 -- allocating too large + typedef double T; + std::allocator<T> a; + test_max<T> (a.max_size() + 1); // just barely too large + test_max<T> (a.max_size() * 2); // significantly too large + test_max<T> (((size_t) -1) / sizeof(T) + 1); // multiply will overflow + test_max<T> ((size_t) -1); // way too large + } + + { + typedef const double T; + std::allocator<T> a; + test_max<T> (a.max_size() + 1); // just barely too large + test_max<T> (a.max_size() * 2); // significantly too large + test_max<T> (((size_t) -1) / sizeof(T) + 1); // multiply will overflow + test_max<T> ((size_t) -1); // way too large + } +} diff --git a/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp b/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp index 5a8f7a28a042c..e1612ae054218 100644 --- a/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp +++ b/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp @@ -10,7 +10,9 @@ #include <memory> #include <cassert> -#if __cplusplus >= 201103L +#include "test_macros.h" + +#if TEST_STD_VER >= 11 // #include <memory> // // template <class Alloc> @@ -19,7 +21,7 @@ // typedef Alloc allocator_type; // typedef typename allocator_type::value_type // value_type; -// +// // typedef Alloc::pointer | value_type* pointer; // typedef Alloc::const_pointer // | pointer_traits<pointer>::rebind<const value_type> @@ -36,7 +38,10 @@ void test_pointer() { typename std::allocator_traits<Alloc>::pointer vp; typename std::allocator_traits<Alloc>::const_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -70,7 +75,10 @@ void test_void_pointer() { typename std::allocator_traits<Alloc>::void_pointer vp; typename std::allocator_traits<Alloc>::const_void_pointer cvp; - + + ((void)vp); // Prevent unused warning + ((void)cvp); // Prevent unused warning + static_assert(std::is_same<bool, decltype( vp == vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp != vp)>::value, ""); static_assert(std::is_same<bool, decltype( vp > vp)>::value, ""); @@ -105,11 +113,11 @@ int main() { test_pointer<std::allocator<char>> (); test_pointer<std::allocator<int>> (); - test_pointer<std::allocator<Foo>> (); + test_pointer<std::allocator<Foo>> (); test_void_pointer<std::allocator<char>> (); test_void_pointer<std::allocator<int>> (); - test_void_pointer<std::allocator<Foo>> (); + test_void_pointer<std::allocator<Foo>> (); } #else int main() {} diff --git a/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp index 4efe61342420c..27b2d08b00610 100644 --- a/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp +++ b/test/std/utilities/memory/pointer.traits/pointer.traits.types/difference_type.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + struct A { typedef short element_type; @@ -39,10 +41,26 @@ struct D typedef char difference_type; }; +template <class T> +struct E +{ + static int difference_type; +}; + +template <class T> +struct F { +private: + typedef int difference_type; +}; + int main() { static_assert((std::is_same<std::pointer_traits<A>::difference_type, char>::value), ""); static_assert((std::is_same<std::pointer_traits<B>::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<std::pointer_traits<C<double> >::difference_type, std::ptrdiff_t>::value), ""); static_assert((std::is_same<std::pointer_traits<D<int> >::difference_type, char>::value), ""); + static_assert((std::is_same<std::pointer_traits<E<int> >::difference_type, std::ptrdiff_t>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::pointer_traits<F<int>>::difference_type, std::ptrdiff_t>::value), ""); +#endif } diff --git a/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp index 0ee1e8c93a674..48399d5355d67 100644 --- a/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp +++ b/test/std/utilities/memory/pointer.traits/pointer.traits.types/element_type.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + struct A { typedef char element_type; @@ -40,10 +42,27 @@ struct D { }; +template <class T, class U> +struct E +{ + static int element_type; +}; + +template <class T> +struct F { +private: + typedef int element_type; +}; + int main() { static_assert((std::is_same<std::pointer_traits<A>::element_type, char>::value), ""); static_assert((std::is_same<std::pointer_traits<B<int> >::element_type, char>::value), ""); static_assert((std::is_same<std::pointer_traits<C<int> >::element_type, int>::value), ""); static_assert((std::is_same<std::pointer_traits<D<double, int> >::element_type, double>::value), ""); + static_assert((std::is_same<std::pointer_traits<E<double, int> >::element_type, double>::value), ""); +#if TEST_STD_VER >= 11 + static_assert((std::is_same<std::pointer_traits<F<double>>::element_type, double>::value), ""); +#endif + } diff --git a/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp b/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp index 4a1455c53ef6f..74c124901211c 100644 --- a/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp +++ b/test/std/utilities/memory/pointer.traits/pointer.traits.types/rebind.pass.cpp @@ -19,6 +19,8 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + template <class T> struct A { @@ -29,7 +31,7 @@ template <class T> struct B1 {}; template <class T> struct B { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 template <class U> using rebind = B1<U>; #else template <class U> struct rebind {typedef B1<U> other;}; @@ -46,24 +48,58 @@ template <class T, class U> struct D1 {}; template <class T, class U> struct D { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 template <class V> using rebind = D1<V, U>; #else template <class V> struct rebind {typedef D1<V, U> other;}; #endif }; +template <class T, class U> +struct E +{ + template <class> + void rebind() {} +}; + + +#if TEST_STD_VER >= 11 +template <class T, class U> +struct F { +private: + template <class> + using rebind = void; +}; +#endif + +#if TEST_STD_VER >= 14 +template <class T, class U> +struct G +{ + template <class> + static constexpr int rebind = 42; +}; +#endif + + int main() { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#if TEST_STD_VER >= 11 static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>, A<double*> >::value), ""); static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>, B1<double> >::value), ""); static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>, C<double, int> >::value), ""); static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>, D1<double, int> >::value), ""); -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES + static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>, E<double, int> >::value), ""); + static_assert((std::is_same<std::pointer_traits<F<char, int> >::rebind<double>, F<double, int> >::value), ""); + +#if TEST_STD_VER >= 14 + static_assert((std::is_same<std::pointer_traits<G<char, int> >::rebind<double>, G<double, int> >::value), ""); +#endif +#else // TEST_STD_VER < 11 static_assert((std::is_same<std::pointer_traits<A<int*> >::rebind<double*>::other, A<double*> >::value), ""); static_assert((std::is_same<std::pointer_traits<B<int> >::rebind<double>::other, B1<double> >::value), ""); static_assert((std::is_same<std::pointer_traits<C<char, int> >::rebind<double>::other, C<double, int> >::value), ""); static_assert((std::is_same<std::pointer_traits<D<char, int> >::rebind<double>::other, D1<double, int> >::value), ""); -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES + static_assert((std::is_same<std::pointer_traits<E<char, int> >::rebind<double>::other, E<double, int> >::value), ""); +#endif } diff --git a/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp new file mode 100644 index 0000000000000..a371f8eda1a80 --- /dev/null +++ b/test/std/utilities/memory/specialized.algorithms/specialized.addressof/constexpr_addressof.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// XFAIL: gcc + +// <memory> + +// template <ObjectType T> constexpr T* addressof(T& r); + +#include <memory> +#include <cassert> + +struct Pointer { + constexpr Pointer(void* v) : value(v) {} + void* value; +}; + +struct A +{ + constexpr A() : n(42) {} + void operator&() const { } + int n; +}; + +constexpr int i = 0; +constexpr double d = 0.0; +constexpr A a{}; + +int main() +{ + static_assert(std::addressof(i) == &i, ""); + static_assert(std::addressof(d) == &d, ""); + constexpr const A* ap = std::addressof(a); + static_assert(&ap->n == &a.n, ""); +} diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp index 8bb818319a37a..1debd6d75ff04 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp @@ -36,7 +36,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; @@ -76,5 +76,5 @@ int main() assert( p[i].i_ == i); } } - + } diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp index ae438ef7d5613..83aa19471adae 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp @@ -36,7 +36,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp index 22aa8b98b8c96..5f90a37920641 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp @@ -35,7 +35,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp index 95c45dd50541b..3816a25286883 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp @@ -36,7 +36,7 @@ struct Nasty Nasty() : i_ ( counter_++ ) {} Nasty * operator &() const { return NULL; } int i_; - static int counter_; + static int counter_; }; int Nasty::counter_ = 0; diff --git a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp index 27b620569b83f..62a3be80d8b60 100644 --- a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp +++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.base.pass.cpp @@ -13,6 +13,8 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int A_constructed = 0; struct A @@ -29,7 +31,7 @@ public: int main() { -#if __cplusplus >= 201402L +#if TEST_STD_VER >= 14 typedef std::aligned_storage<3*sizeof(A), std::alignment_of<A>::value>::type Storage; Storage buffer; diff --git a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp index 914802423ce77..914802423ce77 100644 --- a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.pass.cpp +++ b/test/std/utilities/memory/storage.iterator/raw_storage_iterator.pass.cpp diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp index b2fb58f529f31..30b4ecb94e18f 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <memory> #include <string> #include <cassert> @@ -23,23 +24,21 @@ private: int main() { -#if _LIBCPP_STD_VER > 11 { auto p1 = std::make_unique<int[]>(5); for ( int i = 0; i < 5; ++i ) assert ( p1[i] == 0 ); } - + { auto p2 = std::make_unique<std::string[]>(5); for ( int i = 0; i < 5; ++i ) assert ( p2[i].size () == 0 ); } - + { auto p3 = std::make_unique<foo[]>(7); for ( int i = 0; i < 7; ++i ) assert ( p3[i].get () == 3 ); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp index 26eb59bbfd711..07aa659bd9b02 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp @@ -13,5 +13,5 @@ int main() { - auto up4 = std::make_unique<int[5]>(11, 22, 33, 44, 55); // deleted + auto up4 = std::make_unique<int[5]>(11, 22, 33, 44, 55); // deleted } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp index 7326ed226557c..ace2e4fc71370 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp @@ -7,20 +7,20 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <memory> #include <string> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 { std::unique_ptr<int> p1 = std::make_unique<int>(1); assert ( *p1 == 1 ); p1 = std::make_unique<int> (); assert ( *p1 == 0 ); } - + { std::unique_ptr<std::string> p2 = std::make_unique<std::string> ( "Meow!" ); assert ( *p2 == "Meow!" ); @@ -29,5 +29,4 @@ int main() p2 = std::make_unique<std::string> ( 6, 'z' ); assert ( *p2 == "zzzzzz" ); } -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp index ffc715fe9a5bd..a611b1a12f050 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp @@ -7,21 +7,21 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++98, c++03, c++11 +// <memory> -#include <tuple> -#include <string> -#include <memory> +// default_delete[] + +// template <class U> +// default_delete(const default_delete<U[]>&); +// +// This constructor shall not participate in overload resolution unless +// U(*)[] is convertible to T(*)[]. +#include <memory> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 - typedef std::unique_ptr<int> upint; - std::tuple<upint> t(upint(new int(4))); - upint p = std::get<upint>(t); -#else -#error -#endif + std::default_delete<int[]> d1; + std::default_delete<const int[]> d2 = d1; } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp index 2d62bccdce501..2b0b5f0d945d0 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter01.pass.cpp @@ -40,4 +40,10 @@ int main() assert(s.get_deleter().state() == 0); } assert(A::count == 0); + + { // LWG#2520 says that nullptr is a valid input as well as null + std::unique_ptr<A[], Deleter<A[]> > s1(NULL, Deleter<A[]>()); + std::unique_ptr<A[], Deleter<A[]> > s2(nullptr, Deleter<A[]>()); + } + assert(A::count == 0); } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp index 914076b50f428..a92fdbc1d2c41 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter02.pass.cpp @@ -55,4 +55,10 @@ int main() assert(s.get_deleter().state() == 5); } assert(A::count == 0); + { + Deleter d; + std::unique_ptr<A[], Deleter> s(nullptr, d); + assert(s.get() == nullptr); + assert(s.get_deleter().state() == 5); + } } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp index a6f535f38f088..dd27401731a6d 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter03.pass.cpp @@ -57,4 +57,9 @@ int main() assert(s.get_deleter().state() == 6); } assert(A::count == 0); + { + Deleter d; + std::unique_ptr<A[], Deleter&> s(nullptr, d); + assert(s.get() == nullptr); + } } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp index a4c917c1af76c..02f44d3575615 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.pass.cpp @@ -55,4 +55,9 @@ int main() assert(s.get_deleter().state() == 5); } assert(A::count == 0); + { + Deleter d; + std::unique_ptr<A[], const Deleter&> s(nullptr, d); + assert(s.get() == nullptr); + } } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp index 8721062c6d025..380f2e100eb6e 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/pointer_type.pass.cpp @@ -16,11 +16,22 @@ #include <memory> #include <type_traits> +#include "test_macros.h" + struct Deleter { struct pointer {}; }; +struct D2 { +private: + typedef void pointer; +}; + +struct D3 { + static long pointer; +}; + int main() { { @@ -31,4 +42,14 @@ int main() typedef std::unique_ptr<int, Deleter> P; static_assert((std::is_same<P::pointer, Deleter::pointer>::value), ""); } +#if TEST_STD_VER >= 11 + { + typedef std::unique_ptr<int, D2> P; + static_assert(std::is_same<P::pointer, int*>::value, ""); + } + { + typedef std::unique_ptr<int, D3> P; + static_assert(std::is_same<P::pointer, int*>::value, ""); + } +#endif } diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp index 44b746fbcfd86..c525137d48417 100644 --- a/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp +++ b/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp @@ -16,6 +16,7 @@ #include <memory> #include <cassert> +#include "test_macros.h" #include "../deleter.h" struct A @@ -34,6 +35,16 @@ struct A int A::count = 0; +template <class T> +struct NonSwappableDeleter { + explicit NonSwappableDeleter(int) {} + NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; } + void operator()(T*) const {} +private: + NonSwappableDeleter(NonSwappableDeleter const&); + +}; + int main() { { @@ -74,4 +85,18 @@ int main() assert(A::count == 6); } assert(A::count == 0); +#if TEST_STD_VER >= 11 + { + // test that unique_ptr's specialized swap is disabled when the deleter + // is non-swappable. Instead we should pick up the generic swap(T, T) + // and perform 3 move constructions. + typedef NonSwappableDeleter<int> D; + D d(42); + int x = 42; + int y = 43; + std::unique_ptr<int, D&> p(&x, d); + std::unique_ptr<int, D&> p2(&y, d); + std::swap(p, p2); + } +#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp index 77af13fa90d18..b9f8ee0746c31 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp @@ -18,11 +18,16 @@ // public: // shared_ptr<T> shared_from_this(); // shared_ptr<T const> shared_from_this() const; +// weak_ptr<T> weak_from_this() noexcept; // C++17 +// weak_ptr<T const> weak_from_this() const noexecpt; // C++17 // }; #include <memory> #include <cassert> +#include "test_macros.h" +#include "count_new.hpp" + struct T : public std::enable_shared_from_this<T> { @@ -32,12 +37,31 @@ struct Y : T {}; struct Z : Y {}; +void nullDeleter(void*) {} + +struct Foo : virtual public std::enable_shared_from_this<Foo> +{ + virtual ~Foo() {} +}; + +struct Bar : public Foo { + Bar(int) {} +}; + + int main() { { // https://llvm.org/bugs/show_bug.cgi?id=18843 std::shared_ptr<T const> t1(new T); std::shared_ptr<T const> t2(std::make_shared<T>()); } + { // https://llvm.org/bugs/show_bug.cgi?id=27115 + int x = 42; + std::shared_ptr<Bar> t1(new Bar(42)); + assert(t1->shared_from_this() == t1); + std::shared_ptr<Bar> t2(std::make_shared<Bar>(x)); + assert(t2->shared_from_this() == t2); + } { std::shared_ptr<Y> p(new Z); std::shared_ptr<T> q = p->shared_from_this(); @@ -50,4 +74,89 @@ int main() assert(p == q); assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership } + // Test LWG issue 2529. Only reset '__weak_ptr_' when it's already expired. + // http://cplusplus.github.io/LWG/lwg-active.html#2529. + // Test two different ways: + // * Using 'weak_from_this().expired()' in C++17. + // * Using 'shared_from_this()' in all dialects. + { + assert(globalMemCounter.checkOutstandingNewEq(0)); + T* ptr = new T; + std::shared_ptr<T> s(ptr); + { + // Don't re-initialize the "enabled_shared_from_this" base + // because it already references a non-expired shared_ptr. + std::shared_ptr<T> s2(ptr, &nullDeleter); + } +#if TEST_STD_VER > 14 + // The enabled_shared_from_this base should still be referencing + // the original shared_ptr. + assert(!ptr->weak_from_this().expired()); +#endif +#ifndef TEST_HAS_NO_EXCEPTIONS + { + try { + std::shared_ptr<T> new_s = ptr->shared_from_this(); + assert(new_s == s); + } catch (std::bad_weak_ptr const&) { + assert(false); + } catch (...) { + assert(false); + } + } +#endif + s.reset(); + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + // Test LWG issue 2529 again. This time check that an expired pointer + // is replaced. + { + assert(globalMemCounter.checkOutstandingNewEq(0)); + T* ptr = new T; + std::weak_ptr<T> weak; + { + std::shared_ptr<T> s(ptr, &nullDeleter); + assert(ptr->shared_from_this() == s); + weak = s; + assert(!weak.expired()); + } + assert(weak.expired()); + weak.reset(); + +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + ptr->shared_from_this(); + assert(false); + } catch (std::bad_weak_ptr const&) { + } catch (...) { assert(false); } +#endif + { + std::shared_ptr<T> s2(ptr, &nullDeleter); + assert(ptr->shared_from_this() == s2); + } + delete ptr; + assert(globalMemCounter.checkOutstandingNewEq(0)); + } + // Test weak_from_this_methods +#if TEST_STD_VER > 14 + { + T* ptr = new T; + const T* cptr = ptr; + + static_assert(noexcept(ptr->weak_from_this()), "Operation must be noexcept"); + static_assert(noexcept(cptr->weak_from_this()), "Operation must be noexcept"); + + std::weak_ptr<T> my_weak = ptr->weak_from_this(); + assert(my_weak.expired()); + + std::weak_ptr<T const> my_const_weak = cptr->weak_from_this(); + assert(my_const_weak.expired()); + + // Enable shared_from_this with ptr. + std::shared_ptr<T> sptr(ptr); + my_weak = ptr->weak_from_this(); + assert(!my_weak.expired()); + assert(my_weak.lock().get() == ptr); + } +#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp index 2d586e9c7fdd1..3bad537e34315 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp @@ -23,12 +23,15 @@ // atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, // shared_ptr<T> w); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -49,5 +52,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp index 34da04cc18108..5cc1234ad34ee 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp @@ -24,12 +24,15 @@ // shared_ptr<T> w, memory_order success, // memory_order failure); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -54,5 +57,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp index 50b96e551fd3b..a89c0dbd2207c 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp @@ -23,12 +23,15 @@ // atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, // shared_ptr<T> w); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -49,5 +52,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp index d304319d251de..821cea6868e48 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp @@ -24,12 +24,15 @@ // shared_ptr<T> w, memory_order success, // memory_order failure); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> v(new int(3)); @@ -54,5 +57,4 @@ int main() assert(*v == 4); assert(*w == 2); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp index 3b44c8ba9b330..66be756d54fd6 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp @@ -22,12 +22,15 @@ // shared_ptr<T> // atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> r(new int(3)); @@ -35,5 +38,4 @@ int main() assert(*p == 3); assert(*r == 4); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp index 598a1b8da175c..493ba7fcc94d0 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp @@ -22,12 +22,15 @@ // shared_ptr<T> // atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(4)); std::shared_ptr<int> r(new int(3)); @@ -35,5 +38,4 @@ int main() assert(*p == 3); assert(*r == 4); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp index e3ac84a4fa507..f72a0bb24285c 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp @@ -17,15 +17,17 @@ // bool // atomic_is_lock_free(const shared_ptr<T>* p); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { const std::shared_ptr<int> p(new int(3)); assert(std::atomic_is_lock_free(&p) == false); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp index d4a39c878ac7a..4820d05420a2f 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp @@ -22,16 +22,18 @@ // shared_ptr<T> // atomic_load(const shared_ptr<T>* p) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p(new int(3)); std::shared_ptr<int> q = std::atomic_load(&p); assert(*q == *p); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp index af11dc8bc2c9c..ef8dc822102ff 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp @@ -22,16 +22,18 @@ // shared_ptr<T> // atomic_load_explicit(const shared_ptr<T>* p, memory_order mo) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { const std::shared_ptr<int> p(new int(3)); std::shared_ptr<int> q = std::atomic_load_explicit(&p, std::memory_order_relaxed); assert(*q == *p); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp index 7a85a9934ef0a..a13a7d57ab960 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp @@ -22,17 +22,19 @@ // void // atomic_store(shared_ptr<T>* p, shared_ptr<T> r) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p; std::shared_ptr<int> r(new int(3)); std::atomic_store(&p, r); assert(*p == *r); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp index c81266c55fa47..6dfe3166c8c58 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp @@ -22,17 +22,19 @@ // void // atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo) +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> +#include "test_macros.h" + int main() { -#if __has_feature(cxx_atomic) { std::shared_ptr<int> p; std::shared_ptr<int> r(new int(3)); std::atomic_store_explicit(&p, r, std::memory_order_seq_cst); assert(*p == *r); } -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h index 0263061b3a84a..bae1e013f571c 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h @@ -52,7 +52,7 @@ public: void set_state(int i) {state_ = i;} void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;} - + test_deleter* operator&() const DELETE_FUNCTION; }; diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp index 8175312334f66..f44c05eb7c86d 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/types.pass.cpp @@ -13,14 +13,20 @@ // { // public: // typedef T element_type; +// typedef weak_ptr<T> weak_type; // C++17 // ... // }; #include <memory> +#include "test_macros.h" + struct A; // purposefully incomplete int main() { static_assert((std::is_same<std::shared_ptr<A>::element_type, A>::value), ""); +#if TEST_STD_VER > 14 + static_assert((std::is_same<std::shared_ptr<A>::weak_type, std::weak_ptr<A>>::value), ""); +#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp index f17485108b925..f8fdb7a094782 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp @@ -7,31 +7,18 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // <memory> // template<class Y> explicit shared_ptr(auto_ptr<Y>&& r); -// UNSUPPORTED: sanitizer-new-delete #include <memory> #include <new> #include <cstdlib> #include <cassert> -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} +#include "test_macros.h" +#include "count_new.hpp" struct B { @@ -59,47 +46,51 @@ int A::count = 0; int main() { { - std::auto_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::shared_ptr<B> p(std::move(ptr)); -#else - std::shared_ptr<B> p(ptr); -#endif - assert(A::count == 1); - assert(B::count == 1); - assert(p.use_count() == 1); - assert(p.get() == raw_ptr); - assert(ptr.get() == 0); - } - assert(A::count == 0); - { - std::auto_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); - throw_next = true; - try - { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + std::auto_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); +#if TEST_STD_VER >= 11 std::shared_ptr<B> p(std::move(ptr)); #else std::shared_ptr<B> p(ptr); #endif - assert(false); - } - catch (...) - { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES assert(A::count == 1); assert(B::count == 1); - assert(ptr.get() == raw_ptr); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + assert(A::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) + { + std::auto_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); + globalMemCounter.throw_after = 0; + try + { +#if TEST_STD_VER >= 11 + std::shared_ptr<B> p(std::move(ptr)); #else - // Without rvalue references, ptr got copied into - // the shared_ptr destructor and the copy was - // destroyed during unwinding. - assert(A::count == 0); - assert(B::count == 0); + std::shared_ptr<B> p(ptr); #endif - } + assert(false); + } + catch (...) + { +#if TEST_STD_VER >= 11 + assert(A::count == 1); + assert(B::count == 1); + assert(ptr.get() == raw_ptr); + #else + // Without rvalue references, ptr got copied into + // the shared_ptr destructor and the copy was + // destroyed during unwinding. + assert(A::count == 0); + assert(B::count == 0); +#endif + } } assert(A::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); +#endif // !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp index b67f31ee45a85..8a6cd0f352ff7 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp @@ -65,7 +65,7 @@ int main() assert(test_deleter<A>::count == 0); assert(test_deleter<A>::dealloc_count == 1); test_deleter<A>::dealloc_count = 0; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // Test an allocator that returns class-type pointers { std::shared_ptr<A> p(nullptr, test_deleter<A>(1), min_allocator<void>()); diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp index 6a79a8ef60db6..85fc5e930544b 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp @@ -8,18 +8,22 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // shared_ptr // template<class D> shared_ptr(nullptr_t, D d); -// UNSUPPORTED: sanitizer-new-delete - #include <memory> #include <cassert> #include <new> #include <cstdlib> + +#include "test_macros.h" +#include "count_new.hpp" + #include "../test_deleter.h" struct A @@ -33,23 +37,10 @@ struct A int A::count = 0; -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} int main() { - throw_next = true; + globalMemCounter.throw_after = 0; try { std::shared_ptr<A> p(nullptr, test_deleter<A>(3)); diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp index 1a9c09cdb78ce..b0facfc1a6eb5 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp @@ -68,7 +68,7 @@ int main() assert(test_deleter<A>::count == 0); assert(test_deleter<A>::dealloc_count == 1); test_deleter<A>::dealloc_count = 0; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // Test an allocator that returns class-type pointers { A* ptr = new A; diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp index 982313b074991..70af2964113d0 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp @@ -8,18 +8,20 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // shared_ptr // template<class Y, class D> shared_ptr(Y* p, D d); -// UNSUPPORTED: sanitizer-new-delete - #include <memory> #include <cassert> #include <new> #include <cstdlib> + +#include "count_new.hpp" #include "../test_deleter.h" struct A @@ -33,24 +35,10 @@ struct A int A::count = 0; -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} - int main() { A* ptr = new A; - throw_next = true; + globalMemCounter.throw_after = 0; try { std::shared_ptr<A> p(ptr, test_deleter<A>(3)); @@ -62,4 +50,5 @@ int main() assert(test_deleter<A>::count == 0); assert(test_deleter<A>::dealloc_count == 1); } + assert(globalMemCounter.checkOutstandingNewEq(0)); } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp index 2e761d70bba09..2fa975eca833d 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp @@ -8,17 +8,20 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // template<class Y> explicit shared_ptr(Y* p); -// UNSUPPORTED: sanitizer-new-delete #include <memory> #include <new> #include <cstdlib> #include <cassert> +#include "count_new.hpp" + struct A { static int count; @@ -30,26 +33,12 @@ struct A int A::count = 0; -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} int main() { - { A* ptr = new A; - throw_next = true; assert(A::count == 1); + globalMemCounter.throw_after = 0; try { std::shared_ptr<A> p(ptr); @@ -59,5 +48,5 @@ int main() { assert(A::count == 0); } - } + assert(globalMemCounter.checkOutstandingNewEq(0)); } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp index c62fcd6893205..5c424f5c7428c 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp @@ -8,30 +8,19 @@ //===----------------------------------------------------------------------===// // XFAIL: libcpp-no-exceptions +// UNSUPPORTED: sanitizer-new-delete + // <memory> // template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r); -// UNSUPPORTED: sanitizer-new-delete - #include <memory> #include <new> #include <cstdlib> #include <cassert> -bool throw_next = false; - -void* operator new(std::size_t s) throw(std::bad_alloc) -{ - if (throw_next) - throw std::bad_alloc(); - return std::malloc(s); -} - -void operator delete(void* p) throw() -{ - std::free(p); -} +#include "test_macros.h" +#include "count_new.hpp" struct B { @@ -65,52 +54,46 @@ void assert_deleter ( T * ) { assert(false); } int main() { { - std::unique_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); - std::shared_ptr<B> p(std::move(ptr)); - assert(A::count == 1); - assert(B::count == 1); - assert(p.use_count() == 1); - assert(p.get() == raw_ptr); - assert(ptr.get() == 0); - } - assert(A::count == 0); - { - std::unique_ptr<A> ptr(new A); - A* raw_ptr = ptr.get(); - throw_next = true; - try - { + std::unique_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); std::shared_ptr<B> p(std::move(ptr)); - assert(false); - } - catch (...) - { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES assert(A::count == 1); assert(B::count == 1); - assert(ptr.get() == raw_ptr); -#else - assert(A::count == 0); - assert(B::count == 0); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); assert(ptr.get() == 0); -#endif - } } assert(A::count == 0); - - // LWG 2399 { - throw_next = false; - fn(std::unique_ptr<int>(new int)); + std::unique_ptr<A> ptr(new A); + A* raw_ptr = ptr.get(); + globalMemCounter.throw_after = 0; + try + { + std::shared_ptr<B> p(std::move(ptr)); + assert(false); + } + catch (...) + { +#if TEST_STD_VER >= 11 + assert(A::count == 1); + assert(B::count == 1); + assert(ptr.get() == raw_ptr); +#else + assert(A::count == 0); + assert(B::count == 0); + assert(ptr.get() == 0); +#endif + } } - -#if __cplusplus >= 201402L - // LWG 2415 - { - std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>); - std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope + assert(A::count == 0); + { // LWG 2399 + fn(std::unique_ptr<int>(new int)); + } +#if TEST_STD_VER >= 14 + { // LWG 2415 + std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>); + std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope } #endif - } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp index aa77dab51515f..3e4a99e981d46 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <memory> // shared_ptr @@ -55,7 +57,6 @@ int main() } assert(A::count == 0); assert(test_allocator<A>::alloc_count == 0); -#if __cplusplus >= 201103L { int i = 67; char c = 'e'; @@ -74,5 +75,4 @@ int main() assert(p->get_char() == 'f'); } assert(A::count == 0); -#endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_cxx03.pass.cpp index 8dcd50e494110..527bbce1473e2 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_cxx03.pass.cpp @@ -14,7 +14,7 @@ // template<class T, class A, class... Args> // shared_ptr<T> allocate_shared(const A& a, Args&&... args); -#define _LIBCPP_HAS_NO_VARIADICS + #include <memory> #include <new> #include <cstdlib> @@ -112,7 +112,7 @@ int main() assert(test_allocator<Two>::alloc_count == 0); test<bare_allocator<void> >(); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 test<min_allocator<void> >(); #endif } diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp index 1045f9347b381..59cd3d248639d 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp @@ -34,7 +34,7 @@ void test(const T &t0) assert(*p0 == t0); assert(*p1 == t1); } - + { volatile T t1 = t0; std::shared_ptr<volatile T> p0 = std::make_shared<volatile T>(t0); @@ -50,7 +50,7 @@ void test(const T &t0) assert(*p0 == t0); assert(*p1 == t1); } - + } int main() diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp index bf1719c66ffa3..142eba2d96478 100644 --- a/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.ownerless/owner_less.pass.cpp @@ -30,7 +30,7 @@ // bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const; // bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const; // }; -// +// // Added in C++17 // template<> struct owner_less<void> // { @@ -42,7 +42,7 @@ // bool operator()(weak_ptr<T> const&, shared_ptr<U> const&) const; // template<class T, class U> // bool operator()(weak_ptr<T> const&, weak_ptr<U> const&) const; -// +// // typedef unspecified is_transparent; // }; @@ -113,7 +113,7 @@ int main() cmp(wp1, wp1); } { - // test heterogeneous lookups + // test heterogeneous lookups std::set<std::shared_ptr<X>, std::owner_less<>> s; std::shared_ptr<void> vp; s.find(vp); diff --git a/test/std/utilities/memory/version.pass.cpp b/test/std/utilities/memory/version.pass.cpp deleted file mode 100644 index 790c08a3bd2d9..0000000000000 --- a/test/std/utilities/memory/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <memory> - -#include <memory> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp b/test/std/utilities/meta/meta.help/bool_constant.pass.cpp index 71110ea3bfb09..dcacf379b9ae3 100644 --- a/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp +++ b/test/std/utilities/meta/meta.help/bool_constant.pass.cpp @@ -14,9 +14,11 @@ #include <type_traits> #include <cassert> +#include "test_macros.h" + int main() { -#if __cplusplus > 201402L +#if TEST_STD_VER > 14 typedef std::bool_constant<true> _t; static_assert(_t::value, ""); static_assert((std::is_same<_t::value_type, bool>::value), ""); diff --git a/test/std/utilities/meta/meta.hel/integral_constant.pass.cpp b/test/std/utilities/meta/meta.help/integral_constant.pass.cpp index 335305a282364..335305a282364 100644 --- a/test/std/utilities/meta/meta.hel/integral_constant.pass.cpp +++ b/test/std/utilities/meta/meta.help/integral_constant.pass.cpp diff --git a/test/std/utilities/meta/meta.logical/conjunction.pass.cpp b/test/std/utilities/meta/meta.logical/conjunction.pass.cpp index dce58ec23725d..d8dd386e9347a 100644 --- a/test/std/utilities/meta/meta.logical/conjunction.pass.cpp +++ b/test/std/utilities/meta/meta.logical/conjunction.pass.cpp @@ -11,7 +11,7 @@ // type_traits // template<class... B> struct conjunction; // C++17 -// template<class... B> +// template<class... B> // constexpr bool conjunction_v = conjunction<B...>::value; // C++17 #include <type_traits> @@ -34,7 +34,7 @@ int main() static_assert (!std::conjunction<std::true_type, std::false_type>::value, "" ); static_assert (!std::conjunction<std::false_type, std::true_type >::value, "" ); static_assert (!std::conjunction<std::false_type, std::false_type>::value, "" ); - + static_assert ( std::conjunction_v<std::true_type, std::true_type >, "" ); static_assert (!std::conjunction_v<std::true_type, std::false_type>, "" ); static_assert (!std::conjunction_v<std::false_type, std::true_type >, "" ); diff --git a/test/std/utilities/meta/meta.logical/disjunction.pass.cpp b/test/std/utilities/meta/meta.logical/disjunction.pass.cpp index 13cd9341b99f1..f5ba178d6483d 100644 --- a/test/std/utilities/meta/meta.logical/disjunction.pass.cpp +++ b/test/std/utilities/meta/meta.logical/disjunction.pass.cpp @@ -11,7 +11,7 @@ // type_traits // template<class... B> struct disjunction; // C++17 -// template<class... B> +// template<class... B> // constexpr bool disjunction_v = disjunction<B...>::value; // C++17 #include <type_traits> @@ -34,7 +34,7 @@ int main() static_assert ( std::disjunction<std::true_type, std::false_type>::value, "" ); static_assert ( std::disjunction<std::false_type, std::true_type >::value, "" ); static_assert (!std::disjunction<std::false_type, std::false_type>::value, "" ); - + static_assert ( std::disjunction_v<std::true_type, std::true_type >, "" ); static_assert ( std::disjunction_v<std::true_type, std::false_type>, "" ); static_assert ( std::disjunction_v<std::false_type, std::true_type >, "" ); diff --git a/test/std/utilities/meta/meta.logical/negation.pass.cpp b/test/std/utilities/meta/meta.logical/negation.pass.cpp index 76ff6c5b24db8..7b4eb27a75e1a 100644 --- a/test/std/utilities/meta/meta.logical/negation.pass.cpp +++ b/test/std/utilities/meta/meta.logical/negation.pass.cpp @@ -11,7 +11,7 @@ // type_traits // template<class B> struct negation; // C++17 -// template<class B> +// template<class B> // constexpr bool negation_v = negation<B>::value; // C++17 #include <type_traits> diff --git a/test/std/utilities/meta/meta.rel/is_callable.pass.cpp b/test/std/utilities/meta/meta.rel/is_callable.pass.cpp new file mode 100644 index 0000000000000..4c85f440b0bf9 --- /dev/null +++ b/test/std/utilities/meta/meta.rel/is_callable.pass.cpp @@ -0,0 +1,160 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// type_traits + +// is_callable + +// Most testing of is_callable is done within the [meta.trans.other] result_of +// tests. + +#include <type_traits> +#include <functional> +#include <memory> + +#include "test_macros.h" + +struct Tag {}; +struct DerFromTag : Tag {}; + +struct Implicit { + Implicit(int) {} +}; + +struct Explicit { + explicit Explicit(int) {} +}; + +struct NotCallableWithInt { + int operator()(int) = delete; + int operator()(Tag) { return 42; } +}; + +int main() +{ + { + using Fn = int(Tag::*)(int); + using RFn = int(Tag::*)(int) &&; + // INVOKE bullet 1, 2 and 3 + { + // Bullet 1 + static_assert(std::is_callable<Fn(Tag&, int)>::value, ""); + static_assert(std::is_callable<Fn(DerFromTag&, int)>::value, ""); + static_assert(std::is_callable<RFn(Tag&&, int)>::value, ""); + static_assert(!std::is_callable<RFn(Tag&, int)>::value, ""); + static_assert(!std::is_callable<Fn(Tag&)>::value, ""); + static_assert(!std::is_callable<Fn(Tag const&, int)>::value, ""); + } + { + // Bullet 2 + using T = std::reference_wrapper<Tag>; + using DT = std::reference_wrapper<DerFromTag>; + using CT = std::reference_wrapper<const Tag>; + static_assert(std::is_callable<Fn(T&, int)>::value, ""); + static_assert(std::is_callable<Fn(DT&, int)>::value, ""); + static_assert(std::is_callable<Fn(const T&, int)>::value, ""); + static_assert(std::is_callable<Fn(T&&, int)>::value, ""); + static_assert(!std::is_callable<Fn(CT&, int)>::value, ""); + static_assert(!std::is_callable<RFn(T, int)>::value, ""); + } + { + // Bullet 3 + using T = Tag*; + using DT = DerFromTag*; + using CT = const Tag*; + using ST = std::unique_ptr<Tag>; + static_assert(std::is_callable<Fn(T&, int)>::value, ""); + static_assert(std::is_callable<Fn(DT&, int)>::value, ""); + static_assert(std::is_callable<Fn(const T&, int)>::value, ""); + static_assert(std::is_callable<Fn(T&&, int)>::value, ""); + static_assert(std::is_callable<Fn(ST, int)>::value, ""); + static_assert(!std::is_callable<Fn(CT&, int)>::value, ""); + static_assert(!std::is_callable<RFn(T, int)>::value, ""); + } + } + { + // Bullets 4, 5 and 6 + using Fn = int (Tag::*); + static_assert(!std::is_callable<Fn()>::value, ""); + { + // Bullet 4 + static_assert(std::is_callable<Fn(Tag&)>::value, ""); + static_assert(std::is_callable<Fn(DerFromTag&)>::value, ""); + static_assert(std::is_callable<Fn(Tag&&)>::value, ""); + static_assert(std::is_callable<Fn(Tag const&)>::value, ""); + } + { + // Bullet 5 + using T = std::reference_wrapper<Tag>; + using DT = std::reference_wrapper<DerFromTag>; + using CT = std::reference_wrapper<const Tag>; + static_assert(std::is_callable<Fn(T&)>::value, ""); + static_assert(std::is_callable<Fn(DT&)>::value, ""); + static_assert(std::is_callable<Fn(const T&)>::value, ""); + static_assert(std::is_callable<Fn(T&&)>::value, ""); + static_assert(std::is_callable<Fn(CT&)>::value, ""); + } + { + // Bullet 6 + using T = Tag*; + using DT = DerFromTag*; + using CT = const Tag*; + using ST = std::unique_ptr<Tag>; + static_assert(std::is_callable<Fn(T&)>::value, ""); + static_assert(std::is_callable<Fn(DT&)>::value, ""); + static_assert(std::is_callable<Fn(const T&)>::value, ""); + static_assert(std::is_callable<Fn(T&&)>::value, ""); + static_assert(std::is_callable<Fn(ST)>::value, ""); + static_assert(std::is_callable<Fn(CT&)>::value, ""); + } + } + { + // INVOKE bullet 7 + { + // Function pointer + using Fp = void(*)(Tag&, int); + static_assert(std::is_callable<Fp(Tag&, int)>::value, ""); + static_assert(std::is_callable<Fp(DerFromTag&, int)>::value, ""); + static_assert(!std::is_callable<Fp(const Tag&, int)>::value, ""); + static_assert(!std::is_callable<Fp()>::value, ""); + static_assert(!std::is_callable<Fp(Tag&)>::value, ""); + } + { + // Function reference + using Fp = void(&)(Tag&, int); + static_assert(std::is_callable<Fp(Tag&, int)>::value, ""); + static_assert(std::is_callable<Fp(DerFromTag&, int)>::value, ""); + static_assert(!std::is_callable<Fp(const Tag&, int)>::value, ""); + static_assert(!std::is_callable<Fp()>::value, ""); + static_assert(!std::is_callable<Fp(Tag&)>::value, ""); + } + { + // Function object + using Fn = NotCallableWithInt; + static_assert(std::is_callable<Fn(Tag)>::value, ""); + static_assert(!std::is_callable<Fn(int)>::value, ""); + } + } + { + // Check that the conversion to the return type is properly checked + using Fn = int(*)(); + static_assert(std::is_callable<Fn(), Implicit>::value, ""); + static_assert(std::is_callable<Fn(), double>::value, ""); + static_assert(std::is_callable<Fn(), const volatile void>::value, ""); + static_assert(!std::is_callable<Fn(), Explicit>::value, ""); + } + { + // Check for is_callable_v + using Fn = void(*)(); + static_assert(std::is_callable_v<Fn()>, ""); + static_assert(!std::is_callable_v<Fn(int)>, ""); + } +} diff --git a/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp b/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp index 1681c39972d28..552c16075da7a 100644 --- a/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp +++ b/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp @@ -12,7 +12,6 @@ // is_convertible #include <type_traits> - #include "test_macros.h" template <class T, class U> @@ -46,12 +45,22 @@ void test_is_not_convertible() } typedef void Function(); +typedef void ConstFunction() const; typedef char Array[1]; +struct StringType { + StringType(const char*) {} +}; + class NonCopyable { NonCopyable(NonCopyable&); }; +template <typename T> +class CannotInstantiate { + enum { X = T::ThisExpressionWillBlowUp }; +}; + int main() { // void @@ -64,12 +73,19 @@ int main() test_is_not_convertible<void,char> (); test_is_not_convertible<void,char&> (); test_is_not_convertible<void,char*> (); + test_is_not_convertible<char, void>(); // Function test_is_not_convertible<Function, void> (); test_is_not_convertible<Function, Function> (); test_is_convertible<Function, Function&> (); test_is_convertible<Function, Function*> (); + test_is_convertible<Function, Function*const> (); + +#if TEST_STD_VER >= 11 + static_assert(( std::is_convertible<Function, Function&&>::value), ""); +#endif + test_is_not_convertible<Function, Array> (); test_is_not_convertible<Function, Array&> (); test_is_not_convertible<Function, char> (); @@ -100,6 +116,16 @@ int main() test_is_not_convertible<Function*, char&> (); test_is_not_convertible<Function*, char*> (); + // Non-referencable function type + static_assert((!std::is_convertible<ConstFunction, Function>::value), ""); + static_assert((!std::is_convertible<ConstFunction, Function*>::value), ""); + static_assert((!std::is_convertible<ConstFunction, Function&>::value), ""); + static_assert((!std::is_convertible<ConstFunction, Function>::value), ""); + static_assert((!std::is_convertible<Function*, ConstFunction>::value), ""); + static_assert((!std::is_convertible<Function&, ConstFunction>::value), ""); + static_assert((!std::is_convertible<ConstFunction, ConstFunction>::value), ""); + static_assert((!std::is_convertible<ConstFunction, void>::value), ""); + // Array test_is_not_convertible<Array, void> (); test_is_not_convertible<Array, Function> (); @@ -109,17 +135,37 @@ int main() static_assert((!std::is_convertible<Array, Array&>::value), ""); static_assert(( std::is_convertible<Array, const Array&>::value), ""); + static_assert((!std::is_convertible<Array, const volatile Array&>::value), ""); + static_assert((!std::is_convertible<const Array, Array&>::value), ""); static_assert(( std::is_convertible<const Array, const Array&>::value), ""); + static_assert((!std::is_convertible<Array, volatile Array&>::value), ""); + static_assert((!std::is_convertible<Array, const volatile Array&>::value), ""); + +#if TEST_STD_VER >= 11 + static_assert(( std::is_convertible<Array, Array&&>::value), ""); + static_assert(( std::is_convertible<Array, const Array&&>::value), ""); + static_assert(( std::is_convertible<Array, volatile Array&&>::value), ""); + static_assert(( std::is_convertible<Array, const volatile Array&&>::value), ""); + static_assert(( std::is_convertible<const Array, const Array&&>::value), ""); + static_assert((!std::is_convertible<Array&, Array&&>::value), ""); + static_assert((!std::is_convertible<Array&&, Array&>::value), ""); +#endif test_is_not_convertible<Array, char> (); test_is_not_convertible<Array, char&> (); static_assert(( std::is_convertible<Array, char*>::value), ""); static_assert(( std::is_convertible<Array, const char*>::value), ""); + static_assert(( std::is_convertible<Array, char* const>::value), ""); + static_assert(( std::is_convertible<Array, char* const volatile>::value), ""); + static_assert((!std::is_convertible<const Array, char*>::value), ""); static_assert(( std::is_convertible<const Array, const char*>::value), ""); + static_assert((!std::is_convertible<char[42][42], char*>::value), ""); + static_assert((!std::is_convertible<char[][1], char*>::value), ""); + // Array& test_is_not_convertible<Array&, void> (); test_is_not_convertible<Array&, Function> (); @@ -140,6 +186,9 @@ int main() static_assert((!std::is_convertible<const Array&, char*>::value), ""); static_assert(( std::is_convertible<const Array&, const char*>::value), ""); + static_assert((std::is_convertible<Array, StringType>::value), ""); + static_assert((std::is_convertible<char(&)[], StringType>::value), ""); + // char test_is_not_convertible<char, void> (); test_is_not_convertible<char, Function> (); @@ -149,7 +198,7 @@ int main() test_is_not_convertible<char, Array&> (); test_is_convertible<char, char> (); - + static_assert((!std::is_convertible<char, char&>::value), ""); static_assert(( std::is_convertible<char, const char&>::value), ""); static_assert((!std::is_convertible<const char, char&>::value), ""); @@ -166,7 +215,7 @@ int main() test_is_not_convertible<char&, Array&> (); test_is_convertible<char&, char> (); - + static_assert(( std::is_convertible<char&, char&>::value), ""); static_assert(( std::is_convertible<char&, const char&>::value), ""); static_assert((!std::is_convertible<const char&, char&>::value), ""); @@ -184,7 +233,7 @@ int main() test_is_not_convertible<char*, char> (); test_is_not_convertible<char*, char&> (); - + static_assert(( std::is_convertible<char*, char*>::value), ""); static_assert(( std::is_convertible<char*, const char*>::value), ""); static_assert((!std::is_convertible<const char*, char*>::value), ""); @@ -202,8 +251,11 @@ int main() static_assert((!std::is_convertible<const NonCopyable&, NonCopyable&>::value), ""); // This test requires Access control SFINAE which we only have in C++11 or when // we are using the compiler builtin for is_convertible. -#if __cplusplus >= 201103L || !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) +#if TEST_STD_VER >= 11 || !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) test_is_not_convertible<NonCopyable&, NonCopyable>(); #endif + // Ensure that CannotInstantiate is not instantiated by is_convertible when it is not needed. + // For example CannotInstantiate is instatiated as a part of ADL lookup for arguments of type CannotInstantiate*. + static_assert((std::is_convertible<CannotInstantiate<int>*, CannotInstantiate<int>*>::value), ""); } diff --git a/test/std/utilities/meta/meta.rel/is_nothrow_callable.pass.cpp b/test/std/utilities/meta/meta.rel/is_nothrow_callable.pass.cpp new file mode 100644 index 0000000000000..eefa6d1f22b18 --- /dev/null +++ b/test/std/utilities/meta/meta.rel/is_nothrow_callable.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// type_traits + +// is_nothrow_callable + +#include <type_traits> +#include <functional> + +#include "test_macros.h" + +struct Tag {}; + +struct Implicit { + Implicit(int) noexcept {} +}; + +struct ThrowsImplicit { + ThrowsImplicit(int) {} +}; + +struct Explicit { + explicit Explicit(int) noexcept {} +}; + +template <bool IsNoexcept, class Ret, class ...Args> +struct CallObject { + Ret operator()(Args&&...) const noexcept(IsNoexcept); +}; + +template <class Fn> +constexpr bool throws_callable() { + return std::is_callable<Fn>::value && + !std::is_nothrow_callable<Fn>::value; +} + +template <class Fn, class Ret> +constexpr bool throws_callable() { + return std::is_callable<Fn, Ret>::value && + !std::is_nothrow_callable<Fn, Ret>::value; +} + +// FIXME(EricWF) Don't test the where noexcept is *not* part of the type system +// once implementations have caught up. +void test_noexcept_function_pointers() +{ + struct Dummy { void foo() noexcept {} static void bar() noexcept {} }; +#if !defined(__cpp_noexcept_function_type) + { + // Check that PMF's and function pointers *work*. is_nothrow_callable will always + // return false because 'noexcept' is not part of the function type. + static_assert(throws_callable<decltype(&Dummy::foo)(Dummy&)>(), ""); + static_assert(throws_callable<decltype(&Dummy::bar)()>(), ""); + } +#else + { + // Check that PMF's and function pointers actually work and that + // is_nothrow_callable returns true for noexcept PMF's and function + // pointers. + static_assert(std::is_nothrow_callable<decltype(&Dummy::foo)(Dummy&)>::value, ""); + static_assert(std::is_nothrow_callable<decltype(&Dummy::bar)()>::value, ""); + } +#endif +} + +int main() +{ + { + // Check that the conversion to the return type is properly checked + using Fn = CallObject<true, int>; + static_assert(std::is_nothrow_callable<Fn(), Implicit>::value, ""); + static_assert(std::is_nothrow_callable<Fn(), double>::value, ""); + static_assert(std::is_nothrow_callable<Fn(), const volatile void>::value, ""); + static_assert(throws_callable<Fn(), ThrowsImplicit>(), ""); + static_assert(!std::is_nothrow_callable<Fn(), Explicit>(), ""); + } + { + // Check that the conversion to the parameters is properly checked + using Fn = CallObject<true, void, const Implicit&, const ThrowsImplicit&>; + static_assert(std::is_nothrow_callable<Fn(Implicit&, ThrowsImplicit&)>::value, ""); + static_assert(std::is_nothrow_callable<Fn(int, ThrowsImplicit&)>::value, ""); + static_assert(throws_callable<Fn(int, int)>(), ""); + static_assert(!std::is_nothrow_callable<Fn()>::value, ""); + } + { + // Check that the noexcept-ness of function objects is checked. + using Fn = CallObject<true, void>; + using Fn2 = CallObject<false, void>; + static_assert(std::is_nothrow_callable<Fn()>::value, ""); + static_assert(throws_callable<Fn2()>(), ""); + } + { + // Check that PMD derefs are noexcept + using Fn = int (Tag::*); + static_assert(std::is_nothrow_callable<Fn(Tag&)>::value, ""); + static_assert(std::is_nothrow_callable<Fn(Tag&), Implicit>::value, ""); + static_assert(throws_callable<Fn(Tag&), ThrowsImplicit>(), ""); + } + { + // Check for is_nothrow_callable_v + using Fn = CallObject<true, int>; + static_assert(std::is_nothrow_callable_v<Fn()>, ""); + static_assert(!std::is_nothrow_callable_v<Fn(int)>, ""); + } + test_noexcept_function_pointers(); +} diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp index a53bed984c5e2..079661d0c1749 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp @@ -164,7 +164,7 @@ int main() // Use alignof(std::max_align_t) below to find the max alignment instead of // hardcoding it, because it's different on different platforms. // (For example 8 on arm and 16 on x86.) -#if __cplusplus < 201103L +#if TEST_STD_VER < 11 #define alignof __alignof__ #endif { diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp index 8ce894578c4fd..8c9b42d60f30e 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/enable_if2.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // type_traits // enable_if @@ -15,9 +16,5 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::enable_if_t<false> A; -#else - static_assert ( false, "" ); -#endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp index 5a925bb34b260..fc01b22c36abe 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp @@ -13,6 +13,7 @@ #include <type_traits> #include <memory> +#include <cassert> #include "test_macros.h" struct S @@ -25,6 +26,11 @@ struct S double const volatile& operator()(char, int&) const volatile; }; + +struct SD : public S { }; + +struct NotDerived {}; + template <class Tp> struct Voider { typedef void type; @@ -39,6 +45,10 @@ struct HasType<T, typename Voider<typename T::type>::type> : std::true_type {}; template <class T, class U> void test_result_of() { +#if TEST_STD_VER > 14 + static_assert(std::is_callable<T>::value, ""); + static_assert(std::is_callable<T, U>::value, ""); +#endif static_assert((std::is_same<typename std::result_of<T>::type, U>::value), ""); } @@ -48,10 +58,14 @@ void test_no_result() #if TEST_STD_VER >= 11 static_assert((!HasType<std::result_of<T> >::value), ""); #endif +#if TEST_STD_VER > 14 + static_assert(std::is_callable<T>::value == false, ""); +#endif } int main() { + typedef NotDerived ND; { // functor object test_result_of<S(int), short> (); test_result_of<S&(unsigned char, int&), double> (); @@ -90,32 +104,64 @@ int main() typedef int (S::*PMS0)(); typedef int* (S::*PMS1)(long); typedef int& (S::*PMS2)(long, int); - test_result_of<PMS0( S), int> (); - test_result_of<PMS0( S&), int> (); - test_result_of<PMS0( S*), int> (); - test_result_of<PMS0( S*&), int> (); - test_result_of<PMS0(std::unique_ptr<S>), int> (); + test_result_of<PMS0( S), int> (); + test_result_of<PMS0( S&), int> (); + test_result_of<PMS0( S*), int> (); + test_result_of<PMS0( S*&), int> (); + test_result_of<PMS0( std::reference_wrapper<S>), int> (); + test_result_of<PMS0(const std::reference_wrapper<S>&), int> (); + test_result_of<PMS0( std::reference_wrapper<SD>), int> (); + test_result_of<PMS0(const std::reference_wrapper<SD>&), int> (); + test_result_of<PMS0(std::unique_ptr<S>), int> (); + test_result_of<PMS0(std::unique_ptr<SD>), int> (); test_no_result<PMS0(const S&)>(); test_no_result<PMS0(volatile S&)>(); test_no_result<PMS0(const volatile S&)>(); + test_no_result<PMS0(ND & )>(); + test_no_result<PMS0(const ND& )>(); + test_no_result<PMS0(std::unique_ptr<S const> )>(); + test_no_result<PMS0(std::reference_wrapper<S const>)>(); + test_no_result<PMS0(std::reference_wrapper<ND> )>(); + test_no_result<PMS0(std::unique_ptr<ND> )>(); - test_result_of<PMS1( S, int), int*> (); - test_result_of<PMS1( S&, int), int*> (); - test_result_of<PMS1( S*, int), int*> (); - test_result_of<PMS1( S*&, int), int*> (); - test_result_of<PMS1(std::unique_ptr<S>, int), int*> (); + test_result_of<PMS1( S, int), int*> (); + test_result_of<PMS1( S&, int), int*> (); + test_result_of<PMS1( S*, int), int*> (); + test_result_of<PMS1( S*&, int), int*> (); + test_result_of<PMS1(std::unique_ptr<S>, int), int*> (); + test_result_of<PMS1(std::unique_ptr<SD>, int), int*> (); + test_result_of<PMS1(std::reference_wrapper<S>, int), int*> (); + test_result_of<PMS1(const std::reference_wrapper<S>&, int), int*> (); + test_result_of<PMS1(std::reference_wrapper<SD>, int), int*> (); + test_result_of<PMS1(const std::reference_wrapper<SD>&, int), int*> (); test_no_result<PMS1(const S&, int)>(); test_no_result<PMS1(volatile S&, int)>(); test_no_result<PMS1(const volatile S&, int)>(); + test_no_result<PMS1(ND &, int)>(); + test_no_result<PMS1(const ND&, int)>(); + test_no_result<PMS1(std::unique_ptr<S const>, int)>(); + test_no_result<PMS1(std::reference_wrapper<S const>, int)>(); + test_no_result<PMS1(std::reference_wrapper<ND>, int)>(); + test_no_result<PMS1(std::unique_ptr<ND>, int)>(); test_result_of<PMS2( S, int, int), int&> (); test_result_of<PMS2( S&, int, int), int&> (); test_result_of<PMS2( S*, int, int), int&> (); test_result_of<PMS2( S*&, int, int), int&> (); test_result_of<PMS2(std::unique_ptr<S>, int, int), int&> (); + test_result_of<PMS2(std::unique_ptr<SD>, int, int), int&> (); + test_result_of<PMS2(std::reference_wrapper<S>, int, int), int&> (); + test_result_of<PMS2(const std::reference_wrapper<S>&, int, int), int&> (); + test_result_of<PMS2(std::reference_wrapper<SD>, int, int), int&> (); + test_result_of<PMS2(const std::reference_wrapper<SD>&, int, int), int&> (); test_no_result<PMS2(const S&, int, int)>(); test_no_result<PMS2(volatile S&, int, int)>(); test_no_result<PMS2(const volatile S&, int, int)>(); + test_no_result<PMS2(std::unique_ptr<S const>, int, int)>(); + test_no_result<PMS2(std::reference_wrapper<S const>, int, int)>(); + test_no_result<PMS2(const ND&, int, int)>(); + test_no_result<PMS2(std::reference_wrapper<ND>, int, int)>(); + test_no_result<PMS2(std::unique_ptr<ND>, int, int)>(); typedef int (S::*PMS0C)() const; typedef int* (S::*PMS1C)(long) const; @@ -128,6 +174,15 @@ int main() test_result_of<PMS0C( S*&), int> (); test_result_of<PMS0C(const S*&), int> (); test_result_of<PMS0C(std::unique_ptr<S>), int> (); + test_result_of<PMS0C(std::unique_ptr<SD>), int> (); + test_result_of<PMS0C(std::reference_wrapper<S> ), int> (); + test_result_of<PMS0C(std::reference_wrapper<const S> ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<S> & ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<const S> &), int> (); + test_result_of<PMS0C(std::reference_wrapper<SD> ), int> (); + test_result_of<PMS0C(std::reference_wrapper<const SD> ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<SD> & ), int> (); + test_result_of<PMS0C(const std::reference_wrapper<const SD> &), int> (); test_no_result<PMS0C(volatile S&)>(); test_no_result<PMS0C(const volatile S&)>(); @@ -248,5 +303,16 @@ int main() test_result_of<PMD(volatile S*), volatile char&> (); test_result_of<PMD(const volatile S&), const volatile char&> (); test_result_of<PMD(const volatile S*), const volatile char&> (); + test_result_of<PMD(SD&), char &>(); + test_result_of<PMD(SD const&), const char&>(); + test_result_of<PMD(SD*), char&>(); + test_result_of<PMD(const SD*), const char&>(); + test_result_of<PMD(std::unique_ptr<S>), char &>(); + test_result_of<PMD(std::unique_ptr<S const>), const char&>(); +#if TEST_STD_VER >= 11 + test_result_of<PMD(std::reference_wrapper<S>), char&>(); + test_result_of<PMD(std::reference_wrapper<S const>), const char&>(); +#endif + test_no_result<PMD(ND&)>(); } } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp index 6996cddc08b90..8cb5853bbc6d7 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp @@ -14,6 +14,8 @@ // result_of<Fn(ArgTypes...)> #include <type_traits> +#include <memory> +#include <utility> #include "test_macros.h" struct wat @@ -23,6 +25,8 @@ struct wat }; struct F {}; +struct FD : public F {}; +struct NotDerived {}; template <class T, class U> void test_result_of_imp() @@ -31,10 +35,15 @@ void test_result_of_imp() #if TEST_STD_VER > 11 static_assert((std::is_same<std::result_of_t<T>, U>::value), ""); #endif +#if TEST_STD_VER > 14 + static_assert(std::is_callable<T>::value, ""); + static_assert(std::is_callable<T, U>::value, ""); +#endif } int main() { + typedef NotDerived ND; { typedef char F::*PMD; test_result_of_imp<PMD(F &), char &>(); @@ -51,6 +60,31 @@ int main() test_result_of_imp<PMD(F const ), char &&>(); test_result_of_imp<PMD(F volatile ), char &&>(); test_result_of_imp<PMD(F const volatile ), char &&>(); + + test_result_of_imp<PMD(FD &), char &>(); + test_result_of_imp<PMD(FD const &), char const &>(); + test_result_of_imp<PMD(FD volatile &), char volatile &>(); + test_result_of_imp<PMD(FD const volatile &), char const volatile &>(); + + test_result_of_imp<PMD(FD &&), char &&>(); + test_result_of_imp<PMD(FD const &&), char const &&>(); + test_result_of_imp<PMD(FD volatile &&), char volatile &&>(); + test_result_of_imp<PMD(FD const volatile &&), char const volatile &&>(); + + test_result_of_imp<PMD(FD ), char &&>(); + test_result_of_imp<PMD(FD const ), char &&>(); + test_result_of_imp<PMD(FD volatile ), char &&>(); + test_result_of_imp<PMD(FD const volatile ), char &&>(); + + test_result_of_imp<PMD(std::unique_ptr<F>), char &>(); + test_result_of_imp<PMD(std::unique_ptr<F const>), const char &>(); + test_result_of_imp<PMD(std::unique_ptr<FD>), char &>(); + test_result_of_imp<PMD(std::unique_ptr<FD const>), const char &>(); + + test_result_of_imp<PMD(std::reference_wrapper<F>), char &>(); + test_result_of_imp<PMD(std::reference_wrapper<F const>), const char &>(); + test_result_of_imp<PMD(std::reference_wrapper<FD>), char &>(); + test_result_of_imp<PMD(std::reference_wrapper<FD const>), const char &>(); } { test_result_of_imp<int (F::* (F &)) () &, int> (); @@ -83,6 +117,42 @@ int main() test_result_of_imp<int (F::* (F volatile )) () const volatile &&, int> (); test_result_of_imp<int (F::* (F const volatile )) () const volatile &&, int> (); } + { + test_result_of_imp<int (F::* (FD &)) () &, int> (); + test_result_of_imp<int (F::* (FD &)) () const &, int> (); + test_result_of_imp<int (F::* (FD &)) () volatile &, int> (); + test_result_of_imp<int (F::* (FD &)) () const volatile &, int> (); + test_result_of_imp<int (F::* (FD const &)) () const &, int> (); + test_result_of_imp<int (F::* (FD const &)) () const volatile &, int> (); + test_result_of_imp<int (F::* (FD volatile &)) () volatile &, int> (); + test_result_of_imp<int (F::* (FD volatile &)) () const volatile &, int> (); + test_result_of_imp<int (F::* (FD const volatile &)) () const volatile &, int> (); + + test_result_of_imp<int (F::* (FD &&)) () &&, int> (); + test_result_of_imp<int (F::* (FD &&)) () const &&, int> (); + test_result_of_imp<int (F::* (FD &&)) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const &&)) () const &&, int> (); + test_result_of_imp<int (F::* (FD const &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile &&)) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const volatile &&)) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD )) () &&, int> (); + test_result_of_imp<int (F::* (FD )) () const &&, int> (); + test_result_of_imp<int (F::* (FD )) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD )) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const )) () const &&, int> (); + test_result_of_imp<int (F::* (FD const )) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile )) () volatile &&, int> (); + test_result_of_imp<int (F::* (FD volatile )) () const volatile &&, int> (); + test_result_of_imp<int (F::* (FD const volatile )) () const volatile &&, int> (); + } + { + test_result_of_imp<int (F::* (std::reference_wrapper<F>)) (), int>(); + test_result_of_imp<int (F::* (std::reference_wrapper<const F>)) () const, int>(); + test_result_of_imp<int (F::* (std::unique_ptr<F> )) (), int>(); + test_result_of_imp<int (F::* (std::unique_ptr<const F> )) () const, int>(); + } test_result_of_imp<decltype(&wat::foo)(wat), void>(); } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp index 728062b70684a..1d7b23c192225 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.pass.cpp @@ -14,6 +14,8 @@ #include <type_traits> #include <climits> +#include "test_macros.h" + enum E { V = INT_MIN }; enum F { W = UINT_MAX }; @@ -29,7 +31,7 @@ int main() static_assert((std::is_same<std::underlying_type_t<F>, unsigned>::value), ""); #endif -#if __has_feature(cxx_strong_enums) +#if TEST_STD_VER >= 11 enum G : char { }; static_assert((std::is_same<std::underlying_type<G>::type, char>::value), @@ -37,5 +39,5 @@ int main() #if _LIBCPP_STD_VER > 11 static_assert((std::is_same<std::underlying_type_t<G>, char>::value), ""); #endif -#endif // __has_feature(cxx_strong_enums) +#endif // TEST_STD_VER >= 11 } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp index 76d0f12d03fb5..51b3e5d736882 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ptr/add_pointer.pass.cpp @@ -10,18 +10,42 @@ // type_traits // add_pointer +// If T names a referenceable type or a (possibly cv-qualified) void type then +// the member typedef type shall name the same type as remove_reference_t<T>*; +// otherwise, type shall name T. #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_add_pointer() { static_assert((std::is_same<typename std::add_pointer<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_pointer_t<T>, U>::value), ""); #endif } +template <class F> +void test_function0() +{ + static_assert((std::is_same<typename std::add_pointer<F>::type, F*>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_pointer_t<F>, F*>::value), ""); +#endif +} + +template <class F> +void test_function1() +{ + static_assert((std::is_same<typename std::add_pointer<F>::type, F>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_pointer_t<F>, F>::value), ""); +#endif +} + +struct Foo {}; + int main() { test_add_pointer<void, void*>(); @@ -31,4 +55,26 @@ int main() test_add_pointer<const int&, const int*>(); test_add_pointer<int*, int**>(); test_add_pointer<const int*, const int**>(); + test_add_pointer<Foo, Foo*>(); + +// LWG 2101 specifically talks about add_pointer and functions. +// The term of art is "a referenceable type", which a cv- or ref-qualified function is not. + test_function0<void()>(); +#if TEST_STD_VER >= 11 + test_function1<void() const>(); + test_function1<void() &>(); + test_function1<void() &&>(); + test_function1<void() const &>(); + test_function1<void() const &&>(); +#endif + +// But a cv- or ref-qualified member function *is* "a referenceable type" + test_function0<void (Foo::*)()>(); +#if TEST_STD_VER >= 11 + test_function0<void (Foo::*)() const>(); + test_function0<void (Foo::*)() &>(); + test_function0<void (Foo::*)() &&>(); + test_function0<void (Foo::*)() const &>(); + test_function0<void (Foo::*)() const &&>(); +#endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp index 9cecd39049fc4..cccbb6011edf1 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ptr/remove_pointer.pass.cpp @@ -12,12 +12,13 @@ // remove_pointer #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_remove_pointer() { static_assert((std::is_same<typename std::remove_pointer<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::remove_pointer_t<T>, U>::value), ""); #endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp index fb53312cbe677..c82c282995355 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp @@ -10,14 +10,17 @@ // type_traits // add_lvalue_reference +// If T names a referenceable type then the member typedef type +// shall name T&; otherwise, type shall name T. #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_add_lvalue_reference() { static_assert((std::is_same<typename std::add_lvalue_reference<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_lvalue_reference_t<T>, U>::value), ""); #endif } @@ -26,7 +29,7 @@ template <class F> void test_function0() { static_assert((std::is_same<typename std::add_lvalue_reference<F>::type, F&>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_lvalue_reference_t<F>, F&>::value), ""); #endif } @@ -35,7 +38,7 @@ template <class F> void test_function1() { static_assert((std::is_same<typename std::add_lvalue_reference<F>::type, F>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_lvalue_reference_t<F>, F>::value), ""); #endif } @@ -51,20 +54,26 @@ int main() test_add_lvalue_reference<const int&, const int&>(); test_add_lvalue_reference<int*, int*&>(); test_add_lvalue_reference<const int*, const int*&>(); + test_add_lvalue_reference<Foo, Foo&>(); // LWG 2101 specifically talks about add_lvalue_reference and functions. // The term of art is "a referenceable type", which a cv- or ref-qualified function is not. test_function0<void()>(); -// test_function1<void() const>(); -// test_function1<void() &>(); -// test_function1<void() &&>(); -// test_function1<void() const &>(); -// test_function1<void() const &&>(); +#if TEST_STD_VER >= 11 + test_function1<void() const>(); + test_function1<void() &>(); + test_function1<void() &&>(); + test_function1<void() const &>(); + test_function1<void() const &&>(); +#endif +// But a cv- or ref-qualified member function *is* "a referenceable type" test_function0<void (Foo::*)()>(); +#if TEST_STD_VER >= 11 test_function0<void (Foo::*)() const>(); test_function0<void (Foo::*)() &>(); test_function0<void (Foo::*)() &&>(); test_function0<void (Foo::*)() const &>(); test_function0<void (Foo::*)() const &&>(); +#endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp index e8f08fdc398ad..fc147c37b1acc 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/add_rvalue_ref.pass.cpp @@ -10,8 +10,11 @@ // type_traits // add_rvalue_reference +// If T names a referenceable type then the member typedef type +// shall name T&&; otherwise, type shall name T. #include <type_traits> +#include "test_macros.h" #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -19,13 +22,32 @@ template <class T, class U> void test_add_rvalue_reference() { static_assert((std::is_same<typename std::add_rvalue_reference<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::add_rvalue_reference_t<T>, U>::value), ""); #endif } +template <class F> +void test_function0() +{ + static_assert((std::is_same<typename std::add_rvalue_reference<F>::type, F&&>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_rvalue_reference_t<F>, F&&>::value), ""); +#endif +} + +template <class F> +void test_function1() +{ + static_assert((std::is_same<typename std::add_rvalue_reference<F>::type, F>::value), ""); +#if TEST_STD_VER > 11 + static_assert((std::is_same<std::add_rvalue_reference_t<F>, F>::value), ""); +#endif +} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +struct Foo {}; + int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -36,5 +58,27 @@ int main() test_add_rvalue_reference<const int&, const int&>(); test_add_rvalue_reference<int*, int*&&>(); test_add_rvalue_reference<const int*, const int*&&>(); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + test_add_rvalue_reference<Foo, Foo&&>(); + +// LWG 2101 specifically talks about add_rvalue_reference and functions. +// The term of art is "a referenceable type", which a cv- or ref-qualified function is not. + test_function0<void()>(); +#if TEST_STD_VER >= 11 + test_function1<void() const>(); + test_function1<void() &>(); + test_function1<void() &&>(); + test_function1<void() const &>(); + test_function1<void() const &&>(); +#endif + +// But a cv- or ref-qualified member function *is* "a referenceable type" + test_function0<void (Foo::*)()>(); +#if TEST_STD_VER >= 11 + test_function0<void (Foo::*)() const>(); + test_function0<void (Foo::*)() &>(); + test_function0<void (Foo::*)() &&>(); + test_function0<void (Foo::*)() const &>(); + test_function0<void (Foo::*)() const &&>(); +#endif +#endif } diff --git a/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp index f9ebc37a5dd28..e335bd19ef2d3 100644 --- a/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp +++ b/test/std/utilities/meta/meta.trans/meta.trans.ref/remove_ref.pass.cpp @@ -12,12 +12,13 @@ // remove_reference #include <type_traits> +#include "test_macros.h" template <class T, class U> void test_remove_reference() { static_assert((std::is_same<typename std::remove_reference<T>::type, U>::value), ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert((std::is_same<std::remove_reference_t<T>, U>::value), ""); #endif } diff --git a/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp b/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp index ccec65fec3992..05ef99d0ebf4d 100644 --- a/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp +++ b/test/std/utilities/meta/meta.unary.prop.query/void_t.pass.cpp @@ -57,7 +57,7 @@ int main() test1<Class>(); test1<Class[]>(); test1<Class[5]>(); - + test2<void, int>(); test2<double, int>(); test2<int&, int>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp index f4dd356383af1..ef1fc4040dc75 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/array.pass.cpp @@ -12,12 +12,13 @@ // array #include <type_traits> +#include "test_macros.h" template <class T> void test_array_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -46,10 +47,15 @@ void test_array() typedef char array[3]; typedef const char const_array[3]; typedef char incomplete_array[]; +struct Incomplete; int main() { test_array<array>(); test_array<const_array>(); test_array<incomplete_array>(); + test_array<Incomplete[]>(); + +// LWG#2582 + static_assert(!std::is_array<Incomplete>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp index ac5d6e5923117..8c8510882bf6d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/class.pass.cpp @@ -12,12 +12,13 @@ // class #include <type_traits> +#include "test_macros.h" template <class T> void test_class_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -47,7 +48,13 @@ class Class { }; +struct incomplete_type; + int main() { test_class<Class>(); + test_class<incomplete_type>(); + +// LWG#2582 + static_assert( std::is_class<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp index 7c9c78fcf2b9d..40dea443cd41f 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/enum.pass.cpp @@ -12,12 +12,13 @@ // enum #include <type_traits> +#include "test_macros.h" template <class T> void test_enum_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -44,8 +45,12 @@ void test_enum() } enum Enum {zero, one}; +struct incomplete_type; int main() { test_enum<Enum>(); + +// LWG#2582 + static_assert(!std::is_enum<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp index 286644960315f..217bc7e25659d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/floating_point.pass.cpp @@ -12,12 +12,13 @@ // floating_point #include <type_traits> +#include "test_macros.h" template <class T> void test_floating_point_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -43,9 +44,14 @@ void test_floating_point() test_floating_point_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_floating_point<float>(); test_floating_point<double>(); test_floating_point<long double>(); + +// LWG#2582 + static_assert(!std::is_floating_point<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp index b1df4f2d3f4cc..3f21b9a7dbcfe 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/function.pass.cpp @@ -12,13 +12,14 @@ // function #include <type_traits> +#include "test_macros.h" using namespace std; class Class {}; enum Enum1 {}; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 enum class Enum2 : int {}; #else enum Enum2 {}; @@ -28,7 +29,7 @@ template <class T> void test() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -64,6 +65,7 @@ void test() test<__VA_ARGS__ volatile &&>(); \ test<__VA_ARGS__ const volatile &&>() +struct incomplete_type; int main() { @@ -75,7 +77,7 @@ int main() TEST_REGULAR( void (int, ...) ); TEST_REGULAR( int (double, ...) ); TEST_REGULAR( int (double, char, ...) ); -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 TEST_REF_QUALIFIED( void () ); TEST_REF_QUALIFIED( void (int) ); TEST_REF_QUALIFIED( int (double) ); @@ -85,4 +87,7 @@ int main() TEST_REF_QUALIFIED( int (double, ...) ); TEST_REF_QUALIFIED( int (double, char, ...) ); #endif + +// LWG#2582 + static_assert(!std::is_function<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp index f68ed3ef7e57e..a50beeb3e3106 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/integral.pass.cpp @@ -12,12 +12,13 @@ // integral #include <type_traits> +#include "test_macros.h" template <class T> void test_integral_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert( std::is_integral<T>::value, ""); @@ -43,6 +44,8 @@ void test_integral() test_integral_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_integral<bool>(); @@ -62,4 +65,7 @@ int main() test_integral<__int128_t>(); test_integral<__uint128_t>(); #endif + +// LWG#2582 + static_assert(!std::is_integral<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp index 72955defa3990..dfd09ac52bfa4 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_array.pass.cpp @@ -12,7 +12,7 @@ // is_array #include <type_traits> -#include <cstddef> // for std::nullptr_t +#include <cstddef> // for std::nullptr_t #include "test_macros.h" template <class T> @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -89,5 +90,5 @@ int main() test_is_not_array<Empty>(); test_is_not_array<bit_zero>(); test_is_not_array<NotEmpty>(); - test_is_not_array<Abstract>(); + test_is_not_array<incomplete_type>(); // LWG#2582 } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp index 97671e7b62e00..3c1a2181d2614 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_class.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -76,6 +77,7 @@ int main() test_is_class<bit_zero>(); test_is_class<NotEmpty>(); test_is_class<Abstract>(); + test_is_class<incomplete_type>(); #if TEST_STD_VER >= 11 // In C++03 we have an emulation of std::nullptr_t diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp index 481260ea6e524..2603bdff26d2d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_enum.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -90,4 +91,5 @@ int main() test_is_not_enum<NotEmpty>(); test_is_not_enum<Abstract>(); test_is_not_enum<FunctionPtr>(); + test_is_not_enum<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp index de9c146bcb4e2..7e19c0629672c 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_floating_point.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -98,4 +99,5 @@ int main() test_is_not_floating_point<Abstract>(); test_is_not_floating_point<Enum>(); test_is_not_floating_point<FunctionPtr>(); + test_is_not_floating_point<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp index 9a1d821b0746c..32e4f06beb04e 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_function.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -77,7 +78,7 @@ int main() test_is_function<int(int, double)>(); test_is_function<int(Abstract *)>(); test_is_function<void(...)>(); - + test_is_not_function<std::nullptr_t>(); test_is_not_function<void>(); test_is_not_function<int>(); @@ -95,4 +96,5 @@ int main() test_is_not_function<NotEmpty>(); test_is_not_function<Abstract>(); test_is_not_function<Abstract*>(); + test_is_not_function<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp index 86b63c53da54d..09997626ea06d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_integral.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -101,4 +102,5 @@ int main() test_is_not_integral<bit_zero>(); test_is_not_integral<NotEmpty>(); test_is_not_integral<Abstract>(); + test_is_not_integral<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp index 0e59f7153f506..41b8d44b93158 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_lvalue_reference.pass.cpp @@ -69,6 +69,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -92,4 +93,5 @@ int main() test_is_not_lvalue_reference<bit_zero>(); test_is_not_lvalue_reference<NotEmpty>(); test_is_not_lvalue_reference<Abstract>(); + test_is_not_lvalue_reference<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp index 8da411d2eeed6..9498edc652abf 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_object_pointer.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -94,4 +95,5 @@ int main() test_is_not_member_object_pointer<bit_zero>(); test_is_not_member_object_pointer<NotEmpty>(); test_is_not_member_object_pointer<Abstract>(); + test_is_not_member_object_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp index 19a74b01d0fdc..d4043f48f98ed 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_member_pointer.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -95,4 +96,5 @@ int main() test_is_not_member_pointer<bit_zero>(); test_is_not_member_pointer<NotEmpty>(); test_is_not_member_pointer<Abstract>(); + test_is_not_member_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp index 80f563e8969e3..f575763300a70 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_null_pointer.pass.cpp @@ -69,6 +69,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -92,4 +93,5 @@ int main() test_is_not_null_pointer<bit_zero>(); test_is_not_null_pointer<NotEmpty>(); test_is_not_null_pointer<Abstract>(); + test_is_not_null_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp index a901aed1143e2..257719eb940ee 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_pointer.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -91,4 +92,5 @@ int main() test_is_not_pointer<bit_zero>(); test_is_not_pointer<NotEmpty>(); test_is_not_pointer<Abstract>(); + test_is_not_pointer<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp index b7b52687018a0..89639377ce81a 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_rvalue_reference.pass.cpp @@ -69,6 +69,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -92,4 +93,5 @@ int main() test_is_not_rvalue_reference<bit_zero>(); test_is_not_rvalue_reference<NotEmpty>(); test_is_not_rvalue_reference<Abstract>(); + test_is_not_rvalue_reference<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp index 307fedb32b269..415d9a7813dd2 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_union.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -90,4 +91,5 @@ int main() test_is_not_union<bit_zero>(); test_is_not_union<NotEmpty>(); test_is_not_union<Abstract>(); + test_is_not_union<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp index 1647666adf2e2..952a5b748f532 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/is_void.pass.cpp @@ -67,6 +67,7 @@ class Abstract }; enum Enum {zero, one}; +struct incomplete_type; typedef void (*FunctionPtr)(); @@ -89,4 +90,5 @@ int main() test_is_not_void<Abstract>(); test_is_not_void<Enum>(); test_is_not_void<FunctionPtr>(); + test_is_not_void<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp index 3b6ccade7e742..13cad58c0ef3f 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/lvalue_ref.pass.cpp @@ -34,8 +34,13 @@ void test_lvalue_ref() static_assert(!std::is_function<T>::value, ""); } +struct incomplete_type; + int main() { test_lvalue_ref<int&>(); test_lvalue_ref<const int&>(); + +// LWG#2582 + static_assert(!std::is_lvalue_reference<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp index 6f546efdf51e1..a895a8d447b66 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp @@ -48,6 +48,8 @@ class Class { }; +struct incomplete_type; + int main() { test_member_function_pointer<void (Class::*)()>(); @@ -133,4 +135,7 @@ int main() test_member_function_pointer<void (Class::*)(int,...) const volatile &&>(); test_member_function_pointer<void (Class::*)(int, char,...) const volatile &&>(); #endif + +// LWG#2582 + static_assert(!std::is_member_function_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp index e13e58632a325..b0edea37e8e89 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer_no_variadics.pass.cpp @@ -48,6 +48,8 @@ class Class { }; +struct incomplete_type; + int main() { test_member_function_pointer<void (Class::*)()>(); @@ -73,4 +75,7 @@ int main() test_member_function_pointer<void (Class::*)(...) volatile>(); test_member_function_pointer<void (Class::*)(int, ...) volatile>(); test_member_function_pointer<void (Class::*)(int, char, ...) volatile>(); + +// LWG#2582 + static_assert(!std::is_member_function_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp index 4e6699cc3e7c0..76deef4291e71 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_object_pointer.pass.cpp @@ -12,12 +12,13 @@ // member_object_pointer #include <type_traits> +#include "test_macros.h" template <class T> void test_member_object_pointer_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -47,7 +48,12 @@ class Class { }; +struct incomplete_type; + int main() { test_member_object_pointer<int Class::*>(); + +// LWG#2582 + static_assert(!std::is_member_object_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp index 1c7a32fc9dc97..076204c9c094e 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp @@ -14,8 +14,9 @@ #include <type_traits> #include <cstddef> // for std::nullptr_t +#include "test_macros.h" -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 template <class T> void test_nullptr_imp() { @@ -44,9 +45,14 @@ void test_nullptr() test_nullptr_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_nullptr<std::nullptr_t>(); + +// LWG#2582 + static_assert(!std::is_null_pointer<incomplete_type>::value, ""); } #else int main() {} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp index 7073c106b44b7..f9c83c67d2195 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/pointer.pass.cpp @@ -12,12 +12,14 @@ // pointer #include <type_traits> +#include "test_macros.h" + template <class T> void test_pointer_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -43,10 +45,15 @@ void test_pointer() test_pointer_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_pointer<void*>(); test_pointer<int*>(); test_pointer<const int*>(); test_pointer<void (*)(int)>(); + +// LWG#2582 + static_assert(!std::is_pointer<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp index 7964424036348..99fd2887981f9 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/rvalue_ref.pass.cpp @@ -12,12 +12,13 @@ // rvalue_ref #include <type_traits> +#include "test_macros.h" template <class T> void test_rvalue_ref() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -34,10 +35,15 @@ void test_rvalue_ref() static_assert(!std::is_function<T>::value, ""); } +struct incomplete_type; + int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES test_rvalue_ref<int&&>(); test_rvalue_ref<const int&&>(); + +// LWG#2582 + static_assert(!std::is_rvalue_reference<incomplete_type>::value, ""); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp index 6cabb717c0c68..36ad00400d359 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/union.pass.cpp @@ -12,12 +12,13 @@ // union #include <type_traits> +#include "test_macros.h" template <class T> void test_union_imp() { static_assert(!std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -49,7 +50,12 @@ union Union double __; }; +struct incomplete_type; + int main() { test_union<Union>(); + +// LWG#2582 + static_assert(!std::is_union<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp index f20bcf87ea150..c7597eb4eaf77 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/void.pass.cpp @@ -12,12 +12,13 @@ // void #include <type_traits> +#include "test_macros.h" template <class T> void test_void_imp() { static_assert( std::is_void<T>::value, ""); -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 static_assert(!std::is_null_pointer<T>::value, ""); #endif static_assert(!std::is_integral<T>::value, ""); @@ -43,7 +44,12 @@ void test_void() test_void_imp<const volatile T>(); } +struct incomplete_type; + int main() { test_void<void>(); + +// LWG#2582 + static_assert(!std::is_void<incomplete_type>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp index 3476d5ceea2ba..f601bd12cadbd 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/array.pass.cpp @@ -38,9 +38,12 @@ typedef char array[3]; typedef const char const_array[3]; typedef char incomplete_array[]; +class incomplete_type; + int main() { test_array<array>(); test_array<const_array>(); test_array<incomplete_array>(); + test_array<incomplete_type[]>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp index 49e41380ca273..5fa5da12aef8a 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/class.pass.cpp @@ -38,7 +38,10 @@ class Class { }; +class incomplete_type; + int main() { test_class<Class>(); + test_class<incomplete_type>(); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp index a3f18d52a7067..02c539712c653 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_arithmetic.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_arithmetic() #endif } +class incomplete_type; + class Empty { }; @@ -98,6 +100,7 @@ int main() test_is_not_arithmetic<Enum>(); test_is_not_arithmetic<FunctionPtr>(); test_is_not_arithmetic<Empty>(); + test_is_not_arithmetic<incomplete_type>(); test_is_not_arithmetic<bit_zero>(); test_is_not_arithmetic<NotEmpty>(); test_is_not_arithmetic<Abstract>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp index 6a1798ab5adc2..d8d5162c1a02b 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_compound.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_compound() #endif } +class incomplete_type; + class Empty { }; @@ -81,6 +83,7 @@ int main() test_is_compound<int&&>(); test_is_compound<Union>(); test_is_compound<Empty>(); + test_is_compound<incomplete_type>(); test_is_compound<bit_zero>(); test_is_compound<int*>(); test_is_compound<const int*>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp index e16337e05f1ce..f776196dd7a98 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_fundamental.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_fundamental() #endif } +class incomplete_type; + class Empty { }; @@ -94,7 +96,7 @@ int main() test_is_fundamental<long double>(); test_is_fundamental<char16_t>(); test_is_fundamental<char32_t>(); - + test_is_not_fundamental<char[3]>(); test_is_not_fundamental<char[]>(); test_is_not_fundamental<void *>(); @@ -103,6 +105,7 @@ int main() test_is_not_fundamental<int&&>(); test_is_not_fundamental<Union>(); test_is_not_fundamental<Empty>(); + test_is_not_fundamental<incomplete_type>(); test_is_not_fundamental<bit_zero>(); test_is_not_fundamental<int*>(); test_is_not_fundamental<const int*>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp index 890da659e2180..c2804885ac50b 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_member_pointer.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_member_pointer() #endif } +class incomplete_type; + class Empty { }; @@ -73,9 +75,9 @@ typedef void (*FunctionPtr)(); int main() { -// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), -// std::nullptr_t, and cv-qualified versions of these types (3.9.3) -// are collectively called scalar types. +// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), +// std::nullptr_t, and cv-qualified versions of these types (3.9.3) +// are collectively called scalar types. test_is_member_pointer<int Empty::*>(); test_is_member_pointer<void (Empty::*)(int)>(); @@ -93,6 +95,7 @@ int main() test_is_not_member_pointer<char[]>(); test_is_not_member_pointer<Union>(); test_is_not_member_pointer<Empty>(); + test_is_not_member_pointer<incomplete_type>(); test_is_not_member_pointer<bit_zero>(); test_is_not_member_pointer<NotEmpty>(); test_is_not_member_pointer<Abstract>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp index ff7dda30d111c..311215b816438 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_object.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_object() #endif } +class incomplete_type; + class Empty { }; @@ -73,7 +75,7 @@ typedef void (*FunctionPtr)(); int main() { -// An object type is a (possibly cv-qualified) type that is not a function type, +// An object type is a (possibly cv-qualified) type that is not a function type, // not a reference type, and not a void type. test_is_object<std::nullptr_t>(); @@ -86,8 +88,8 @@ int main() test_is_object<int*>(); test_is_object<const int*>(); test_is_object<Enum>(); - test_is_object<Empty>(); - test_is_object<bit_zero>(); + test_is_object<incomplete_type>(); + test_is_object<bit_zero>(); test_is_object<NotEmpty>(); test_is_object<Abstract>(); test_is_object<FunctionPtr>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp index e56c8f7618147..b546458bdcb82 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_reference.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_reference() #endif } +class incomplete_type; + class Empty { }; @@ -87,6 +89,7 @@ int main() test_is_not_reference<void *>(); test_is_not_reference<FunctionPtr>(); test_is_not_reference<Union>(); + test_is_not_reference<incomplete_type>(); test_is_not_reference<Empty>(); test_is_not_reference<bit_zero>(); test_is_not_reference<int*>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp index 2b412a68833bf..39ac07ad4bc51 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.comp/is_scalar.pass.cpp @@ -45,6 +45,8 @@ void test_is_not_scalar() #endif } +class incomplete_type; + class Empty { }; @@ -73,9 +75,9 @@ typedef void (*FunctionPtr)(); int main() { -// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), -// std::nullptr_t, and cv-qualified versions of these types (3.9.3) -// are collectively called scalar types. +// Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), +// std::nullptr_t, and cv-qualified versions of these types (3.9.3) +// are collectively called scalar types. test_is_scalar<std::nullptr_t>(); test_is_scalar<short>(); @@ -104,6 +106,7 @@ int main() test_is_not_scalar<char[]>(); test_is_not_scalar<Union>(); test_is_not_scalar<Empty>(); + test_is_not_scalar<incomplete_type>(); test_is_not_scalar<bit_zero>(); test_is_not_scalar<NotEmpty>(); test_is_not_scalar<Abstract>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp deleted file mode 100644 index 1c715e04970c7..0000000000000 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// type_traits - -// extension - -// template <typename _Tp> struct __has_operator_addressof - - -#include <type_traits> - -#ifndef _LIBCPP_HAS_NO_CONSTEXPR - -struct A -{ -}; - -struct B -{ - constexpr B* operator&() const; -}; - -struct D; - -struct C -{ - template <class U> - D operator,(U&&); -}; - -struct E -{ - constexpr C operator&() const; -}; - -struct F {}; -constexpr F* operator&(F const &) { return nullptr; } - -struct G {}; -constexpr G* operator&(G &&) { return nullptr; } - -struct H {}; -constexpr H* operator&(H const &&) { return nullptr; } - -struct J -{ - constexpr J* operator&() const &&; -}; - -#endif // _LIBCPP_HAS_NO_CONSTEXPR - -int main() -{ -#ifndef _LIBCPP_HAS_NO_CONSTEXPR - static_assert(std::__has_operator_addressof<int>::value == false, ""); - static_assert(std::__has_operator_addressof<A>::value == false, ""); - static_assert(std::__has_operator_addressof<B>::value == true, ""); - static_assert(std::__has_operator_addressof<E>::value == true, ""); - static_assert(std::__has_operator_addressof<F>::value == true, ""); - static_assert(std::__has_operator_addressof<G>::value == true, ""); - static_assert(std::__has_operator_addressof<H>::value == true, ""); - static_assert(std::__has_operator_addressof<J>::value == true, ""); -#endif // _LIBCPP_HAS_NO_CONSTEXPR -} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp index 36020139ec586..7330f4b351258 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp @@ -13,6 +13,8 @@ #include <type_traits> +#include "test_macros.h" + template <class T> void test_has_virtual_destructor() { diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp index c0f6bb9bdfafc..b734a1aa60d86 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp @@ -77,7 +77,7 @@ int main() test_is_not_assignable<void, const void> (); test_is_not_assignable<const void, const void> (); test_is_not_assignable<int(), int> (); - + // pointer to incomplete template type test_is_assignable<X<D>*&, X<D>*> (); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp index 7f63ae40aca78..616f25180a600 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp @@ -29,6 +29,8 @@ void test_is_const() #endif } +struct A; // incomplete + int main() { test_is_const<void>(); @@ -39,6 +41,8 @@ int main() test_is_const<char[3]>(); test_is_const<char[]>(); + test_is_const<A>(); + static_assert(!std::is_const<int&>::value, ""); static_assert(!std::is_const<const int&>::value, ""); } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp index 5401d95532b1d..9f8fdc7fc6357 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_constructible.pass.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// // type_traits +// XFAIL: apple-clang-6.0 +// The Apple-6 compiler gets is_constructible<void ()> wrong. // template <class T, class... Args> // struct is_constructible; @@ -19,7 +21,7 @@ struct A { explicit A(int); A(int, double); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 private: #endif A(char); @@ -89,7 +91,7 @@ int main() test_is_constructible<int&, int&> (); test_is_not_constructible<A> (); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_constructible<A, char> (); #else test_is_constructible<A, char> (); @@ -99,4 +101,13 @@ int main() test_is_not_constructible<int&> (); test_is_not_constructible<Abstract> (); test_is_not_constructible<AbstractDestructor> (); + +// LWG 2560 -- postpone this test until bots updated +// test_is_not_constructible<void()> (); +#if TEST_STD_VER > 11 +// test_is_not_constructible<void() const> (); +// test_is_not_constructible<void() volatile> (); +// test_is_not_constructible<void() &> (); +// test_is_not_constructible<void() &&> (); +#endif } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp index 421f865a623c4..ac8b80bbd3a4d 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp @@ -79,7 +79,7 @@ int main() test_is_not_copy_assignable<int[]> (); test_is_not_copy_assignable<int[3]> (); #endif -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_copy_assignable<B> (); #endif test_is_not_copy_assignable<void> (); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp index fe2e01429b22b..684d85d3d40ce 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp @@ -89,7 +89,7 @@ int main() test_is_not_copy_constructible<void>(); test_is_not_copy_constructible<Abstract>(); test_is_not_copy_constructible<C>(); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_copy_constructible<B>(); #endif } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp index 7b46eeaab66b9..318147e5d4a34 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_default_constructible.pass.cpp @@ -100,7 +100,7 @@ int main() test_is_not_default_constructible<char[]>(); test_is_not_default_constructible<Abstract>(); test_is_not_default_constructible<NoDefaultConstructor>(); -#if __has_feature(cxx_access_control_sfinae) +#if TEST_STD_VER >= 11 test_is_not_default_constructible<B>(); #endif } diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp index 60d607aba61c3..5e8bfeaa41d28 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp @@ -11,9 +11,15 @@ // is_destructible +// Prevent warning when testing the Abstract test type. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + #include <type_traits> #include "test_macros.h" + template <class T> void test_is_destructible() { diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp index baf85e3e81395..5a440598bb020 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_final.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // type_traits // is_final @@ -14,8 +15,6 @@ #include <type_traits> #include "test_macros.h" -#if _LIBCPP_STD_VER > 11 - struct P final { }; union U1 { }; union U2 final { }; @@ -54,13 +53,10 @@ int main () { test_is_not_final<int>(); test_is_not_final<int*>(); - test_is_final <P>(); - test_is_not_final<P*>(); + test_is_final <P>(); + test_is_not_final<P*>(); test_is_not_final<U1>(); test_is_not_final<U1*>(); - test_is_final <U2>(); - test_is_not_final<U2*>(); + test_is_final <U2>(); + test_is_not_final<U2*>(); } -#else -int main () {} -#endif diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp index c778a5d24b2e6..8200b468fe3a4 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp @@ -107,7 +107,7 @@ int main() #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES test_is_nothrow_constructible<Tuple &&, Empty> (); // See bug #19616. #endif - + test_is_not_nothrow_constructible<A, int> (); test_is_not_nothrow_constructible<A, int, double> (); test_is_not_nothrow_constructible<A> (); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp index 42c9807efa833..58e0e0f98b580 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp @@ -11,6 +11,11 @@ // is_nothrow_destructible +// Prevent warning when testing the Abstract test type. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp new file mode 100644 index 0000000000000..7510b4e7293c9 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// type_traits + +// is_swappable + +#include <type_traits> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +// Make the test types non-copyable so that generic std::swap is not valid. +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +void swap(A&, A&) noexcept {} +void swap(B&, B&) {} + +struct M { + M(M const&) = delete; + M& operator=(M const&) = delete; +}; + +void swap(M&&, M&&) noexcept {} + +struct ThrowingMove { + ThrowingMove(ThrowingMove&&) {} + ThrowingMove& operator=(ThrowingMove&&) { return *this; } +}; + +} // namespace MyNS + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable applies an lvalue reference to the type. + static_assert(std::is_nothrow_swappable<int>::value, ""); + static_assert(std::is_nothrow_swappable<int&>::value, ""); + static_assert(!std::is_nothrow_swappable<M>::value, ""); + static_assert(!std::is_nothrow_swappable<M&&>::value, ""); + } + { + // Test that it correctly deduces the noexcept of swap. + static_assert(std::is_nothrow_swappable<A>::value, ""); + static_assert(!std::is_nothrow_swappable<B>::value + && std::is_swappable<B>::value, ""); + static_assert(!std::is_nothrow_swappable<ThrowingMove>::value + && std::is_swappable<ThrowingMove>::value, ""); + } + { + // Test that it doesn't drop the qualifiers + static_assert(!std::is_nothrow_swappable<const A>::value, ""); + } + { + // test non-referenceable types + static_assert(!std::is_nothrow_swappable<void>::value, ""); + static_assert(!std::is_nothrow_swappable<int() const>::value, ""); + static_assert(!std::is_nothrow_swappable<int(int, ...) const &>::value, ""); + } + { + // test for presence of is_nothrow_swappable_v + static_assert(std::is_nothrow_swappable_v<int>, ""); + static_assert(!std::is_nothrow_swappable_v<void>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp new file mode 100644 index 0000000000000..408231f6057f8 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// type_traits + +// is_nothrow_swappable_with + +#include <type_traits> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +struct C {}; +struct D {}; + +void swap(A&, A&) {} + +void swap(A&, B&) noexcept {} +void swap(B&, A&) noexcept {} + +void swap(A&, C&) noexcept {} +void swap(C&, A&) {} + +struct M {}; + +void swap(M&&, M&&) noexcept {} + +} // namespace MyNS + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable_with doesn't apply an lvalue reference + // to the type. Instead it is up to the user. + static_assert(!std::is_nothrow_swappable_with<int, int>::value, ""); + static_assert(std::is_nothrow_swappable_with<int&, int&>::value, ""); + static_assert(std::is_nothrow_swappable_with<M, M>::value, ""); + static_assert(std::is_swappable_with<A&, A&>::value && + !std::is_nothrow_swappable_with<A&, A&>::value, ""); + } + { + // test that hetrogenius swap is allowed only if both 'swap(A, B)' and + // 'swap(B, A)' are valid. + static_assert(std::is_nothrow_swappable_with<A&, B&>::value, ""); + static_assert(!std::is_nothrow_swappable_with<A&, C&>::value && + std::is_swappable_with<A&, C&>::value, ""); + static_assert(!std::is_nothrow_swappable_with<D&, C&>::value, ""); + } + { + // test we guard against cv void inputs as required. + static_assert(!std::is_nothrow_swappable_with_v<void, int>, ""); + static_assert(!std::is_nothrow_swappable_with_v<int, void>, ""); + static_assert(!std::is_nothrow_swappable_with_v<const void, const volatile void>, ""); + + } + { + // test for presence of is_nothrow_swappable_with_v + static_assert(std::is_nothrow_swappable_with_v<int&, int&>, ""); + static_assert(!std::is_nothrow_swappable_with_v<int&&, int&&>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp index b66e7a296f39a..6ce1c03775262 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp @@ -65,7 +65,7 @@ class Abstract virtual ~Abstract() = 0; }; -#if __has_feature(cxx_attributes) +#if TEST_STD_VER >= 11 class Final final { }; #else diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp index 94bf7fb580412..745efd00895c8 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp @@ -50,6 +50,8 @@ public: ~Class(); }; +struct A; // incomplete + int main() { test_is_not_signed<void>(); @@ -61,6 +63,7 @@ int main() test_is_not_signed<char[]>(); test_is_not_signed<bool>(); test_is_not_signed<unsigned>(); + test_is_not_signed<A>(); test_is_signed<int>(); test_is_signed<double>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp new file mode 100644 index 0000000000000..b17ca76fd5869 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// type_traits + +// is_swappable + +#include <type_traits> +#include <utility> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +// Make the test types non-copyable so that generic std::swap is not valid. +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +struct C {}; +struct D {}; + +void swap(A&, A&) {} + +void swap(A&, B&) {} +void swap(B&, A&) {} + +void swap(A&, C&) {} // missing swap(C, A) +void swap(D&, C&) {} + +struct M { + M(M const&) = delete; + M& operator=(M const&) = delete; +}; + +void swap(M&&, M&&) {} + +struct DeletedSwap { + friend void swap(DeletedSwap&, DeletedSwap&) = delete; +}; + +} // namespace MyNS + +namespace MyNS2 { + +struct AmbiguousSwap {}; + +template <class T> +void swap(T&, T&) {} + +} // end namespace MyNS2 + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable applies an lvalue reference to the type. + static_assert(std::is_swappable<A>::value, ""); + static_assert(std::is_swappable<A&>::value, ""); + static_assert(!std::is_swappable<M>::value, ""); + static_assert(!std::is_swappable<M&&>::value, ""); + } + static_assert(!std::is_swappable<B>::value, ""); + static_assert(std::is_swappable<C>::value, ""); + { + // test non-referencable types + static_assert(!std::is_swappable<void>::value, ""); + static_assert(!std::is_swappable<int() const>::value, ""); + static_assert(!std::is_swappable<int() &>::value, ""); + } + { + // test that a deleted swap is correctly handled. + static_assert(!std::is_swappable<DeletedSwap>::value, ""); + } + { + // test that a swap with ambiguous overloads is handled correctly. + static_assert(!std::is_swappable<MyNS2::AmbiguousSwap>::value, ""); + } + { + // test for presence of is_swappable_v + static_assert(std::is_swappable_v<int>, ""); + static_assert(!std::is_swappable_v<M>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp new file mode 100644 index 0000000000000..c3ae1706f0950 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// type_traits + +// is_swappable + +// IMPORTANT: The include order is part of the test. We want to pick up +// the following definitions in this order: +// 1) is_swappable, is_nothrow_swappable +// 2) iter_swap, swap_ranges +// 3) swap(T (&)[N], T (&)[N]) +// This test checks that (1) and (2) see forward declarations +// for (3). +#include <type_traits> +#include <algorithm> +#include <utility> + +#include "test_macros.h" + +int main() +{ + // Use a builtin type so we don't get ADL lookup. + typedef double T[17][29]; + { + LIBCPP_STATIC_ASSERT(std::__is_swappable<T>::value, ""); +#if TEST_STD_VER > 14 + static_assert(std::is_swappable_v<T>, ""); +#endif + } + { + T t1 = {}; + T t2 = {}; + std::iter_swap(t1, t2); + std::swap_ranges(t1, t1 + 17, t2); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp new file mode 100644 index 0000000000000..a049eab9a1923 --- /dev/null +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// type_traits + +// is_swappable_with + +#include <type_traits> +#include <vector> +#include "test_macros.h" + +namespace MyNS { + +struct A { + A(A const&) = delete; + A& operator=(A const&) = delete; +}; + +struct B { + B(B const&) = delete; + B& operator=(B const&) = delete; +}; + +struct C {}; +struct D {}; + +void swap(A&, A&) {} + +void swap(A&, B&) {} +void swap(B&, A&) {} + +void swap(A&, C&) {} // missing swap(C, A) +void swap(D&, C&) {} + +struct M {}; + +void swap(M&&, M&&) {} + +} // namespace MyNS + +int main() +{ + using namespace MyNS; + { + // Test that is_swappable_with doesn't apply an lvalue reference + // to the type. Instead it is up to the user. + static_assert(!std::is_swappable_with<int, int>::value, ""); + static_assert(std::is_swappable_with<int&, int&>::value, ""); + static_assert(std::is_swappable_with<M, M>::value, ""); + static_assert(std::is_swappable_with<A&, A&>::value, ""); + } + { + // test that heterogeneous swap is allowed only if both 'swap(A, B)' and + // 'swap(B, A)' are valid. + static_assert(std::is_swappable_with<A&, B&>::value, ""); + static_assert(!std::is_swappable_with<A&, C&>::value, ""); + static_assert(!std::is_swappable_with<D&, C&>::value, ""); + } + { + // test that cv void is guarded against as required. + static_assert(!std::is_swappable_with_v<void, int>, ""); + static_assert(!std::is_swappable_with_v<int, void>, ""); + static_assert(!std::is_swappable_with_v<const void, const volatile void>, ""); + } + { + // test for presence of is_swappable_with_v + static_assert(std::is_swappable_with_v<int&, int&>, ""); + static_assert(!std::is_swappable_with_v<D&, C&>, ""); + } +} diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp index 3ebb9dba429d0..a9b538b2dffc7 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_assignable +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp index 25429f5470e7b..966573c9f0fe5 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_assignable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_copy_assignable +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp index 9556959e12621..2922f22766696 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copy_constructible.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_copy_constructible +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp index c19a29ffb5869..42ecdb3b896a8 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_copyable +// XFAIL: gcc-4.9 + #include <type_traits> #include <cassert> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp index 9e2507067d2d3..3372e615d71de 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp @@ -11,6 +11,11 @@ // is_trivially_destructible +// Prevent warning when testing the Abstract test type. +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp index eca596ee1c19e..9a27c73cdfd8b 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_assignable.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_move_assignable +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp index 313da175f7156..941ff31f89da8 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_move_constructible.pass.cpp @@ -11,6 +11,8 @@ // is_trivially_move_constructible +// XFAIL: gcc-4.9 + #include <type_traits> #include "test_macros.h" @@ -60,7 +62,7 @@ struct A A(const A&); }; -#if __has_feature(cxx_defaulted_functions) +#if TEST_STD_VER >= 11 struct MoveOnly1 { @@ -89,7 +91,7 @@ int main() test_is_trivially_move_constructible<const int*>(); test_is_trivially_move_constructible<bit_zero>(); -#if __has_feature(cxx_defaulted_functions) +#if TEST_STD_VER >= 11 static_assert(!std::is_trivially_move_constructible<MoveOnly1>::value, ""); static_assert( std::is_trivially_move_constructible<MoveOnly2>::value, ""); #endif diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp index 9ca42432df169..376c7e005ce9e 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp @@ -50,6 +50,8 @@ public: ~Class(); }; +struct A; // incomplete + int main() { test_is_not_unsigned<void>(); @@ -61,6 +63,7 @@ int main() test_is_not_unsigned<char[]>(); test_is_not_unsigned<int>(); test_is_not_unsigned<double>(); + test_is_not_unsigned<A>(); test_is_unsigned<bool>(); test_is_unsigned<unsigned>(); diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp index 36697a3f3eba0..cc8d66ae6888c 100644 --- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp +++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp @@ -29,6 +29,8 @@ void test_is_volatile() #endif } +struct A; // incomplete + int main() { test_is_volatile<void>(); @@ -39,6 +41,8 @@ int main() test_is_volatile<char[3]>(); test_is_volatile<char[]>(); + test_is_volatile<A>(); + static_assert(!std::is_volatile<int&>::value, ""); static_assert(!std::is_volatile<volatile int&>::value, ""); } diff --git a/test/std/utilities/meta/version.pass.cpp b/test/std/utilities/meta/version.pass.cpp deleted file mode 100644 index 3a1033bbb5605..0000000000000 --- a/test/std/utilities/meta/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <type_traits> - -#include <type_traits> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/utilities/ratio/version.pass.cpp b/test/std/utilities/ratio/version.pass.cpp deleted file mode 100644 index 26c455fb0a9ab..0000000000000 --- a/test/std/utilities/ratio/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <ratio> - -#include <ratio> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp index 9411435e29e87..ab623bb01f789 100644 --- a/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // template <class charT> // explicit bitset(const charT* str, // typename basic_string<charT>::size_type n = basic_string<charT>::npos, @@ -18,20 +17,19 @@ #include <algorithm> // for 'min' and 'max' #include <stdexcept> // for 'invalid_argument' -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_char_pointer_ctor() { { - try - { - std::bitset<N> v("xxx1010101010xxxx"); - assert(false); - } - catch (std::invalid_argument&) - { - } +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + std::bitset<N> v("xxx1010101010xxxx"); + assert(false); + } + catch (std::invalid_argument&) {} +#endif } { diff --git a/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp index bd5ca7e08b2ab..f4f8d390de08f 100644 --- a/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp @@ -12,19 +12,26 @@ #include <bitset> #include <cassert> -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_default_ctor() { { - _LIBCPP_CONSTEXPR std::bitset<N> v1; - assert(v1.size() == N); - for (std::size_t i = 0; i < N; ++i) - assert(v1[i] == false); + TEST_CONSTEXPR std::bitset<N> v1; + assert(v1.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v1[i] == false); } +#if TEST_STD_VER >= 11 + { + constexpr std::bitset<N> v1; + static_assert(v1.size() == N, ""); + } +#endif } + int main() { test_default_ctor<0>(); diff --git a/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp index b08720f57ee36..0e4793027c989 100644 --- a/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// XFAIL: libcpp-no-exceptions // test bitset(string, pos, n, zero, one); #include <bitset> @@ -15,65 +14,60 @@ #include <algorithm> // for 'min' and 'max' #include <stdexcept> // for 'invalid_argument' -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_string_ctor() { +#ifndef TEST_HAS_NO_EXCEPTIONS { - try - { - std::string str("xxx1010101010xxxx"); - std::bitset<N> v(str, str.size()+1, 10); - assert(false); - } - catch (std::out_of_range&) - { - } + try { + std::string str("xxx1010101010xxxx"); + std::bitset<N> v(str, str.size()+1, 10); + assert(false); + } + catch (std::out_of_range&) + { + } } - - { - try { - std::string str("xxx1010101010xxxx"); - std::bitset<N> v(str, 2, 10); - assert(false); + try { + std::string str("xxx1010101010xxxx"); + std::bitset<N> v(str, 2, 10); + assert(false); + } + catch (std::invalid_argument&) + { + } } - catch (std::invalid_argument&) { + try { + std::string str("xxxbababababaxxxx"); + std::bitset<N> v(str, 2, 10, 'a', 'b'); + assert(false); + } + catch (std::invalid_argument&) + { + } } - } - +#endif // TEST_HAS_NO_EXCEPTIONS { - std::string str("xxx1010101010xxxx"); - std::bitset<N> v(str, 3, 10); - std::size_t M = std::min<std::size_t>(N, 10); - for (std::size_t i = 0; i < M; ++i) - assert(v[i] == (str[3 + M - 1 - i] == '1')); - for (std::size_t i = 10; i < N; ++i) - assert(v[i] == false); + std::string str("xxx1010101010xxxx"); + std::bitset<N> v(str, 3, 10); + std::size_t M = std::min<std::size_t>(N, 10); + for (std::size_t i = 0; i < M; ++i) + assert(v[i] == (str[3 + M - 1 - i] == '1')); + for (std::size_t i = 10; i < N; ++i) + assert(v[i] == false); } - - { - try { std::string str("xxxbababababaxxxx"); - std::bitset<N> v(str, 2, 10, 'a', 'b'); - assert(false); - } - catch (std::invalid_argument&) - { - } - } - - { - std::string str("xxxbababababaxxxx"); - std::bitset<N> v(str, 3, 10, 'a', 'b'); - std::size_t M = std::min<std::size_t>(N, 10); - for (std::size_t i = 0; i < M; ++i) - assert(v[i] == (str[3 + M - 1 - i] == 'b')); - for (std::size_t i = 10; i < N; ++i) - assert(v[i] == false); + std::bitset<N> v(str, 3, 10, 'a', 'b'); + std::size_t M = std::min<std::size_t>(N, 10); + for (std::size_t i = 0; i < M; ++i) + assert(v[i] == (str[3 + M - 1 - i] == 'b')); + for (std::size_t i = 10; i < N; ++i) + assert(v[i] == false); } } diff --git a/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp index f232447e08c3a..1b121c5fb9280 100644 --- a/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp @@ -13,20 +13,26 @@ #include <cassert> #include <algorithm> // for 'min' and 'max' -#pragma clang diagnostic ignored "-Wtautological-compare" +#include "test_macros.h" template <std::size_t N> void test_val_ctor() { { - _LIBCPP_CONSTEXPR std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL); - assert(v.size() == N); - unsigned M = std::min<std::size_t>(N, 64); - for (std::size_t i = 0; i < M; ++i) - assert(v[i] == (i & 1)); - for (std::size_t i = M; i < N; ++i) - assert(v[i] == false); + TEST_CONSTEXPR std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL); + assert(v.size() == N); + unsigned M = std::min<std::size_t>(N, 64); + for (std::size_t i = 0; i < M; ++i) + assert(v[i] == (i & 1)); + for (std::size_t i = M; i < N; ++i) + assert(v[i] == false); } +#if TEST_STD_VER >= 11 + { + constexpr std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL); + static_assert(v.size() == N, ""); + } +#endif } int main() diff --git a/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp b/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp index 520f2e8757c27..bc65078911b2c 100644 --- a/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.hash/bitset.pass.cpp @@ -16,12 +16,12 @@ // size_t operator()(T val) const; // }; -// Not very portable - #include <bitset> #include <cassert> #include <type_traits> +#include "test_macros.h" + template <std::size_t N> void test() @@ -32,7 +32,9 @@ test() static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); H h; T bs(static_cast<unsigned long long>(N)); - assert(h(bs) == N); + const std::size_t result = h(bs); + LIBCPP_ASSERT(result == N); + ((void)result); // Prevent unused warning } int main() diff --git a/test/std/utilities/template.bitset/bitset.members/count.pass.cpp b/test/std/utilities/template.bitset/bitset.members/count.pass.cpp index fb9ce6422997a..c8a14c9b60496 100644 --- a/test/std/utilities/template.bitset/bitset.members/count.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/count.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp index 6c4f5c699850e..a25e5bd9da220 100644 --- a/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp index cffca68fb1ea6..88ce8e943caf1 100644 --- a/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp @@ -14,8 +14,6 @@ #include <cstdlib> #include <cassert> -#pragma clang diagnostic ignored "-Wtautological-compare" - template <std::size_t N> std::bitset<N> make_bitset() diff --git a/test/std/utilities/template.bitset/bitset.members/index.pass.cpp b/test/std/utilities/template.bitset/bitset.members/index.pass.cpp index b96aaa51ab8fc..02e58a7890c54 100644 --- a/test/std/utilities/template.bitset/bitset.members/index.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/index.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp b/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp index e3c28c6935767..870a504c2d751 100644 --- a/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp b/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp index 7fe9fa72e9243..57b77d2570d54 100644 --- a/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp index bed3e28ece818..3adab77b4131f 100644 --- a/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp index 2f8f7111f5a13..d9fbb3e11dad8 100644 --- a/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp index b599ec398b309..64ca15fda137d 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp index 5f6cf3d0a30c1..24761c628c03e 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp @@ -16,7 +16,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp index 6e63879890a64..f2880f67ab6e6 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp index e68a641cadc66..420996759d0d7 100644 --- a/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp index ee44d92c43b8e..eed25e27448df 100644 --- a/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp @@ -12,7 +12,9 @@ #include <bitset> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> void test_reset_all() diff --git a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp index 6de256b00cc55..f01d35b9a33c3 100644 --- a/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp @@ -13,9 +13,6 @@ #include <bitset> #include <cassert> -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtautological-compare" - template <std::size_t N> void test_reset_one() { diff --git a/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp b/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp index 87fcc281fa26e..180fa84f4488b 100644 --- a/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp b/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp index 1dd89c1844b94..47494fc459a50 100644 --- a/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp b/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp index 56454a84f1135..e5c3e25352cc4 100644 --- a/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp @@ -12,7 +12,9 @@ #include <bitset> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> void test_set_all() diff --git a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp index ce594d0ae891b..161afd11c291d 100644 --- a/test/std/utilities/template.bitset/bitset.members/test.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/test.pass.cpp @@ -14,8 +14,6 @@ #include <cstdlib> #include <cassert> -#pragma clang diagnostic ignored "-Wtautological-compare" - template <std::size_t N> std::bitset<N> make_bitset() diff --git a/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp b/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp index b65794097470f..5b2958cca5239 100644 --- a/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp @@ -26,7 +26,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp index 751cee69102a3..80792d919ccfd 100644 --- a/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp index fda5e5cda8eea..65a7004acb86d 100644 --- a/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp b/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp index 067f868215be9..dcabaa4a9a4d4 100644 --- a/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp +++ b/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp @@ -13,7 +13,9 @@ #include <cstdlib> #include <cassert> +#if defined(__clang__) #pragma clang diagnostic ignored "-Wtautological-compare" +#endif template <std::size_t N> std::bitset<N> diff --git a/test/std/utilities/template.bitset/version.pass.cpp b/test/std/utilities/template.bitset/version.pass.cpp deleted file mode 100644 index 5ae984c0092df..0000000000000 --- a/test/std/utilities/template.bitset/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <bitset> - -#include <bitset> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/utilities/time/date.time/ctime.pass.cpp b/test/std/utilities/time/date.time/ctime.pass.cpp index d0a838e0c2714..b9e19af32952e 100644 --- a/test/std/utilities/time/date.time/ctime.pass.cpp +++ b/test/std/utilities/time/date.time/ctime.pass.cpp @@ -21,11 +21,15 @@ int main() { std::clock_t c = 0; - ((void)c); // avoid unused warning std::size_t s = 0; std::time_t t = 0; - std::tm tm = {0}; + std::tm tm = {}; char str[3]; + ((void)c); // Prevent unused warning + ((void)s); // Prevent unused warning + ((void)t); // Prevent unused warning + ((void)tm); // Prevent unused warning + ((void)str); // Prevent unused warning static_assert((std::is_same<decltype(std::clock()), std::clock_t>::value), ""); static_assert((std::is_same<decltype(std::difftime(t,t)), double>::value), ""); static_assert((std::is_same<decltype(std::mktime(&tm)), std::time_t>::value), ""); diff --git a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp index 2e3acbc52b115..b6b3aeea94f85 100644 --- a/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.hires/consistency.pass.cpp @@ -12,6 +12,10 @@ // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// Due to C++17 inline variables ASAN flags this test as containing an ODR +// violation because Clock::is_steady is defined in both the dylib and this TU. +// UNSUPPORTED: asan + // <chrono> // high_resolution_clock diff --git a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp index 0e0b83b2f2440..6302ce6efb34b 100644 --- a/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp @@ -13,6 +13,10 @@ // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 // UNSUPPORTED: libcpp-has-no-monotonic-clock +// Due to C++17 inline variables ASAN flags this test as containing an ODR +// violation because Clock::is_steady is defined in both the dylib and this TU. +// UNSUPPORTED: asan + // <chrono> // steady_clock diff --git a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp index e277d4e67dc7a..cfbe9bd570329 100644 --- a/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp +++ b/test/std/utilities/time/time.clock/time.clock.system/consistency.pass.cpp @@ -12,6 +12,10 @@ // XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 // XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// Due to C++17 inline variables ASAN flags this test as containing an ODR +// violation because Clock::is_steady is defined in both the dylib and this TU. +// UNSUPPORTED: asan + // <chrono> // system_clock diff --git a/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp b/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp index ec32c37a94232..30ea029b7ef4a 100644 --- a/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.alg/abs.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> diff --git a/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp b/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp index 6fb73b97db17e..8d7623c85e194 100644 --- a/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.cast/ceil.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> diff --git a/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp b/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp index 57929dd912281..38db42a84cedf 100644 --- a/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.cast/floor.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // floor diff --git a/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp b/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp index e50b85c991a21..2f9689007dfd9 100644 --- a/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.cast/round.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // round diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp index 48324ae836513..d5c0207c0ee76 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <chrono> #include <chrono> @@ -15,7 +16,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals::chrono_literals; // Make sure the types are right @@ -25,12 +25,12 @@ int main() static_assert ( std::is_same<decltype( 3ms ), std::chrono::milliseconds>::value, "" ); static_assert ( std::is_same<decltype( 3us ), std::chrono::microseconds>::value, "" ); static_assert ( std::is_same<decltype( 3ns ), std::chrono::nanoseconds>::value, "" ); - + std::chrono::hours h = 4h; assert ( h == std::chrono::hours(4)); auto h2 = 4.0h; assert ( h == h2 ); - + std::chrono::minutes min = 36min; assert ( min == std::chrono::minutes(36)); auto min2 = 36.0min; @@ -55,5 +55,4 @@ int main() assert ( ns == std::chrono::nanoseconds(645)); auto ns2 = 645.ns; assert ( ns == ns2 ); -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp index 46aaa30e51e4a..52208cb54d6d8 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals1.fail.cpp @@ -7,15 +7,13 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 #include <chrono> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 std::chrono::hours h = 4h; // should fail w/conversion operator not found -#else -#error -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp index 574f9bcce8741..5e59e1153787d 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals1.pass.cpp @@ -7,19 +7,20 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 #include <chrono> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::chrono; hours h = 4h; assert ( h == hours(4)); auto h2 = 4.0h; assert ( h == h2 ); - + minutes min = 36min; assert ( min == minutes(36)); auto min2 = 36.0min; @@ -44,5 +45,4 @@ int main() assert ( ns == nanoseconds(645)); auto ns2 = 645.ns; assert ( ns == ns2 ); -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp index 17358e589f4fa..f190d7863066c 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals2.fail.cpp @@ -7,16 +7,14 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 #include <chrono> #include <cassert> int main() { -#if _LIBCPP_STD_VER > 11 using std::chrono::hours; hours foo = 4h; // should fail w/conversion operator not found -#else -#error -#endif } diff --git a/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp b/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp index e37bc6e679614..282b1c6572e24 100644 --- a/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp +++ b/test/std/utilities/time/time.duration/time.duration.literals/literals2.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <chrono> #include <chrono> @@ -15,14 +16,13 @@ int main() { -#if _LIBCPP_STD_VER > 11 using namespace std::literals; std::chrono::hours h = 4h; assert ( h == std::chrono::hours(4)); auto h2 = 4.0h; assert ( h == h2 ); - + std::chrono::minutes min = 36min; assert ( min == std::chrono::minutes(36)); auto min2 = 36.0min; @@ -47,5 +47,4 @@ int main() assert ( ns == std::chrono::nanoseconds(645)); auto ns2 = 645.ns; assert ( ns == ns2 ); -#endif } diff --git a/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp b/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp index 379929c7f2d81..e6e7c053885ae 100644 --- a/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.cast/ceil.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // ceil diff --git a/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp b/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp index d0a908fa932a0..efd2d9e25cd7a 100644 --- a/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.cast/floor.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // floor diff --git a/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp b/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp index ab8bf3a75e79f..b5d16cf11d98d 100644 --- a/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.cast/round.pass.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // <chrono> // round diff --git a/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp b/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp index fbd3a1386d35b..a37bb266a0a95 100644 --- a/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp +++ b/test/std/utilities/time/time.point/time.point.comparisons/op_equal.pass.cpp @@ -54,7 +54,7 @@ int main() assert(!(t1 == t2)); assert( (t1 != t2)); } - + #if _LIBCPP_STD_VER > 11 { constexpr T1 t1(Duration1(3)); diff --git a/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp b/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp index f9ddc87a7a148..faacb573d74b0 100644 --- a/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp +++ b/test/std/utilities/time/time.traits/time.traits.is_fp/treat_as_floating_point.pass.cpp @@ -14,6 +14,8 @@ #include <chrono> #include <type_traits> +#include "test_macros.h" + template <class T> void test() @@ -21,8 +23,8 @@ test() static_assert((std::is_base_of<std::is_floating_point<T>, std::chrono::treat_as_floating_point<T> >::value), ""); #if TEST_STD_VER > 14 - static_assert((std::is_base_of<std::is_floating_point<T>, - std::chrono::treat_as_floating_point_v<T> >), ""); + static_assert(std::is_floating_point<T>::value == + std::chrono::treat_as_floating_point_v<T>, ""); #endif } diff --git a/test/std/utilities/time/version.pass.cpp b/test/std/utilities/time/version.pass.cpp deleted file mode 100644 index bfa3f6d6797d9..0000000000000 --- a/test/std/utilities/time/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <chrono> - -#include <chrono> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp b/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp index 1d8be420d8376..d1b974c50753a 100644 --- a/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp +++ b/test/std/utilities/tuple/tuple.general/tuple.smartptr.pass.cpp @@ -21,18 +21,13 @@ int main () { std::tuple<std::unique_ptr<char>> up; std::tuple<std::shared_ptr<char>> sp; std::tuple<std::weak_ptr <char>> wp; -// std::tuple<std::auto_ptr <char>> ap; } { std::tuple<std::unique_ptr<char[]>> up; std::tuple<std::shared_ptr<char[]>> sp; std::tuple<std::weak_ptr <char[]>> wp; -// std::tuple<std::auto_ptr <char[]>> ap; } - { - std::tuple<std::unique_ptr<char[5]>> up; - std::tuple<std::shared_ptr<char[5]>> sp; - std::tuple<std::weak_ptr <char[5]>> wp; -// std::tuple<std::auto_ptr <char[5]>> ap; - } -}
\ No newline at end of file + // Smart pointers of type 'T[N]' are not tested here since they are not + // supported by the standard nor by libc++'s implementation. + // See http://reviews.llvm.org/D21320 for more information. +} diff --git a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp index df5fdff511e35..ce6dcf811e468 100644 --- a/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/TupleFunction.pass.cpp @@ -9,7 +9,9 @@ // This is for bugs 18853 and 19118 -#if __cplusplus >= 201103L +#include "test_macros.h" + +#if TEST_STD_VER >= 11 #include <tuple> #include <functional> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp new file mode 100644 index 0000000000000..2e821945d09a1 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply.pass.cpp @@ -0,0 +1,275 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <tuple> + +// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&) + +// Test with different ref/ptr/cv qualified argument types. + +#include <tuple> +#include <array> +#include <utility> +#include <cassert> + +#include "test_macros.h" +#include "type_id.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + + +constexpr int constexpr_sum_fn() { return 0; } + +template <class ...Ints> +constexpr int constexpr_sum_fn(int x1, Ints... rest) { return x1 + constexpr_sum_fn(rest...); } + +struct ConstexprSumT { + constexpr ConstexprSumT() = default; + template <class ...Ints> + constexpr int operator()(Ints... values) const { + return constexpr_sum_fn(values...); + } +}; + + +void test_constexpr_evaluation() +{ + constexpr ConstexprSumT sum_obj{}; + { + using Tup = std::tuple<>; + using Fn = int(&)(); + constexpr Tup t; + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 0, ""); + static_assert(std::apply(sum_obj, t) == 0, ""); + } + { + using Tup = std::tuple<int>; + using Fn = int(&)(int); + constexpr Tup t(42); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 42, ""); + static_assert(std::apply(sum_obj, t) == 42, ""); + } + { + using Tup = std::tuple<int, long>; + using Fn = int(&)(int, int); + constexpr Tup t(42, 101); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 143, ""); + static_assert(std::apply(sum_obj, t) == 143, ""); + } + { + using Tup = std::pair<int, long>; + using Fn = int(&)(int, int); + constexpr Tup t(42, 101); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 143, ""); + static_assert(std::apply(sum_obj, t) == 143, ""); + } + { + using Tup = std::tuple<int, long, int>; + using Fn = int(&)(int, int, int); + constexpr Tup t(42, 101, -1); + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 142, ""); + static_assert(std::apply(sum_obj, t) == 142, ""); + } + { + using Tup = std::array<int, 3>; + using Fn = int(&)(int, int, int); + constexpr Tup t = {42, 101, -1}; + static_assert(std::apply(static_cast<Fn>(constexpr_sum_fn), t) == 142, ""); + static_assert(std::apply(sum_obj, t) == 142, ""); + } +} + + +enum CallQuals { + CQ_None, + CQ_LValue, + CQ_ConstLValue, + CQ_RValue, + CQ_ConstRValue +}; + +template <class Tuple> +struct CallInfo { + CallQuals quals; + TypeID const* arg_types; + Tuple args; + + template <class ...Args> + CallInfo(CallQuals q, Args&&... xargs) + : quals(q), arg_types(&makeArgumentID<Args&&...>()), args(std::forward<Args>(xargs)...) + {} +}; + +template <class ...Args> +inline CallInfo<decltype(std::forward_as_tuple(std::declval<Args>()...))> +makeCallInfo(CallQuals quals, Args&&... args) { + return {quals, std::forward<Args>(args)...}; +} + +struct TrackedCallable { + + TrackedCallable() = default; + + template <class ...Args> auto operator()(Args&&... xargs) & + { return makeCallInfo(CQ_LValue, std::forward<Args>(xargs)...); } + + template <class ...Args> auto operator()(Args&&... xargs) const& + { return makeCallInfo(CQ_ConstLValue, std::forward<Args>(xargs)...); } + + template <class ...Args> auto operator()(Args&&... xargs) && + { return makeCallInfo(CQ_RValue, std::forward<Args>(xargs)...); } + + template <class ...Args> auto operator()(Args&&... xargs) const&& + { return makeCallInfo(CQ_ConstRValue, std::forward<Args>(xargs)...); } +}; + +template <class ...ExpectArgs, class Tuple> +void check_apply_quals_and_types(Tuple&& t) { + TypeID const* const expect_args = &makeArgumentID<ExpectArgs...>(); + TrackedCallable obj; + TrackedCallable const& cobj = obj; + { + auto ret = std::apply(obj, std::forward<Tuple>(t)); + assert(ret.quals == CQ_LValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } + { + auto ret = std::apply(cobj, std::forward<Tuple>(t)); + assert(ret.quals == CQ_ConstLValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } + { + auto ret = std::apply(std::move(obj), std::forward<Tuple>(t)); + assert(ret.quals == CQ_RValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } + { + auto ret = std::apply(std::move(cobj), std::forward<Tuple>(t)); + assert(ret.quals == CQ_ConstRValue); + assert(ret.arg_types == expect_args); + assert(ret.args == t); + } +} + +void test_call_quals_and_arg_types() +{ + TrackedCallable obj; + using Tup = std::tuple<int, int const&, unsigned&&>; + const int x = 42; + unsigned y = 101; + Tup t(-1, x, std::move(y)); + Tup const& ct = t; + check_apply_quals_and_types<int&, int const&, unsigned&>(t); + check_apply_quals_and_types<int const&, int const&, unsigned&>(ct); + check_apply_quals_and_types<int&&, int const&, unsigned&&>(std::move(t)); + check_apply_quals_and_types<int const&&, int const&, unsigned&&>(std::move(ct)); +} + + +struct NothrowMoveable { + NothrowMoveable() noexcept = default; + NothrowMoveable(NothrowMoveable const&) noexcept(false) {} + NothrowMoveable(NothrowMoveable&&) noexcept {} +}; + +template <bool IsNoexcept> +struct TestNoexceptCallable { + template <class ...Args> + NothrowMoveable operator()(Args...) const noexcept(IsNoexcept) { return {}; } +}; + +void test_noexcept() +{ + TestNoexceptCallable<true> nec; + TestNoexceptCallable<false> tc; + { + // test that the functions noexcept-ness is propagated + using Tup = std::tuple<int, const char*, long>; + Tup t; + ASSERT_NOEXCEPT(std::apply(nec, t)); + ASSERT_NOT_NOEXCEPT(std::apply(tc, t)); + } + { + // test that the noexcept-ness of the argument conversions is checked. + using Tup = std::tuple<NothrowMoveable, int>; + Tup t; + ASSERT_NOT_NOEXCEPT(std::apply(nec, t)); + ASSERT_NOEXCEPT(std::apply(nec, std::move(t))); + } +} + +namespace ReturnTypeTest { + static int my_int = 42; + + template <int N> struct index {}; + + void f(index<0>) {} + + int f(index<1>) { return 0; } + + int & f(index<2>) { return static_cast<int &>(my_int); } + int const & f(index<3>) { return static_cast<int const &>(my_int); } + int volatile & f(index<4>) { return static_cast<int volatile &>(my_int); } + int const volatile & f(index<5>) { return static_cast<int const volatile &>(my_int); } + + int && f(index<6>) { return static_cast<int &&>(my_int); } + int const && f(index<7>) { return static_cast<int const &&>(my_int); } + int volatile && f(index<8>) { return static_cast<int volatile &&>(my_int); } + int const volatile && f(index<9>) { return static_cast<int const volatile &&>(my_int); } + + int * f(index<10>) { return static_cast<int *>(&my_int); } + int const * f(index<11>) { return static_cast<int const *>(&my_int); } + int volatile * f(index<12>) { return static_cast<int volatile *>(&my_int); } + int const volatile * f(index<13>) { return static_cast<int const volatile *>(&my_int); } + + template <int Func, class Expect> + void test() + { + using RawInvokeResult = decltype(f(index<Func>{})); + static_assert(std::is_same<RawInvokeResult, Expect>::value, ""); + using FnType = RawInvokeResult (*) (index<Func>); + FnType fn = f; + std::tuple<index<Func>> t; ((void)t); + using InvokeResult = decltype(std::apply(fn, t)); + static_assert(std::is_same<InvokeResult, Expect>::value, ""); + } +} // end namespace ReturnTypeTest + +void test_return_type() +{ + using ReturnTypeTest::test; + test<0, void>(); + test<1, int>(); + test<2, int &>(); + test<3, int const &>(); + test<4, int volatile &>(); + test<5, int const volatile &>(); + test<6, int &&>(); + test<7, int const &&>(); + test<8, int volatile &&>(); + test<9, int const volatile &&>(); + test<10, int *>(); + test<11, int const *>(); + test<12, int volatile *>(); + test<13, int const volatile *>(); +} + +int main() { + test_constexpr_evaluation(); + test_call_quals_and_arg_types(); + test_return_type(); + test_noexcept(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_extended_types.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_extended_types.pass.cpp new file mode 100644 index 0000000000000..02d7fe43e9cdc --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_extended_types.pass.cpp @@ -0,0 +1,426 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <tuple> + +// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&) + +// Testing extended function types. The extended function types are those +// named by INVOKE but that are not actual callable objects. These include +// bullets 1-4 of invoke. + +#include <tuple> +#include <array> +#include <utility> +#include <cassert> + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + +int count = 0; + +struct A_int_0 +{ + A_int_0() : obj1(0){} + A_int_0(int x) : obj1(x) {} + int mem1() { return ++count; } + int mem2() const { return ++count; } + int const obj1; +}; + +struct A_int_1 +{ + A_int_1() {} + A_int_1(int) {} + int mem1(int x) { return count += x; } + int mem2(int x) const { return count += x; } +}; + +struct A_int_2 +{ + A_int_2() {} + A_int_2(int) {} + int mem1(int x, int y) { return count += (x + y); } + int mem2(int x, int y) const { return count += (x + y); } +}; + +template <class A> +struct A_wrap +{ + A_wrap() {} + A_wrap(int x) : m_a(x) {} + A & operator*() { return m_a; } + A const & operator*() const { return m_a; } + A m_a; +}; + +typedef A_wrap<A_int_0> A_wrap_0; +typedef A_wrap<A_int_1> A_wrap_1; +typedef A_wrap<A_int_2> A_wrap_2; + + +template <class A> +struct A_base : public A +{ + A_base() : A() {} + A_base(int x) : A(x) {} +}; + +typedef A_base<A_int_0> A_base_0; +typedef A_base<A_int_1> A_base_1; +typedef A_base<A_int_2> A_base_2; + + +template < + class Tuple, class ConstTuple + , class TuplePtr, class ConstTuplePtr + , class TupleWrap, class ConstTupleWrap + , class TupleBase, class ConstTupleBase + > +void test_ext_int_0() +{ + count = 0; + typedef A_int_0 T; + typedef A_wrap_0 Wrap; + typedef A_base_0 Base; + + typedef int(T::*mem1_t)(); + mem1_t mem1 = &T::mem1; + + typedef int(T::*mem2_t)() const; + mem2_t mem2 = &T::mem2; + + typedef int const T::*obj1_t; + obj1_t obj1 = &T::obj1; + + // member function w/ref + { + T a; + Tuple t{a}; + assert(1 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // member function w/pointer + { + T a; + TuplePtr t{&a}; + assert(1 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // member function w/base + { + Base a; + TupleBase t{a}; + assert(1 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // member function w/wrap + { + Wrap a; + TupleWrap t{a}; + assert(1 == std::apply(mem1, t)); + assert(count == 1); + } + count = 0; + // const member function w/ref + { + T const a; + ConstTuple t{a}; + assert(1 == std::apply(mem2, t)); + assert(count == 1); + } + count = 0; + // const member function w/pointer + { + T const a; + ConstTuplePtr t{&a}; + assert(1 == std::apply(mem2, t)); + assert(count == 1); + } + count = 0; + // const member function w/base + { + Base const a; + ConstTupleBase t{a}; + assert(1 == std::apply(mem2, t)); + assert(count == 1); + } + count = 0; + // const member function w/wrapper + { + Wrap const a; + ConstTupleWrap t{a}; + assert(1 == std::apply(mem2, t)); + assert(1 == count); + } + // member object w/ref + { + T a{42}; + Tuple t{a}; + assert(42 == std::apply(obj1, t)); + } + // member object w/pointer + { + T a{42}; + TuplePtr t{&a}; + assert(42 == std::apply(obj1, t)); + } + // member object w/base + { + Base a{42}; + TupleBase t{a}; + assert(42 == std::apply(obj1, t)); + } + // member object w/wrapper + { + Wrap a{42}; + TupleWrap t{a}; + assert(42 == std::apply(obj1, t)); + } +} + + +template < + class Tuple, class ConstTuple + , class TuplePtr, class ConstTuplePtr + , class TupleWrap, class ConstTupleWrap + , class TupleBase, class ConstTupleBase + > +void test_ext_int_1() +{ + count = 0; + typedef A_int_1 T; + typedef A_wrap_1 Wrap; + typedef A_base_1 Base; + + typedef int(T::*mem1_t)(int); + mem1_t mem1 = &T::mem1; + + typedef int(T::*mem2_t)(int) const; + mem2_t mem2 = &T::mem2; + + // member function w/ref + { + T a; + Tuple t{a, 2}; + assert(2 == std::apply(mem1, t)); + assert(count == 2); + } + count = 0; + // member function w/pointer + { + T a; + TuplePtr t{&a, 3}; + assert(3 == std::apply(mem1, t)); + assert(count == 3); + } + count = 0; + // member function w/base + { + Base a; + TupleBase t{a, 4}; + assert(4 == std::apply(mem1, t)); + assert(count == 4); + } + count = 0; + // member function w/wrap + { + Wrap a; + TupleWrap t{a, 5}; + assert(5 == std::apply(mem1, t)); + assert(count == 5); + } + count = 0; + // const member function w/ref + { + T const a; + ConstTuple t{a, 6}; + assert(6 == std::apply(mem2, t)); + assert(count == 6); + } + count = 0; + // const member function w/pointer + { + T const a; + ConstTuplePtr t{&a, 7}; + assert(7 == std::apply(mem2, t)); + assert(count == 7); + } + count = 0; + // const member function w/base + { + Base const a; + ConstTupleBase t{a, 8}; + assert(8 == std::apply(mem2, t)); + assert(count == 8); + } + count = 0; + // const member function w/wrapper + { + Wrap const a; + ConstTupleWrap t{a, 9}; + assert(9 == std::apply(mem2, t)); + assert(9 == count); + } +} + + +template < + class Tuple, class ConstTuple + , class TuplePtr, class ConstTuplePtr + , class TupleWrap, class ConstTupleWrap + , class TupleBase, class ConstTupleBase + > +void test_ext_int_2() +{ + count = 0; + typedef A_int_2 T; + typedef A_wrap_2 Wrap; + typedef A_base_2 Base; + + typedef int(T::*mem1_t)(int, int); + mem1_t mem1 = &T::mem1; + + typedef int(T::*mem2_t)(int, int) const; + mem2_t mem2 = &T::mem2; + + // member function w/ref + { + T a; + Tuple t{a, 1, 1}; + assert(2 == std::apply(mem1, t)); + assert(count == 2); + } + count = 0; + // member function w/pointer + { + T a; + TuplePtr t{&a, 1, 2}; + assert(3 == std::apply(mem1, t)); + assert(count == 3); + } + count = 0; + // member function w/base + { + Base a; + TupleBase t{a, 2, 2}; + assert(4 == std::apply(mem1, t)); + assert(count == 4); + } + count = 0; + // member function w/wrap + { + Wrap a; + TupleWrap t{a, 2, 3}; + assert(5 == std::apply(mem1, t)); + assert(count == 5); + } + count = 0; + // const member function w/ref + { + T const a; + ConstTuple t{a, 3, 3}; + assert(6 == std::apply(mem2, t)); + assert(count == 6); + } + count = 0; + // const member function w/pointer + { + T const a; + ConstTuplePtr t{&a, 3, 4}; + assert(7 == std::apply(mem2, t)); + assert(count == 7); + } + count = 0; + // const member function w/base + { + Base const a; + ConstTupleBase t{a, 4, 4}; + assert(8 == std::apply(mem2, t)); + assert(count == 8); + } + count = 0; + // const member function w/wrapper + { + Wrap const a; + ConstTupleWrap t{a, 4, 5}; + assert(9 == std::apply(mem2, t)); + assert(9 == count); + } +} + +int main() +{ + { + test_ext_int_0< + std::tuple<A_int_0 &>, std::tuple<A_int_0 const &> + , std::tuple<A_int_0 *>, std::tuple<A_int_0 const *> + , std::tuple<A_wrap_0 &>, std::tuple<A_wrap_0 const &> + , std::tuple<A_base_0 &>, std::tuple<A_base_0 const &> + >(); + test_ext_int_0< + std::tuple<A_int_0>, std::tuple<A_int_0 const> + , std::tuple<A_int_0 *>, std::tuple<A_int_0 const *> + , std::tuple<A_wrap_0>, std::tuple<A_wrap_0 const> + , std::tuple<A_base_0>, std::tuple<A_base_0 const> + >(); + test_ext_int_0< + std::array<A_int_0, 1>, std::array<A_int_0 const, 1> + , std::array<A_int_0*, 1>, std::array<A_int_0 const*, 1> + , std::array<A_wrap_0, 1>, std::array<A_wrap_0 const, 1> + , std::array<A_base_0, 1>, std::array<A_base_0 const, 1> + >(); + } + { + test_ext_int_1< + std::tuple<A_int_1 &, int>, std::tuple<A_int_1 const &, int> + , std::tuple<A_int_1 *, int>, std::tuple<A_int_1 const *, int> + , std::tuple<A_wrap_1 &, int>, std::tuple<A_wrap_1 const &, int> + , std::tuple<A_base_1 &, int>, std::tuple<A_base_1 const &, int> + >(); + test_ext_int_1< + std::tuple<A_int_1, int>, std::tuple<A_int_1 const, int> + , std::tuple<A_int_1 *, int>, std::tuple<A_int_1 const *, int> + , std::tuple<A_wrap_1, int>, std::tuple<A_wrap_1 const, int> + , std::tuple<A_base_1, int>, std::tuple<A_base_1 const, int> + >(); + test_ext_int_1< + std::pair<A_int_1 &, int>, std::pair<A_int_1 const &, int> + , std::pair<A_int_1 *, int>, std::pair<A_int_1 const *, int> + , std::pair<A_wrap_1 &, int>, std::pair<A_wrap_1 const &, int> + , std::pair<A_base_1 &, int>, std::pair<A_base_1 const &, int> + >(); + test_ext_int_1< + std::pair<A_int_1, int>, std::pair<A_int_1 const, int> + , std::pair<A_int_1 *, int>, std::pair<A_int_1 const *, int> + , std::pair<A_wrap_1, int>, std::pair<A_wrap_1 const, int> + , std::pair<A_base_1, int>, std::pair<A_base_1 const, int> + >(); + } + { + test_ext_int_2< + std::tuple<A_int_2 &, int, int>, std::tuple<A_int_2 const &, int, int> + , std::tuple<A_int_2 *, int, int>, std::tuple<A_int_2 const *, int, int> + , std::tuple<A_wrap_2 &, int, int>, std::tuple<A_wrap_2 const &, int, int> + , std::tuple<A_base_2 &, int, int>, std::tuple<A_base_2 const &, int, int> + >(); + test_ext_int_2< + std::tuple<A_int_2, int, int>, std::tuple<A_int_2 const, int, int> + , std::tuple<A_int_2 *, int, int>, std::tuple<A_int_2 const *, int, int> + , std::tuple<A_wrap_2, int, int>, std::tuple<A_wrap_2 const, int, int> + , std::tuple<A_base_2, int, int>, std::tuple<A_base_2 const, int, int> + >(); + } +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_large_arity.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_large_arity.pass.cpp new file mode 100644 index 0000000000000..33c3ef5956e4e --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/apply_large_arity.pass.cpp @@ -0,0 +1,144 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <tuple> + +// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&) + +// Stress testing large arities with tuple and array. + +#include <tuple> +#include <array> +#include <utility> +#include <cassert> + +//////////////////////////////////////////////////////////////////////////////// +template <class T, std::size_t Dummy = 0> +struct always_imp +{ + typedef T type; +}; + +template <class T, std::size_t Dummy = 0> +using always_t = typename always_imp<T, Dummy>::type; + +//////////////////////////////////////////////////////////////////////////////// +template <class Tuple, class Idx> +struct make_function; + +template <class Tp, std::size_t ...Idx> +struct make_function<Tp, std::integer_sequence<std::size_t, Idx...>> +{ + using type = bool (*)(always_t<Tp, Idx>...); +}; + +template <class Tp, std::size_t Size> +using make_function_t = typename make_function<Tp, std::make_index_sequence<Size>>::type; + +//////////////////////////////////////////////////////////////////////////////// +template <class Tp, class Idx> +struct make_tuple_imp; + +//////////////////////////////////////////////////////////////////////////////// +template <class Tp, std::size_t ...Idx> +struct make_tuple_imp<Tp, std::integer_sequence<std::size_t, Idx...>> +{ + using type = std::tuple<always_t<Tp, Idx>...>; +}; + +template <class Tp, std::size_t Size> +using make_tuple_t = typename make_tuple_imp<Tp, std::make_index_sequence<Size>>::type; + +template <class ...Types> +bool test_apply_fn(Types...) { return true; } + + +template <std::size_t Size> +void test_all() +{ + + using A = std::array<int, Size>; + using ConstA = std::array<int const, Size>; + + using Tuple = make_tuple_t<int, Size>; + using CTuple = make_tuple_t<const int, Size>; + + using ValFn = make_function_t<int, Size>; + ValFn val_fn = &test_apply_fn; + + using RefFn = make_function_t<int &, Size>; + RefFn ref_fn = &test_apply_fn; + + using CRefFn = make_function_t<int const &, Size>; + CRefFn cref_fn = &test_apply_fn; + + using RRefFn = make_function_t<int &&, Size>; + RRefFn rref_fn = &test_apply_fn; + + { + A a{}; + assert(std::apply(val_fn, a)); + assert(std::apply(ref_fn, a)); + assert(std::apply(cref_fn, a)); + assert(std::apply(rref_fn, std::move(a))); + } + { + ConstA a{}; + assert(std::apply(val_fn, a)); + assert(std::apply(cref_fn, a)); + } + { + Tuple a{}; + assert(std::apply(val_fn, a)); + assert(std::apply(ref_fn, a)); + assert(std::apply(cref_fn, a)); + assert(std::apply(rref_fn, std::move(a))); + } + { + CTuple a{}; + assert(std::apply(val_fn, a)); + assert(std::apply(cref_fn, a)); + } + +} + + +template <std::size_t Size> +void test_one() +{ + using A = std::array<int, Size>; + using Tuple = make_tuple_t<int, Size>; + + using ValFn = make_function_t<int, Size>; + ValFn val_fn = &test_apply_fn; + + { + A a{}; + assert(std::apply(val_fn, a)); + } + { + Tuple a{}; + assert(std::apply(val_fn, a)); + } +} + +int main() +{ + // Instantiate with 1-5 arguments. + test_all<1>(); + test_all<2>(); + test_all<3>(); + test_all<4>(); + test_all<5>(); + + // Stress test with 256 + test_one<256>(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp new file mode 100644 index 0000000000000..143ae195e6f44 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp @@ -0,0 +1,214 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <tuple> + +// template <class T, class Tuple> constexpr T make_from_tuple(Tuple&&); + +#include <tuple> +#include <array> +#include <utility> +#include <string> +#include <cassert> + +#include "test_macros.h" +#include "type_id.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + +template <class Tuple> +struct ConstexprConstructibleFromTuple { + template <class ...Args> + explicit constexpr ConstexprConstructibleFromTuple(Args&&... xargs) + : args{std::forward<Args>(xargs)...} {} + Tuple args; +}; + +template <class TupleLike> +struct ConstructibleFromTuple; + +template <template <class ...> class Tuple, class ...Types> +struct ConstructibleFromTuple<Tuple<Types...>> { + template <class ...Args> + explicit ConstructibleFromTuple(Args&&... xargs) + : args(xargs...), + arg_types(&makeArgumentID<Args&&...>()) + {} + Tuple<std::decay_t<Types>...> args; + TypeID const* arg_types; +}; + +template <class Tp, size_t N> +struct ConstructibleFromTuple<std::array<Tp, N>> { +template <class ...Args> + explicit ConstructibleFromTuple(Args&&... xargs) + : args{xargs...}, + arg_types(&makeArgumentID<Args&&...>()) + {} + std::array<Tp, N> args; + TypeID const* arg_types; +}; + +template <class Tuple> +constexpr bool do_constexpr_test(Tuple&& tup) { + using RawTuple = std::decay_t<Tuple>; + using Tp = ConstexprConstructibleFromTuple<RawTuple>; + return std::make_from_tuple<Tp>(std::forward<Tuple>(tup)).args == tup; +} + +// Needed by do_forwarding_test() since it compare pairs of different types. +template <class T1, class T2, class U1, class U2> +inline bool operator==(const std::pair<T1, T2>& lhs, const std::pair<U1, U2>& rhs) { + return lhs.first == rhs.first && lhs.second == rhs.second; +} + +template <class ...ExpectTypes, class Tuple> +bool do_forwarding_test(Tuple&& tup) { + using RawTuple = std::decay_t<Tuple>; + using Tp = ConstructibleFromTuple<RawTuple>; + const Tp value = std::make_from_tuple<Tp>(std::forward<Tuple>(tup)); + return value.args == tup + && value.arg_types == &makeArgumentID<ExpectTypes...>(); +} + +void test_constexpr_construction() { + { + constexpr std::tuple<> tup; + static_assert(do_constexpr_test(tup), ""); + } + { + constexpr std::tuple<int> tup(42); + static_assert(do_constexpr_test(tup), ""); + } + { + constexpr std::tuple<int, long, void*> tup(42, 101, nullptr); + static_assert(do_constexpr_test(tup), ""); + } + { + constexpr std::pair<int, const char*> p(42, "hello world"); + static_assert(do_constexpr_test(p), ""); + } + { + using Tuple = std::array<int, 3>; + using ValueTp = ConstexprConstructibleFromTuple<Tuple>; + constexpr Tuple arr = {42, 101, -1}; + constexpr ValueTp value = std::make_from_tuple<ValueTp>(arr); + static_assert(value.args[0] == arr[0] && value.args[1] == arr[1] + && value.args[2] == arr[2], ""); + } +} + +void test_perfect_forwarding() { + { + using Tup = std::tuple<>; + Tup tup; + Tup const& ctup = tup; + assert(do_forwarding_test<>(tup)); + assert(do_forwarding_test<>(ctup)); + } + { + using Tup = std::tuple<int>; + Tup tup(42); + Tup const& ctup = tup; + assert(do_forwarding_test<int&>(tup)); + assert(do_forwarding_test<int const&>(ctup)); + assert(do_forwarding_test<int&&>(std::move(tup))); + assert(do_forwarding_test<int const&&>(std::move(ctup))); + } + { + using Tup = std::tuple<int&, const char*, unsigned&&>; + int x = 42; + unsigned y = 101; + Tup tup(x, "hello world", std::move(y)); + Tup const& ctup = tup; + assert((do_forwarding_test<int&, const char*&, unsigned&>(tup))); + assert((do_forwarding_test<int&, const char* const&, unsigned &>(ctup))); + assert((do_forwarding_test<int&, const char*&&, unsigned&&>(std::move(tup)))); + assert((do_forwarding_test<int&, const char* const&&, unsigned &&>(std::move(ctup)))); + } + // test with pair<T, U> + { + using Tup = std::pair<int&, const char*>; + int x = 42; + Tup tup(x, "hello world"); + Tup const& ctup = tup; + assert((do_forwarding_test<int&, const char*&>(tup))); + assert((do_forwarding_test<int&, const char* const&>(ctup))); + assert((do_forwarding_test<int&, const char*&&>(std::move(tup)))); + assert((do_forwarding_test<int&, const char* const&&>(std::move(ctup)))); + } + // test with array<T, I> + { + using Tup = std::array<int, 3>; + Tup tup = {42, 101, -1}; + Tup const& ctup = tup; + assert((do_forwarding_test<int&, int&, int&>(tup))); + assert((do_forwarding_test<int const&, int const&, int const&>(ctup))); + assert((do_forwarding_test<int&&, int&&, int&&>(std::move(tup)))); + assert((do_forwarding_test<int const&&, int const&&, int const&&>(std::move(ctup)))); + } +} + +void test_noexcept() { + struct NothrowMoveable { + NothrowMoveable() = default; + NothrowMoveable(NothrowMoveable const&) {} + NothrowMoveable(NothrowMoveable&&) noexcept {} + }; + struct TestType { + TestType(int, NothrowMoveable) noexcept {} + TestType(int, int, int) noexcept(false) {} + TestType(long, long, long) noexcept {} + }; + { + using Tuple = std::tuple<int, NothrowMoveable>; + Tuple tup; ((void)tup); + Tuple const& ctup = tup; ((void)ctup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(ctup)); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup))); + } + { + using Tuple = std::pair<int, NothrowMoveable>; + Tuple tup; ((void)tup); + Tuple const& ctup = tup; ((void)ctup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(ctup)); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(std::move(tup))); + } + { + using Tuple = std::tuple<int, int, int>; + Tuple tup; ((void)tup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } + { + using Tuple = std::tuple<long, long, long>; + Tuple tup; ((void)tup); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } + { + using Tuple = std::array<int, 3>; + Tuple tup; ((void)tup); + ASSERT_NOT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } + { + using Tuple = std::array<long, 3>; + Tuple tup; ((void)tup); + ASSERT_NOEXCEPT(std::make_from_tuple<TestType>(tup)); + } +} + +int main() +{ + test_constexpr_construction(); + test_perfect_forwarding(); + test_noexcept(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp index 2dde6b5521f2d..91892efaf1393 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp @@ -74,4 +74,16 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1).id_ == 2); } + { + // Test that tuple evaluates correctly applies an lvalue reference + // before evaluating is_assignable (ie 'is_assignable<int&, int&>') + // instead of evaluating 'is_assignable<int&&, int&>' which is false. + int x = 42; + int y = 43; + std::tuple<int&&> t(std::move(x)); + std::tuple<int&> t2(y); + t = t2; + assert(std::get<0>(t) == 43); + assert(&std::get<0>(t) == &x); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp index 11bfdd0c94a98..afd3e0fdb8e3d 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp @@ -37,6 +37,13 @@ struct D explicit D(int i) : B(i) {} }; +struct E { + E() = default; + E& operator=(int val) { + return *this; + } +}; + int main() { { @@ -88,4 +95,16 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1)->id_ == 3); } + { + // Test that tuple evaluates correctly applies an lvalue reference + // before evaluating is_assignable (ie 'is_assignable<int&, int&&>') + // instead of evaluating 'is_assignable<int&&, int&&>' which is false. + int x = 42; + int y = 43; + std::tuple<int&&, E> t(std::move(x), E{}); + std::tuple<int&&, int> t2(std::move(y), 44); + t = std::move(t2); + assert(std::get<0>(t) == 43); + assert(&std::get<0>(t) == &x); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR22806_constrain_tuple_like_ctor.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR22806_constrain_tuple_like_ctor.pass.cpp new file mode 100644 index 0000000000000..4ddfb463385c7 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR22806_constrain_tuple_like_ctor.pass.cpp @@ -0,0 +1,178 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++98, c++03 + +// <tuple> + +// template <class... Types> class tuple; + +// template <class TupleLike> +// tuple(TupleLike&&); +// template <class Alloc, class TupleLike> +// tuple(std::allocator_arg_t, Alloc const&, TupleLike&&); + +// Check that the tuple-like ctors are properly disabled when the UTypes... +// constructor should be selected. See PR22806. + +#include <tuple> +#include <memory> +#include <cassert> + +template <class Tp> +using uncvref_t = typename std::remove_cv<typename std::remove_reference<Tp>::type>::type; + +template <class Tuple, class = uncvref_t<Tuple>> +struct IsTuple : std::false_type {}; + +template <class Tuple, class ...Args> +struct IsTuple<Tuple, std::tuple<Args...>> : std::true_type {}; + +struct ConstructibleFromTupleAndInt { + enum State { FromTuple, FromInt, Copied, Moved }; + State state; + + ConstructibleFromTupleAndInt(ConstructibleFromTupleAndInt const&) : state(Copied) {} + ConstructibleFromTupleAndInt(ConstructibleFromTupleAndInt &&) : state(Moved) {} + + template <class Tuple, class = typename std::enable_if<IsTuple<Tuple>::value>::type> + explicit ConstructibleFromTupleAndInt(Tuple&&) : state(FromTuple) {} + + explicit ConstructibleFromTupleAndInt(int) : state(FromInt) {} +}; + +struct ConvertibleFromTupleAndInt { + enum State { FromTuple, FromInt, Copied, Moved }; + State state; + + ConvertibleFromTupleAndInt(ConvertibleFromTupleAndInt const&) : state(Copied) {} + ConvertibleFromTupleAndInt(ConvertibleFromTupleAndInt &&) : state(Moved) {} + + template <class Tuple, class = typename std::enable_if<IsTuple<Tuple>::value>::type> + ConvertibleFromTupleAndInt(Tuple&&) : state(FromTuple) {} + + ConvertibleFromTupleAndInt(int) : state(FromInt) {} +}; + +struct ConstructibleFromInt { + enum State { FromInt, Copied, Moved }; + State state; + + ConstructibleFromInt(ConstructibleFromInt const&) : state(Copied) {} + ConstructibleFromInt(ConstructibleFromInt &&) : state(Moved) {} + + explicit ConstructibleFromInt(int) : state(FromInt) {} +}; + +struct ConvertibleFromInt { + enum State { FromInt, Copied, Moved }; + State state; + + ConvertibleFromInt(ConvertibleFromInt const&) : state(Copied) {} + ConvertibleFromInt(ConvertibleFromInt &&) : state(Moved) {} + ConvertibleFromInt(int) : state(FromInt) {} +}; + +int main() +{ + // Test for the creation of dangling references when a tuple is used to + // store a reference to another tuple as its only element. + // Ex std::tuple<std::tuple<int>&&>. + // In this case the constructors 1) 'tuple(UTypes&&...)' + // and 2) 'tuple(TupleLike&&)' need to be manually disambiguated because + // when both #1 and #2 participate in partial ordering #2 will always + // be chosen over #1. + // See PR22806 and LWG issue #2549 for more information. + // (https://llvm.org/bugs/show_bug.cgi?id=22806) + using T = std::tuple<int>; + std::allocator<int> A; + { // rvalue reference + T t1(42); + std::tuple< T&& > t2(std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + { // const lvalue reference + T t1(42); + + std::tuple< T const & > t2(t1); + assert(&std::get<0>(t2) == &t1); + + std::tuple< T const & > t3(static_cast<T const&>(t1)); + assert(&std::get<0>(t3) == &t1); + } + { // lvalue reference + T t1(42); + + std::tuple< T & > t2(t1); + assert(&std::get<0>(t2) == &t1); + } + { // const rvalue reference + T t1(42); + + std::tuple< T const && > t2(std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + { // rvalue reference via uses-allocator + T t1(42); + std::tuple< T&& > t2(std::allocator_arg, A, std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + { // const lvalue reference via uses-allocator + T t1(42); + + std::tuple< T const & > t2(std::allocator_arg, A, t1); + assert(&std::get<0>(t2) == &t1); + + std::tuple< T const & > t3(std::allocator_arg, A, static_cast<T const&>(t1)); + assert(&std::get<0>(t3) == &t1); + } + { // lvalue reference via uses-allocator + T t1(42); + + std::tuple< T & > t2(std::allocator_arg, A, t1); + assert(&std::get<0>(t2) == &t1); + } + { // const rvalue reference via uses-allocator + T const t1(42); + std::tuple< T const && > t2(std::allocator_arg, A, std::move(t1)); + assert(&std::get<0>(t2) == &t1); + } + // Test constructing a 1-tuple of the form tuple<UDT> from another 1-tuple + // 'tuple<T>' where UDT *can* be constructed from 'tuple<T>' In this case + // the 'tuple(UTypes...)' ctor should be choosen and 'UDT' constructed frow + // 'tuple<T>'. + { + using VT = ConstructibleFromTupleAndInt; + std::tuple<int> t1(42); + std::tuple<VT> t2(t1); + assert(std::get<0>(t2).state == VT::FromTuple); + } + { + using VT = ConvertibleFromTupleAndInt; + std::tuple<int> t1(42); + std::tuple<VT> t2 = {t1}; + assert(std::get<0>(t2).state == VT::FromTuple); + } + // Test constructing a 1-tuple of the form tuple<UDT> from another 1-tuple + // 'tuple<T>' where UDT cannot be constructed from 'tuple<T>' but can + // be constructed from 'T'. In this case the tuple-like ctor should be + // chosen and 'UDT' constructed from 'T' + { + using VT = ConstructibleFromInt; + std::tuple<int> t1(42); + std::tuple<VT> t2(t1); + assert(std::get<0>(t2).state == VT::FromInt); + } + { + using VT = ConvertibleFromInt; + std::tuple<int> t1(42); + std::tuple<VT> t2 = {t1}; + assert(std::get<0>(t2).state == VT::FromInt); + } +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp new file mode 100644 index 0000000000000..ed3cafadbf08d --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR23256_constrain_UTypes_ctor.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++98, c++03 + +// <tuple> + +// template <class... Types> class tuple; + +// template <class ...UTypes> +// EXPLICIT(...) tuple(UTypes&&...) + +// Check that the UTypes... ctor is properly disabled before evaluating any +// SFINAE when the tuple-like copy/move ctor should *clearly* be selected +// instead. This happens 'sizeof...(UTypes) == 1' and the first element of +// 'UTypes...' is an instance of the tuple itself. See PR23256. + +#include <tuple> +#include <memory> +#include <type_traits> + + +struct UnconstrainedCtor { + int value_; + + UnconstrainedCtor() : value_(0) {} + + // Blows up when instantiated for any type other than int. Because the ctor + // is constexpr it is instantiated by 'is_constructible' and 'is_convertible' + // for Clang based compilers. GCC does not instantiate the ctor body + // but it does instantiate the noexcept specifier and it will blow up there. + template <typename T> + constexpr UnconstrainedCtor(T value) noexcept(noexcept(value_ = value)) + : value_(static_cast<int>(value)) + { + static_assert(std::is_same<int, T>::value, ""); + } +}; + +struct ExplicitUnconstrainedCtor { + int value_; + + ExplicitUnconstrainedCtor() : value_(0) {} + + template <typename T> + constexpr explicit ExplicitUnconstrainedCtor(T value) + noexcept(noexcept(value_ = value)) + : value_(static_cast<int>(value)) + { + static_assert(std::is_same<int, T>::value, ""); + } + +}; + +int main() { + typedef UnconstrainedCtor A; + typedef ExplicitUnconstrainedCtor ExplicitA; + { + static_assert(std::is_copy_constructible<std::tuple<A>>::value, ""); + static_assert(std::is_move_constructible<std::tuple<A>>::value, ""); + static_assert(std::is_copy_constructible<std::tuple<ExplicitA>>::value, ""); + static_assert(std::is_move_constructible<std::tuple<ExplicitA>>::value, ""); + } + { + static_assert(std::is_constructible< + std::tuple<A>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<A> const& + >::value, ""); + static_assert(std::is_constructible< + std::tuple<A>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<A> && + >::value, ""); + static_assert(std::is_constructible< + std::tuple<ExplicitA>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<ExplicitA> const& + >::value, ""); + static_assert(std::is_constructible< + std::tuple<ExplicitA>, + std::allocator_arg_t, std::allocator<void>, + std::tuple<ExplicitA> && + >::value, ""); + } + { + std::tuple<A&&> t(std::forward_as_tuple(A{})); + std::tuple<ExplicitA&&> t2(std::forward_as_tuple(ExplicitA{})); + } +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp new file mode 100644 index 0000000000000..c8b722f836c17 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR27684_contains_ref_to_incomplete_type.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++98, c++03 + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc> tuple(allocator_arg_t, Alloc const&) + +// Libc++ has to deduce the 'allocator_arg_t' parameter for this constructor +// as 'AllocArgT'. 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 PR27684. + +#include <tuple> +#include <cassert> + +struct IncompleteType; +extern IncompleteType inc1; +extern IncompleteType inc2; +IncompleteType const& cinc1 = inc1; +IncompleteType const& cinc2 = inc2; + +int main() { + using IT = IncompleteType; + { // try calling tuple(Tp const&...) + using Tup = std::tuple<const IT&, const IT&>; + Tup t(cinc1, cinc2); + assert(&std::get<0>(t) == &inc1); + assert(&std::get<1>(t) == &inc2); + } + { // try calling tuple(Up&&...) + using Tup = std::tuple<const IT&, const IT&>; + Tup t(inc1, inc2); + assert(&std::get<0>(t) == &inc1); + assert(&std::get<1>(t) == &inc2); + } +} + +struct IncompleteType {}; +IncompleteType inc1; +IncompleteType inc2; diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp index 817cc8f109905..6ab303c735bec 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp @@ -82,6 +82,8 @@ void test_default_constructible_extension_sfinae() MoveOnly, Tuple, MoveOnly, MoveOnly >::value, ""); } + // testing extensions +#ifdef _LIBCPP_VERSION { typedef std::tuple<MoveOnly, int> Tuple; typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; @@ -96,6 +98,7 @@ void test_default_constructible_extension_sfinae() MoveOnly, Tuple, MoveOnly, MoveOnly >::value, ""); } +#endif } int main() @@ -118,6 +121,7 @@ int main() assert(std::get<2>(t) == 2); } // extensions +#ifdef _LIBCPP_VERSION { std::tuple<MoveOnly, MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1)); @@ -131,7 +135,8 @@ int main() assert(std::get<1>(t) == MoveOnly()); assert(std::get<2>(t) == MoveOnly()); } -#if _LIBCPP_STD_VER > 11 +#endif +#if TEST_STD_VER > 11 { constexpr std::tuple<Empty> t0{Empty()}; } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp index 39776822cbda4..4da5fc7f83979 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <tuple> // template <class... Types> class tuple; @@ -14,7 +16,9 @@ // template <class Alloc> // tuple(allocator_arg_t, const Alloc& a); -// UNSUPPORTED: c++98, c++03 +// NOTE: this constructor does not currently support tags derived from +// allocator_arg_t because libc++ has to deduce the parameter as a template +// argument. See PR27684 (https://llvm.org/bugs/show_bug.cgi?id=27684) #include <tuple> #include <cassert> @@ -24,6 +28,18 @@ #include "../alloc_first.h" #include "../alloc_last.h" +template <class T = void> +struct NonDefaultConstructible { + constexpr NonDefaultConstructible() { + static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); + } + + explicit constexpr NonDefaultConstructible(int) {} +}; + + +struct DerivedFromAllocArgT : std::allocator_arg_t {}; + int main() { { @@ -78,4 +94,14 @@ int main() assert(!alloc_last::allocator_constructed); assert(std::get<2>(t) == alloc_last()); } + { + // Test that the uses-allocator default constructor does not evaluate + // it's SFINAE when it otherwise shouldn't be selected. Do this by + // using 'NonDefaultConstructible' which will cause a compile error + // if std::is_default_constructible is evaluated on it. + using T = NonDefaultConstructible<>; + T v(42); + std::tuple<T, T> t(v, v); + std::tuple<T, T> t2(42, 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp index 3929965cd2735..e174e9b321b8d 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp @@ -24,16 +24,29 @@ #include "../alloc_first.h" #include "../alloc_last.h" -struct NoDefault { NoDefault() = delete; }; +template <class T = void> +struct DefaultCtorBlowsUp { + constexpr DefaultCtorBlowsUp() { + static_assert(!std::is_same<T, T>::value, "Default Ctor instantiated"); + } -// Make sure the _Up... constructor SFINAEs out when the types that -// are not explicitly initialized are not all default constructible. -// Otherwise, std::is_constructible would return true but instantiating -// the constructor would fail. -void test_default_constructible_extension_sfinae() + explicit constexpr DefaultCtorBlowsUp(int x) : value(x) {} + + int value; +}; + + +struct DerivedFromAllocArgT : std::allocator_arg_t {}; + + +// Make sure the _Up... constructor SFINAEs out when the number of initializers +// is less that the number of elements in the tuple. Previously libc++ would +// offer these constructers as an extension but they broke conforming code. +void test_uses_allocator_sfinae_evaluation() { + using BadDefault = DefaultCtorBlowsUp<>; { - typedef std::tuple<MoveOnly, NoDefault> Tuple; + typedef std::tuple<MoveOnly, MoveOnly, BadDefault> Tuple; static_assert(!std::is_constructible< Tuple, @@ -42,11 +55,11 @@ void test_default_constructible_extension_sfinae() static_assert(std::is_constructible< Tuple, - std::allocator_arg_t, A1<int>, MoveOnly, NoDefault + std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, BadDefault >::value, ""); } { - typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple; + typedef std::tuple<MoveOnly, MoveOnly, BadDefault, BadDefault> Tuple; static_assert(!std::is_constructible< Tuple, @@ -55,53 +68,44 @@ void test_default_constructible_extension_sfinae() static_assert(std::is_constructible< Tuple, - std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, NoDefault - >::value, ""); - } - { - // Same idea as above but with a nested tuple - typedef std::tuple<MoveOnly, NoDefault> Tuple; - typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; - - static_assert(!std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly - >::value, ""); - - static_assert(std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly - >::value, ""); - } - { - typedef std::tuple<MoveOnly, int> Tuple; - typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple; - - static_assert(std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly - >::value, ""); - - static_assert(std::is_constructible< - NestedTuple, - std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly + std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, BadDefault, BadDefault >::value, ""); } } +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + int main() { { + std::tuple<Explicit> t{std::allocator_arg, std::allocator<void>{}, 42}; + assert(std::get<0>(t).value == 42); + } + { std::tuple<MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0)); assert(std::get<0>(t) == 0); } { + using T = DefaultCtorBlowsUp<>; + std::tuple<T> t(std::allocator_arg, A1<int>(), T(42)); + assert(std::get<0>(t).value == 42); + } + { std::tuple<MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0), MoveOnly(1)); assert(std::get<0>(t) == 0); assert(std::get<1>(t) == 1); } { + using T = DefaultCtorBlowsUp<>; + std::tuple<T, T> t(std::allocator_arg, A1<int>(), T(42), T(43)); + assert(std::get<0>(t).value == 42); + assert(std::get<1>(t).value == 43); + } + { std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0), 1, 2); @@ -110,6 +114,13 @@ int main() assert(std::get<2>(t) == 2); } { + using T = DefaultCtorBlowsUp<>; + std::tuple<T, T, T> t(std::allocator_arg, A1<int>(), T(1), T(2), T(3)); + assert(std::get<0>(t).value == 1); + assert(std::get<1>(t).value == 2); + assert(std::get<2>(t).value == 3); + } + { alloc_first::allocator_constructed = false; alloc_last::allocator_constructed = false; std::tuple<int, alloc_first, alloc_last> t(std::allocator_arg, @@ -120,22 +131,22 @@ int main() assert(alloc_last::allocator_constructed); assert(std::get<2>(t) == alloc_last(3)); } - // extensions - { - std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), - 0, 1); - assert(std::get<0>(t) == 0); - assert(std::get<1>(t) == 1); - assert(std::get<2>(t) == MoveOnly()); - } { - std::tuple<MoveOnly, MoveOnly, MoveOnly> t(std::allocator_arg, A1<int>(), - 0); - assert(std::get<0>(t) == 0); - assert(std::get<1>(t) == MoveOnly()); - assert(std::get<2>(t) == MoveOnly()); + // Check that uses-allocator construction is still selected when + // given a tag type that derives from allocator_arg_t. + DerivedFromAllocArgT tag; + alloc_first::allocator_constructed = false; + alloc_last::allocator_constructed = false; + std::tuple<int, alloc_first, alloc_last> t(tag, + A1<int>(5), 1, 2, 3); + assert(std::get<0>(t) == 1); + assert(alloc_first::allocator_constructed); + assert(std::get<1>(t) == alloc_first(2)); + assert(alloc_last::allocator_constructed); + assert(std::get<2>(t) == alloc_last(3)); } - // Check that SFINAE is properly applied with the default reduced arity - // constructor extensions. - test_default_constructible_extension_sfinae(); + // Stress test the SFINAE on the uses-allocator constructors and + // ensure that the "reduced-arity-initialization" extension is not offered + // for these constructors. + test_uses_allocator_sfinae_evaluation(); } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp new file mode 100644 index 0000000000000..b28ad6dab5ab7 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc> +// EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> +#include <cassert> + +struct ExplicitCopy { + explicit ExplicitCopy(ExplicitCopy const&) {} + explicit ExplicitCopy(int) {} +}; + +std::tuple<ExplicitCopy> const_explicit_copy_test() { + const ExplicitCopy e(42); + return {std::allocator_arg, std::allocator<void>{}, e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> non_const_explicity_copy_test() { + ExplicitCopy e(42); + return {std::allocator_arg, std::allocator<void>{}, e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} +int main() +{ + const_explicit_copy_test(); + non_const_explicity_copy_test(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp index 0f68926376f24..73d53a4c0e261 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp @@ -17,15 +17,37 @@ // UNSUPPORTED: c++98, c++03 #include <tuple> +#include <memory> #include <cassert> #include "allocators.h" #include "../alloc_first.h" #include "../alloc_last.h" +struct ImplicitCopy { + explicit ImplicitCopy(int) {} + ImplicitCopy(ImplicitCopy const&) {} +}; + +// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit +// copy conversions in return value expressions. +std::tuple<ImplicitCopy> testImplicitCopy1() { + ImplicitCopy i(42); + return {std::allocator_arg, std::allocator<void>{}, i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy2() { + const ImplicitCopy i(42); + return {std::allocator_arg, std::allocator<void>{}, i}; +} + int main() { { + // check that the literal '0' can implicitly initialize a stored pointer. + std::tuple<int*> t = {std::allocator_arg, std::allocator<void>{}, 0}; + } + { std::tuple<int> t(std::allocator_arg, A1<int>(), 3); assert(std::get<0>(t) == 3); } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp new file mode 100644 index 0000000000000..ccf08833b537e --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc, class ...UTypes> +// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...> const&); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> + +struct ExplicitCopy { + explicit ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} + +}; + +std::tuple<ExplicitCopy> const_explicit_copy_test() { + const std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, t1}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> non_const_explicit_copy_test() { + std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, t1}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +int main() +{ + +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp index 8acfde7a98eb1..36d9f32879cbb 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp @@ -17,12 +17,23 @@ // UNSUPPORTED: c++98, c++03 #include <tuple> +#include <memory> #include <cassert> #include "allocators.h" #include "../alloc_first.h" #include "../alloc_last.h" +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + int main() { { @@ -66,4 +77,14 @@ int main() assert(std::get<1>(t1) == 2); assert(std::get<2>(t1) == 3); } + { + const std::tuple<int> t1(42); + std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{}, t1}; + assert(std::get<0>(t2).value == 42); + } + { + const std::tuple<int> t1(42); + std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, t1}; + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp new file mode 100644 index 0000000000000..d3539cebf9500 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Alloc, class ...UTypes> +// tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <memory> + +struct ExplicitCopy { + explicit ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} +}; + +std::tuple<ExplicitCopy> explicit_move_test() { + std::tuple<int> t1(42); + return {std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +int main() +{ + +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp index c862d3b64d56f..d3a6add5da6a8 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp @@ -40,6 +40,16 @@ struct D explicit D(int i) : B(i) {} }; +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + int main() { { @@ -81,4 +91,14 @@ int main() assert(std::get<1>(t1) == 2); assert(std::get<2>(t1)->id_ == 3); } + { + std::tuple<int> t1(42); + std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + assert(std::get<0>(t2).value == 42); + } + { + std::tuple<int> t1(42); + std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, std::move(t1)}; + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp index 14e127e59ba91..7c9f60cbf901b 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_copy.pass.cpp @@ -52,6 +52,8 @@ int main() assert(alloc_last::allocator_constructed); assert(std::get<0>(t) == 2); } +// testing extensions +#ifdef _LIBCPP_VERSION { typedef std::tuple<alloc_first, alloc_last> T; T t0(2, 3); @@ -75,4 +77,5 @@ int main() assert(std::get<1>(t) == 2); assert(std::get<2>(t) == 3); } +#endif } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp index 54d3f7ee0c079..a3e1a9de61958 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_move.pass.cpp @@ -53,6 +53,8 @@ int main() assert(alloc_last::allocator_constructed); assert(std::get<0>(t) == 1); } +// testing extensions +#ifdef _LIBCPP_VERSION { typedef std::tuple<MoveOnly, alloc_first> T; T t0(0 ,1); @@ -74,4 +76,5 @@ int main() assert(std::get<1>(t) == 2); assert(std::get<2>(t) == 3); } +#endif } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp index 00e2af265b360..b72f0fc2efec4 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp @@ -19,9 +19,30 @@ #include <string> #include <cassert> +struct ExplicitCopy { + ExplicitCopy(int) {} + explicit ExplicitCopy(ExplicitCopy const&) {} +}; + +std::tuple<ExplicitCopy> const_explicit_copy() { + const ExplicitCopy e(42); + return {e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + + +std::tuple<ExplicitCopy> non_const_explicit_copy() { + ExplicitCopy e(42); + return {e}; + // expected-error@-1 {{chosen constructor is explicit in copy-initialization}} +} + +std::tuple<ExplicitCopy> const_explicit_copy_no_brace() { + const ExplicitCopy e(42); + return e; + // expected-error@-1 {{no viable conversion}} +} + int main() { - { - std::tuple<int*> t = 0; - } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp index bbadf8de16001..367f19e5d8dd6 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp @@ -53,13 +53,40 @@ struct NoValueCtorEmpty { static_assert(never<T>::value, "This should not be instantiated"); } }; + +struct ImplicitCopy { + explicit ImplicitCopy(int) {} + ImplicitCopy(ImplicitCopy const&) {} +}; + +// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit +// copy conversions in return value expressions. +std::tuple<ImplicitCopy> testImplicitCopy1() { + ImplicitCopy i(42); + return {i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy2() { + const ImplicitCopy i(42); + return {i}; +} + +std::tuple<ImplicitCopy> testImplicitCopy3() { + const ImplicitCopy i(42); + return i; +} + int main() { { + // check that the literal '0' can implicitly initialize a stored pointer. + std::tuple<int*> t = 0; + } + { std::tuple<int> t(2); assert(std::get<0>(t) == 2); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { constexpr std::tuple<int> t(2); static_assert(std::get<0>(t) == 2, ""); @@ -74,7 +101,7 @@ int main() assert(std::get<0>(t) == 2); assert(std::get<1>(t) == nullptr); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { constexpr std::tuple<int, char*> t(2, nullptr); static_assert(std::get<0>(t) == 2, ""); @@ -109,7 +136,8 @@ int main() assert(std::get<2>(t) == 2); assert(std::get<3>(t) == 3); } - // extensions +// extensions +#ifdef _LIBCPP_VERSION { std::tuple<int, char*, std::string> t(2); assert(std::get<0>(t) == 2); @@ -129,4 +157,5 @@ int main() assert(std::get<2>(t) == "text"); assert(std::get<3>(t) == 0.0); } +#endif } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp index 740b6589e5114..d6d489fd0ea44 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_pair.pass.cpp @@ -29,7 +29,7 @@ int main() assert(std::get<0>(t1) == 2); assert(std::get<1>(t1) == short('a')); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::pair<double, char> P0; typedef std::tuple<int, short> T1; diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp index 5ad4f9227f481..b7fa2e3a03cc5 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp @@ -20,6 +20,16 @@ #include <string> #include <cassert> +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + struct B { int id_; @@ -33,7 +43,7 @@ struct D explicit D(int i) : B(i) {} }; -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 struct A { @@ -62,7 +72,7 @@ int main() T1 t1 = t0; assert(std::get<0>(t1) == 2); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<double> T0; typedef std::tuple<A> T1; @@ -115,4 +125,14 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1).id_ == 3); } + { + const std::tuple<int> t1(42); + std::tuple<Explicit> t2(t1); + assert(std::get<0>(t2).value == 42); + } + { + const std::tuple<int> t1(42); + std::tuple<Implicit> t2 = t1; + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp index 3a6abd3a95af4..8423f5d0145fc 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp @@ -20,6 +20,16 @@ #include <memory> #include <cassert> +struct Explicit { + int value; + explicit Explicit(int x) : value(x) {} +}; + +struct Implicit { + int value; + Implicit(int x) : value(x) {} +}; + struct B { int id_; @@ -81,4 +91,14 @@ int main() assert(std::get<1>(t1) == int('a')); assert(std::get<2>(t1)->id_ == 3); } + { + std::tuple<int> t1(42); + std::tuple<Explicit> t2(std::move(t1)); + assert(std::get<0>(t2).value == 42); + } + { + std::tuple<int> t1(42); + std::tuple<Implicit> t2 = std::move(t1); + assert(std::get<0>(t2).value == 42); + } } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp index 0cda96846f717..1bd7d6d4e8a87 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/move.pass.cpp @@ -29,8 +29,10 @@ struct ConstructsWithTupleLeaf ConstructsWithTupleLeaf(ConstructsWithTupleLeaf &&) {} template <class T> - ConstructsWithTupleLeaf(T t) - { assert(false); } + ConstructsWithTupleLeaf(T t) { + static_assert(!std::is_same<T, T>::value, + "Constructor instantiated for type other than int"); + } }; int main() diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/test_lazy_sfinae.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/test_lazy_sfinae.pass.cpp new file mode 100644 index 0000000000000..76f7e794a8e81 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/test_lazy_sfinae.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <utility> +#include <cassert> + +template <class ConstructFrom> +struct ConstructibleFromT { + ConstructibleFromT() = default; + ConstructibleFromT(ConstructFrom v) : value(v) {} + ConstructFrom value; +}; + +template <class AssertOn> +struct CtorAssertsT { + bool defaulted; + CtorAssertsT() : defaulted(true) {} + template <class T> + constexpr CtorAssertsT(T) : defaulted(false) { + static_assert(!std::is_same<T, AssertOn>::value, ""); + } +}; + +template <class AllowT, class AssertT> +struct AllowAssertT { + AllowAssertT() = default; + AllowAssertT(AllowT) {} + template <class U> + constexpr AllowAssertT(U) { + static_assert(!std::is_same<U, AssertT>::value, ""); + } +}; + +// Construct a tuple<T1, T2> from pair<int, int> where T1 and T2 +// are not constructible from ints but T1 is constructible from std::pair. +// This considers the following constructors: +// (1) tuple(TupleLike) -> checks is_constructible<Tn, int> +// (2) tuple(UTypes...) -> checks is_constructible<T1, pair<int, int>> +// and is_default_constructible<T2> +// The point of this test is to ensure that the consideration of (1) +// short circuits before evaluating is_constructible<T2, int>, which +// will cause a static assertion. +void test_tuple_like_lazy_sfinae() { +#if defined(_LIBCPP_VERSION) + // This test requires libc++'s reduced arity initialization. + using T1 = ConstructibleFromT<std::pair<int, int>>; + using T2 = CtorAssertsT<int>; + std::pair<int, int> p(42, 100); + std::tuple<T1, T2> t(p); + assert(std::get<0>(t).value == p); + assert(std::get<1>(t).defaulted); +#endif +} + + +struct NonConstCopyable { + NonConstCopyable() = default; + explicit NonConstCopyable(int v) : value(v) {} + NonConstCopyable(NonConstCopyable&) = default; + NonConstCopyable(NonConstCopyable const&) = delete; + int value; +}; + +template <class T> +struct BlowsUpOnConstCopy { + BlowsUpOnConstCopy() = default; + constexpr BlowsUpOnConstCopy(BlowsUpOnConstCopy const&) { + static_assert(!std::is_same<T, T>::value, ""); + } + BlowsUpOnConstCopy(BlowsUpOnConstCopy&) = default; +}; + +// Test the following constructors: +// (1) tuple(Types const&...) +// (2) tuple(UTypes&&...) +// Test that (1) short circuits before evaluating the copy constructor of the +// second argument. Constructor (2) should be selected. +void test_const_Types_lazy_sfinae() +{ + NonConstCopyable v(42); + BlowsUpOnConstCopy<int> b; + std::tuple<NonConstCopyable, BlowsUpOnConstCopy<int>> t(v, b); + assert(std::get<0>(t).value == 42); +} + +int main() { + test_tuple_like_lazy_sfinae(); + test_const_Types_lazy_sfinae(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp index 0e556b1b6c8e0..2dbe81513a1a3 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/forward_as_tuple.pass.cpp @@ -20,7 +20,7 @@ template <class Tuple> void -test0(const Tuple& t) +test0(const Tuple&) { static_assert(std::tuple_size<Tuple>::value == 0, ""); } @@ -56,8 +56,8 @@ test2a(const Tuple& t) #if _LIBCPP_STD_VER > 11 template <class Tuple> -constexpr int -test3(const Tuple& t) +constexpr int +test3(const Tuple&) { return std::tuple_size<Tuple>::value; } diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp index 2ee96dc7ebf45..f27e8a09fb974 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp @@ -40,7 +40,7 @@ int main() assert(i == 0); assert(j == 0); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { constexpr auto t1 = std::make_tuple(0, 1, 3.14); constexpr int i1 = std::get<1>(t1); diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp index e21768cb6f5fd..002ad148ad6df 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_const.pass.cpp @@ -36,7 +36,7 @@ int main() assert(std::get<0>(t) == "high"); assert(std::get<1>(t) == 5); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<double, int> T; constexpr T t(2.718, 5); diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp index 1c2b17ad88325..86d1191db5564 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/get_non_const.pass.cpp @@ -21,7 +21,9 @@ #include <string> #include <cassert> -#if __cplusplus > 201103L +#include "test_macros.h" + +#if TEST_STD_VER > 11 struct Empty {}; @@ -69,7 +71,7 @@ int main() assert(std::get<2>(t) == 4); assert(d == 2.5); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { // get on an rvalue tuple static_assert ( std::get<0> ( std::make_tuple ( 0.0f, 1, 2.0, 3L )) == 0, "" ); static_assert ( std::get<1> ( std::make_tuple ( 0.0f, 1, 2.0, 3L )) == 1, "" ); diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp new file mode 100644 index 0000000000000..74e6efd983bd4 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +#include <tuple> +#include <string> + +struct UserType {}; + +void test_bad_index() { + std::tuple<long, long, char, std::string, char, UserType, char> t1; + (void)std::get<int>(t1); // expected-error@tuple:* {{type not found}} + (void)std::get<long>(t1); // expected-note {{requested here}} + (void)std::get<char>(t1); // expected-note {{requested here}} + // expected-error@tuple:* 2 {{type occurs more than once}} + std::tuple<> t0; + (void)std::get<char*>(t0); // expected-node {{requested here}} + // expected-error@tuple:* 1 {{type not in empty type list}} +} + +void test_bad_return_type() { + typedef std::unique_ptr<int> upint; + std::tuple<upint> t; + upint p = std::get<upint>(t); // expected-error{{deleted copy constructor}} +} + +int main() +{ + test_bad_index(); + test_bad_return_type(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp index b661a78de8dba..01ee1ca1f4342 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp @@ -11,6 +11,7 @@ #include <tuple> #include <utility> +#include <memory> #include <string> #include <complex> #include <type_traits> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp deleted file mode 100644 index 85c32ca6d4955..0000000000000 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11 - -#include <tuple> -#include <string> -#include <complex> - -#include <cassert> - -int main() -{ -#if _LIBCPP_STD_VER > 11 - typedef std::complex<float> cf; - auto t1 = std::make_tuple<int, std::string> ( 42, "Hi" ); - assert (( std::get<cf>(t1) == cf {1,2} )); // no such type -#else -#error -#endif -} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp deleted file mode 100644 index 0a8d5829d02b1..0000000000000 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11 - -#include <tuple> -#include <string> -#include <complex> - -#include <cassert> - -int main() -{ -#if _LIBCPP_STD_VER > 11 - typedef std::complex<float> cf; - auto t1 = std::make_tuple<int, int, std::string, cf> ( 42, 21, "Hi", { 1,2 } ); - assert ( std::get<int>(t1) == 42 ); // two ints here -#else -#error -#endif -} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp deleted file mode 100644 index 0a4550f387dc0..0000000000000 --- a/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11 - -#include <tuple> -#include <string> -#include <complex> - -#include <cassert> - -int main() -{ -#if _LIBCPP_STD_VER > 11 - typedef std::complex<float> cf; - auto t1 = std::make_tuple<double, int, std::string, cf, int> ( 42, 21, "Hi", { 1,2 } ); - assert ( std::get<int>(t1) == 42 ); // two ints here (one at the end) -#else -#error -#endif -} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp index d8a72c617cb5c..57da4b04cdfd9 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp @@ -18,7 +18,7 @@ // typedef Ti type; // }; // -// LWG #2212 says that tuple_size and tuple_element must be +// LWG #2212 says that tuple_size and tuple_element must be // available after including <utility> #include <array> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp index 8c8357d95d994..bd015ab5bbd6e 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp @@ -15,9 +15,10 @@ // class tuple_size<tuple<Types...>> // : public integral_constant<size_t, sizeof...(Types)> { }; // -// LWG #2212 says that tuple_size and tuple_element must be +// LWG #2212 says that tuple_size and tuple_element must be // available after including <utility> +#include <cstddef> #include <utility> #include <type_traits> diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.fail.cpp new file mode 100644 index 0000000000000..4cb73573e7c9d --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_element.fail.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <size_t I, class... Types> +// class tuple_element<I, tuple<Types...> > +// { +// public: +// typedef Ti type; +// }; + +// UNSUPPORTED: c++98, c++03 + +#include <tuple> +#include <type_traits> + +int main() +{ + using T = std::tuple<int, long, void*>; + using E1 = typename std::tuple_element<1, T &>::type; // expected-error{{undefined template}} + using E2 = typename std::tuple_element<3, T>::type; + using E3 = typename std::tuple_element<4, T const>::type; + // expected-error@__tuple:* 2 {{static_assert failed}} + +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp new file mode 100644 index 0000000000000..3f132e47b626c --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <tuple> + +// template <class... Types> +// class tuple_size<tuple<Types...>> +// : public integral_constant<size_t, sizeof...(Types)> { }; + +// Expect failures with a reference type, pointer type, and a non-tuple type. + +#include <tuple> + +int main() +{ + (void)std::tuple_size<std::tuple<> &>::value; // expected-error {{implicit instantiation of undefined template}} + (void)std::tuple_size<int>::value; // expected-error {{implicit instantiation of undefined template}} + (void)std::tuple_size<std::tuple<>*>::value; // expected-error {{implicit instantiation of undefined template}} +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp new file mode 100644 index 0000000000000..957a683b47f85 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.fail.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <tuple> + +// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value; + +// Expect failures with a reference type, pointer type, and a non-tuple type. + +#include <tuple> + +int main() +{ + (void)std::tuple_size_v<std::tuple<> &>; // expected-note {{requested here}} + (void)std::tuple_size_v<int>; // expected-note {{requested here}} + (void)std::tuple_size_v<std::tuple<>*>; // expected-note {{requested here}} + // expected-error@tuple:* 3 {{implicit instantiation of undefined template}} +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.pass.cpp new file mode 100644 index 0000000000000..24878a1d560e0 --- /dev/null +++ b/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_v.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <tuple> + +// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value; + +#include <tuple> +#include <utility> +#include <array> + +template <class Tuple, int Expect> +void test() +{ + static_assert(std::tuple_size_v<Tuple> == Expect, ""); + static_assert(std::tuple_size_v<Tuple> == std::tuple_size<Tuple>::value, ""); + static_assert(std::tuple_size_v<Tuple const> == std::tuple_size<Tuple>::value, ""); + static_assert(std::tuple_size_v<Tuple volatile> == std::tuple_size<Tuple>::value, ""); + static_assert(std::tuple_size_v<Tuple const volatile> == std::tuple_size<Tuple>::value, ""); +} + +int main() +{ + test<std::tuple<>, 0>(); + + test<std::tuple<int>, 1>(); + test<std::array<int, 1>, 1>(); + + test<std::tuple<int, int>, 2>(); + test<std::pair<int, int>, 2>(); + test<std::array<int, 2>, 2>(); + + test<std::tuple<int, int, int>, 3>(); + test<std::array<int, 3>, 3>(); +} diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp index 0d25edc4547b1..e5991df636f8b 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp @@ -143,7 +143,7 @@ int main() assert(!(t1 == t2)); assert(t1 != t2); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<char, int, double> T1; typedef std::tuple<double, char, int> T2; diff --git a/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp b/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp index eac84a9c35f6a..34aafb1e1347a 100644 --- a/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp +++ b/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp @@ -195,7 +195,7 @@ int main() assert(!(t1 > t2)); assert(!(t1 >= t2)); } -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 11 { typedef std::tuple<char, int, double> T1; typedef std::tuple<double, char, int> T2; diff --git a/test/std/utilities/tuple/version.pass.cpp b/test/std/utilities/tuple/version.pass.cpp deleted file mode 100644 index 2fdbb5d2784a8..0000000000000 --- a/test/std/utilities/tuple/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <tuple> - -#include <tuple> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/utilities/type.index/version.pass.cpp b/test/std/utilities/type.index/version.pass.cpp deleted file mode 100644 index 26f462042fd33..0000000000000 --- a/test/std/utilities/type.index/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <typeindex> - -#include <typeindex> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/utilities/utility/as_const/as_const.pass.cpp b/test/std/utilities/utility/as_const/as_const.pass.cpp index ff3f84a5532fb..7bb5849d0bd05 100644 --- a/test/std/utilities/utility/as_const/as_const.pass.cpp +++ b/test/std/utilities/utility/as_const/as_const.pass.cpp @@ -27,7 +27,7 @@ void test(T& t) static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const<const T>(t))>::type>::value, ""); static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const<volatile T>(t))>::type>::value, ""); static_assert(std::is_const<typename std::remove_reference<decltype(std::as_const<const volatile T>(t))>::type>::value, ""); - + assert(std::as_const(t) == t); assert(std::as_const< T>(t) == t); assert(std::as_const<const T>(t) == t); diff --git a/test/std/utilities/utility/exchange/exchange.pass.cpp b/test/std/utilities/utility/exchange/exchange.pass.cpp index 620b4149d1d0b..5ef0ac3b09f52 100644 --- a/test/std/utilities/utility/exchange/exchange.pass.cpp +++ b/test/std/utilities/utility/exchange/exchange.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // utilities // exchange @@ -17,7 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 { int v = 12; assert ( std::exchange ( v, 23 ) == 12 ); @@ -27,7 +27,7 @@ int main() assert ((std::exchange<int, float> ( v, {} )) == 67 ); assert ( v == 0 ); - + } { @@ -48,11 +48,9 @@ int main() s3 = s2; // Dad assert ( std::exchange ( s3, {} ) == s2 ); assert ( s3.size () == 0 ); - + s3 = s2; // Dad assert ( std::exchange ( s3, "" ) == s2 ); assert ( s3.size () == 0 ); } - -#endif } diff --git a/test/std/utilities/utility/forward/forward.pass.cpp b/test/std/utilities/utility/forward/forward.pass.cpp index 357b36fafa960..94575485df047 100644 --- a/test/std/utilities/utility/forward/forward.pass.cpp +++ b/test/std/utilities/utility/forward/forward.pass.cpp @@ -39,6 +39,9 @@ int main() A a; const A ca = A(); + ((void)a); // Prevent unused warning + ((void)ca); // Prevent unused warning + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES static_assert(sizeof(test(std::forward<A&>(a))) == 1, ""); static_assert(sizeof(test(std::forward<A>(a))) == 4, ""); diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp index fcda3664d9b62..9ef7bcff2ba83 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/get_const.pass.cpp @@ -18,6 +18,8 @@ #include <utility> #include <cassert> +#include "test_macros.h" + int main() { { @@ -27,7 +29,7 @@ int main() assert(std::get<1>(p) == 4); } -#if __cplusplus > 201103L +#if TEST_STD_VER > 11 { typedef std::pair<int, short> P; constexpr P p1(3, 4); diff --git a/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp index 6d61c47ffbf03..47b4c06134d97 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp @@ -18,7 +18,9 @@ #include <utility> #include <cassert> -#if __cplusplus > 201103L +#include "test_macros.h" + +#if TEST_STD_VER > 11 struct S { std::pair<int, int> a; int k; @@ -41,7 +43,7 @@ int main() assert(std::get<1>(p) == 6); } -#if __cplusplus > 201103L +#if TEST_STD_VER > 11 { static_assert(S().k == 1, ""); static_assert(std::get<1>(getP()) == 4, ""); diff --git a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp index 27194effe5c32..f0d55a6618227 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <utility> #include <complex> @@ -14,11 +15,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::complex<float> cf; auto t1 = std::make_pair<int, double> ( 42, 3.4 ); assert (( std::get<cf>(t1) == cf {1,2} )); // no such type -#else -#error -#endif } diff --git a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp index f9e3942d7e773..72e637592483f 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <utility> #include <complex> @@ -14,11 +15,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::complex<float> cf; auto t1 = std::make_pair<int, int> ( 42, 43 ); assert ( std::get<int>(t1) == 42 ); // two ints -#else -#error -#endif } diff --git a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp index 484347345747d..d5179e4355b90 100644 --- a/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp +++ b/test/std/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 #include <utility> #include <complex> @@ -14,11 +15,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 typedef std::unique_ptr<int> upint; std::pair<upint, int> t(upint(new int(4)), 23); upint p = std::get<upint>(t); -#else -#error -#endif } diff --git a/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp index 4b54f717045ad..1117db3297b85 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/copy_ctor.pass.cpp @@ -16,6 +16,8 @@ #include <utility> #include <cassert> +#include "test_macros.h" + int main() { { @@ -25,10 +27,7 @@ int main() assert(p2.first == 3); assert(p2.second == 4); } - - static_assert((std::is_trivially_copy_constructible<std::pair<int, int> >::value), ""); - -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER > 11 { typedef std::pair<int, short> P1; constexpr P1 p1(3, 4); diff --git a/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp index d83328b8f2d0c..97182d24d0217 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/default.pass.cpp @@ -13,9 +13,15 @@ // constexpr pair(); +// This test doesn't pass due to a constexpr bug in GCC 4.9 that fails +// to initialize any type without a user provided constructor in a constant +// expression (ie float). +// XFAIL: gcc-4.9 + // NOTE: The SFINAE on the default constructor is tested in // default-sfinae.pass.cpp + #include <utility> #include <type_traits> #include <cassert> diff --git a/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp new file mode 100644 index 0000000000000..06cb5e5658c90 --- /dev/null +++ b/test/std/utilities/utility/pairs/pairs.pair/move_ctor.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <utility> + +// template <class T1, class T2> struct pair + +// pair(pair&&) = default; + +#include <utility> +#include <memory> +#include <cassert> + +#include "test_macros.h" + +struct Dummy { + Dummy(Dummy const&) = delete; + Dummy(Dummy &&) = default; +}; + +int main() +{ + { + typedef std::pair<int, short> P1; + static_assert(std::is_move_constructible<P1>::value, ""); + P1 p1(3, 4); + P1 p2 = std::move(p1); + assert(p2.first == 3); + assert(p2.second == 4); + } + { + using P = std::pair<Dummy, int>; + static_assert(!std::is_copy_constructible<P>::value, ""); + static_assert(std::is_move_constructible<P>::value, ""); + } +} diff --git a/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp index 0ad5786bce29d..dfea61eeacdb0 100644 --- a/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.pair/swap.pass.cpp @@ -17,7 +17,7 @@ #include <cassert> struct S { - int i; + int i; S() : i(0) {} S(int j) : i(j) {} S * operator& () { assert(false); return this; } diff --git a/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp b/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp new file mode 100644 index 0000000000000..53cf56700df88 --- /dev/null +++ b/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// <utility> + +// template <class T1, class T2> struct pair + +// pair(pair const&) = default; +// pair(pair&&) = default; + +// Doesn't pass due to use of is_trivially_* trait. +// XFAIL: gcc-4.9 + +#include <utility> +#include <cassert> + +#include "test_macros.h" + +struct Dummy { + Dummy(Dummy const&) = delete; + Dummy(Dummy &&) = default; +}; + +int main() +{ + typedef std::pair<int, short> P; + { + static_assert(std::is_copy_constructible<P>::value, ""); + static_assert(std::is_trivially_copy_constructible<P>::value, ""); + } +#if TEST_STD_VER >= 11 + { + static_assert(std::is_move_constructible<P>::value, ""); + static_assert(std::is_trivially_move_constructible<P>::value, ""); + } + { + using P1 = std::pair<Dummy, int>; + static_assert(!std::is_copy_constructible<P1>::value, ""); + static_assert(!std::is_trivially_copy_constructible<P1>::value, ""); + static_assert(std::is_move_constructible<P1>::value, ""); + static_assert(std::is_trivially_move_constructible<P1>::value, ""); + } +#endif +} diff --git a/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp b/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp index 48e09735abb02..4a6d71e7b9c85 100644 --- a/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp +++ b/test/std/utilities/utility/pairs/pairs.spec/make_pair.pass.cpp @@ -23,7 +23,7 @@ int main() assert(p1.first == 3); assert(p1.second == 4); } - + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { typedef std::pair<std::unique_ptr<int>, short> P1; diff --git a/test/std/utilities/utility/version.pass.cpp b/test/std/utilities/utility/synopsis.pass.cpp index 77d145d944574..5f5b4eeaad524 100644 --- a/test/std/utilities/utility/version.pass.cpp +++ b/test/std/utilities/utility/synopsis.pass.cpp @@ -8,13 +8,14 @@ //===----------------------------------------------------------------------===// // <utility> +// XFAIL: c++98, c++03 -#include <utility> +// #include <initializer_list> -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif +#include <utility> int main() { + std::initializer_list<int> x; } + diff --git a/test/std/utilities/utility/utility.swap/swap.pass.cpp b/test/std/utilities/utility/utility.swap/swap.pass.cpp index 8606611f6603c..c9c9f3b527605 100644 --- a/test/std/utilities/utility/utility.swap/swap.pass.cpp +++ b/test/std/utilities/utility/utility.swap/swap.pass.cpp @@ -16,38 +16,88 @@ #include <utility> #include <cassert> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #include <memory> -#endif -void -test() -{ - int i = 1; - int j = 2; - std::swap(i, j); - assert(i == 2); - assert(j == 1); -} +#include "test_macros.h" -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 +struct CopyOnly { + CopyOnly() {} + CopyOnly(CopyOnly const&) noexcept {} + CopyOnly& operator=(CopyOnly const&) { return *this; } +}; -void -test1() -{ - std::unique_ptr<int> i(new int(1)); - std::unique_ptr<int> j(new int(2)); - std::swap(i, j); - assert(*i == 2); - assert(*j == 1); -} +struct MoveOnly { + MoveOnly() {} + MoveOnly(MoveOnly&&) {} + MoveOnly& operator=(MoveOnly&&) noexcept { return *this; } +}; + +struct NoexceptMoveOnly { + NoexceptMoveOnly() {} + NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {} + NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; } +}; + +struct NotMoveConstructible { + NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; } +private: + NotMoveConstructible(NotMoveConstructible&&); +}; + +struct NotMoveAssignable { + NotMoveAssignable(NotMoveAssignable&&); +private: + NotMoveAssignable& operator=(NotMoveAssignable&&); +}; + +template <class Tp> +auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>())); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +template <class Tp> +auto can_swap_test(...) -> std::false_type; + +template <class Tp> +constexpr bool can_swap() { + return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value; +} +#endif int main() { - test(); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - test1(); + + { + int i = 1; + int j = 2; + std::swap(i, j); + assert(i == 2); + assert(j == 1); + } +#if TEST_STD_VER >= 11 + { + + std::unique_ptr<int> i(new int(1)); + std::unique_ptr<int> j(new int(2)); + std::swap(i, j); + assert(*i == 2); + assert(*j == 1); + + } + { + // test that the swap + static_assert(can_swap<CopyOnly&>(), ""); + static_assert(can_swap<MoveOnly&>(), ""); + static_assert(can_swap<NoexceptMoveOnly&>(), ""); + + static_assert(!can_swap<NotMoveConstructible&>(), ""); + static_assert(!can_swap<NotMoveAssignable&>(), ""); + + CopyOnly c; + MoveOnly m; + NoexceptMoveOnly nm; + static_assert(!noexcept(std::swap(c, c)), ""); + static_assert(!noexcept(std::swap(m, m)), ""); + static_assert(noexcept(std::swap(nm, nm)), ""); + } #endif } diff --git a/test/std/utilities/utility/utility.swap/swap_array.pass.cpp b/test/std/utilities/utility/utility.swap/swap_array.pass.cpp index b1209c3c3651b..ad39934b20cac 100644 --- a/test/std/utilities/utility/utility.swap/swap_array.pass.cpp +++ b/test/std/utilities/utility/utility.swap/swap_array.pass.cpp @@ -16,50 +16,86 @@ #include <utility> #include <cassert> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #include <memory> -#endif -void -test() -{ - int i[3] = {1, 2, 3}; - int j[3] = {4, 5, 6}; - std::swap(i, j); - assert(i[0] == 4); - assert(i[1] == 5); - assert(i[2] == 6); - assert(j[0] == 1); - assert(j[1] == 2); - assert(j[2] == 3); -} +#include "test_macros.h" -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -void -test1() -{ - std::unique_ptr<int> i[3]; - for (int k = 0; k < 3; ++k) - i[k].reset(new int(k+1)); - std::unique_ptr<int> j[3]; - for (int k = 0; k < 3; ++k) - j[k].reset(new int(k+4)); - std::swap(i, j); - assert(*i[0] == 4); - assert(*i[1] == 5); - assert(*i[2] == 6); - assert(*j[0] == 1); - assert(*j[1] == 2); - assert(*j[2] == 3); +#if TEST_STD_VER >= 11 +struct CopyOnly { + CopyOnly() {} + CopyOnly(CopyOnly const&) noexcept {} + CopyOnly& operator=(CopyOnly const&) { return *this; } +}; + + +struct NoexceptMoveOnly { + NoexceptMoveOnly() {} + NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {} + NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; } +}; + +struct NotMoveConstructible { + NotMoveConstructible() {} + NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; } +private: + NotMoveConstructible(NotMoveConstructible&&); +}; + +template <class Tp> +auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>())); + +template <class Tp> +auto can_swap_test(...) -> std::false_type; + +template <class Tp> +constexpr bool can_swap() { + return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value; } +#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES int main() { - test(); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - test1(); + { + int i[3] = {1, 2, 3}; + int j[3] = {4, 5, 6}; + std::swap(i, j); + assert(i[0] == 4); + assert(i[1] == 5); + assert(i[2] == 6); + assert(j[0] == 1); + assert(j[1] == 2); + assert(j[2] == 3); + } +#if TEST_STD_VER >= 11 + { + std::unique_ptr<int> i[3]; + for (int k = 0; k < 3; ++k) + i[k].reset(new int(k+1)); + std::unique_ptr<int> j[3]; + for (int k = 0; k < 3; ++k) + j[k].reset(new int(k+4)); + std::swap(i, j); + assert(*i[0] == 4); + assert(*i[1] == 5); + assert(*i[2] == 6); + assert(*j[0] == 1); + assert(*j[1] == 2); + assert(*j[2] == 3); + } + { + using CA = CopyOnly[42]; + using MA = NoexceptMoveOnly[42]; + using NA = NotMoveConstructible[42]; + static_assert(can_swap<CA&>(), ""); + static_assert(can_swap<MA&>(), ""); + static_assert(!can_swap<NA&>(), ""); + + CA ca; + MA ma; + static_assert(!noexcept(std::swap(ca, ca)), ""); + static_assert(noexcept(std::swap(ma, ma)), ""); + } #endif } |