brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.0 KiB · 6ed4c5c Raw
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