123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- //===----------------------------------------------------------------------===//
- //
- // 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://bugs.llvm.org/show_bug.cgi?id=23589
- //------------------------------------------------------------------------------
- // 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;
- 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;
- assert(f.template target<TestFn>() != nullptr);
- 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;
- }
|