From 58ff77c2e065af6a77d62299b31e0606c89ddedc Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Thu, 2 Jun 2016 05:44:14 +0000 Subject: Mark LWG issue 2545 as complete. Add extra tests llvm-svn: 271489 --- .../func.bind.bind/bind_return_type.pass.cpp | 131 +++++++++++++++++++++ .../func.bind.bind/invoke_lvalue.pass.cpp | 1 + 2 files changed, 132 insertions(+) create mode 100644 libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp (limited to 'libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind') diff --git a/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp b/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp new file mode 100644 index 00000000000..63d3c9b0de9 --- /dev/null +++ b/libcxx/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 + +// + +// template +// unspecified bind(Fn, Types...); +// template +// 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 +#include +#include + +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 +auto CheckCallImp(int) + -> decltype((std::declval()(std::declval()...)), std::true_type{}); + +template +auto CheckCallImp(long) -> std::false_type; + +template +constexpr bool CheckCall() { + return decltype(CheckCallImp(0))::value; +} + +template +void do_test(Fn* func) { + using namespace std::placeholders; + auto ret = std::bind(func, _1); + auto ret_r = std::bind(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::value, ""); + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + static_assert(std::is_same::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::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(), ""); + static_assert(CheckCall(), ""); + static_assert(CheckCall(), ""); + static_assert(!CheckCall(), ""); + static_assert(CheckCall(), ""); + static_assert(CheckCall(), ""); + } +} + + +// Test but with an explicit return type which differs from the real one. +template +void do_test_r(Fn* func) { + using namespace std::placeholders; + auto ret = std::bind(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::value, ""); + static_assert(std::is_same::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(), ""); + static_assert(CheckCall(), ""); + static_assert(CheckCall(), ""); + } +} + +int main() +{ + do_test(return_value); + do_test(return_lvalue); + do_test(return_const_lvalue); + do_test(return_rvalue); + do_test(return_const_rvalue); + + do_test_r(return_value); + do_test_r(return_lvalue); + do_test_r(return_const_lvalue); + do_test_r(return_rvalue); + do_test_r(return_const_rvalue); + +} diff --git a/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp b/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp index f69afbf5766..dbbd184c783 100644 --- a/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp +++ b/libcxx/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(); } -- cgit v1.2.3