You've already forked Zygisk-Assistant
mirror of
https://github.com/snake-4/Zygisk-Assistant.git
synced 2025-09-06 06:37:02 +00:00
Initial commit
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
// Make sure we can use std::function with a type that has a hostile overload
|
||||
// of operator&().
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "operator_hijacker.h"
|
||||
|
||||
struct TrapAddressof : operator_hijacker {
|
||||
int operator()() const { return 1; }
|
||||
};
|
||||
|
||||
int main(int, char**) {
|
||||
std::function<int()> f = TrapAddressof();
|
||||
assert(f() == 1);
|
||||
return 0;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
// XFAIL: c++11, c++14
|
||||
|
||||
// <functional>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct S : public std::function<void()> { using function::function; };
|
||||
|
||||
int main(int, char**) {
|
||||
S f1( [](){} );
|
||||
S f2(std::allocator_arg, std::allocator<int>{}, f1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
|
||||
// <functional>
|
||||
|
||||
// See https://llvm.org/PR20002
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
using Fn = std::function<void()>;
|
||||
struct S : public std::function<void()> { using function::function; };
|
||||
|
||||
int main(int, char**) {
|
||||
S s( [](){} );
|
||||
S f1( s );
|
||||
#if TEST_STD_VER <= 14
|
||||
S f2(std::allocator_arg, std::allocator<int>{}, s);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template <MoveConstructible R, MoveConstructible ... ArgTypes>
|
||||
// void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "count_new.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
explicit A(int j)
|
||||
{
|
||||
++count;
|
||||
data_[0] = j;
|
||||
}
|
||||
|
||||
A(const A& a)
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = a.data_[i];
|
||||
}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int id() const {return data_[0];}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) {return 0;}
|
||||
int h(int) {return 1;}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = A(1);
|
||||
std::function<int(int)> f2 = A(2);
|
||||
#if TEST_STD_VER >= 11
|
||||
static_assert(noexcept(swap(f1, f2)), "" );
|
||||
#endif
|
||||
assert(A::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(2));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 2);
|
||||
swap(f1, f2);
|
||||
assert(A::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(2));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 2);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = A(1);
|
||||
std::function<int(int)> f2 = g;
|
||||
#if TEST_STD_VER >= 11
|
||||
static_assert(noexcept(swap(f1, f2)), "" );
|
||||
#endif
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
|
||||
swap(f1, f2);
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = g;
|
||||
std::function<int(int)> f2 = A(1);
|
||||
#if TEST_STD_VER >= 11
|
||||
static_assert(noexcept(swap(f1, f2)), "" );
|
||||
#endif
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 1);
|
||||
swap(f1, f2);
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = g;
|
||||
std::function<int(int)> f2 = h;
|
||||
#if TEST_STD_VER >= 11
|
||||
static_assert(noexcept(swap(f1, f2)), "" );
|
||||
#endif
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
|
||||
RTTI_ASSERT(*f2.target<int(*)(int)>() == h);
|
||||
swap(f1, f2);
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(*f1.target<int(*)(int)>() == h);
|
||||
RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// explicit operator bool() const
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
static_assert(std::is_constructible<bool, std::function<void()> >::value, "");
|
||||
static_assert(!std::is_convertible<std::function<void()>, bool>::value, "");
|
||||
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
assert(!f);
|
||||
f = g;
|
||||
assert(f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function(F);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "count_new.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int foo(int) const {return 1;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
struct RValueCallable {
|
||||
template <class ...Args>
|
||||
void operator()(Args&&...) && {}
|
||||
};
|
||||
struct LValueCallable {
|
||||
template <class ...Args>
|
||||
void operator()(Args&&...) & {}
|
||||
};
|
||||
#endif
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = g;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>());
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = (int (*)(int))0;
|
||||
assert(!f);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
}
|
||||
{
|
||||
std::function<int(const A*, int)> f = &A::foo;
|
||||
assert(f);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int (A::*)(int) const>() != 0);
|
||||
}
|
||||
{
|
||||
std::function<void(int)> f(&g);
|
||||
assert(f);
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() != 0);
|
||||
f(1);
|
||||
}
|
||||
{
|
||||
std::function <void()> f(static_cast<void (*)()>(0));
|
||||
assert(!f);
|
||||
}
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
using Fn = std::function<void(int, int, int)>;
|
||||
static_assert(std::is_constructible<Fn, LValueCallable&>::value, "");
|
||||
static_assert(std::is_constructible<Fn, LValueCallable>::value, "");
|
||||
static_assert(!std::is_constructible<Fn, RValueCallable&>::value, "");
|
||||
static_assert(!std::is_constructible<Fn, RValueCallable>::value, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class F>
|
||||
// requires CopyConstructible<F> && Callable<F, ArgTypes..>
|
||||
// && Convertible<Callable<F, ArgTypes...>::result_type
|
||||
// operator=(F f);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "count_new.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int foo(int) const {return 1;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
struct RValueCallable {
|
||||
template <class ...Args>
|
||||
void operator()(Args&&...) && {}
|
||||
};
|
||||
struct LValueCallable {
|
||||
template <class ...Args>
|
||||
void operator()(Args&&...) & {}
|
||||
};
|
||||
#endif
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
f = A();
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
f = g;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>());
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
f = (int (*)(int))0;
|
||||
assert(!f);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
}
|
||||
{
|
||||
std::function<int(const A*, int)> f;
|
||||
f = &A::foo;
|
||||
assert(f);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int (A::*)(int) const>() != 0);
|
||||
}
|
||||
{
|
||||
std::function<void(int)> f;
|
||||
f = &g;
|
||||
assert(f);
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() != 0);
|
||||
f(1);
|
||||
}
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
using Fn = std::function<void(int, int, int)>;
|
||||
static_assert(std::is_assignable<Fn&, LValueCallable&>::value, "");
|
||||
static_assert(std::is_assignable<Fn&, LValueCallable>::value, "");
|
||||
static_assert(!std::is_assignable<Fn&, RValueCallable&>::value, "");
|
||||
static_assert(!std::is_assignable<Fn&, RValueCallable>::value, "");
|
||||
}
|
||||
{
|
||||
using Fn = std::function<void(int, int, int)>;
|
||||
static_assert(std::is_assignable<Fn&, Fn&&>::value, "");
|
||||
}
|
||||
{
|
||||
using F1 = std::function<void(int, int)>;
|
||||
using F2 = std::function<void(int, int, int)>;
|
||||
static_assert(!std::is_assignable<F1&, F2&&>::value, "");
|
||||
}
|
||||
{
|
||||
using F1 = std::function<int(int, int)>;
|
||||
using F2 = std::function<A (int, int)>;
|
||||
static_assert(!std::is_assignable<F1&, F2&&>::value, "");
|
||||
static_assert(!std::is_assignable<F2&, F1&&>::value, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class F> function(F);
|
||||
|
||||
// Allow incomplete argument types in the __is_callable check
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct X{
|
||||
typedef std::function<void(X&)> callback_type;
|
||||
virtual ~X() {}
|
||||
private:
|
||||
callback_type _cb;
|
||||
};
|
||||
|
||||
struct IncompleteReturnType {
|
||||
std::function<IncompleteReturnType ()> fn;
|
||||
};
|
||||
|
||||
|
||||
int called = 0;
|
||||
IncompleteReturnType test_fn() {
|
||||
++called;
|
||||
IncompleteReturnType I;
|
||||
return I;
|
||||
}
|
||||
|
||||
// See llvm.org/PR34298
|
||||
void test_pr34298()
|
||||
{
|
||||
static_assert(std::is_copy_constructible<IncompleteReturnType>::value, "");
|
||||
static_assert(std::is_copy_assignable<IncompleteReturnType>::value, "");
|
||||
{
|
||||
IncompleteReturnType X;
|
||||
X.fn = test_fn;
|
||||
const IncompleteReturnType& CX = X;
|
||||
IncompleteReturnType X2 = CX;
|
||||
assert(X2.fn);
|
||||
assert(called == 0);
|
||||
X2.fn();
|
||||
assert(called == 1);
|
||||
}
|
||||
{
|
||||
IncompleteReturnType Empty;
|
||||
IncompleteReturnType X2 = Empty;
|
||||
assert(!X2.fn);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test_pr34298();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function(Fp);
|
||||
|
||||
// Ensure that __not_null works for all function types.
|
||||
// See https://llvm.org/PR23589
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// TESTING std::function<...>::__not_null(Callable)
|
||||
//
|
||||
// Concerns:
|
||||
// 1) The call __not_null(Callable) is well formed and correct for each
|
||||
// possible 'Callable' type category. These categories include:
|
||||
// 1a) function pointers
|
||||
// 1b) member function pointer
|
||||
// 1c) member data pointer
|
||||
// 1d) callable class type
|
||||
// 1e) lambdas
|
||||
// Categories 1a, 1b, and 1c are 'Nullable' types. Only objects of these
|
||||
// types can be null. The other categories are not tested here.
|
||||
// 3) '__not_null(Callable)' is well formed when the call signature includes
|
||||
// varargs.
|
||||
// 4) '__not_null(Callable)' works for Callable types with all arities less
|
||||
// than or equal to 3 in C++03.
|
||||
// 5) '__not_null(Callable)' works when 'Callable' is a member function
|
||||
// pointer to a cv or ref qualified function type.
|
||||
//
|
||||
// Plan:
|
||||
// 1 For categories 1a, 1b and 1c define a set of
|
||||
// 'Callable' objects for this category. This set should include examples
|
||||
// of arity 0, 1, 2 and possible 3 including versions with varargs as the
|
||||
// last parameter.
|
||||
//
|
||||
// 2 For each 'Callable' object in categories 1a, 1b and 1c do the following.
|
||||
//
|
||||
// 1 Define a type 'std::function<Sig>' as 'F' where 'Sig' is compatible with
|
||||
// the signature of the 'Callable' object.
|
||||
//
|
||||
// 2 Create an object of type 'F' using a null pointer of type 'Callable'.
|
||||
// Check that 'F.target<Callable>()' is null.
|
||||
//
|
||||
// 3 Create an object of type 'F' that is not null. Check that
|
||||
// 'F.target<Callable>()' is not null and is equal to the original
|
||||
// argument.
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int foo() { return 42; }
|
||||
int foo(int) { return 42; }
|
||||
int foo(int, int) { return 42; }
|
||||
int foo(int, int, int) { return 42; }
|
||||
|
||||
int foo(...) { return 42; }
|
||||
int foo(int, ...) { return 42; }
|
||||
int foo(int, int, ...) { return 42; }
|
||||
int foo(int, int, int, ...) { return 42; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct MemFun03 {
|
||||
int foo() { return 42; }
|
||||
int foo() const { return 42; }
|
||||
int foo() volatile { return 42; }
|
||||
int foo() const volatile { return 42; }
|
||||
|
||||
int foo(int) { return 42; }
|
||||
int foo(int) const { return 42; }
|
||||
int foo(int) volatile { return 42; }
|
||||
int foo(int) const volatile { return 42; }
|
||||
|
||||
int foo(int, int) { return 42; }
|
||||
int foo(int, int) const { return 42; }
|
||||
int foo(int, int) volatile { return 42; }
|
||||
int foo(int, int) const volatile { return 42; }
|
||||
|
||||
int foo(int, int, int) { return 42; }
|
||||
int foo(int, int, int) const { return 42; }
|
||||
int foo(int, int, int) volatile { return 42; }
|
||||
int foo(int, int, int) const volatile { return 42; }
|
||||
|
||||
int foo(...) { return 42; }
|
||||
int foo(...) const { return 42; }
|
||||
int foo(...) volatile { return 42; }
|
||||
int foo(...) const volatile { return 42; }
|
||||
|
||||
int foo(int, ...) { return 42; }
|
||||
int foo(int, ...) const { return 42; }
|
||||
int foo(int, ...) volatile { return 42; }
|
||||
int foo(int, ...) const volatile { return 42; }
|
||||
|
||||
int foo(int, int, ...) { return 42; }
|
||||
int foo(int, int, ...) const { return 42; }
|
||||
int foo(int, int, ...) volatile { return 42; }
|
||||
int foo(int, int, ...) const volatile { return 42; }
|
||||
|
||||
int foo(int, int, int, ...) { return 42; }
|
||||
int foo(int, int, int, ...) const { return 42; }
|
||||
int foo(int, int, int, ...) volatile { return 42; }
|
||||
int foo(int, int, int, ...) const volatile { return 42; }
|
||||
};
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
struct MemFun11 {
|
||||
int foo() & { return 42; }
|
||||
int foo() const & { return 42; }
|
||||
int foo() volatile & { return 42; }
|
||||
int foo() const volatile & { return 42; }
|
||||
|
||||
int foo(...) & { return 42; }
|
||||
int foo(...) const & { return 42; }
|
||||
int foo(...) volatile & { return 42; }
|
||||
int foo(...) const volatile & { return 42; }
|
||||
|
||||
int foo() && { return 42; }
|
||||
int foo() const && { return 42; }
|
||||
int foo() volatile && { return 42; }
|
||||
int foo() const volatile && { return 42; }
|
||||
|
||||
int foo(...) && { return 42; }
|
||||
int foo(...) const && { return 42; }
|
||||
int foo(...) volatile && { return 42; }
|
||||
int foo(...) const volatile && { return 42; }
|
||||
};
|
||||
#endif // TEST_STD_VER >= 11
|
||||
|
||||
struct MemData {
|
||||
int foo;
|
||||
};
|
||||
|
||||
// Create a non-null free function by taking the address of
|
||||
// &static_cast<Tp&>(foo);
|
||||
template <class Tp>
|
||||
struct Creator {
|
||||
static Tp create() {
|
||||
return &foo;
|
||||
}
|
||||
};
|
||||
|
||||
// Create a non-null member pointer.
|
||||
template <class Ret, class Class>
|
||||
struct Creator<Ret Class::*> {
|
||||
typedef Ret Class::*ReturnType;
|
||||
static ReturnType create() {
|
||||
return &Class::foo;
|
||||
}
|
||||
};
|
||||
|
||||
template <class TestFn, class Fn>
|
||||
void test_imp() {
|
||||
{ // Check that the null value is detected
|
||||
TestFn tf = nullptr;
|
||||
std::function<Fn> f = tf;
|
||||
RTTI_ASSERT(f.template target<TestFn>() == nullptr);
|
||||
}
|
||||
{ // Check that the non-null value is detected.
|
||||
TestFn tf = Creator<TestFn>::create();
|
||||
assert(tf != nullptr);
|
||||
std::function<Fn> f = tf;
|
||||
RTTI_ASSERT(f.template target<TestFn>() != nullptr);
|
||||
RTTI_ASSERT(*f.template target<TestFn>() == tf);
|
||||
}
|
||||
}
|
||||
|
||||
void test_func() {
|
||||
test_imp<int(*)(), int()>();
|
||||
test_imp<int(*)(...), int()>();
|
||||
test_imp<int(*)(int), int(int)>();
|
||||
test_imp<int(*)(int, ...), int(int)>();
|
||||
test_imp<int(*)(int, int), int(int, int)>();
|
||||
test_imp<int(*)(int, int, ...), int(int, int)>();
|
||||
test_imp<int(*)(int, int, int), int(int, int, int)>();
|
||||
test_imp<int(*)(int, int, int, ...), int(int, int, int)>();
|
||||
}
|
||||
|
||||
void test_mf() {
|
||||
test_imp<int(MemFun03::*)(), int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...), int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)() const, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...) const, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)() volatile, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...) volatile, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)() const volatile, int(MemFun03&)>();
|
||||
test_imp<int(MemFun03::*)(...) const volatile, int(MemFun03&)>();
|
||||
|
||||
test_imp<int(MemFun03::*)(int), int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...), int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int) const, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...) const, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int) volatile, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...) volatile, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int) const volatile, int(MemFun03&, int)>();
|
||||
test_imp<int(MemFun03::*)(int, ...) const volatile, int(MemFun03&, int)>();
|
||||
|
||||
test_imp<int(MemFun03::*)(int, int), int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...), int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int) const, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...) const, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int) volatile, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...) volatile, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int) const volatile, int(MemFun03&, int, int)>();
|
||||
test_imp<int(MemFun03::*)(int, int, ...) const volatile, int(MemFun03&, int, int)>();
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
test_imp<int(MemFun11::*)() &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)() const &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) const &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)() volatile &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) volatile &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)() const volatile &, int(MemFun11&)>();
|
||||
test_imp<int(MemFun11::*)(...) const volatile &, int(MemFun11&)>();
|
||||
|
||||
test_imp<int(MemFun11::*)() &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)() const &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) const &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)() volatile &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) volatile &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)() const volatile &&, int(MemFun11&&)>();
|
||||
test_imp<int(MemFun11::*)(...) const volatile &&, int(MemFun11&&)>();
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_md() {
|
||||
test_imp<int MemData::*, int(MemData&)>();
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test_func();
|
||||
test_mf();
|
||||
test_md();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
// REQUIRES: c++03 || c++11 || c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
std::function<int(int)> f(std::allocator_arg, bare_allocator<int>());
|
||||
assert(!f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "min_allocator.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::function<int(int)> f(std::allocator_arg, std::allocator<int>()); // expected-error {{no matching constructor for initialization of}}
|
||||
return 0;
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
// REQUIRES: c++03 || c++11 || c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class F, class A> function(allocator_arg_t, const A&, F);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "min_allocator.h"
|
||||
#include "test_allocator.h"
|
||||
#include "count_new.h"
|
||||
#include "../function_types.h"
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
struct RValueCallable {
|
||||
template <class ...Args>
|
||||
void operator()(Args&&...) && {}
|
||||
};
|
||||
struct LValueCallable {
|
||||
template <class ...Args>
|
||||
void operator()(Args&&...) & {}
|
||||
};
|
||||
#endif
|
||||
|
||||
test_allocator_statistics alloc_stats;
|
||||
|
||||
class DummyClass {};
|
||||
|
||||
template <class FuncType, class AllocType>
|
||||
void test_FunctionObject(AllocType& alloc)
|
||||
{
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
FunctionObject target;
|
||||
assert(FunctionObject::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
std::function<FuncType> f2(std::allocator_arg, alloc, target);
|
||||
assert(FunctionObject::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
assert(f2.template target<FunctionObject>());
|
||||
assert(f2.template target<FuncType>() == 0);
|
||||
assert(f2.template target<FuncType*>() == 0);
|
||||
}
|
||||
assert(FunctionObject::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
}
|
||||
|
||||
|
||||
template <class FuncType, class AllocType>
|
||||
void test_FreeFunction(AllocType& alloc)
|
||||
{
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
FuncType* target = &FreeFunction;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
std::function<FuncType> f2(std::allocator_arg, alloc, target);
|
||||
// The allocator may not fit in the small object buffer, if we allocated
|
||||
// check it was done via the allocator.
|
||||
assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count));
|
||||
assert(f2.template target<FuncType*>());
|
||||
assert(*f2.template target<FuncType*>() == target);
|
||||
assert(f2.template target<FuncType>() == 0);
|
||||
assert(f2.template target<DummyClass>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
}
|
||||
|
||||
template <class TargetType, class FuncType, class AllocType>
|
||||
void test_MemFunClass(AllocType& alloc)
|
||||
{
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
TargetType target = &MemFunClass::foo;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
std::function<FuncType> f2(std::allocator_arg, alloc, target);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count));
|
||||
assert(f2.template target<TargetType>());
|
||||
assert(*f2.template target<TargetType>() == target);
|
||||
assert(f2.template target<FuncType*>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
}
|
||||
|
||||
template <class Alloc>
|
||||
void test_for_alloc(Alloc& alloc) {
|
||||
test_FunctionObject<int()>(alloc);
|
||||
test_FunctionObject<int(int)>(alloc);
|
||||
test_FunctionObject<int(int, int)>(alloc);
|
||||
test_FunctionObject<int(int, int, int)>(alloc);
|
||||
|
||||
test_FreeFunction<int()>(alloc);
|
||||
test_FreeFunction<int(int)>(alloc);
|
||||
test_FreeFunction<int(int, int)>(alloc);
|
||||
test_FreeFunction<int(int, int, int)>(alloc);
|
||||
|
||||
test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
|
||||
test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
|
||||
test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
globalMemCounter.reset();
|
||||
{
|
||||
bare_allocator<DummyClass> bare_alloc;
|
||||
test_for_alloc(bare_alloc);
|
||||
}
|
||||
{
|
||||
non_default_test_allocator<DummyClass> non_default_alloc(42, &alloc_stats);
|
||||
test_for_alloc(non_default_alloc);
|
||||
}
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
using Fn = std::function<void(int, int, int)>;
|
||||
static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable&>::value, "");
|
||||
static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable>::value, "");
|
||||
static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, "");
|
||||
static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class F, class A> function(allocator_arg_t, const A&, F);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
void foo(int) {}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::function<void(int)> f(std::allocator_arg, std::allocator<int>(), foo); // expected-error {{no matching constructor for initialization of}}
|
||||
return 0;
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
// REQUIRES: c++03 || c++11 || c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&, const function&);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "min_allocator.h"
|
||||
#include "test_allocator.h"
|
||||
#include "count_new.h"
|
||||
#include "../function_types.h"
|
||||
|
||||
class DummyClass {};
|
||||
|
||||
template <class FuncType, class AllocType>
|
||||
void test_FunctionObject(AllocType& alloc)
|
||||
{
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
// Construct function from FunctionObject.
|
||||
std::function<FuncType> f = FunctionObject();
|
||||
assert(FunctionObject::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.template target<FunctionObject>());
|
||||
RTTI_ASSERT(f.template target<FuncType>() == 0);
|
||||
RTTI_ASSERT(f.template target<FuncType*>() == 0);
|
||||
// Copy function with allocator
|
||||
std::function<FuncType> f2(std::allocator_arg, alloc, f);
|
||||
assert(FunctionObject::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(2));
|
||||
RTTI_ASSERT(f2.template target<FunctionObject>());
|
||||
RTTI_ASSERT(f2.template target<FuncType>() == 0);
|
||||
RTTI_ASSERT(f2.template target<FuncType*>() == 0);
|
||||
}
|
||||
assert(FunctionObject::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
}
|
||||
|
||||
template <class FuncType, class AllocType>
|
||||
void test_FreeFunction(AllocType& alloc)
|
||||
{
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
// Construct function from function pointer.
|
||||
FuncType* target = &FreeFunction;
|
||||
std::function<FuncType> f = target;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.template target<FuncType*>());
|
||||
RTTI_ASSERT(*f.template target<FuncType*>() == target);
|
||||
RTTI_ASSERT(f.template target<FuncType>() == 0);
|
||||
// Copy function with allocator
|
||||
std::function<FuncType> f2(std::allocator_arg, alloc, f);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f2.template target<FuncType*>());
|
||||
RTTI_ASSERT(*f2.template target<FuncType*>() == target);
|
||||
RTTI_ASSERT(f2.template target<FuncType>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
}
|
||||
|
||||
template <class TargetType, class FuncType, class AllocType>
|
||||
void test_MemFunClass(AllocType& alloc)
|
||||
{
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
// Construct function from function pointer.
|
||||
TargetType target = &MemFunClass::foo;
|
||||
std::function<FuncType> f = target;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.template target<TargetType>());
|
||||
RTTI_ASSERT(*f.template target<TargetType>() == target);
|
||||
RTTI_ASSERT(f.template target<FuncType*>() == 0);
|
||||
// Copy function with allocator
|
||||
std::function<FuncType> f2(std::allocator_arg, alloc, f);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f2.template target<TargetType>());
|
||||
RTTI_ASSERT(*f2.template target<TargetType>() == target);
|
||||
RTTI_ASSERT(f2.template target<FuncType*>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
}
|
||||
|
||||
template <class Alloc>
|
||||
void test_for_alloc(Alloc& alloc)
|
||||
{
|
||||
// Large FunctionObject -- Allocation should occur
|
||||
test_FunctionObject<int()>(alloc);
|
||||
test_FunctionObject<int(int)>(alloc);
|
||||
test_FunctionObject<int(int, int)>(alloc);
|
||||
test_FunctionObject<int(int, int, int)>(alloc);
|
||||
// Free function -- No allocation should occur
|
||||
test_FreeFunction<int()>(alloc);
|
||||
test_FreeFunction<int(int)>(alloc);
|
||||
test_FreeFunction<int(int, int)>(alloc);
|
||||
test_FreeFunction<int(int, int, int)>(alloc);
|
||||
// Member function -- No allocation should occur.
|
||||
test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
|
||||
test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
|
||||
test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
globalMemCounter.reset();
|
||||
{
|
||||
bare_allocator<DummyClass> alloc;
|
||||
test_for_alloc(alloc);
|
||||
}
|
||||
{
|
||||
non_default_test_allocator<DummyClass> alloc(42);
|
||||
test_for_alloc(alloc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&, const function&);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
typedef std::function<void(int)> F;
|
||||
F f1;
|
||||
F f2(std::allocator_arg, std::allocator<int>(), f1); // expected-error {{no matching constructor for initialization of}}
|
||||
return 0;
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
// REQUIRES: c++03 || c++11 || c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&, nullptr_t);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::function<int(int)> f(std::allocator_arg, bare_allocator<int>(), nullptr);
|
||||
assert(!f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&, nullptr_t);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "min_allocator.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::function<int(int)> f(std::allocator_arg, std::allocator<int>(), nullptr); // expected-error {{no matching constructor for initialization of}}
|
||||
return 0;
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
// REQUIRES: c++11 || c++14
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&, function&&);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "min_allocator.h"
|
||||
#include "count_new.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) { return 0; }
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
RTTI_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));
|
||||
RTTI_ASSERT(f2.target<A>());
|
||||
RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
RTTI_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);
|
||||
RTTI_ASSERT(f.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f.target<Ref>());
|
||||
std::function<int(int)> f2(std::allocator_arg, std::allocator<int>{},
|
||||
std::move(f));
|
||||
assert(A::count == 1);
|
||||
RTTI_ASSERT(f2.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f2.target<Ref>());
|
||||
RTTI_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);
|
||||
RTTI_ASSERT(f.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f.target<Ptr>());
|
||||
std::function<int(int)> f2(std::allocator_arg, std::allocator<int>(),
|
||||
std::move(f));
|
||||
RTTI_ASSERT(f2.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f2.target<Ptr>());
|
||||
RTTI_ASSERT(f.target<Ptr>()); // f is unchanged because the target is small
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class A> function(allocator_arg_t, const A&, function&&);
|
||||
//
|
||||
// This signature was removed in C++17
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) { return 0; }
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
std::function<int(int)> f2(std::allocator_arg, std::allocator<A>(), std::move(f)); // expected-error {{no matching constructor for initialization of}}
|
||||
return 0;
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function& operator=(const function& f);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "count_new.h"
|
||||
|
||||
class A {
|
||||
int data_[10];
|
||||
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A() {
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A &) { ++count; }
|
||||
|
||||
~A() { --count; }
|
||||
|
||||
int operator()(int i) const {
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g0() { return 0; }
|
||||
int g(int) { return 0; }
|
||||
int g2(int, int) { return 2; }
|
||||
int g3(int, int, int) { return 3; }
|
||||
|
||||
int main(int, char**) {
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
RTTI_ASSERT(f.target<int (*)(int)>() == 0);
|
||||
std::function<int(int)> f2;
|
||||
f2 = f;
|
||||
assert(A::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(2));
|
||||
RTTI_ASSERT(f2.target<A>());
|
||||
RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = g;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int (*)(int)>());
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
std::function<int(int)> f2;
|
||||
f2 = f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f2.target<int (*)(int)>());
|
||||
RTTI_ASSERT(f2.target<A>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int (*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
std::function<int(int)> f2;
|
||||
f2 = f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
|
||||
RTTI_ASSERT(f2.target<A>() == 0);
|
||||
}
|
||||
{
|
||||
typedef std::function<int()> Func;
|
||||
Func f = g0;
|
||||
Func& fr = (f = (Func &)f);
|
||||
assert(&fr == &f);
|
||||
RTTI_ASSERT(*f.target<int(*)()>() == g0);
|
||||
}
|
||||
{
|
||||
typedef std::function<int(int)> Func;
|
||||
Func f = g;
|
||||
Func& fr = (f = (Func &)f);
|
||||
assert(&fr == &f);
|
||||
RTTI_ASSERT(*f.target<int(*)(int)>() == g);
|
||||
}
|
||||
{
|
||||
typedef std::function<int(int, int)> Func;
|
||||
Func f = g2;
|
||||
Func& fr = (f = (Func &)f);
|
||||
assert(&fr == &f);
|
||||
RTTI_ASSERT(*f.target<int(*)(int, int)>() == g2);
|
||||
}
|
||||
{
|
||||
typedef std::function<int(int, int, int)> Func;
|
||||
Func f = g3;
|
||||
Func& fr = (f = (Func &)f);
|
||||
assert(&fr == &f);
|
||||
RTTI_ASSERT(*f.target<int(*)(int, int, int)>() == g3);
|
||||
}
|
||||
#if TEST_STD_VER >= 11
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
RTTI_ASSERT(f.target<int (*)(int)>() == 0);
|
||||
std::function<int(int)> f2;
|
||||
f2 = std::move(f);
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f2.target<A>());
|
||||
RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
RTTI_ASSERT(f.target<int (*)(int)>() == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// FIXME: In MSVC mode, even "std::function<int(int)> f(aref);" causes
|
||||
// allocations.
|
||||
// XFAIL: target=x86_64-pc-windows-msvc && stdlib=libc++
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function(const function& f);
|
||||
// function(function&& f); // noexcept in C++20
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "count_new.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
std::function<int(int)> f2 = f;
|
||||
assert(A::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(2));
|
||||
RTTI_ASSERT(f2.target<A>());
|
||||
RTTI_ASSERT(f2.target<int(*)(int)>() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = g;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>());
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
std::function<int(int)> f2 = f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f2.target<int(*)(int)>());
|
||||
RTTI_ASSERT(f2.target<A>() == 0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
std::function<int(int)> f2 = f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f2.target<int(*)(int)>() == 0);
|
||||
RTTI_ASSERT(f2.target<A>() == 0);
|
||||
}
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
assert(!f);
|
||||
std::function<long(int)> g = f;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(g.target<long(*)(int)>() == 0);
|
||||
RTTI_ASSERT(g.target<A>() == 0);
|
||||
assert(!g);
|
||||
}
|
||||
#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));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
|
||||
#if TEST_STD_VER > 17
|
||||
ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
|
||||
#endif
|
||||
std::function<int(int)> f2 = std::move(f);
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f2.target<A>());
|
||||
RTTI_ASSERT(f2.target<int(*)(int)>() == 0);
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
RTTI_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);
|
||||
RTTI_ASSERT(f.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f.target<Ref>());
|
||||
LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
|
||||
#if TEST_STD_VER > 17
|
||||
ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
|
||||
#endif
|
||||
std::function<int(int)> f2(std::move(f));
|
||||
assert(A::count == 1);
|
||||
RTTI_ASSERT(f2.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f2.target<Ref>());
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
RTTI_ASSERT(f.target<Ref>()); // f is unchanged because the target is small
|
||||
#endif
|
||||
}
|
||||
{
|
||||
// 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);
|
||||
RTTI_ASSERT(f.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f.target<Ptr>());
|
||||
LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
|
||||
#if TEST_STD_VER > 17
|
||||
ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));
|
||||
#endif
|
||||
std::function<int(int)> f2(std::move(f));
|
||||
RTTI_ASSERT(f2.target<A>() == nullptr);
|
||||
RTTI_ASSERT(f2.target<Ptr>());
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
RTTI_ASSERT(f.target<Ptr>()); // f is unchanged because the target is small
|
||||
#endif
|
||||
}
|
||||
#endif // TEST_STD_VER >= 11
|
||||
|
||||
return 0;
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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>
|
||||
|
||||
// template<class F>
|
||||
// function(F) -> function<see-below>;
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// The deduction guides for std::function do not handle rvalue-ref qualified
|
||||
// call operators and C-style variadics. It also doesn't deduce from nullptr_t.
|
||||
// Make sure we stick to the specification.
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
struct R { };
|
||||
struct f0 { R operator()() && { return {}; } };
|
||||
struct f1 { R operator()(int, ...) { return {}; } };
|
||||
|
||||
int main(int, char**) {
|
||||
std::function f = f0{}; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'function'}}
|
||||
std::function g = f1{}; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'function'}}
|
||||
std::function h = nullptr; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'function'}}
|
||||
return 0;
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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>
|
||||
|
||||
// template<class F>
|
||||
// function(F) -> function<see-below>;
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct R { };
|
||||
struct A1 { };
|
||||
struct A2 { };
|
||||
struct A3 { };
|
||||
|
||||
#define DECLARE_FUNCTIONS_WITH_QUALS(N, ...) \
|
||||
struct f0_##N { R operator()() __VA_ARGS__ { return {}; } }; \
|
||||
struct f1_##N { R operator()(A1) __VA_ARGS__ { return {}; } }; \
|
||||
struct f2_##N { R operator()(A1, A2) __VA_ARGS__ { return {}; } }; \
|
||||
struct f3_##N { R operator()(A1, A2, A3) __VA_ARGS__ { return {}; } } \
|
||||
/**/
|
||||
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(0, /* nothing */);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(1, const);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(2, volatile);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(3, const volatile);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(4, &);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(5 , const &);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(6 , volatile &);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(7 , const volatile &);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(8 , noexcept);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(9 , const noexcept);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(10, volatile noexcept);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(11, const volatile noexcept);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(12, & noexcept);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(13, const & noexcept);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(14, volatile & noexcept);
|
||||
DECLARE_FUNCTIONS_WITH_QUALS(15, const volatile & noexcept);
|
||||
|
||||
int main(int, char**) {
|
||||
#define CHECK_FUNCTIONS(N) \
|
||||
do { \
|
||||
/* implicit */ \
|
||||
std::function g0 = f0_##N{}; \
|
||||
ASSERT_SAME_TYPE(decltype(g0), std::function<R()>); \
|
||||
\
|
||||
std::function g1 = f1_##N{}; \
|
||||
ASSERT_SAME_TYPE(decltype(g1), std::function<R(A1)>); \
|
||||
\
|
||||
std::function g2 = f2_##N{}; \
|
||||
ASSERT_SAME_TYPE(decltype(g2), std::function<R(A1, A2)>); \
|
||||
\
|
||||
std::function g3 = f3_##N{}; \
|
||||
ASSERT_SAME_TYPE(decltype(g3), std::function<R(A1, A2, A3)>); \
|
||||
\
|
||||
/* explicit */ \
|
||||
std::function g4{f0_##N{}}; \
|
||||
ASSERT_SAME_TYPE(decltype(g4), std::function<R()>); \
|
||||
\
|
||||
std::function g5{f1_##N{}}; \
|
||||
ASSERT_SAME_TYPE(decltype(g5), std::function<R(A1)>); \
|
||||
\
|
||||
std::function g6{f2_##N{}}; \
|
||||
ASSERT_SAME_TYPE(decltype(g6), std::function<R(A1, A2)>); \
|
||||
\
|
||||
std::function g7{f3_##N{}}; \
|
||||
ASSERT_SAME_TYPE(decltype(g7), std::function<R(A1, A2, A3)>); \
|
||||
\
|
||||
/* from std::function */ \
|
||||
std::function<R(A1)> unary; \
|
||||
std::function g8 = unary; \
|
||||
ASSERT_SAME_TYPE(decltype(g8), std::function<R(A1)>); \
|
||||
\
|
||||
std::function g9 = std::move(unary); \
|
||||
ASSERT_SAME_TYPE(decltype(g9), std::function<R(A1)>); \
|
||||
\
|
||||
std::function<R(A1&&)> unary_ref; \
|
||||
std::function g10 = unary_ref; \
|
||||
ASSERT_SAME_TYPE(decltype(g10), std::function<R(A1&&)>); \
|
||||
\
|
||||
std::function g11 = std::move(unary_ref); \
|
||||
ASSERT_SAME_TYPE(decltype(g11), std::function<R(A1&&)>); \
|
||||
} while (false) \
|
||||
/**/
|
||||
|
||||
// Make sure we can deduce from function objects with valid call operators
|
||||
CHECK_FUNCTIONS(0);
|
||||
CHECK_FUNCTIONS(1);
|
||||
CHECK_FUNCTIONS(2);
|
||||
CHECK_FUNCTIONS(3);
|
||||
CHECK_FUNCTIONS(4);
|
||||
CHECK_FUNCTIONS(5);
|
||||
CHECK_FUNCTIONS(6);
|
||||
CHECK_FUNCTIONS(7);
|
||||
CHECK_FUNCTIONS(8);
|
||||
CHECK_FUNCTIONS(9);
|
||||
CHECK_FUNCTIONS(10);
|
||||
CHECK_FUNCTIONS(11);
|
||||
CHECK_FUNCTIONS(12);
|
||||
CHECK_FUNCTIONS(13);
|
||||
CHECK_FUNCTIONS(14);
|
||||
CHECK_FUNCTIONS(15);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make sure we fail in a SFINAE-friendly manner when we try to deduce
|
||||
// from a type without a valid call operator.
|
||||
template <typename F, typename = decltype(std::function{std::declval<F>()})>
|
||||
constexpr bool can_deduce() { return true; }
|
||||
template <typename F>
|
||||
constexpr bool can_deduce(...) { return false; }
|
||||
|
||||
struct invalid1 { };
|
||||
struct invalid2 {
|
||||
template <typename ...Args>
|
||||
void operator()(Args ...);
|
||||
};
|
||||
struct invalid3 {
|
||||
void operator()(int);
|
||||
void operator()(long);
|
||||
};
|
||||
static_assert(!can_deduce<invalid1>());
|
||||
static_assert(!can_deduce<invalid2>());
|
||||
static_assert(!can_deduce<invalid3>());
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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>
|
||||
|
||||
// template<class R, class ...Args>
|
||||
// function(R(*)(Args...)) -> function<R(Args...)>;
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct R { };
|
||||
struct A1 { };
|
||||
struct A2 { };
|
||||
struct A3 { };
|
||||
|
||||
R f0() { return {}; }
|
||||
R f1(A1) { return {}; }
|
||||
R f2(A1, A2) { return {}; }
|
||||
R f3(A1, A2, A3) { return {}; }
|
||||
R f4(A1 = {}) { return {}; }
|
||||
|
||||
int main(int, char**) {
|
||||
{
|
||||
// implicit
|
||||
std::function a = f0;
|
||||
ASSERT_SAME_TYPE(decltype(a), std::function<R()>);
|
||||
|
||||
std::function b = &f0;
|
||||
ASSERT_SAME_TYPE(decltype(b), std::function<R()>);
|
||||
|
||||
// explicit
|
||||
std::function c{f0};
|
||||
ASSERT_SAME_TYPE(decltype(c), std::function<R()>);
|
||||
|
||||
std::function d{&f0};
|
||||
ASSERT_SAME_TYPE(decltype(d), std::function<R()>);
|
||||
}
|
||||
{
|
||||
// implicit
|
||||
std::function a = f1;
|
||||
ASSERT_SAME_TYPE(decltype(a), std::function<R(A1)>);
|
||||
|
||||
std::function b = &f1;
|
||||
ASSERT_SAME_TYPE(decltype(b), std::function<R(A1)>);
|
||||
|
||||
// explicit
|
||||
std::function c{f1};
|
||||
ASSERT_SAME_TYPE(decltype(c), std::function<R(A1)>);
|
||||
|
||||
std::function d{&f1};
|
||||
ASSERT_SAME_TYPE(decltype(d), std::function<R(A1)>);
|
||||
}
|
||||
{
|
||||
// implicit
|
||||
std::function a = f2;
|
||||
ASSERT_SAME_TYPE(decltype(a), std::function<R(A1, A2)>);
|
||||
|
||||
std::function b = &f2;
|
||||
ASSERT_SAME_TYPE(decltype(b), std::function<R(A1, A2)>);
|
||||
|
||||
// explicit
|
||||
std::function c{f2};
|
||||
ASSERT_SAME_TYPE(decltype(c), std::function<R(A1, A2)>);
|
||||
|
||||
std::function d{&f2};
|
||||
ASSERT_SAME_TYPE(decltype(d), std::function<R(A1, A2)>);
|
||||
}
|
||||
{
|
||||
// implicit
|
||||
std::function a = f3;
|
||||
ASSERT_SAME_TYPE(decltype(a), std::function<R(A1, A2, A3)>);
|
||||
|
||||
std::function b = &f3;
|
||||
ASSERT_SAME_TYPE(decltype(b), std::function<R(A1, A2, A3)>);
|
||||
|
||||
// explicit
|
||||
std::function c{f3};
|
||||
ASSERT_SAME_TYPE(decltype(c), std::function<R(A1, A2, A3)>);
|
||||
|
||||
std::function d{&f3};
|
||||
ASSERT_SAME_TYPE(decltype(d), std::function<R(A1, A2, A3)>);
|
||||
}
|
||||
// Make sure defaulted arguments don't mess up the deduction
|
||||
{
|
||||
// implicit
|
||||
std::function a = f4;
|
||||
ASSERT_SAME_TYPE(decltype(a), std::function<R(A1)>);
|
||||
|
||||
std::function b = &f4;
|
||||
ASSERT_SAME_TYPE(decltype(b), std::function<R(A1)>);
|
||||
|
||||
// explicit
|
||||
std::function c{f4};
|
||||
ASSERT_SAME_TYPE(decltype(c), std::function<R(A1)>);
|
||||
|
||||
std::function d{&f4};
|
||||
ASSERT_SAME_TYPE(decltype(d), std::function<R(A1)>);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function();
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
assert(!f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function(nullptr_t);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::function<int(int)> f(nullptr);
|
||||
assert(!f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function& operator=(nullptr_t);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "count_new.h"
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f.target<A>());
|
||||
f = nullptr;
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
}
|
||||
{
|
||||
std::function<int(int)> f = g;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>());
|
||||
RTTI_ASSERT(f.target<A>() == 0);
|
||||
f = nullptr;
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(f.target<int(*)(int)>() == 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// R operator()(ArgTypes... args) const
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
// member data pointer: cv qualifiers should transfer from argument to return type
|
||||
|
||||
struct A_int_1
|
||||
{
|
||||
A_int_1() : data_(5) {}
|
||||
|
||||
int data_;
|
||||
};
|
||||
|
||||
void
|
||||
test_int_1()
|
||||
{
|
||||
// member data pointer
|
||||
{
|
||||
int A_int_1::*fp = &A_int_1::data_;
|
||||
A_int_1 a;
|
||||
std::function<int& (const A_int_1*)> r2(fp);
|
||||
const A_int_1* ap = &a;
|
||||
assert(r2(ap) == 6);
|
||||
r2(ap) = 7;
|
||||
assert(r2(ap) == 7);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test_int_1();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+432
@@ -0,0 +1,432 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// R operator()(ArgTypes... args) const
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
// Address Sanitizer doesn't instrument weak symbols on Linux. When a key
|
||||
// function is defined for bad_function_call's vtable, its typeinfo and vtable
|
||||
// will be defined as strong symbols in the library and weak symbols in other
|
||||
// translation units. Only the strong symbol will be instrumented, increasing
|
||||
// its size (due to the redzone) and leading to a serious ODR violation
|
||||
// resulting in a crash.
|
||||
// Some relevant bugs:
|
||||
// https://github.com/google/sanitizers/issues/1017
|
||||
// https://github.com/google/sanitizers/issues/619
|
||||
// https://github.com/google/sanitizers/issues/398
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016
|
||||
// UNSUPPORTED: asan
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
|
||||
int count = 0;
|
||||
|
||||
|
||||
// 0 args, return int
|
||||
|
||||
int f_int_0()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
struct A_int_0
|
||||
{
|
||||
int operator()() {return 4;}
|
||||
};
|
||||
|
||||
void test_int_0()
|
||||
{
|
||||
// function
|
||||
{
|
||||
std::function<int ()> r1(f_int_0);
|
||||
assert(r1() == 3);
|
||||
}
|
||||
// function pointer
|
||||
{
|
||||
int (*fp)() = f_int_0;
|
||||
std::function<int ()> r1(fp);
|
||||
assert(r1() == 3);
|
||||
}
|
||||
// functor
|
||||
{
|
||||
A_int_0 a0;
|
||||
std::function<int ()> r1(a0);
|
||||
assert(r1() == 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 0 args, return void
|
||||
|
||||
void f_void_0()
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
struct A_void_0
|
||||
{
|
||||
void operator()() {++count;}
|
||||
};
|
||||
|
||||
void
|
||||
test_void_0()
|
||||
{
|
||||
int save_count = count;
|
||||
// function
|
||||
{
|
||||
std::function<void ()> r1(f_void_0);
|
||||
r1();
|
||||
assert(count == save_count+1);
|
||||
save_count = count;
|
||||
}
|
||||
// function pointer
|
||||
{
|
||||
void (*fp)() = f_void_0;
|
||||
std::function<void ()> r1(fp);
|
||||
r1();
|
||||
assert(count == save_count+1);
|
||||
save_count = count;
|
||||
}
|
||||
// functor
|
||||
{
|
||||
A_void_0 a0;
|
||||
std::function<void ()> r1(a0);
|
||||
r1();
|
||||
assert(count == save_count+1);
|
||||
save_count = count;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 arg, return void
|
||||
|
||||
void f_void_1(int i)
|
||||
{
|
||||
count += i;
|
||||
}
|
||||
|
||||
struct A_void_1
|
||||
{
|
||||
void operator()(int i)
|
||||
{
|
||||
count += i;
|
||||
}
|
||||
|
||||
void mem1() {++count;}
|
||||
void mem2() const {++count;}
|
||||
};
|
||||
|
||||
void
|
||||
test_void_1()
|
||||
{
|
||||
int save_count = count;
|
||||
// function
|
||||
{
|
||||
std::function<void (int)> r1(f_void_1);
|
||||
int i = 2;
|
||||
r1(i);
|
||||
assert(count == save_count+2);
|
||||
save_count = count;
|
||||
}
|
||||
// function pointer
|
||||
{
|
||||
void (*fp)(int) = f_void_1;
|
||||
std::function<void (int)> r1(fp);
|
||||
int i = 3;
|
||||
r1(i);
|
||||
assert(count == save_count+3);
|
||||
save_count = count;
|
||||
}
|
||||
// functor
|
||||
{
|
||||
A_void_1 a0;
|
||||
std::function<void (int)> r1(a0);
|
||||
int i = 4;
|
||||
r1(i);
|
||||
assert(count == save_count+4);
|
||||
save_count = count;
|
||||
}
|
||||
// member function pointer
|
||||
{
|
||||
void (A_void_1::*fp)() = &A_void_1::mem1;
|
||||
std::function<void (A_void_1)> r1(fp);
|
||||
A_void_1 a;
|
||||
r1(a);
|
||||
assert(count == save_count+1);
|
||||
save_count = count;
|
||||
A_void_1* ap = &a;
|
||||
std::function<void (A_void_1*)> r2 = fp;
|
||||
r2(ap);
|
||||
assert(count == save_count+1);
|
||||
save_count = count;
|
||||
}
|
||||
// const member function pointer
|
||||
{
|
||||
void (A_void_1::*fp)() const = &A_void_1::mem2;
|
||||
std::function<void (A_void_1)> r1(fp);
|
||||
A_void_1 a;
|
||||
r1(a);
|
||||
assert(count == save_count+1);
|
||||
save_count = count;
|
||||
std::function<void (A_void_1*)> r2(fp);
|
||||
A_void_1* ap = &a;
|
||||
r2(ap);
|
||||
assert(count == save_count+1);
|
||||
save_count = count;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 arg, return int
|
||||
|
||||
int f_int_1(int i)
|
||||
{
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
struct A_int_1
|
||||
{
|
||||
A_int_1() : data_(5) {}
|
||||
int operator()(int i)
|
||||
{
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
int mem1() {return 3;}
|
||||
int mem2() const {return 4;}
|
||||
int data_;
|
||||
};
|
||||
|
||||
void
|
||||
test_int_1()
|
||||
{
|
||||
// function
|
||||
{
|
||||
std::function<int (int)> r1(f_int_1);
|
||||
int i = 2;
|
||||
assert(r1(i) == 3);
|
||||
}
|
||||
// function pointer
|
||||
{
|
||||
int (*fp)(int) = f_int_1;
|
||||
std::function<int (int)> r1(fp);
|
||||
int i = 3;
|
||||
assert(r1(i) == 4);
|
||||
}
|
||||
// functor
|
||||
{
|
||||
A_int_1 a0;
|
||||
std::function<int (int)> r1(a0);
|
||||
int i = 4;
|
||||
assert(r1(i) == 3);
|
||||
}
|
||||
// member function pointer
|
||||
{
|
||||
int (A_int_1::*fp)() = &A_int_1::mem1;
|
||||
std::function<int (A_int_1)> r1(fp);
|
||||
A_int_1 a;
|
||||
assert(r1(a) == 3);
|
||||
std::function<int (A_int_1*)> r2(fp);
|
||||
A_int_1* ap = &a;
|
||||
assert(r2(ap) == 3);
|
||||
}
|
||||
// const member function pointer
|
||||
{
|
||||
int (A_int_1::*fp)() const = &A_int_1::mem2;
|
||||
std::function<int (A_int_1)> r1(fp);
|
||||
A_int_1 a;
|
||||
assert(r1(a) == 4);
|
||||
std::function<int (A_int_1*)> r2(fp);
|
||||
A_int_1* ap = &a;
|
||||
assert(r2(ap) == 4);
|
||||
}
|
||||
// member data pointer
|
||||
{
|
||||
int A_int_1::*fp = &A_int_1::data_;
|
||||
std::function<int& (A_int_1&)> r1(fp);
|
||||
A_int_1 a;
|
||||
assert(r1(a) == 5);
|
||||
r1(a) = 6;
|
||||
assert(r1(a) == 6);
|
||||
std::function<int& (A_int_1*)> r2(fp);
|
||||
A_int_1* ap = &a;
|
||||
assert(r2(ap) == 6);
|
||||
r2(ap) = 7;
|
||||
assert(r2(ap) == 7);
|
||||
}
|
||||
}
|
||||
|
||||
// 2 arg, return void
|
||||
|
||||
void f_void_2(int i, int j)
|
||||
{
|
||||
count += i+j;
|
||||
}
|
||||
|
||||
struct A_void_2
|
||||
{
|
||||
void operator()(int i, int j)
|
||||
{
|
||||
count += i+j;
|
||||
}
|
||||
|
||||
void mem1(int i) {count += i;}
|
||||
void mem2(int i) const {count += i;}
|
||||
};
|
||||
|
||||
void
|
||||
test_void_2()
|
||||
{
|
||||
int save_count = count;
|
||||
// function
|
||||
{
|
||||
std::function<void (int, int)> r1(f_void_2);
|
||||
int i = 2;
|
||||
int j = 3;
|
||||
r1(i, j);
|
||||
assert(count == save_count+5);
|
||||
save_count = count;
|
||||
}
|
||||
// function pointer
|
||||
{
|
||||
void (*fp)(int, int) = f_void_2;
|
||||
std::function<void (int, int)> r1(fp);
|
||||
int i = 3;
|
||||
int j = 4;
|
||||
r1(i, j);
|
||||
assert(count == save_count+7);
|
||||
save_count = count;
|
||||
}
|
||||
// functor
|
||||
{
|
||||
A_void_2 a0;
|
||||
std::function<void (int, int)> r1(a0);
|
||||
int i = 4;
|
||||
int j = 5;
|
||||
r1(i, j);
|
||||
assert(count == save_count+9);
|
||||
save_count = count;
|
||||
}
|
||||
// member function pointer
|
||||
{
|
||||
void (A_void_2::*fp)(int) = &A_void_2::mem1;
|
||||
std::function<void (A_void_2, int)> r1(fp);
|
||||
A_void_2 a;
|
||||
int i = 3;
|
||||
r1(a, i);
|
||||
assert(count == save_count+3);
|
||||
save_count = count;
|
||||
std::function<void (A_void_2*, int)> r2(fp);
|
||||
A_void_2* ap = &a;
|
||||
r2(ap, i);
|
||||
assert(count == save_count+3);
|
||||
save_count = count;
|
||||
}
|
||||
// const member function pointer
|
||||
{
|
||||
void (A_void_2::*fp)(int) const = &A_void_2::mem2;
|
||||
std::function<void (A_void_2, int)> r1(fp);
|
||||
A_void_2 a;
|
||||
int i = 4;
|
||||
r1(a, i);
|
||||
assert(count == save_count+4);
|
||||
save_count = count;
|
||||
std::function<void (A_void_2*, int)> r2(fp);
|
||||
A_void_2* ap = &a;
|
||||
r2(ap, i);
|
||||
assert(count == save_count+4);
|
||||
save_count = count;
|
||||
}
|
||||
}
|
||||
|
||||
// 2 arg, return int
|
||||
|
||||
int f_int_2(int i, int j)
|
||||
{
|
||||
return i+j;
|
||||
}
|
||||
|
||||
struct A_int_2
|
||||
{
|
||||
int operator()(int i, int j)
|
||||
{
|
||||
return i+j;
|
||||
}
|
||||
|
||||
int mem1(int i) {return i+1;}
|
||||
int mem2(int i) const {return i+2;}
|
||||
};
|
||||
|
||||
void test_int_2()
|
||||
{
|
||||
// function
|
||||
{
|
||||
std::function<int (int, int)> r1(f_int_2);
|
||||
int i = 2;
|
||||
int j = 3;
|
||||
assert(r1(i, j) == i+j);
|
||||
}
|
||||
// function pointer
|
||||
{
|
||||
int (*fp)(int, int) = f_int_2;
|
||||
std::function<int (int, int)> r1(fp);
|
||||
int i = 3;
|
||||
int j = 4;
|
||||
assert(r1(i, j) == i+j);
|
||||
}
|
||||
// functor
|
||||
{
|
||||
A_int_2 a0;
|
||||
std::function<int (int, int)> r1(a0);
|
||||
int i = 4;
|
||||
int j = 5;
|
||||
assert(r1(i, j) == i+j);
|
||||
}
|
||||
// member function pointer
|
||||
{
|
||||
int(A_int_2::*fp)(int) = &A_int_2::mem1;
|
||||
std::function<int (A_int_2, int)> r1(fp);
|
||||
A_int_2 a;
|
||||
int i = 3;
|
||||
assert(r1(a, i) == i+1);
|
||||
std::function<int (A_int_2*, int)> r2(fp);
|
||||
A_int_2* ap = &a;
|
||||
assert(r2(ap, i) == i+1);
|
||||
}
|
||||
// const member function pointer
|
||||
{
|
||||
int (A_int_2::*fp)(int) const = &A_int_2::mem2;
|
||||
std::function<int (A_int_2, int)> r1(fp);
|
||||
A_int_2 a;
|
||||
int i = 4;
|
||||
assert(r1(a, i) == i+2);
|
||||
std::function<int (A_int_2*, int)> r2(fp);
|
||||
A_int_2* ap = &a;
|
||||
assert(r2(ap, i) == i+2);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test_void_0();
|
||||
test_int_0();
|
||||
test_void_1();
|
||||
test_int_1();
|
||||
test_void_2();
|
||||
test_int_2();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<class F, class A> void assign(F&&, const A&);
|
||||
// This call was removed post-C++14
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "test_allocator.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int foo(int) const {return 1;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
#if TEST_STD_VER <= 14
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
f.assign(A(), test_allocator<A>());
|
||||
assert(A::count == 1);
|
||||
assert(f.target<A>());
|
||||
assert(f.target<int(*)(int)>() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// void swap(function& other);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "count_new.h"
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
class A {
|
||||
int data_[10];
|
||||
|
||||
public:
|
||||
static int count;
|
||||
|
||||
explicit A(int j) {
|
||||
++count;
|
||||
data_[0] = j;
|
||||
}
|
||||
|
||||
A(const A &a) {
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = a.data_[i];
|
||||
}
|
||||
|
||||
~A() { --count; }
|
||||
|
||||
int operator()(int i) const {
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int operator()() const { return -1; }
|
||||
int operator()(int, int) const { return -2; }
|
||||
int operator()(int, int, int) const { return -3; }
|
||||
|
||||
int id() const { return data_[0]; }
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g0() { return 0; }
|
||||
int g(int) { return 0; }
|
||||
int h(int) { return 1; }
|
||||
int g2(int, int) { return 2; }
|
||||
int g3(int, int, int) { return 3; }
|
||||
|
||||
int main(int, char**) {
|
||||
globalMemCounter.reset();
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = A(1);
|
||||
std::function<int(int)> f2 = A(2);
|
||||
assert(A::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(2));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 2);
|
||||
f1.swap(f2);
|
||||
assert(A::count == 2);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(2));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 2);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = A(1);
|
||||
std::function<int(int)> f2 = g;
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
RTTI_ASSERT(*f2.target<int (*)(int)>() == g);
|
||||
f1.swap(f2);
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(*f1.target<int (*)(int)>() == g);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = g;
|
||||
std::function<int(int)> f2 = A(1);
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(*f1.target<int (*)(int)>() == g);
|
||||
RTTI_ASSERT(f2.target<A>()->id() == 1);
|
||||
f1.swap(f2);
|
||||
assert(A::count == 1);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(1));
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
RTTI_ASSERT(*f2.target<int (*)(int)>() == g);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = g;
|
||||
std::function<int(int)> f2 = h;
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(*f1.target<int (*)(int)>() == g);
|
||||
RTTI_ASSERT(*f2.target<int (*)(int)>() == h);
|
||||
f1.swap(f2);
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
RTTI_ASSERT(*f1.target<int (*)(int)>() == h);
|
||||
RTTI_ASSERT(*f2.target<int (*)(int)>() == g);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int)> f1 = A(1);
|
||||
assert(A::count == 1);
|
||||
{
|
||||
DisableAllocationGuard guard;
|
||||
((void)guard);
|
||||
f1.swap(f1);
|
||||
}
|
||||
assert(A::count == 1);
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int()> f1 = g0;
|
||||
DisableAllocationGuard guard;
|
||||
((void)guard);
|
||||
f1.swap(f1);
|
||||
RTTI_ASSERT(*f1.target<int (*)()>() == g0);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int, int)> f1 = g2;
|
||||
DisableAllocationGuard guard;
|
||||
((void)guard);
|
||||
f1.swap(f1);
|
||||
RTTI_ASSERT(*f1.target<int (*)(int, int)>() == g2);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int(int, int, int)> f1 = g3;
|
||||
DisableAllocationGuard guard;
|
||||
((void)guard);
|
||||
f1.swap(f1);
|
||||
RTTI_ASSERT(*f1.target<int (*)(int, int, int)>() == g3);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
{
|
||||
std::function<int()> f1 = A(1);
|
||||
assert(A::count == 1);
|
||||
DisableAllocationGuard guard;
|
||||
((void)guard);
|
||||
f1.swap(f1);
|
||||
assert(A::count == 1);
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 1);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
assert(A::count == 0);
|
||||
{
|
||||
std::function<int(int, int)> f1 = A(2);
|
||||
assert(A::count == 1);
|
||||
DisableAllocationGuard guard;
|
||||
((void)guard);
|
||||
f1.swap(f1);
|
||||
assert(A::count == 1);
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 2);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
assert(A::count == 0);
|
||||
{
|
||||
std::function<int(int, int, int)> f1 = A(3);
|
||||
assert(A::count == 1);
|
||||
DisableAllocationGuard guard;
|
||||
((void)guard);
|
||||
f1.swap(f1);
|
||||
assert(A::count == 1);
|
||||
RTTI_ASSERT(f1.target<A>()->id() == 3);
|
||||
}
|
||||
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||
assert(A::count == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template <MoveConstructible R, MoveConstructible ... ArgTypes>
|
||||
// bool operator==(const function<R(ArgTypes...)>&, nullptr_t);
|
||||
//
|
||||
// template <MoveConstructible R, MoveConstructible ... ArgTypes>
|
||||
// bool operator==(nullptr_t, const function<R(ArgTypes...)>&);
|
||||
//
|
||||
// template <MoveConstructible R, MoveConstructible ... ArgTypes>
|
||||
// bool operator!=(const function<R(ArgTypes...)>&, nullptr_t);
|
||||
//
|
||||
// template <MoveConstructible R, MoveConstructible ... ArgTypes>
|
||||
// bool operator!=(nullptr_t, const function<R(ArgTypes...)>&);
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
assert(f == nullptr);
|
||||
assert(nullptr == f);
|
||||
f = g;
|
||||
assert(f != nullptr);
|
||||
assert(nullptr != f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// template<typename T>
|
||||
// requires Callable<T, ArgTypes...> && Convertible<Callable<T, ArgTypes...>::result_type, R>
|
||||
// T*
|
||||
// target();
|
||||
// template<typename T>
|
||||
// requires Callable<T, ArgTypes...> && Convertible<Callable<T, ArgTypes...>::result_type, R>
|
||||
// const T*
|
||||
// target() const;
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
// UNSUPPORTED: no-rtti
|
||||
|
||||
#include <functional>
|
||||
#include <new>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int foo(int) const {return 1;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(f.target<A>());
|
||||
assert(f.target<int(*)(int)>() == 0);
|
||||
assert(f.target<int>() == nullptr);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
std::function<int(int)> f = g;
|
||||
assert(A::count == 0);
|
||||
assert(f.target<int(*)(int)>());
|
||||
assert(f.target<A>() == 0);
|
||||
assert(f.target<int>() == nullptr);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
const std::function<int(int)> f = A();
|
||||
assert(A::count == 1);
|
||||
assert(f.target<A>());
|
||||
assert(f.target<int(*)(int)>() == 0);
|
||||
assert(f.target<int>() == nullptr);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
const std::function<int(int)> f = g;
|
||||
assert(A::count == 0);
|
||||
assert(f.target<int(*)(int)>());
|
||||
assert(f.target<A>() == 0);
|
||||
assert(f.target<int>() == nullptr);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// const std::type_info& target_type() const;
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
// UNSUPPORTED: no-rtti
|
||||
|
||||
#include <functional>
|
||||
#include <typeinfo>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
class A
|
||||
{
|
||||
int data_[10];
|
||||
public:
|
||||
static int count;
|
||||
|
||||
A()
|
||||
{
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
data_[i] = i;
|
||||
}
|
||||
|
||||
A(const A&) {++count;}
|
||||
|
||||
~A() {--count;}
|
||||
|
||||
int operator()(int i) const
|
||||
{
|
||||
for (int j = 0; j < 10; ++j)
|
||||
i += data_[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int foo(int) const {return 1;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
int g(int) {return 0;}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
std::function<int(int)> f = A();
|
||||
assert(f.target_type() == typeid(A));
|
||||
}
|
||||
{
|
||||
std::function<int(int)> f;
|
||||
assert(f.target_type() == typeid(void));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef FUNCTION_TYPES_H
|
||||
#define FUNCTION_TYPES_H
|
||||
|
||||
|
||||
class FunctionObject
|
||||
{
|
||||
int data_[10]; // dummy variable to prevent small object optimization in
|
||||
// std::function
|
||||
public:
|
||||
static int count;
|
||||
|
||||
FunctionObject() {
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i) data_[i] = i;
|
||||
}
|
||||
|
||||
FunctionObject(const FunctionObject&) {++count;}
|
||||
~FunctionObject() {--count; ((void)data_); }
|
||||
|
||||
int operator()() const { return 42; }
|
||||
int operator()(int i) const { return i; }
|
||||
int operator()(int i, int) const { return i; }
|
||||
int operator()(int i, int, int) const { return i; }
|
||||
};
|
||||
|
||||
int FunctionObject::count = 0;
|
||||
|
||||
class MemFunClass
|
||||
{
|
||||
int data_[10]; // dummy variable to prevent small object optimization in
|
||||
// std::function
|
||||
public:
|
||||
static int count;
|
||||
|
||||
MemFunClass() {
|
||||
++count;
|
||||
for (int i = 0; i < 10; ++i) data_[i] = 0;
|
||||
}
|
||||
|
||||
MemFunClass(const MemFunClass&) {++count; ((void)data_); }
|
||||
|
||||
~MemFunClass() {--count;}
|
||||
|
||||
int foo() const { return 42; }
|
||||
int foo(int i) const { return i; }
|
||||
int foo(int i, int) const { return i; }
|
||||
int foo(int i, int, int) const { return i; }
|
||||
};
|
||||
|
||||
int MemFunClass::count = 0;
|
||||
|
||||
int FreeFunction() { return 42; }
|
||||
int FreeFunction(int i) {return i;}
|
||||
int FreeFunction(int i, int) { return i; }
|
||||
int FreeFunction(int i, int, int) { return i; }
|
||||
|
||||
#endif // FUNCTION_TYPES_H
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// FIXME: Building this in MSVC mode fails when instantiating two cases of
|
||||
// std::function that only differ in constness of the return type, with this
|
||||
// error:
|
||||
// include/c++/v1/__functional/function.h:254:31: error: definition with same mangled name '??0?$__base@$$A6AXXZ@__function@__1@std@@QEAA@XZ' as another definition
|
||||
// _LIBCPP_INLINE_VISIBILITY __base() {}
|
||||
// include/c++/v1/__functional/function.h:254:31: note: previous definition is here
|
||||
// XFAIL: msvc
|
||||
|
||||
// <functional>
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
// Prevent warning on the `const NonCopyable()` function type.
|
||||
TEST_CLANG_DIAGNOSTIC_IGNORED("-Wignored-qualifiers")
|
||||
TEST_GCC_DIAGNOSTIC_IGNORED("-Wignored-qualifiers")
|
||||
|
||||
struct NonCopyable {
|
||||
NonCopyable() = default;
|
||||
NonCopyable(NonCopyable&&) = delete;
|
||||
friend bool operator==(NonCopyable, NonCopyable) { return true; }
|
||||
};
|
||||
|
||||
struct LargeLambda {
|
||||
int a[100];
|
||||
NonCopyable operator()() const { return NonCopyable(); }
|
||||
NonCopyable operator()(int) const { return NonCopyable(); }
|
||||
NonCopyable f() const { return NonCopyable(); }
|
||||
};
|
||||
|
||||
void test()
|
||||
{
|
||||
std::function<NonCopyable()> f1a = []() { return NonCopyable(); };
|
||||
std::function<NonCopyable()> f2a = +[]() { return NonCopyable(); };
|
||||
std::function<NonCopyable()> f3a = LargeLambda();
|
||||
std::function<NonCopyable()> f4a = std::ref(f1a);
|
||||
std::function<NonCopyable(int)> f1b = [](int) { return NonCopyable(); };
|
||||
std::function<NonCopyable(int)> f2b = +[](int) { return NonCopyable(); };
|
||||
std::function<NonCopyable(int)> f3b = LargeLambda();
|
||||
std::function<NonCopyable(int)> f4b = std::ref(f1b);
|
||||
|
||||
assert(f1a() == f2a());
|
||||
assert(f3a() == f4a());
|
||||
assert(f1b(1) == f2b(1));
|
||||
assert(f3b(1) == f4b(1));
|
||||
}
|
||||
|
||||
void const_test()
|
||||
{
|
||||
std::function<const NonCopyable()> f1a = []() { return NonCopyable(); };
|
||||
std::function<const NonCopyable()> f2a = +[]() { return NonCopyable(); };
|
||||
std::function<const NonCopyable()> f3a = LargeLambda();
|
||||
std::function<const NonCopyable()> f4a = std::ref(f1a);
|
||||
std::function<const NonCopyable(int)> f1b = [](int) { return NonCopyable(); };
|
||||
std::function<const NonCopyable(int)> f2b = +[](int) { return NonCopyable(); };
|
||||
std::function<const NonCopyable(int)> f3b = LargeLambda();
|
||||
std::function<const NonCopyable(int)> f4b = std::ref(f1b);
|
||||
|
||||
assert(f1a() == f2a());
|
||||
assert(f3a() == f4a());
|
||||
assert(f1b(1) == f2b(1));
|
||||
assert(f3b(1) == f4b(1));
|
||||
}
|
||||
|
||||
void void_test()
|
||||
{
|
||||
std::function<void()> f1a = []() { return NonCopyable(); };
|
||||
std::function<void()> f2a = +[]() { return NonCopyable(); };
|
||||
std::function<void()> f3a = LargeLambda();
|
||||
std::function<void()> f4a = std::ref(f1a);
|
||||
std::function<void(int)> f1b = [](int) { return NonCopyable(); };
|
||||
std::function<void(int)> f2b = +[](int) { return NonCopyable(); };
|
||||
std::function<void(int)> f3b = LargeLambda();
|
||||
std::function<void(int)> f4b = std::ref(f1b);
|
||||
}
|
||||
|
||||
void const_void_test()
|
||||
{
|
||||
std::function<const void()> f1a = []() { return NonCopyable(); };
|
||||
std::function<const void()> f2a = +[]() { return NonCopyable(); };
|
||||
std::function<const void()> f3a = LargeLambda();
|
||||
std::function<const void()> f4a = std::ref(f1a);
|
||||
std::function<const void(int)> f1b = [](int) { return NonCopyable(); };
|
||||
std::function<const void(int)> f2b = +[](int) { return NonCopyable(); };
|
||||
std::function<const void(int)> f3b = LargeLambda();
|
||||
std::function<const void(int)> f4b = std::ref(f1b);
|
||||
}
|
||||
|
||||
void member_pointer_test()
|
||||
{
|
||||
std::function<NonCopyable(LargeLambda*)> f1a = &LargeLambda::f;
|
||||
std::function<NonCopyable(LargeLambda&)> f2a = &LargeLambda::f;
|
||||
LargeLambda ll;
|
||||
assert(f1a(&ll) == f2a(ll));
|
||||
|
||||
static_assert(std::is_convertible_v<NonCopyable (LargeLambda::*)(), std::function<NonCopyable(LargeLambda*)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable (LargeLambda::*)(), std::function<NonCopyable(LargeLambda&)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable (LargeLambda::*)() const, std::function<NonCopyable(LargeLambda*)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable (LargeLambda::*)() const, std::function<NonCopyable(LargeLambda&)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable (LargeLambda::*)() const, std::function<NonCopyable(const LargeLambda*)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable (LargeLambda::*)() const, std::function<NonCopyable(const LargeLambda&)>>);
|
||||
|
||||
// Verify we have SFINAE against invoking a pointer-to-data-member in a way that would have to copy the NonCopyable.
|
||||
static_assert(!std::is_convertible_v<NonCopyable LargeLambda::*, std::function<NonCopyable(LargeLambda*)>>);
|
||||
static_assert(!std::is_convertible_v<NonCopyable LargeLambda::*, std::function<NonCopyable(LargeLambda&)>>);
|
||||
static_assert(!std::is_convertible_v<NonCopyable LargeLambda::*, std::function<NonCopyable&(const LargeLambda&)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable LargeLambda::*, std::function<NonCopyable&(LargeLambda*)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable LargeLambda::*, std::function<NonCopyable&(LargeLambda&)>>);
|
||||
static_assert(std::is_convertible_v<NonCopyable LargeLambda::*, std::function<const NonCopyable&(const LargeLambda&)>>);
|
||||
}
|
||||
|
||||
void ctad_test()
|
||||
{
|
||||
std::function f1a = []() { return NonCopyable(); };
|
||||
std::function f2a = +[]() { return NonCopyable(); };
|
||||
std::function f1b = [](int) { return NonCopyable(); };
|
||||
std::function f2b = +[](int) { return NonCopyable(); };
|
||||
static_assert(std::is_same_v<decltype(f1a), std::function<NonCopyable()>>);
|
||||
static_assert(std::is_same_v<decltype(f2a), std::function<NonCopyable()>>);
|
||||
static_assert(std::is_same_v<decltype(f1b), std::function<NonCopyable(int)>>);
|
||||
static_assert(std::is_same_v<decltype(f2b), std::function<NonCopyable(int)>>);
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test();
|
||||
const_test();
|
||||
void_test();
|
||||
const_void_test();
|
||||
member_pointer_test();
|
||||
ctad_test();
|
||||
return 0;
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Address Sanitizer doesn't instrument weak symbols on Linux. When a key
|
||||
// function is defined for bad_function_call's vtable, its typeinfo and vtable
|
||||
// will be defined as strong symbols in the library and weak symbols in other
|
||||
// translation units. Only the strong symbol will be instrumented, increasing
|
||||
// its size (due to the redzone) and leading to a serious ODR violation
|
||||
// resulting in a crash.
|
||||
// Some relevant bugs:
|
||||
// https://github.com/google/sanitizers/issues/1017
|
||||
// https://github.com/google/sanitizers/issues/619
|
||||
// https://github.com/google/sanitizers/issues/398
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016
|
||||
// UNSUPPORTED: c++03, asan
|
||||
|
||||
// <functional>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct Incomplete;
|
||||
template<class T> struct Holder { T t; };
|
||||
|
||||
typedef Holder<Incomplete> *Ptr;
|
||||
|
||||
template<class T>
|
||||
struct Callable {
|
||||
void operator()() const { }
|
||||
};
|
||||
|
||||
Ptr no_args() { return nullptr; }
|
||||
Ptr one_arg(Ptr p) { return p; }
|
||||
Ptr two_args(Ptr p, Ptr) { return p; }
|
||||
Ptr three_args(Ptr p, Ptr, Ptr) { return p; }
|
||||
Ptr four_args(Ptr p, Ptr, Ptr, Ptr) { return p; }
|
||||
|
||||
void one_arg_void(Ptr) { }
|
||||
|
||||
int main(int, char**) {
|
||||
Ptr x = nullptr;
|
||||
std::function<Ptr()> f(no_args); f();
|
||||
std::function<Ptr(Ptr)> g(one_arg); g(x);
|
||||
std::function<void(Ptr)> h(one_arg_void); h(x);
|
||||
std::function<void()> i(Callable<Holder<Incomplete>>{});
|
||||
return 0;
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// template<Returnable R, CopyConstructible... ArgTypes>
|
||||
// class function<R(ArgTypes...)> {
|
||||
// public:
|
||||
// typedef R result_type;
|
||||
// typedef T1 argument_type; // iff sizeof...(ArgTypes) == 1 and
|
||||
// // 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
|
||||
// // ArgTypes contains T1 and T2
|
||||
// ...
|
||||
// };
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
|
||||
template <typename T>
|
||||
class has_argument_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef long no;
|
||||
|
||||
template <typename C> static yes check( typename C::argument_type * );
|
||||
template <typename C> static no check(...);
|
||||
public:
|
||||
enum { value = sizeof(check<T>(0)) == sizeof(yes) };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class has_first_argument_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef long no;
|
||||
|
||||
template <typename C> static yes check( typename C::first_argument_type * );
|
||||
template <typename C> static no check(...);
|
||||
public:
|
||||
enum { value = sizeof(check<T>(0)) == sizeof(yes) };
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class has_second_argument_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef long no;
|
||||
|
||||
template <typename C> static yes check( typename C::second_argument_type *);
|
||||
template <typename C> static no check(...);
|
||||
public:
|
||||
enum { value = sizeof(check<T>(0)) == sizeof(yes) };
|
||||
};
|
||||
|
||||
template <class F, class return_type>
|
||||
void test_nullary_function ()
|
||||
{
|
||||
#if TEST_STD_VER <= 17
|
||||
static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
|
||||
#endif
|
||||
static_assert((!has_argument_type<F>::value), "" );
|
||||
static_assert((!has_first_argument_type<F>::value), "" );
|
||||
static_assert((!has_second_argument_type<F>::value), "" );
|
||||
}
|
||||
|
||||
template <class F, class return_type, class arg_type>
|
||||
void test_unary_function ()
|
||||
{
|
||||
#if TEST_STD_VER <= 17
|
||||
static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
|
||||
static_assert((std::is_same<typename F::argument_type, arg_type>::value), "" );
|
||||
#endif
|
||||
static_assert((!has_first_argument_type<F>::value), "" );
|
||||
static_assert((!has_second_argument_type<F>::value), "" );
|
||||
}
|
||||
|
||||
template <class F, class return_type, class arg_type1, class arg_type2>
|
||||
void test_binary_function ()
|
||||
{
|
||||
#if TEST_STD_VER <= 17
|
||||
static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
|
||||
static_assert((std::is_same<typename F::first_argument_type, arg_type1>::value), "" );
|
||||
static_assert((std::is_same<typename F::second_argument_type, arg_type2>::value), "" );
|
||||
#endif
|
||||
static_assert((!has_argument_type<F>::value), "" );
|
||||
}
|
||||
|
||||
template <class F, class return_type>
|
||||
void test_other_function ()
|
||||
{
|
||||
#if TEST_STD_VER <= 17
|
||||
static_assert((std::is_same<typename F::result_type, return_type>::value), "" );
|
||||
#endif
|
||||
static_assert((!has_argument_type<F>::value), "" );
|
||||
static_assert((!has_first_argument_type<F>::value), "" );
|
||||
static_assert((!has_second_argument_type<F>::value), "" );
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test_nullary_function<std::function<int()>, int>();
|
||||
test_unary_function <std::function<double(int)>, double, int>();
|
||||
test_binary_function <std::function<double(int, char)>, double, int, char>();
|
||||
test_other_function <std::function<double(int, char, double)>, double>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user