Initial commit

This commit is contained in:
Yervant7
2024-01-16 19:28:29 -03:00
commit 8c0524dc0f
9054 changed files with 1081727 additions and 0 deletions
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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>());
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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
@@ -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;
}
@@ -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;
}
@@ -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;
}