diff options
Diffstat (limited to 'test/std/utilities/function.objects/bind/func.bind/func.bind.bind')
7 files changed, 813 insertions, 0 deletions
| diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp new file mode 100644 index 000000000000..6315598125c9 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); + +// http://llvm.org/bugs/show_bug.cgi?id=16385 + +#include <functional> +#include <cmath> +#include <cassert> + +float _pow(float a, float b) +{ +    return std::pow(a, b); +} + +int main() +{ +    std::function<float(float, float)> fnc = _pow; +    auto task = std::bind(fnc, 2.f, 4.f); +    auto task2(task); +    assert(task() == 16); +    assert(task2() == 16); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp new file mode 100644 index 000000000000..33bf01855908 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); + +// http://llvm.org/bugs/show_bug.cgi?id=22003 + +#include <functional> + +struct DummyUnaryFunction +{ +    template <typename S> +    int operator()(S const & s) const { return 0; } +}; + +struct BadUnaryFunction +{ +    template <typename S> +    constexpr int operator()(S const & s) const +    { +        // Trigger a compile error if this function is instantiated. +        // The constexpr is needed so that it is instantiated while checking +        // __invoke_of<BadUnaryFunction &, ...>. +        static_assert(!std::is_same<S, S>::value, "Shit"); +        return 0; +    } +}; + +int main(int argc, char* argv[]) +{ +    // Check that BadUnaryFunction::operator()(S const &) is not +    // instantiated when checking if BadUnaryFunction is a nested bind +    // expression during b(0). See PR22003. +    auto b = std::bind(DummyUnaryFunction(), BadUnaryFunction()); +    b(0); +    auto b2 = std::bind<long>(DummyUnaryFunction(), BadUnaryFunction()); +    b2(0); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_int_0.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_int_0.pass.cpp new file mode 100644 index 000000000000..ab4dd59534d5 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_int_0.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); + +#include <functional> +#include <cassert> + +template <class R, class F> +void +test(F f, R expected) +{ +    assert(f() == expected); +} + +template <class R, class F> +void +test_const(const F& f, R expected) +{ +    assert(f() == expected); +} + +int f() {return 1;} + +struct A_int_0 +{ +    int operator()() {return 4;} +    int operator()() const {return 5;} +}; + +int main() +{ +    test(std::bind(f), 1); +    test(std::bind(&f), 1); +    test(std::bind(A_int_0()), 4); +    test_const(std::bind(A_int_0()), 5); + +    test(std::bind<int>(f), 1); +    test(std::bind<int>(&f), 1); +    test(std::bind<int>(A_int_0()), 4); +    test_const(std::bind<int>(A_int_0()), 5); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp new file mode 100644 index 000000000000..af5efe464d5d --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp @@ -0,0 +1,287 @@ +//===----------------------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); + +#include <stdio.h> + +#include <functional> +#include <cassert> + +int count = 0; + +// 1 arg, return void + +void f_void_1(int i) +{ +    count += i; +} + +struct A_void_1 +{ +    void operator()(int i) +    { +        count += i; +    } + +    void mem1() {++count;} +    void mem2() const {count += 2;} +}; + +void +test_void_1() +{ +    using namespace std::placeholders; +    int save_count = count; +    // function +    { +    int i = 2; +    std::bind(f_void_1, _1)(i); +    assert(count == save_count + 2); +    save_count = count; +    } +    { +    int i = 2; +    std::bind(f_void_1, i)(); +    assert(count == save_count + 2); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)(int) = f_void_1; +    int i = 3; +    std::bind(fp, _1)(i); +    assert(count == save_count+3); +    save_count = count; +    } +    { +    void (*fp)(int) = f_void_1; +    int i = 3; +    std::bind(fp, i)(); +    assert(count == save_count+3); +    save_count = count; +    } +    // functor +    { +    A_void_1 a0; +    int i = 4; +    std::bind(a0, _1)(i); +    assert(count == save_count+4); +    save_count = count; +    } +    { +    A_void_1 a0; +    int i = 4; +    std::bind(a0, i)(); +    assert(count == save_count+4); +    save_count = count; +    } +    // member function pointer +    { +    void (A_void_1::*fp)() = &A_void_1::mem1; +    A_void_1 a; +    std::bind(fp, _1)(a); +    assert(count == save_count+1); +    save_count = count; +    A_void_1* ap = &a; +    std::bind(fp, _1)(ap); +    assert(count == save_count+1); +    save_count = count; +    } +    { +    void (A_void_1::*fp)() = &A_void_1::mem1; +    A_void_1 a; +    std::bind(fp, a)(); +    assert(count == save_count+1); +    save_count = count; +    A_void_1* ap = &a; +    std::bind(fp, ap)(); +    assert(count == save_count+1); +    save_count = count; +    } +    // const member function pointer +    { +    void (A_void_1::*fp)() const = &A_void_1::mem2; +    A_void_1 a; +    std::bind(fp, _1)(a); +    assert(count == save_count+2); +    save_count = count; +    A_void_1* ap = &a; +    std::bind(fp, _1)(ap); +    assert(count == save_count+2); +    save_count = count; +    } +    { +    void (A_void_1::*fp)() const = &A_void_1::mem2; +    A_void_1 a; +    std::bind(fp, a)(); +    assert(count == save_count+2); +    save_count = count; +    A_void_1* ap = &a; +    std::bind(fp, ap)(); +    assert(count == save_count+2); +    save_count = count; +    } +} + +// 1 arg, return int + +int f_int_1(int i) +{ +    return i + 1; +} + +struct A_int_1 +{ +    A_int_1() : data_(5) {} +    int operator()(int i) +    { +        return i - 1; +    } + +    int mem1() {return 3;} +    int mem2() const {return 4;} +    int data_; +}; + +void +test_int_1() +{ +    using namespace std::placeholders; +    // function +    { +    int i = 2; +    assert(std::bind(f_int_1, _1)(i) == 3); +    assert(std::bind(f_int_1, i)() == 3); +    } +    // function pointer +    { +    int (*fp)(int) = f_int_1; +    int i = 3; +    assert(std::bind(fp, _1)(i) == 4); +    assert(std::bind(fp, i)() == 4); +    } +    // functor +    { +    int i = 4; +    assert(std::bind(A_int_1(), _1)(i) == 3); +    assert(std::bind(A_int_1(), i)() == 3); +    } +    // member function pointer +    { +    A_int_1 a; +    assert(std::bind(&A_int_1::mem1, _1)(a) == 3); +    assert(std::bind(&A_int_1::mem1, a)() == 3); +    A_int_1* ap = &a; +    assert(std::bind(&A_int_1::mem1, _1)(ap) == 3); +    assert(std::bind(&A_int_1::mem1, ap)() == 3); +    } +    // const member function pointer +    { +    A_int_1 a; +    assert(std::bind(&A_int_1::mem2, _1)(A_int_1()) == 4); +    assert(std::bind(&A_int_1::mem2, A_int_1())() == 4); +    A_int_1* ap = &a; +    assert(std::bind(&A_int_1::mem2, _1)(ap) == 4); +    assert(std::bind(&A_int_1::mem2, ap)() == 4); +    } +    // member data pointer +    { +    A_int_1 a; +    assert(std::bind(&A_int_1::data_, _1)(a) == 5); +    assert(std::bind(&A_int_1::data_, a)() == 5); +    A_int_1* ap = &a; +    assert(std::bind(&A_int_1::data_, _1)(a) == 5); +    std::bind(&A_int_1::data_, _1)(a) = 6; +    assert(std::bind(&A_int_1::data_, _1)(a) == 6); +    assert(std::bind(&A_int_1::data_, _1)(ap) == 6); +    std::bind(&A_int_1::data_, _1)(ap) = 7; +    assert(std::bind(&A_int_1::data_, _1)(ap) == 7); +    } +} + +// 2 arg, return void + +void f_void_2(int i, int j) +{ +    count += i+j; +} + +struct A_void_2 +{ +    void operator()(int i, int j) +    { +        count += i+j; +    } + +    void mem1(int i) {count += i;} +    void mem2(int i) const {count += i;} +}; + +void +test_void_2() +{ +    using namespace std::placeholders; +    int save_count = count; +    // function +    { +    int i = 2; +    int j = 3; +    std::bind(f_void_2, _1, _2)(i, j); +    assert(count == save_count+5); +    save_count = count; +    std::bind(f_void_2, i, _1)(j); +    assert(count == save_count+5); +    save_count = count; +    std::bind(f_void_2, i, j)(); +    assert(count == save_count+5); +    save_count = count; +    } +    // member function pointer +    { +    int j = 3; +    std::bind(&A_void_2::mem1, _1, _2)(A_void_2(), j); +    assert(count == save_count+3); +    save_count = count; +    std::bind(&A_void_2::mem1, _2, _1)(j, A_void_2()); +    assert(count == save_count+3); +    save_count = count; +    } +} + +struct TFENode +{ +    bool foo(unsigned long long) const +    { +        return true; +    } +}; + +void +test3() +{ +    using namespace std; +    using namespace std::placeholders; +    const auto f = bind(&TFENode::foo, _1, 0UL); +    const TFENode n = TFENode{}; +    bool b = f(n); +    assert(b); +} + +int main() +{ +    test_void_1(); +    test_int_1(); +    test_void_2(); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_rvalue.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_rvalue.pass.cpp new file mode 100644 index 000000000000..4913a510c36e --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_rvalue.pass.cpp @@ -0,0 +1,266 @@ +//===----------------------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); + +#include <stdio.h> + +#include <functional> +#include <cassert> + +int count = 0; + +// 1 arg, return void + +void f_void_1(int i) +{ +    count += i; +} + +struct A_void_1 +{ +    void operator()(int i) +    { +        count += i; +    } + +    void mem1() {++count;} +    void mem2() const {count += 2;} +}; + +void +test_void_1() +{ +    using namespace std::placeholders; +    int save_count = count; +    // function +    { +    std::bind(f_void_1, _1)(2); +    assert(count == save_count + 2); +    save_count = count; +    } +    { +    std::bind(f_void_1, 2)(); +    assert(count == save_count + 2); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)(int) = f_void_1; +    std::bind(fp, _1)(3); +    assert(count == save_count+3); +    save_count = count; +    } +    { +    void (*fp)(int) = f_void_1; +    std::bind(fp, 3)(); +    assert(count == save_count+3); +    save_count = count; +    } +    // functor +    { +    A_void_1 a0; +    std::bind(a0, _1)(4); +    assert(count == save_count+4); +    save_count = count; +    } +    { +    A_void_1 a0; +    std::bind(a0, 4)(); +    assert(count == save_count+4); +    save_count = count; +    } +    // member function pointer +    { +    void (A_void_1::*fp)() = &A_void_1::mem1; +    std::bind(fp, _1)(A_void_1()); +    assert(count == save_count+1); +    save_count = count; +    A_void_1 a; +    std::bind(fp, _1)(&a); +    assert(count == save_count+1); +    save_count = count; +    } +    { +    void (A_void_1::*fp)() = &A_void_1::mem1; +    std::bind(fp, A_void_1())(); +    assert(count == save_count+1); +    save_count = count; +    A_void_1 a; +    std::bind(fp, &a)(); +    assert(count == save_count+1); +    save_count = count; +    } +    // const member function pointer +    { +    void (A_void_1::*fp)() const = &A_void_1::mem2; +    std::bind(fp, _1)(A_void_1()); +    assert(count == save_count+2); +    save_count = count; +    A_void_1 a; +    std::bind(fp, _1)(&a); +    assert(count == save_count+2); +    save_count = count; +    } +    { +    void (A_void_1::*fp)() const = &A_void_1::mem2; +    std::bind(fp, A_void_1())(); +    assert(count == save_count+2); +    save_count = count; +    A_void_1 a; +    std::bind(fp, &a)(); +    assert(count == save_count+2); +    save_count = count; +    } +} + +// 1 arg, return int + +int f_int_1(int i) +{ +    return i + 1; +} + +struct A_int_1 +{ +    A_int_1() : data_(5) {} +    int operator()(int i) +    { +        return i - 1; +    } + +    int mem1() {return 3;} +    int mem2() const {return 4;} +    int data_; +}; + +void +test_int_1() +{ +    using namespace std::placeholders; +    // function +    { +    assert(std::bind(f_int_1, _1)(2) == 3); +    assert(std::bind(f_int_1, 2)() == 3); +    } +    // function pointer +    { +    int (*fp)(int) = f_int_1; +    assert(std::bind(fp, _1)(3) == 4); +    assert(std::bind(fp, 3)() == 4); +    } +    // functor +    { +    assert(std::bind(A_int_1(), _1)(4) == 3); +    assert(std::bind(A_int_1(), 4)() == 3); +    } +    // member function pointer +    { +    assert(std::bind(&A_int_1::mem1, _1)(A_int_1()) == 3); +    assert(std::bind(&A_int_1::mem1, A_int_1())() == 3); +    A_int_1 a; +    assert(std::bind(&A_int_1::mem1, _1)(&a) == 3); +    assert(std::bind(&A_int_1::mem1, &a)() == 3); +    } +    // const member function pointer +    { +    assert(std::bind(&A_int_1::mem2, _1)(A_int_1()) == 4); +    assert(std::bind(&A_int_1::mem2, A_int_1())() == 4); +    A_int_1 a; +    assert(std::bind(&A_int_1::mem2, _1)(&a) == 4); +    assert(std::bind(&A_int_1::mem2, &a)() == 4); +    } +    // member data pointer +    { +    assert(std::bind(&A_int_1::data_, _1)(A_int_1()) == 5); +    assert(std::bind(&A_int_1::data_, A_int_1())() == 5); +    A_int_1 a; +    assert(std::bind(&A_int_1::data_, _1)(a) == 5); +    std::bind(&A_int_1::data_, _1)(a) = 6; +    assert(std::bind(&A_int_1::data_, _1)(a) == 6); +    assert(std::bind(&A_int_1::data_, _1)(&a) == 6); +    std::bind(&A_int_1::data_, _1)(&a) = 7; +    assert(std::bind(&A_int_1::data_, _1)(&a) == 7); +    } +} + +// 2 arg, return void + +void f_void_2(int i, int j) +{ +    count += i+j; +} + +struct A_void_2 +{ +    void operator()(int i, int j) +    { +        count += i+j; +    } + +    void mem1(int i) {count += i;} +    void mem2(int i) const {count += i;} +}; + +void +test_void_2() +{ +    using namespace std::placeholders; +    int save_count = count; +    // function +    { +    std::bind(f_void_2, _1, _2)(2, 3); +    assert(count == save_count+5); +    save_count = count; +    std::bind(f_void_2, 2, _1)(3); +    assert(count == save_count+5); +    save_count = count; +    std::bind(f_void_2, 2, 3)(); +    assert(count == save_count+5); +    save_count = count; +    } +    // member function pointer +    { +    std::bind(&A_void_2::mem1, _1, _2)(A_void_2(), 3); +    assert(count == save_count+3); +    save_count = count; +    std::bind(&A_void_2::mem1, _2, _1)(3, A_void_2()); +    assert(count == save_count+3); +    save_count = count; +    } +} + +int f_nested(int i) +{ +    return i+1; +} + +int g_nested(int i) +{ +    return i*10; +} + +void test_nested() +{ +    using namespace std::placeholders; +    assert(std::bind(f_nested, std::bind(g_nested, _1))(3) == 31); +} + +int main() +{ +    test_void_1(); +    test_int_1(); +    test_void_2(); +    test_nested(); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_void_0.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_void_0.pass.cpp new file mode 100644 index 000000000000..b7874b77cf03 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_void_0.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); + +#include <functional> +#include <cassert> + +int count = 0; + +template <class F> +void +test(F f) +{ +    int save_count = count; +    f(); +    assert(count == save_count + 1); +} + +template <class F> +void +test_const(const F& f) +{ +    int save_count = count; +    f(); +    assert(count == save_count + 2); +} + +void f() {++count;} + +int g() {++count; return 0;} + +struct A_void_0 +{ +    void operator()() {++count;} +    void operator()() const {count += 2;} +}; + +struct A_int_0 +{ +    int operator()() {++count; return 4;} +    int operator()() const {count += 2; return 5;} +}; + +int main() +{ +    test(std::bind(f)); +    test(std::bind(&f)); +    test(std::bind(A_void_0())); +    test_const(std::bind(A_void_0())); + +    test(std::bind<void>(f)); +    test(std::bind<void>(&f)); +    test(std::bind<void>(A_void_0())); +    test_const(std::bind<void>(A_void_0())); + +    test(std::bind<void>(g)); +    test(std::bind<void>(&g)); +    test(std::bind<void>(A_int_0())); +    test_const(std::bind<void>(A_int_0())); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp new file mode 100644 index 000000000000..12720f7b550a --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <functional> + +// template<CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); +// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types> +//   unspecified bind(Fn, Types...); + +// http://llvm.org/bugs/show_bug.cgi?id=16343 + +#include <cmath> +#include <functional> +#include <cassert> + +struct power +{ +  template <typename T> +  T +  operator()(T a, T b) +  { +    return std::pow(a, b); +  } +}; + +struct plus_one +{ +  template <typename T> +  T +  operator()(T a) +  { +    return a + 1; +  } +}; + +int +main() +{ +    using std::placeholders::_1; + +    auto g = std::bind(power(), 2, _1); +    assert(g(5) == 32); +    assert(std::bind(plus_one(), g)(5) == 33); +} | 
