diff options
Diffstat (limited to 'test/std/utilities/function.objects')
35 files changed, 1100 insertions, 1269 deletions
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 3c093fc093c3..ce544c78b676 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 72b4b4a0a1fe..b85f439ba7a0 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 000000000000..5e347c4c5715 --- /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 000000000000..63d3c9b0de92 --- /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 4577d0bf4d54..a0c686de77ba 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 f69afbf57667..dbbd184c7833 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 246186040c56..68986ac1aeb3 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 48800a366a81..d5788986dd25 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 9f8e15dd55fe..db7168c44f8b 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 60415ec75d60..d4d99756fecc 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 164f09aa605c..50bdcceee1c9 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 e89c14e24625..0aacb81e9cb4 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 74fe166a0cd9..191d58d6e544 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 e6ba1f7f8a21..a6aca5d19569 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 3e710b3e0c70..777c25d520a9 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 000000000000..66d783a6e357 --- /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 41ce4bcae65f..f353fe7a72a6 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 97b0b4d158a0..d1ae6b7809ce 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 f371223ee84c..465e001c3deb 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 000000000000..c12fa7920974 --- /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 99d731a74543..d61c3773e539 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 e579f207a33f..000000000000 --- 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 b6fe190bd2a7..000000000000 --- 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 3f3c96a9b9bd..000000000000 --- 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 25681630a80c..000000000000 --- 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 a85b39f37175..000000000000 --- 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 aa6b743b5236..403d646f4216 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 f603da9dd131..387b371a9331 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 e9ecfa5539ce..cb45b30a9fd4 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 eb4eac65cd2c..e48b8f986916 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 6e3b7a2eee24..00e513ec546f 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 61e0bfa162d8..3c00bd20ac64 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 bd92a4ac4d2e..8aa2c1df8935 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 f1f198f23599..643e2d8c5d86 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 c20f31ff2c99..8954f4f3664b 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 } |