diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:47:26 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:47:26 +0000 |
commit | 51072bd6bf79ef2bc6a922079bff57c31c1effbc (patch) | |
tree | 91a2effbc9e6f80bdbbf9eb70e06c51ad0867ea0 /test/std/utilities/function.objects/bind | |
parent | bb5e33f003797b67974a8893f7f2930fc51b8210 (diff) |
Notes
Diffstat (limited to 'test/std/utilities/function.objects/bind')
5 files changed, 197 insertions, 2 deletions
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); |