summaryrefslogtreecommitdiff
path: root/test/std/utilities/function.objects
diff options
context:
space:
mode:
Diffstat (limited to 'test/std/utilities/function.objects')
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp2
-rw-r--r--test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp10
-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
-rw-r--r--test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp3
-rw-r--r--test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp7
-rw-r--r--test/std/utilities/function.objects/comparisons/equal_to.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/comparisons/greater.pass.cpp10
-rw-r--r--test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp10
-rw-r--r--test/std/utilities/function.objects/comparisons/less.pass.cpp9
-rw-r--r--test/std/utilities/function.objects/comparisons/less_equal.pass.cpp10
-rw-r--r--test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/comparisons/pointer_comparison_test_helper.hpp39
-rw-r--r--test/std/utilities/function.objects/comparisons/transparent.pass.cpp10
-rw-r--r--test/std/utilities/function.objects/func.invoke/invoke.pass.cpp80
-rw-r--r--test/std/utilities/function.objects/func.memfn/member_function.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/func.not_fn/not_fn.pass.cpp589
-rw-r--r--test/std/utilities/function.objects/func.require/INVOKE_tested_elsewhere.pass.cpp (renamed from test/std/utilities/function.objects/version.pass.cpp)14
-rw-r--r--test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp318
-rw-r--r--test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp164
-rw-r--r--test/std/utilities/function.objects/func.require/bullet_5.pass.cpp327
-rw-r--r--test/std/utilities/function.objects/func.require/invoke.pass.cpp50
-rw-r--r--test/std/utilities/function.objects/func.require/invoke_helpers.h326
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp66
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_move.pass.cpp (renamed from test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp)62
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp4
-rw-r--r--test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp2
-rw-r--r--test/std/utilities/function.objects/logical.operations/transparent.pass.cpp10
-rw-r--r--test/std/utilities/function.objects/refwrap/type_properties.pass.cpp7
-rw-r--r--test/std/utilities/function.objects/unord.hash/enum.pass.cpp6
-rw-r--r--test/std/utilities/function.objects/unord.hash/floating.pass.cpp2
-rw-r--r--test/std/utilities/function.objects/unord.hash/integral.pass.cpp21
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
}