mirror of
https://github.com/apple/swift.git
synced 2026-02-27 18:26:24 +01:00
This introduces support for converting a Swift closure that captures variables from its surrounding context into an instance of `std::function`, which is useful for working with C++ APIs that use callbacks. Each instantiation of `std::function` gets a synthesized Swift constructor that takes a Swift closure. Unlike the previous implementation, the closure is _not_ marked as `@convention(c)`. The body of the constructor is created lazily. Under the hood, the closure is bitcast to a pair of a function pointer and a context pointer, which are then wrapped in a C++ object, `__SwiftFunctionWrapper`, that manages the lifetime of the context object via calls to `swift_retain`/`swift_release` from the copy constructor and the destructor. The `__SwiftFunctionWrapper` class is templated, and is instantiated by ClangImporter. rdar://133777029
90 lines
3.7 KiB
C++
90 lines
3.7 KiB
C++
#ifndef TEST_INTEROP_CXX_STDLIB_INPUTS_STD_FUNCTION_H
|
|
#define TEST_INTEROP_CXX_STDLIB_INPUTS_STD_FUNCTION_H
|
|
|
|
#include <functional>
|
|
#include <string>
|
|
|
|
using FunctionVoidToVoid = std::function<void()>;
|
|
using FunctionVoidToInt = std::function<int()>;
|
|
using FunctionIntToVoid = std::function<void(int)>;
|
|
using FunctionIntToInt = std::function<int(int)>;
|
|
using FunctionConstIntToInt = std::function<int(const int)>;
|
|
using FunctionConstRefIntToInt = std::function<int(const int&)>;
|
|
using FunctionIntIntToInt = std::function<int(int, int)>;
|
|
using FunctionStringToString = std::function<std::string(std::string)>;
|
|
using FunctionConstRefStringToString = std::function<std::string(const std::string&)>;
|
|
using FunctionConstRefStringToConstRefString = std::function<const std::string&(const std::string&)>;
|
|
|
|
struct HasDeletedCopyCtor {
|
|
int value;
|
|
HasDeletedCopyCtor(int value) : value(value) {}
|
|
HasDeletedCopyCtor(const HasDeletedCopyCtor &other) = delete;
|
|
HasDeletedCopyCtor(HasDeletedCopyCtor &&other) = default;
|
|
HasDeletedCopyCtor& operator=(const HasDeletedCopyCtor &other) = delete;
|
|
HasDeletedCopyCtor& operator=(HasDeletedCopyCtor &&other) = default;
|
|
~HasDeletedCopyCtor() = default;
|
|
};
|
|
using FunctionIntToHasDeletedCopyCtor = std::function<HasDeletedCopyCtor(int)>;
|
|
using FunctionConstRefHasDeletedCopyCtorToVoid = std::function<void(const HasDeletedCopyCtor&)>;
|
|
using FunctionConstRefHasDeletedCopyCtorToInt = std::function<int(const HasDeletedCopyCtor&)>;
|
|
using FunctionHasDeletedCopyCtor = std::function<HasDeletedCopyCtor(const HasDeletedCopyCtor&)>;
|
|
|
|
int invokeFunctionConstRefHasDeletedCopyCtorToInt(FunctionConstRefHasDeletedCopyCtorToInt f) {
|
|
HasDeletedCopyCtor arg(123);
|
|
return f(arg);
|
|
}
|
|
|
|
struct NonTrivialHasDeletedCopyCtor {
|
|
int value;
|
|
bool destroyed = false;
|
|
NonTrivialHasDeletedCopyCtor(int value) : value(value) {}
|
|
NonTrivialHasDeletedCopyCtor(const NonTrivialHasDeletedCopyCtor &other) = delete;
|
|
NonTrivialHasDeletedCopyCtor(NonTrivialHasDeletedCopyCtor &&other) = default;
|
|
NonTrivialHasDeletedCopyCtor& operator=(const NonTrivialHasDeletedCopyCtor &other) = delete;
|
|
NonTrivialHasDeletedCopyCtor& operator=(NonTrivialHasDeletedCopyCtor &&other) = default;
|
|
~NonTrivialHasDeletedCopyCtor() { destroyed = true; } // makes the type non-trivial
|
|
};
|
|
using FunctionIntToNonTrivialHasDeletedCopyCtor = std::function<NonTrivialHasDeletedCopyCtor(int)>;
|
|
using FunctionConstRefNonTrivialHasDeletedCopyCtorToVoid = std::function<void(const NonTrivialHasDeletedCopyCtor&)>;
|
|
using FunctionNonTrivialHasDeletedCopyCtor = std::function<NonTrivialHasDeletedCopyCtor(const NonTrivialHasDeletedCopyCtor&)>;
|
|
|
|
inline FunctionIntToInt getIdentityFunction() {
|
|
return [](int x) { return x; };
|
|
}
|
|
|
|
inline bool isEmptyFunction(FunctionIntToInt f) { return !(bool)f; }
|
|
|
|
inline int invokeFunction(FunctionIntToInt f, int x) { return f(x); }
|
|
|
|
int invokeFunctionIntToIntTwice(FunctionIntToInt f, int i) {
|
|
return f(f(i));
|
|
}
|
|
int invokeFunctionIntToIntByConstRefTwice(const FunctionIntToInt& f, int i) {
|
|
return f(f(i));
|
|
}
|
|
int invokeFunctionIntToIntByRValueRefTwice(const FunctionIntToInt& f, int i) {
|
|
return f(f(i));
|
|
}
|
|
|
|
std::string invokeFunctionTwice(FunctionStringToString f, std::string s) {
|
|
return f(f(s));
|
|
}
|
|
std::string invokeFunctionByConstRefTwice(const FunctionStringToString& f, std::string s) {
|
|
return f(f(s));
|
|
}
|
|
|
|
std::string invokeFunctionTwiceConstRef(FunctionConstRefStringToString f, std::string s) {
|
|
return f(f(s));
|
|
}
|
|
|
|
std::string invokeFunctionTwiceConstRefX2(FunctionConstRefStringToConstRefString f, std::string s) {
|
|
return f(f(s));
|
|
}
|
|
|
|
template<typename Func>
|
|
int invokeTemplatedCallableIntToInt(Func f) { return f(123); };
|
|
template<typename Func>
|
|
int invokeTemplatedCallableByConstRefIntToInt(const Func& f) { return f(321); };
|
|
|
|
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_FUNCTION_H
|