10d28f784SEric Fiselier //===----------------------------------------------------------------------===//
20d28f784SEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60d28f784SEric Fiselier //
70d28f784SEric Fiselier //===----------------------------------------------------------------------===//
80d28f784SEric Fiselier
90d28f784SEric Fiselier // <functional>
100d28f784SEric Fiselier
110d28f784SEric Fiselier // class function<R(ArgTypes...)>
120d28f784SEric Fiselier
130d28f784SEric Fiselier // function(Fp);
140d28f784SEric Fiselier
150d28f784SEric Fiselier // Ensure that __not_null works for all function types.
163c62198cSLouis Dionne // See https://llvm.org/PR23589
170d28f784SEric Fiselier
18b4fb705eSLouis Dionne // This test runs in C++03, but we have deprecated using std::function in C++03.
19*c475e31aSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
20b4fb705eSLouis Dionne
210d28f784SEric Fiselier //------------------------------------------------------------------------------
220d28f784SEric Fiselier // TESTING std::function<...>::__not_null(Callable)
230d28f784SEric Fiselier //
240d28f784SEric Fiselier // Concerns:
250d28f784SEric Fiselier // 1) The call __not_null(Callable) is well formed and correct for each
260d28f784SEric Fiselier // possible 'Callable' type category. These categories include:
270d28f784SEric Fiselier // 1a) function pointers
280d28f784SEric Fiselier // 1b) member function pointer
290d28f784SEric Fiselier // 1c) member data pointer
300d28f784SEric Fiselier // 1d) callable class type
310d28f784SEric Fiselier // 1e) lambdas
320d28f784SEric Fiselier // Categories 1a, 1b, and 1c are 'Nullable' types. Only objects of these
330d28f784SEric Fiselier // types can be null. The other categories are not tested here.
340d28f784SEric Fiselier // 3) '__not_null(Callable)' is well formed when the call signature includes
350d28f784SEric Fiselier // varargs.
36a730ed31SStephan T. Lavavej // 4) '__not_null(Callable)' works for Callable types with all arities less
370d28f784SEric Fiselier // than or equal to 3 in C++03.
380d28f784SEric Fiselier // 5) '__not_null(Callable)' works when 'Callable' is a member function
390d28f784SEric Fiselier // pointer to a cv or ref qualified function type.
400d28f784SEric Fiselier //
410d28f784SEric Fiselier // Plan:
420d28f784SEric Fiselier // 1 For categories 1a, 1b and 1c define a set of
430d28f784SEric Fiselier // 'Callable' objects for this category. This set should include examples
440d28f784SEric Fiselier // of arity 0, 1, 2 and possible 3 including versions with varargs as the
450d28f784SEric Fiselier // last parameter.
460d28f784SEric Fiselier //
470d28f784SEric Fiselier // 2 For each 'Callable' object in categories 1a, 1b and 1c do the following.
480d28f784SEric Fiselier //
490d28f784SEric Fiselier // 1 Define a type 'std::function<Sig>' as 'F' where 'Sig' is compatible with
500d28f784SEric Fiselier // the signature of the 'Callable' object.
510d28f784SEric Fiselier //
520d28f784SEric Fiselier // 2 Create an object of type 'F' using a null pointer of type 'Callable'.
530d28f784SEric Fiselier // Check that 'F.target<Callable>()' is null.
540d28f784SEric Fiselier //
550d28f784SEric Fiselier // 3 Create an object of type 'F' that is not null. Check that
560d28f784SEric Fiselier // 'F.target<Callable>()' is not null and is equal to the original
570d28f784SEric Fiselier // argument.
580d28f784SEric Fiselier
590d28f784SEric Fiselier #include <functional>
600d28f784SEric Fiselier #include <type_traits>
610d28f784SEric Fiselier #include <cassert>
620d28f784SEric Fiselier
630d28f784SEric Fiselier #include "test_macros.h"
640d28f784SEric Fiselier
650d28f784SEric Fiselier ///////////////////////////////////////////////////////////////////////////////
foo()660d28f784SEric Fiselier int foo() { return 42; }
foo(int)670d28f784SEric Fiselier int foo(int) { return 42; }
foo(int,int)680d28f784SEric Fiselier int foo(int, int) { return 42; }
foo(int,int,int)690d28f784SEric Fiselier int foo(int, int, int) { return 42; }
700d28f784SEric Fiselier
foo(...)710d28f784SEric Fiselier int foo(...) { return 42; }
foo(int,...)720d28f784SEric Fiselier int foo(int, ...) { return 42; }
foo(int,int,...)730d28f784SEric Fiselier int foo(int, int, ...) { return 42; }
foo(int,int,int,...)740d28f784SEric Fiselier int foo(int, int, int, ...) { return 42; }
750d28f784SEric Fiselier
760d28f784SEric Fiselier ///////////////////////////////////////////////////////////////////////////////
770d28f784SEric Fiselier struct MemFun03 {
fooMemFun03780d28f784SEric Fiselier int foo() { return 42; }
fooMemFun03790d28f784SEric Fiselier int foo() const { return 42; }
fooMemFun03800d28f784SEric Fiselier int foo() volatile { return 42; }
fooMemFun03810d28f784SEric Fiselier int foo() const volatile { return 42; }
820d28f784SEric Fiselier
fooMemFun03830d28f784SEric Fiselier int foo(int) { return 42; }
fooMemFun03840d28f784SEric Fiselier int foo(int) const { return 42; }
fooMemFun03850d28f784SEric Fiselier int foo(int) volatile { return 42; }
fooMemFun03860d28f784SEric Fiselier int foo(int) const volatile { return 42; }
870d28f784SEric Fiselier
fooMemFun03880d28f784SEric Fiselier int foo(int, int) { return 42; }
fooMemFun03890d28f784SEric Fiselier int foo(int, int) const { return 42; }
fooMemFun03900d28f784SEric Fiselier int foo(int, int) volatile { return 42; }
fooMemFun03910d28f784SEric Fiselier int foo(int, int) const volatile { return 42; }
920d28f784SEric Fiselier
fooMemFun03930d28f784SEric Fiselier int foo(int, int, int) { return 42; }
fooMemFun03940d28f784SEric Fiselier int foo(int, int, int) const { return 42; }
fooMemFun03950d28f784SEric Fiselier int foo(int, int, int) volatile { return 42; }
fooMemFun03960d28f784SEric Fiselier int foo(int, int, int) const volatile { return 42; }
970d28f784SEric Fiselier
fooMemFun03980d28f784SEric Fiselier int foo(...) { return 42; }
fooMemFun03990d28f784SEric Fiselier int foo(...) const { return 42; }
fooMemFun031000d28f784SEric Fiselier int foo(...) volatile { return 42; }
fooMemFun031010d28f784SEric Fiselier int foo(...) const volatile { return 42; }
1020d28f784SEric Fiselier
fooMemFun031030d28f784SEric Fiselier int foo(int, ...) { return 42; }
fooMemFun031040d28f784SEric Fiselier int foo(int, ...) const { return 42; }
fooMemFun031050d28f784SEric Fiselier int foo(int, ...) volatile { return 42; }
fooMemFun031060d28f784SEric Fiselier int foo(int, ...) const volatile { return 42; }
1070d28f784SEric Fiselier
fooMemFun031080d28f784SEric Fiselier int foo(int, int, ...) { return 42; }
fooMemFun031090d28f784SEric Fiselier int foo(int, int, ...) const { return 42; }
fooMemFun031100d28f784SEric Fiselier int foo(int, int, ...) volatile { return 42; }
fooMemFun031110d28f784SEric Fiselier int foo(int, int, ...) const volatile { return 42; }
1120d28f784SEric Fiselier
fooMemFun031130d28f784SEric Fiselier int foo(int, int, int, ...) { return 42; }
fooMemFun031140d28f784SEric Fiselier int foo(int, int, int, ...) const { return 42; }
fooMemFun031150d28f784SEric Fiselier int foo(int, int, int, ...) volatile { return 42; }
fooMemFun031160d28f784SEric Fiselier int foo(int, int, int, ...) const volatile { return 42; }
1170d28f784SEric Fiselier };
1180d28f784SEric Fiselier
1190d28f784SEric Fiselier #if TEST_STD_VER >= 11
1200d28f784SEric Fiselier struct MemFun11 {
fooMemFun111210d28f784SEric Fiselier int foo() & { return 42; }
fooMemFun111220d28f784SEric Fiselier int foo() const & { return 42; }
fooMemFun111230d28f784SEric Fiselier int foo() volatile & { return 42; }
fooMemFun111240d28f784SEric Fiselier int foo() const volatile & { return 42; }
1250d28f784SEric Fiselier
fooMemFun111260d28f784SEric Fiselier int foo(...) & { return 42; }
fooMemFun111270d28f784SEric Fiselier int foo(...) const & { return 42; }
fooMemFun111280d28f784SEric Fiselier int foo(...) volatile & { return 42; }
fooMemFun111290d28f784SEric Fiselier int foo(...) const volatile & { return 42; }
1300d28f784SEric Fiselier
fooMemFun111310d28f784SEric Fiselier int foo() && { return 42; }
fooMemFun111320d28f784SEric Fiselier int foo() const && { return 42; }
fooMemFun111330d28f784SEric Fiselier int foo() volatile && { return 42; }
fooMemFun111340d28f784SEric Fiselier int foo() const volatile && { return 42; }
1350d28f784SEric Fiselier
fooMemFun111360d28f784SEric Fiselier int foo(...) && { return 42; }
fooMemFun111370d28f784SEric Fiselier int foo(...) const && { return 42; }
fooMemFun111380d28f784SEric Fiselier int foo(...) volatile && { return 42; }
fooMemFun111390d28f784SEric Fiselier int foo(...) const volatile && { return 42; }
1400d28f784SEric Fiselier };
1410d28f784SEric Fiselier #endif // TEST_STD_VER >= 11
1420d28f784SEric Fiselier
1430d28f784SEric Fiselier struct MemData {
1440d28f784SEric Fiselier int foo;
1450d28f784SEric Fiselier };
1460d28f784SEric Fiselier
1470d28f784SEric Fiselier // Create a non-null free function by taking the address of
1480d28f784SEric Fiselier // &static_cast<Tp&>(foo);
1490d28f784SEric Fiselier template <class Tp>
1500d28f784SEric Fiselier struct Creator {
createCreator1510d28f784SEric Fiselier static Tp create() {
1520d28f784SEric Fiselier return &foo;
1530d28f784SEric Fiselier }
1540d28f784SEric Fiselier };
1550d28f784SEric Fiselier
1560d28f784SEric Fiselier // Create a non-null member pointer.
1570d28f784SEric Fiselier template <class Ret, class Class>
1580d28f784SEric Fiselier struct Creator<Ret Class::*> {
1590d28f784SEric Fiselier typedef Ret Class::*ReturnType;
createCreator1600d28f784SEric Fiselier static ReturnType create() {
1610d28f784SEric Fiselier return &Class::foo;
1620d28f784SEric Fiselier }
1630d28f784SEric Fiselier };
1640d28f784SEric Fiselier
1650d28f784SEric Fiselier template <class TestFn, class Fn>
test_imp()1660d28f784SEric Fiselier void test_imp() {
1670d28f784SEric Fiselier { // Check that the null value is detected
1680d28f784SEric Fiselier TestFn tf = nullptr;
1690d28f784SEric Fiselier std::function<Fn> f = tf;
170bb09ef95SLouis Dionne RTTI_ASSERT(f.template target<TestFn>() == nullptr);
1710d28f784SEric Fiselier }
1720d28f784SEric Fiselier { // Check that the non-null value is detected.
1730d28f784SEric Fiselier TestFn tf = Creator<TestFn>::create();
1740d28f784SEric Fiselier assert(tf != nullptr);
1750d28f784SEric Fiselier std::function<Fn> f = tf;
176bb09ef95SLouis Dionne RTTI_ASSERT(f.template target<TestFn>() != nullptr);
177bb09ef95SLouis Dionne RTTI_ASSERT(*f.template target<TestFn>() == tf);
1780d28f784SEric Fiselier }
1790d28f784SEric Fiselier }
1800d28f784SEric Fiselier
test_func()1810d28f784SEric Fiselier void test_func() {
1820d28f784SEric Fiselier test_imp<int(*)(), int()>();
1830d28f784SEric Fiselier test_imp<int(*)(...), int()>();
1840d28f784SEric Fiselier test_imp<int(*)(int), int(int)>();
1850d28f784SEric Fiselier test_imp<int(*)(int, ...), int(int)>();
1860d28f784SEric Fiselier test_imp<int(*)(int, int), int(int, int)>();
1870d28f784SEric Fiselier test_imp<int(*)(int, int, ...), int(int, int)>();
1880d28f784SEric Fiselier test_imp<int(*)(int, int, int), int(int, int, int)>();
1890d28f784SEric Fiselier test_imp<int(*)(int, int, int, ...), int(int, int, int)>();
1900d28f784SEric Fiselier }
1910d28f784SEric Fiselier
test_mf()1920d28f784SEric Fiselier void test_mf() {
1930d28f784SEric Fiselier test_imp<int(MemFun03::*)(), int(MemFun03&)>();
1940d28f784SEric Fiselier test_imp<int(MemFun03::*)(...), int(MemFun03&)>();
1950d28f784SEric Fiselier test_imp<int(MemFun03::*)() const, int(MemFun03&)>();
1960d28f784SEric Fiselier test_imp<int(MemFun03::*)(...) const, int(MemFun03&)>();
1970d28f784SEric Fiselier test_imp<int(MemFun03::*)() volatile, int(MemFun03&)>();
1980d28f784SEric Fiselier test_imp<int(MemFun03::*)(...) volatile, int(MemFun03&)>();
1990d28f784SEric Fiselier test_imp<int(MemFun03::*)() const volatile, int(MemFun03&)>();
2000d28f784SEric Fiselier test_imp<int(MemFun03::*)(...) const volatile, int(MemFun03&)>();
2010d28f784SEric Fiselier
2020d28f784SEric Fiselier test_imp<int(MemFun03::*)(int), int(MemFun03&, int)>();
2030d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, ...), int(MemFun03&, int)>();
2040d28f784SEric Fiselier test_imp<int(MemFun03::*)(int) const, int(MemFun03&, int)>();
2050d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, ...) const, int(MemFun03&, int)>();
2060d28f784SEric Fiselier test_imp<int(MemFun03::*)(int) volatile, int(MemFun03&, int)>();
2070d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, ...) volatile, int(MemFun03&, int)>();
2080d28f784SEric Fiselier test_imp<int(MemFun03::*)(int) const volatile, int(MemFun03&, int)>();
2090d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, ...) const volatile, int(MemFun03&, int)>();
2100d28f784SEric Fiselier
2110d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int), int(MemFun03&, int, int)>();
2120d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int, ...), int(MemFun03&, int, int)>();
2130d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int) const, int(MemFun03&, int, int)>();
2140d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int, ...) const, int(MemFun03&, int, int)>();
2150d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int) volatile, int(MemFun03&, int, int)>();
2160d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int, ...) volatile, int(MemFun03&, int, int)>();
2170d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int) const volatile, int(MemFun03&, int, int)>();
2180d28f784SEric Fiselier test_imp<int(MemFun03::*)(int, int, ...) const volatile, int(MemFun03&, int, int)>();
2190d28f784SEric Fiselier
2200d28f784SEric Fiselier #if TEST_STD_VER >= 11
2210d28f784SEric Fiselier test_imp<int(MemFun11::*)() &, int(MemFun11&)>();
2220d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) &, int(MemFun11&)>();
2230d28f784SEric Fiselier test_imp<int(MemFun11::*)() const &, int(MemFun11&)>();
2240d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) const &, int(MemFun11&)>();
2250d28f784SEric Fiselier test_imp<int(MemFun11::*)() volatile &, int(MemFun11&)>();
2260d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) volatile &, int(MemFun11&)>();
2270d28f784SEric Fiselier test_imp<int(MemFun11::*)() const volatile &, int(MemFun11&)>();
2280d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) const volatile &, int(MemFun11&)>();
2290d28f784SEric Fiselier
2300d28f784SEric Fiselier test_imp<int(MemFun11::*)() &&, int(MemFun11&&)>();
2310d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) &&, int(MemFun11&&)>();
2320d28f784SEric Fiselier test_imp<int(MemFun11::*)() const &&, int(MemFun11&&)>();
2330d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) const &&, int(MemFun11&&)>();
2340d28f784SEric Fiselier test_imp<int(MemFun11::*)() volatile &&, int(MemFun11&&)>();
2350d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) volatile &&, int(MemFun11&&)>();
2360d28f784SEric Fiselier test_imp<int(MemFun11::*)() const volatile &&, int(MemFun11&&)>();
2370d28f784SEric Fiselier test_imp<int(MemFun11::*)(...) const volatile &&, int(MemFun11&&)>();
2380d28f784SEric Fiselier #endif
2390d28f784SEric Fiselier }
2400d28f784SEric Fiselier
test_md()2410d28f784SEric Fiselier void test_md() {
2420d28f784SEric Fiselier test_imp<int MemData::*, int(MemData&)>();
2430d28f784SEric Fiselier }
2440d28f784SEric Fiselier
main(int,char **)2452df59c50SJF Bastien int main(int, char**) {
2460d28f784SEric Fiselier test_func();
2470d28f784SEric Fiselier test_mf();
2480d28f784SEric Fiselier test_md();
2492df59c50SJF Bastien
2502df59c50SJF Bastien return 0;
2510d28f784SEric Fiselier }
252