summaryrefslogtreecommitdiff
path: root/test/std/utilities/function.objects/bind
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:47:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:47:26 +0000
commit51072bd6bf79ef2bc6a922079bff57c31c1effbc (patch)
tree91a2effbc9e6f80bdbbf9eb70e06c51ad0867ea0 /test/std/utilities/function.objects/bind
parentbb5e33f003797b67974a8893f7f2930fc51b8210 (diff)
Notes
Diffstat (limited to 'test/std/utilities/function.objects/bind')
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/PR23141_invoke_not_constexpr.pass.cpp35
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/bind_return_type.pass.cpp131
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp1
-rw-r--r--test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp28
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);