251 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++0310 11// <functional>12 13// class function<R(ArgTypes...)>14 15// function(Fp);16 17// Ensure that __not_null works for all function types.18// See https://llvm.org/PR2358919 20//------------------------------------------------------------------------------21// TESTING std::function<...>::__not_null(Callable)22//23// Concerns:24// 1) The call __not_null(Callable) is well formed and correct for each25// possible 'Callable' type category. These categories include:26// 1a) function pointers27// 1b) member function pointer28// 1c) member data pointer29// 1d) callable class type30// 1e) lambdas31// Categories 1a, 1b, and 1c are 'Nullable' types. Only objects of these32// types can be null. The other categories are not tested here.33// 3) '__not_null(Callable)' is well formed when the call signature includes34// varargs.35// 4) '__not_null(Callable)' works for Callable types with all arities less36// than or equal to 3 in C++03.37// 5) '__not_null(Callable)' works when 'Callable' is a member function38// pointer to a cv or ref qualified function type.39//40// Plan:41// 1 For categories 1a, 1b and 1c define a set of42// 'Callable' objects for this category. This set should include examples43// of arity 0, 1, 2 and possible 3 including versions with varargs as the44// last parameter.45//46// 2 For each 'Callable' object in categories 1a, 1b and 1c do the following.47//48// 1 Define a type 'std::function<Sig>' as 'F' where 'Sig' is compatible with49// the signature of the 'Callable' object.50//51// 2 Create an object of type 'F' using a null pointer of type 'Callable'.52// Check that 'F.target<Callable>()' is null.53//54// 3 Create an object of type 'F' that is not null. Check that55// 'F.target<Callable>()' is not null and is equal to the original56// argument.57 58#include <functional>59#include <type_traits>60#include <cassert>61 62#include "test_macros.h"63 64///////////////////////////////////////////////////////////////////////////////65int foo() { return 42; }66int foo(int) { return 42; }67int foo(int, int) { return 42; }68int foo(int, int, int) { return 42; }69 70int foo(...) { return 42; }71int foo(int, ...) { return 42; }72int foo(int, int, ...) { return 42; }73int foo(int, int, int, ...) { return 42; }74 75///////////////////////////////////////////////////////////////////////////////76struct MemFun03 {77 int foo() { return 42; }78 int foo() const { return 42; }79 int foo() volatile { return 42; }80 int foo() const volatile { return 42; }81 82 int foo(int) { return 42; }83 int foo(int) const { return 42; }84 int foo(int) volatile { return 42; }85 int foo(int) const volatile { return 42; }86 87 int foo(int, int) { return 42; }88 int foo(int, int) const { return 42; }89 int foo(int, int) volatile { return 42; }90 int foo(int, int) const volatile { return 42; }91 92 int foo(int, int, int) { return 42; }93 int foo(int, int, int) const { return 42; }94 int foo(int, int, int) volatile { return 42; }95 int foo(int, int, int) const volatile { return 42; }96 97 int foo(...) { return 42; }98 int foo(...) const { return 42; }99 int foo(...) volatile { return 42; }100 int foo(...) const volatile { return 42; }101 102 int foo(int, ...) { return 42; }103 int foo(int, ...) const { return 42; }104 int foo(int, ...) volatile { return 42; }105 int foo(int, ...) const volatile { return 42; }106 107 int foo(int, int, ...) { return 42; }108 int foo(int, int, ...) const { return 42; }109 int foo(int, int, ...) volatile { return 42; }110 int foo(int, int, ...) const volatile { return 42; }111 112 int foo(int, int, int, ...) { return 42; }113 int foo(int, int, int, ...) const { return 42; }114 int foo(int, int, int, ...) volatile { return 42; }115 int foo(int, int, int, ...) const volatile { return 42; }116};117 118#if TEST_STD_VER >= 11119struct MemFun11 {120 int foo() & { return 42; }121 int foo() const & { return 42; }122 int foo() volatile & { return 42; }123 int foo() const volatile & { return 42; }124 125 int foo(...) & { return 42; }126 int foo(...) const & { return 42; }127 int foo(...) volatile & { return 42; }128 int foo(...) const volatile & { return 42; }129 130 int foo() && { return 42; }131 int foo() const && { return 42; }132 int foo() volatile && { return 42; }133 int foo() const volatile && { return 42; }134 135 int foo(...) && { return 42; }136 int foo(...) const && { return 42; }137 int foo(...) volatile && { return 42; }138 int foo(...) const volatile && { return 42; }139};140#endif // TEST_STD_VER >= 11141 142struct MemData {143 int foo;144};145 146// Create a non-null free function by taking the address of147// &static_cast<Tp&>(foo);148template <class Tp>149struct Creator {150 static Tp create() {151 return &foo;152 }153};154 155// Create a non-null member pointer.156template <class Ret, class Class>157struct Creator<Ret Class::*> {158 typedef Ret Class::*ReturnType;159 static ReturnType create() {160 return &Class::foo;161 }162};163 164template <class TestFn, class Fn>165void test_imp() {166 { // Check that the null value is detected167 TestFn tf = nullptr;168 std::function<Fn> f = tf;169 RTTI_ASSERT(f.template target<TestFn>() == nullptr);170 }171 { // Check that the non-null value is detected.172 TestFn tf = Creator<TestFn>::create();173 assert(tf != nullptr);174 std::function<Fn> f = tf;175 RTTI_ASSERT(f.template target<TestFn>() != nullptr);176 RTTI_ASSERT(*f.template target<TestFn>() == tf);177 }178}179 180void test_func() {181 test_imp<int(*)(), int()>();182 test_imp<int(*)(...), int()>();183 test_imp<int(*)(int), int(int)>();184 test_imp<int(*)(int, ...), int(int)>();185 test_imp<int(*)(int, int), int(int, int)>();186 test_imp<int(*)(int, int, ...), int(int, int)>();187 test_imp<int(*)(int, int, int), int(int, int, int)>();188 test_imp<int(*)(int, int, int, ...), int(int, int, int)>();189}190 191void test_mf() {192 test_imp<int(MemFun03::*)(), int(MemFun03&)>();193 test_imp<int(MemFun03::*)(...), int(MemFun03&)>();194 test_imp<int(MemFun03::*)() const, int(MemFun03&)>();195 test_imp<int(MemFun03::*)(...) const, int(MemFun03&)>();196 test_imp<int(MemFun03::*)() volatile, int(MemFun03&)>();197 test_imp<int(MemFun03::*)(...) volatile, int(MemFun03&)>();198 test_imp<int(MemFun03::*)() const volatile, int(MemFun03&)>();199 test_imp<int(MemFun03::*)(...) const volatile, int(MemFun03&)>();200 201 test_imp<int(MemFun03::*)(int), int(MemFun03&, int)>();202 test_imp<int(MemFun03::*)(int, ...), int(MemFun03&, int)>();203 test_imp<int(MemFun03::*)(int) const, int(MemFun03&, int)>();204 test_imp<int(MemFun03::*)(int, ...) const, int(MemFun03&, int)>();205 test_imp<int(MemFun03::*)(int) volatile, int(MemFun03&, int)>();206 test_imp<int(MemFun03::*)(int, ...) volatile, int(MemFun03&, int)>();207 test_imp<int(MemFun03::*)(int) const volatile, int(MemFun03&, int)>();208 test_imp<int(MemFun03::*)(int, ...) const volatile, int(MemFun03&, int)>();209 210 test_imp<int(MemFun03::*)(int, int), int(MemFun03&, int, int)>();211 test_imp<int(MemFun03::*)(int, int, ...), int(MemFun03&, int, int)>();212 test_imp<int(MemFun03::*)(int, int) const, int(MemFun03&, int, int)>();213 test_imp<int(MemFun03::*)(int, int, ...) const, int(MemFun03&, int, int)>();214 test_imp<int(MemFun03::*)(int, int) volatile, int(MemFun03&, int, int)>();215 test_imp<int(MemFun03::*)(int, int, ...) volatile, int(MemFun03&, int, int)>();216 test_imp<int(MemFun03::*)(int, int) const volatile, int(MemFun03&, int, int)>();217 test_imp<int(MemFun03::*)(int, int, ...) const volatile, int(MemFun03&, int, int)>();218 219#if TEST_STD_VER >= 11220 test_imp<int(MemFun11::*)() &, int(MemFun11&)>();221 test_imp<int(MemFun11::*)(...) &, int(MemFun11&)>();222 test_imp<int(MemFun11::*)() const &, int(MemFun11&)>();223 test_imp<int(MemFun11::*)(...) const &, int(MemFun11&)>();224 test_imp<int(MemFun11::*)() volatile &, int(MemFun11&)>();225 test_imp<int(MemFun11::*)(...) volatile &, int(MemFun11&)>();226 test_imp<int(MemFun11::*)() const volatile &, int(MemFun11&)>();227 test_imp<int(MemFun11::*)(...) const volatile &, int(MemFun11&)>();228 229 test_imp<int(MemFun11::*)() &&, int(MemFun11&&)>();230 test_imp<int(MemFun11::*)(...) &&, int(MemFun11&&)>();231 test_imp<int(MemFun11::*)() const &&, int(MemFun11&&)>();232 test_imp<int(MemFun11::*)(...) const &&, int(MemFun11&&)>();233 test_imp<int(MemFun11::*)() volatile &&, int(MemFun11&&)>();234 test_imp<int(MemFun11::*)(...) volatile &&, int(MemFun11&&)>();235 test_imp<int(MemFun11::*)() const volatile &&, int(MemFun11&&)>();236 test_imp<int(MemFun11::*)(...) const volatile &&, int(MemFun11&&)>();237#endif238}239 240void test_md() {241 test_imp<int MemData::*, int(MemData&)>();242}243 244int main(int, char**) {245 test_func();246 test_mf();247 test_md();248 249 return 0;250}251