diff options
Diffstat (limited to 'test/std/utilities/function.objects')
106 files changed, 6651 insertions, 0 deletions
| diff --git a/test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp new file mode 100644 index 000000000000..490dc16b60e2 --- /dev/null +++ b/test/std/utilities/function.objects/arithmetic.operations/divides.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// divides + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::divides<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(36, 4) == 9); +#if _LIBCPP_STD_VER > 11 +    typedef std::divides<> F2; +    const F2 f2 = F2(); +    assert(f2(36, 4) == 9); +    assert(f2(36.0, 4) == 9); +    assert(f2(18, 4.0) == 4.5); // exact in binary + +    constexpr int foo = std::divides<int> () (3, 2); +    static_assert ( foo == 1, "" ); + +    constexpr int bar = std::divides<> () (3.0, 2); +    static_assert ( bar == 1, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp new file mode 100644 index 000000000000..9bda541f896a --- /dev/null +++ b/test/std/utilities/function.objects/arithmetic.operations/minus.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// minus + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::minus<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(3, 2) == 1); +#if _LIBCPP_STD_VER > 11 +    typedef std::minus<> F2; +    const F2 f2 = F2(); +    assert(f2(3,2) == 1); +    assert(f2(3.0, 2) == 1); +    assert(f2(3, 2.5) == 0.5); + +    constexpr int foo = std::minus<int> () (3, 2); +    static_assert ( foo == 1, "" ); + +    constexpr int bar = std::minus<> () (3.0, 2); +    static_assert ( bar == 1, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp new file mode 100644 index 000000000000..ca5bba6d5b8e --- /dev/null +++ b/test/std/utilities/function.objects/arithmetic.operations/modulus.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// modulus + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::modulus<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(36, 8) == 4); +#if _LIBCPP_STD_VER > 11 +    typedef std::modulus<> F2; +    const F2 f2 = F2(); +    assert(f2(36, 8) == 4); +    assert(f2(36L, 8) == 4); +    assert(f2(36, 8L) == 4); + +    constexpr int foo = std::modulus<int> () (3, 2); +    static_assert ( foo == 1, "" ); + +    constexpr int bar = std::modulus<> () (3L, 2); +    static_assert ( bar == 1, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp new file mode 100644 index 000000000000..f132c8d4bd9b --- /dev/null +++ b/test/std/utilities/function.objects/arithmetic.operations/multiplies.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// multiplies + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::multiplies<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(3, 2) == 6); +#if _LIBCPP_STD_VER > 11 +    typedef std::multiplies<> F2; +    const F2 f2 = F2(); +    assert(f2(3,2) == 6); +    assert(f2(3.0, 2) == 6); +    assert(f2(3, 2.5) == 7.5); // exact in binary + +    constexpr int foo = std::multiplies<int> () (3, 2); +    static_assert ( foo == 6, "" ); + +    constexpr int bar = std::multiplies<> () (3.0, 2); +    static_assert ( bar == 6, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp new file mode 100644 index 000000000000..0adac659123b --- /dev/null +++ b/test/std/utilities/function.objects/arithmetic.operations/negate.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// negate + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::negate<int> F; +    const F f = F(); +    static_assert((std::is_same<F::argument_type, int>::value), "" ); +    static_assert((std::is_same<F::result_type, int>::value), "" ); +    assert(f(36) == -36); +#if _LIBCPP_STD_VER > 11 +    typedef std::negate<> F2; +    const F2 f2 = F2(); +    assert(f2(36) == -36); +    assert(f2(36L) == -36); +    assert(f2(36.0) == -36); + +    constexpr int foo = std::negate<int> () (3); +    static_assert ( foo == -3, "" ); + +    constexpr int bar = std::negate<> () (3.0); +    static_assert ( bar == -3, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp new file mode 100644 index 000000000000..3c093fc093c3 --- /dev/null +++ b/test/std/utilities/function.objects/arithmetic.operations/plus.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// plus + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::plus<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(3, 2) == 5); +#if _LIBCPP_STD_VER > 11 +    typedef std::plus<> F2; +    const F2 f2 = F2(); +    assert(f2(3,2) == 5); +    assert(f2(3.0, 2) == 5); +    assert(f2(3, 2.5) == 5.5); +     +    constexpr int foo = std::plus<int> () (3, 2); +    static_assert ( foo == 5, "" ); + +    constexpr int bar = std::plus<> () (3.0, 2); +    static_assert ( bar == 5, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp b/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp new file mode 100644 index 000000000000..72b4b4a0a1fe --- /dev/null +++ b/test/std/utilities/function.objects/arithmetic.operations/transparent.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +#include <functional> +#include <string> + +template <class _Tp> +struct is_transparent +{ +private: +    struct __two {char __lx; char __lxx;}; +    template <class _Up> static __two __test(...); +    template <class _Up> static char __test(typename _Up::is_transparent* = 0); +public: +    static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + + +int main () { +#if _LIBCPP_STD_VER > 11 + +    static_assert ( !is_transparent<std::plus<int>>::value, "" ); +    static_assert ( !is_transparent<std::plus<std::string>>::value, "" ); +    static_assert (  is_transparent<std::plus<void>>::value, "" ); +    static_assert (  is_transparent<std::plus<>>::value, "" ); + +    static_assert ( !is_transparent<std::minus<int>>::value, "" ); +    static_assert ( !is_transparent<std::minus<std::string>>::value, "" ); +    static_assert (  is_transparent<std::minus<void>>::value, "" ); +    static_assert (  is_transparent<std::minus<>>::value, "" ); + +    static_assert ( !is_transparent<std::multiplies<int>>::value, "" ); +    static_assert ( !is_transparent<std::multiplies<std::string>>::value, "" ); +    static_assert (  is_transparent<std::multiplies<void>>::value, "" ); +    static_assert (  is_transparent<std::multiplies<>>::value, "" ); + +    static_assert ( !is_transparent<std::divides<int>>::value, "" ); +    static_assert ( !is_transparent<std::divides<std::string>>::value, "" ); +    static_assert (  is_transparent<std::divides<void>>::value, "" ); +    static_assert (  is_transparent<std::divides<>>::value, "" ); + +    static_assert ( !is_transparent<std::modulus<int>>::value, "" ); +    static_assert ( !is_transparent<std::modulus<std::string>>::value, "" ); +    static_assert (  is_transparent<std::modulus<void>>::value, "" ); +    static_assert (  is_transparent<std::modulus<>>::value, "" ); + +    static_assert ( !is_transparent<std::negate<int>>::value, "" ); +    static_assert ( !is_transparent<std::negate<std::string>>::value, "" ); +    static_assert (  is_transparent<std::negate<void>>::value, "" ); +    static_assert (  is_transparent<std::negate<>>::value, "" ); +     +#endif + +    return 0; +    } 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); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp new file mode 100644 index 000000000000..7f8dd4a98d2b --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +//                     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<class T> struct is_bind_expression + +#include <functional> + +template <bool Expected, class T> +void +test(const T&) +{ +    static_assert(std::is_bind_expression<T>::value == Expected, ""); +} + +struct C {}; + +int main() +{ +    test<true>(std::bind(C())); +    test<true>(std::bind(C(), std::placeholders::_2)); +    test<true>(std::bind<int>(C())); +    test<false>(1); +    test<false>(std::placeholders::_2); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp new file mode 100644 index 000000000000..6a52bd1848e9 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_placeholder.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// struct is_placeholder + +#include <functional> + +template <int Expected, class T> +void +test(const T&) +{ +    static_assert(std::is_placeholder<T>::value == Expected, ""); +} + +struct C {}; + +int main() +{ +    test<1>(std::placeholders::_1); +    test<2>(std::placeholders::_2); +    test<3>(std::placeholders::_3); +    test<4>(std::placeholders::_4); +    test<5>(std::placeholders::_5); +    test<6>(std::placeholders::_6); +    test<7>(std::placeholders::_7); +    test<8>(std::placeholders::_8); +    test<9>(std::placeholders::_9); +    test<10>(std::placeholders::_10); +    test<0>(4); +    test<0>(5.5); +    test<0>('a'); +    test<0>(C()); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp new file mode 100644 index 000000000000..246186040c56 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.place/placeholders.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// placeholders + +#include <functional> +#include <type_traits> + +template <class T> +void +test(const T& t) +{ +    // Test default constructible. +    T t2; +    ((void)t2); +    // Test copy constructible. +    T t3 = t; +    ((void)t3); +    static_assert(std::is_nothrow_copy_constructible<T>::value, ""); +    static_assert(std::is_nothrow_move_constructible<T>::value, ""); +} + +int main() +{ +    test(std::placeholders::_1); +    test(std::placeholders::_2); +    test(std::placeholders::_3); +    test(std::placeholders::_4); +    test(std::placeholders::_5); +    test(std::placeholders::_6); +    test(std::placeholders::_7); +    test(std::placeholders::_8); +    test(std::placeholders::_9); +    test(std::placeholders::_10); +} diff --git a/test/std/utilities/function.objects/bind/func.bind/nothing_to_do.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/utilities/function.objects/bind/func.bind/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/utilities/function.objects/bind/nothing_to_do.pass.cpp b/test/std/utilities/function.objects/bind/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/utilities/function.objects/bind/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp new file mode 100644 index 000000000000..c0135fad1982 --- /dev/null +++ b/test/std/utilities/function.objects/bitwise.operations/bit_and.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// bit_and + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::bit_and<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(0xEA95, 0xEA95) == 0xEA95); +    assert(f(0xEA95, 0x58D3) == 0x4891); +    assert(f(0x58D3, 0xEA95) == 0x4891); +    assert(f(0x58D3, 0) == 0); +    assert(f(0xFFFF, 0x58D3) == 0x58D3); +#if _LIBCPP_STD_VER > 11 +    typedef std::bit_and<> F2; +    const F2 f2 = F2(); +    assert(f2(0xEA95, 0xEA95) == 0xEA95); +    assert(f2(0xEA95L, 0xEA95) == 0xEA95); +    assert(f2(0xEA95, 0xEA95L) == 0xEA95); + +    assert(f2(0xEA95, 0x58D3) == 0x4891); +    assert(f2(0xEA95L, 0x58D3) == 0x4891); +    assert(f2(0xEA95, 0x58D3L) == 0x4891); + +    assert(f2(0x58D3, 0xEA95) == 0x4891); +    assert(f2(0x58D3L, 0xEA95) == 0x4891); +    assert(f2(0x58D3, 0xEA95L) == 0x4891); + +    assert(f2(0x58D3, 0) == 0); +    assert(f2(0x58D3L, 0) == 0); +    assert(f2(0x58D3, 0L) == 0); + +    assert(f2(0xFFFF, 0x58D3) == 0x58D3); +    assert(f2(0xFFFFL, 0x58D3) == 0x58D3); +    assert(f2(0xFFFF, 0x58D3L) == 0x58D3); + +    constexpr int foo = std::bit_and<int> () (0x58D3, 0xEA95); +    static_assert ( foo == 0x4891, "" ); + +    constexpr int bar = std::bit_and<> () (0x58D3L, 0xEA95); +    static_assert ( bar == 0x4891, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp new file mode 100644 index 000000000000..48800a366a81 --- /dev/null +++ b/test/std/utilities/function.objects/bitwise.operations/bit_not.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// bit_not + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 +    typedef std::bit_not<int> F; +    const F f = F(); +    static_assert((std::is_same<F::argument_type, int>::value), "" ); +    static_assert((std::is_same<F::result_type, int>::value), "" ); +    assert((f(0xEA95) & 0xFFFF ) == 0x156A); +    assert((f(0x58D3) & 0xFFFF ) == 0xA72C); +    assert((f(0)      & 0xFFFF ) == 0xFFFF); +    assert((f(0xFFFF) & 0xFFFF ) == 0); + +    typedef std::bit_not<> F2; +    const F2 f2 = F2(); +    assert((f2(0xEA95)  & 0xFFFF ) == 0x156A); +    assert((f2(0xEA95L) & 0xFFFF ) == 0x156A); +    assert((f2(0x58D3)  & 0xFFFF ) == 0xA72C); +    assert((f2(0x58D3L) & 0xFFFF ) == 0xA72C); +    assert((f2(0)       & 0xFFFF ) == 0xFFFF); +    assert((f2(0L)      & 0xFFFF ) == 0xFFFF); +    assert((f2(0xFFFF)  & 0xFFFF ) == 0); +    assert((f2(0xFFFFL)  & 0xFFFF ) == 0); + +    constexpr int foo = std::bit_not<int> () (0xEA95) & 0xFFFF; +    static_assert ( foo == 0x156A, "" ); + +    constexpr int bar = std::bit_not<> () (0xEA95) & 0xFFFF; +    static_assert ( bar == 0x156A, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp new file mode 100644 index 000000000000..cb33df3d84b7 --- /dev/null +++ b/test/std/utilities/function.objects/bitwise.operations/bit_or.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// bit_or + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::bit_or<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(0xEA95, 0xEA95) == 0xEA95); +    assert(f(0xEA95, 0x58D3) == 0xFAD7); +    assert(f(0x58D3, 0xEA95) == 0xFAD7); +    assert(f(0x58D3, 0) == 0x58D3); +    assert(f(0xFFFF, 0x58D3) == 0xFFFF); +#if _LIBCPP_STD_VER > 11 +    typedef std::bit_or<> F2; +    const F2 f2 = F2(); +    assert(f2(0xEA95, 0xEA95) == 0xEA95); +    assert(f2(0xEA95L, 0xEA95) == 0xEA95); +    assert(f2(0xEA95, 0xEA95L) == 0xEA95); + +    assert(f2(0xEA95, 0x58D3) == 0xFAD7); +    assert(f2(0xEA95L, 0x58D3) == 0xFAD7); +    assert(f2(0xEA95, 0x58D3L) == 0xFAD7); + +    assert(f2(0x58D3, 0xEA95) == 0xFAD7); +    assert(f2(0x58D3L, 0xEA95) == 0xFAD7); +    assert(f2(0x58D3, 0xEA95L) == 0xFAD7); + +    assert(f2(0x58D3, 0) == 0x58D3); +    assert(f2(0x58D3L, 0) == 0x58D3); +    assert(f2(0x58D3, 0L) == 0x58D3); + +    assert(f2(0xFFFF, 0x58D3) == 0xFFFF); +    assert(f2(0xFFFFL, 0x58D3) == 0xFFFF); +    assert(f2(0xFFFF, 0x58D3L) == 0xFFFF); + +    constexpr int foo = std::bit_or<int> () (0x58D3, 0xEA95); +    static_assert ( foo == 0xFAD7, "" ); + +    constexpr int bar = std::bit_or<> () (0x58D3L, 0xEA95); +    static_assert ( bar == 0xFAD7, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp new file mode 100644 index 000000000000..bbf2ce5baf1b --- /dev/null +++ b/test/std/utilities/function.objects/bitwise.operations/bit_xor.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// bit_xor + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    { +    typedef std::bit_xor<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::result_type>::value), "" ); +    assert(f(0xEA95, 0xEA95) == 0); +    assert(f(0xEA95, 0x58D3) == 0xB246); +    assert(f(0x58D3, 0xEA95) == 0xB246); +    assert(f(0x58D3, 0) == 0x58D3); +    assert(f(0xFFFF, 0x58D3) == 0xA72C); +    } +#if _LIBCPP_STD_VER > 11 +    { +    typedef std::bit_xor<> F2; +    const F2 f = F2(); +    assert(f(0xEA95, 0xEA95) == 0); +    assert(f(0xEA95L, 0xEA95) == 0); +    assert(f(0xEA95, 0xEA95L) == 0); + +    assert(f(0xEA95, 0x58D3) == 0xB246); +    assert(f(0xEA95L, 0x58D3) == 0xB246); +    assert(f(0xEA95, 0x58D3L) == 0xB246); + +    assert(f(0x58D3, 0xEA95) == 0xB246); +    assert(f(0x58D3L, 0xEA95) == 0xB246); +    assert(f(0x58D3, 0xEA95L) == 0xB246); + +    assert(f(0x58D3, 0) == 0x58D3); +    assert(f(0x58D3L, 0) == 0x58D3); +    assert(f(0x58D3, 0L) == 0x58D3); + +    assert(f(0xFFFF, 0x58D3) == 0xA72C); +    assert(f(0xFFFFL, 0x58D3) == 0xA72C); +    assert(f(0xFFFF, 0x58D3L) == 0xA72C); + +    constexpr int foo = std::bit_xor<int> () (0x58D3, 0xEA95); +    static_assert ( foo == 0xB246, "" ); + +    constexpr int bar = std::bit_xor<> () (0x58D3L, 0xEA95); +    static_assert ( bar == 0xB246, "" ); +    } +#endif +} diff --git a/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp b/test/std/utilities/function.objects/bitwise.operations/transparent.pass.cpp new file mode 100644 index 000000000000..9f8e15dd55fe --- /dev/null +++ b/test/std/utilities/function.objects/bitwise.operations/transparent.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. +// +//===----------------------------------------------------------------------===// + +#include <functional> +#include <string> + +template <class _Tp> +struct is_transparent +{ +private: +    struct __two {char __lx; char __lxx;}; +    template <class _Up> static __two __test(...); +    template <class _Up> static char __test(typename _Up::is_transparent* = 0); +public: +    static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + + +int main () { +#if _LIBCPP_STD_VER > 11 + +    static_assert ( !is_transparent<std::bit_and<int>>::value, "" ); +    static_assert ( !is_transparent<std::bit_and<std::string>>::value, "" ); +    static_assert (  is_transparent<std::bit_and<void>>::value, "" ); +    static_assert (  is_transparent<std::bit_and<>>::value, "" ); + +    static_assert ( !is_transparent<std::bit_or<int>>::value, "" ); +    static_assert ( !is_transparent<std::bit_or<std::string>>::value, "" ); +    static_assert (  is_transparent<std::bit_or<void>>::value, "" ); +    static_assert (  is_transparent<std::bit_or<>>::value, "" ); + +    static_assert ( !is_transparent<std::bit_xor<int>>::value, "" ); +    static_assert ( !is_transparent<std::bit_xor<std::string>>::value, "" ); +    static_assert (  is_transparent<std::bit_xor<void>>::value, "" ); +    static_assert (  is_transparent<std::bit_xor<>>::value, "" ); + +    static_assert ( !is_transparent<std::bit_not<int>>::value, "" ); +    static_assert ( !is_transparent<std::bit_not<std::string>>::value, "" ); +    static_assert (  is_transparent<std::bit_not<void>>::value, "" ); +    static_assert (  is_transparent<std::bit_not<>>::value, "" ); +     +#endif + +    return 0; +    } diff --git a/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp b/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp new file mode 100644 index 000000000000..60415ec75d60 --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/equal_to.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// equal_to + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::equal_to<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(f(36, 36)); +    assert(!f(36, 6)); +#if _LIBCPP_STD_VER > 11 +    typedef std::equal_to<> F2; +    const F2 f2 = F2(); +    assert(f2(36, 36)); +    assert(!f2(36, 6)); +    assert(f2(36, 36.0)); +    assert(f2(36.0, 36L)); + +    constexpr bool foo = std::equal_to<int> () (36, 36); +    static_assert ( foo, "" ); + +    constexpr bool bar = std::equal_to<> () (36.0, 36); +    static_assert ( bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/comparisons/greater.pass.cpp b/test/std/utilities/function.objects/comparisons/greater.pass.cpp new file mode 100644 index 000000000000..164f09aa605c --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/greater.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// greater + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::greater<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(!f(36, 36)); +    assert(f(36, 6)); +    assert(!f(6, 36)); +#if _LIBCPP_STD_VER > 11 +    typedef std::greater<> F2; +    const F2 f2 = F2(); +    assert(!f2(36, 36)); +    assert(f2(36, 6)); +    assert(!f2(6, 36)); +    assert( f2(36, 6.0)); +    assert( f2(36.0, 6)); +    assert(!f2(6, 36.0)); +    assert(!f2(6.0, 36)); + +    constexpr bool foo = std::greater<int> () (36, 36); +    static_assert ( !foo, "" ); + +    constexpr bool bar = std::greater<> () (36.0, 36); +    static_assert ( !bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp b/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp new file mode 100644 index 000000000000..e89c14e24625 --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/greater_equal.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// greater_equal + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::greater_equal<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(f(36, 36)); +    assert(f(36, 6)); +    assert(!f(6, 36)); +#if _LIBCPP_STD_VER > 11 +    typedef std::greater_equal<> F2; +    const F2 f2 = F2(); +    assert(f2(36, 36)); +    assert(f2(36, 6)); +    assert(!f2(6, 36)); +    assert( f2(36, 6.0)); +    assert( f2(36.0, 6)); +    assert(!f2(6, 36.0)); +    assert(!f2(6.0, 36)); + +    constexpr bool foo = std::greater_equal<int> () (36, 36); +    static_assert ( foo, "" ); + +    constexpr bool bar = std::greater_equal<> () (36.0, 36); +    static_assert ( bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/comparisons/less.pass.cpp b/test/std/utilities/function.objects/comparisons/less.pass.cpp new file mode 100644 index 000000000000..74fe166a0cd9 --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/less.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// less + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::less<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(!f(36, 36)); +    assert(!f(36, 6)); +    assert(f(6, 36)); +#if _LIBCPP_STD_VER > 11 +    typedef std::less<> F2; +    const F2 f2 = F2(); +    assert(!f2(36, 36)); +    assert(!f2(36, 6)); +    assert( f2(6, 36)); +    assert(!f2(36, 6.0)); +    assert(!f2(36.0, 6)); +    assert( f2(6, 36.0)); +    assert( f2(6.0, 36)); + +    constexpr bool foo = std::less<int> () (36, 36); +    static_assert ( !foo, "" ); + +    constexpr bool bar = std::less<> () (36.0, 36); +    static_assert ( !bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp b/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp new file mode 100644 index 000000000000..e6ba1f7f8a21 --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/less_equal.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// less_equal + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::less_equal<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(f(36, 36)); +    assert(!f(36, 6)); +    assert(f(6, 36)); +#if _LIBCPP_STD_VER > 11 +    typedef std::less_equal<> F2; +    const F2 f2 = F2(); +    assert( f2(36, 36)); +    assert(!f2(36, 6)); +    assert( f2(6, 36)); +    assert(!f2(36, 6.0)); +    assert(!f2(36.0, 6)); +    assert( f2(6, 36.0)); +    assert( f2(6.0, 36)); + +    constexpr bool foo = std::less_equal<int> () (36, 36); +    static_assert ( foo, "" ); + +    constexpr bool bar = std::less_equal<> () (36.0, 36); +    static_assert ( bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp b/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp new file mode 100644 index 000000000000..3e710b3e0c70 --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/not_equal_to.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// not_equal_to + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::not_equal_to<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(!f(36, 36)); +    assert(f(36, 6)); +#if _LIBCPP_STD_VER > 11 +    typedef std::not_equal_to<> F2; +    const F2 f2 = F2(); +    assert(!f2(36, 36)); +    assert( f2(36, 6)); +    assert( f2(36, 6.0)); +    assert( f2(36.0, 6)); +    assert(!f2(36.0, 36)); +    assert(!f2(36, 36.0)); + +    constexpr bool foo = std::not_equal_to<int> () (36, 36); +    static_assert ( !foo, "" ); + +    constexpr bool bar = std::not_equal_to<> () (36.0, 36); +    static_assert ( !bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/comparisons/transparent.pass.cpp b/test/std/utilities/function.objects/comparisons/transparent.pass.cpp new file mode 100644 index 000000000000..41ce4bcae65f --- /dev/null +++ b/test/std/utilities/function.objects/comparisons/transparent.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +#include <functional> +#include <string> + +template <class _Tp> +struct is_transparent +{ +private: +    struct __two {char __lx; char __lxx;}; +    template <class _Up> static __two __test(...); +    template <class _Up> static char __test(typename _Up::is_transparent* = 0); +public: +    static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + + +int main () { +#if _LIBCPP_STD_VER > 11 + +    static_assert ( !is_transparent<std::less<int>>::value, "" ); +    static_assert ( !is_transparent<std::less<std::string>>::value, "" ); +    static_assert (  is_transparent<std::less<void>>::value, "" ); +    static_assert (  is_transparent<std::less<>>::value, "" ); + +    static_assert ( !is_transparent<std::less_equal<int>>::value, "" ); +    static_assert ( !is_transparent<std::less_equal<std::string>>::value, "" ); +    static_assert (  is_transparent<std::less_equal<void>>::value, "" ); +    static_assert (  is_transparent<std::less_equal<>>::value, "" ); + +    static_assert ( !is_transparent<std::equal_to<int>>::value, "" ); +    static_assert ( !is_transparent<std::equal_to<std::string>>::value, "" ); +    static_assert (  is_transparent<std::equal_to<void>>::value, "" ); +    static_assert (  is_transparent<std::equal_to<>>::value, "" ); + +    static_assert ( !is_transparent<std::not_equal_to<int>>::value, "" ); +    static_assert ( !is_transparent<std::not_equal_to<std::string>>::value, "" ); +    static_assert (  is_transparent<std::not_equal_to<void>>::value, "" ); +    static_assert (  is_transparent<std::not_equal_to<>>::value, "" ); + +    static_assert ( !is_transparent<std::greater<int>>::value, "" ); +    static_assert ( !is_transparent<std::greater<std::string>>::value, "" ); +    static_assert (  is_transparent<std::greater<void>>::value, "" ); +    static_assert (  is_transparent<std::greater<>>::value, "" ); + +    static_assert ( !is_transparent<std::greater_equal<int>>::value, "" ); +    static_assert ( !is_transparent<std::greater_equal<std::string>>::value, "" ); +    static_assert (  is_transparent<std::greater_equal<void>>::value, "" ); +    static_assert (  is_transparent<std::greater_equal<>>::value, "" ); + +#endif + +    return 0; +    } diff --git a/test/std/utilities/function.objects/func.def/nothing_to_do.pass.cpp b/test/std/utilities/function.objects/func.def/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/utilities/function.objects/func.def/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp new file mode 100644 index 000000000000..4b9cc76f7e4f --- /dev/null +++ b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp @@ -0,0 +1,268 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// <functional> + +// template <class F, class ...Args> +// result_of_t<F&&(Args&&...)> invoke(F&&, Args&&...); + +/// C++14 [func.def] 20.9.0 +/// (1) The following definitions apply to this Clause: +/// (2) A call signature is the name of a return type followed by a parenthesized +///     comma-separated list of zero or more argument types. +/// (3) A callable type is a function object type (20.9) or a pointer to member. +/// (4) A callable object is an object of a callable type. +/// (5) A call wrapper type is a type that holds a callable object and supports +///     a call operation that forwards to that object. +/// (6) A call wrapper is an object of a call wrapper type. +/// (7) A target object is the callable object held by a call wrapper. + +/// C++14 [func.require] 20.9.1 +/// +/// Define INVOKE (f, t1, t2, ..., tN) as follows: +///   (1.1) - (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of +///   type T or a reference to an object of type T or a reference to an object of a type derived from T; +///   (1.2) - ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of +///   the types described in the previous item; +///   (1.3) - t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a +///   reference to an object of type T or a reference to an object of a type derived from T; +///   (1.4) - (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types +///   described in the previous item; +///   (1.5) - f(t1, t2, ..., tN) in all other cases. + +#include <functional> +#include <type_traits> +#include <cassert> + +struct NonCopyable { +    NonCopyable() {} +private: +    NonCopyable(NonCopyable const&) = delete; +    NonCopyable& operator=(NonCopyable const&) = delete; +}; + +struct TestClass { +    explicit TestClass(int x) : data(x) {} + +    int& operator()(NonCopyable&&) & { return data; } +    int const& operator()(NonCopyable&&) const & { return data; } +    int volatile& operator()(NonCopyable&&) volatile & { return data; } +    int const volatile& operator()(NonCopyable&&) const volatile & { return data; } + +    int&& operator()(NonCopyable&&) && { return std::move(data); } +    int const&& operator()(NonCopyable&&) const && { return std::move(data); } +    int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); } +    int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); } + +    int data; +private: +    TestClass(TestClass const&) = delete; +    TestClass& operator=(TestClass const&) = delete; +}; + +struct DerivedFromTestClass : public TestClass { +    explicit DerivedFromTestClass(int x) : TestClass(x) {} +}; + +int& foo(NonCopyable&&) { +    static int data = 42; +    return data; +} + +template <class Signature,  class Expect, class Functor> +void test_b12(Functor&& f) { +    // Create the callable object. +    typedef Signature TestClass::*ClassFunc; +    ClassFunc func_ptr = &TestClass::operator(); + +    // Create the dummy arg. +    NonCopyable arg; + +    // Check that the deduced return type of invoke is what is expected. +    typedef decltype( +        std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg)) +    ) DeducedReturnType; +    static_assert((std::is_same<DeducedReturnType, Expect>::value), ""); + +    // Check that result_of_t matches Expect. +    typedef typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type +      ResultOfReturnType; +    static_assert((std::is_same<ResultOfReturnType, Expect>::value), ""); + +    // Run invoke and check the return value. +    DeducedReturnType ret = +            std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg)); +    assert(ret == 42); +} + +template <class Expect, class Functor> +void test_b34(Functor&& f) { +    // Create the callable object. +    typedef int TestClass::*ClassFunc; +    ClassFunc func_ptr = &TestClass::data; + +    // Check that the deduced return type of invoke is what is expected. +    typedef decltype( +        std::invoke(func_ptr, std::forward<Functor>(f)) +    ) DeducedReturnType; +    static_assert((std::is_same<DeducedReturnType, Expect>::value), ""); + +    // Check that result_of_t matches Expect. +    typedef typename std::result_of<ClassFunc&&(Functor&&)>::type +            ResultOfReturnType; +    static_assert((std::is_same<ResultOfReturnType, Expect>::value), ""); + +    // Run invoke and check the return value. +    DeducedReturnType ret = +            std::invoke(func_ptr, std::forward<Functor>(f)); +    assert(ret == 42); +} + +template <class Expect, class Functor> +void test_b5(Functor&& f) { +    NonCopyable arg; + +    // Check that the deduced return type of invoke is what is expected. +    typedef decltype( +        std::invoke(std::forward<Functor>(f), std::move(arg)) +    ) DeducedReturnType; +    static_assert((std::is_same<DeducedReturnType, Expect>::value), ""); + +    // Check that result_of_t matches Expect. +    typedef typename std::result_of<Functor&&(NonCopyable&&)>::type +            ResultOfReturnType; +    static_assert((std::is_same<ResultOfReturnType, Expect>::value), ""); + +    // Run invoke and check the return value. +    DeducedReturnType ret = std::invoke(std::forward<Functor>(f), std::move(arg)); +    assert(ret == 42); +} + +void bullet_one_two_tests() { +    { +        TestClass cl(42); +        test_b12<int&(NonCopyable&&) &, int&>(cl); +        test_b12<int const&(NonCopyable&&) const &, int const&>(cl); +        test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); +        test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); + +        test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl)); +        test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl)); +        test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl)); +        test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl)); +    } +    { +        DerivedFromTestClass cl(42); +        test_b12<int&(NonCopyable&&) &, int&>(cl); +        test_b12<int const&(NonCopyable&&) const &, int const&>(cl); +        test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); +        test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); + +        test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl)); +        test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl)); +        test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl)); +        test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl)); +    } +    { +        TestClass cl_obj(42); +        TestClass *cl = &cl_obj; +        test_b12<int&(NonCopyable&&) &, int&>(cl); +        test_b12<int const&(NonCopyable&&) const &, int const&>(cl); +        test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); +        test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); +    } +    { +        DerivedFromTestClass cl_obj(42); +        DerivedFromTestClass *cl = &cl_obj; +        test_b12<int&(NonCopyable&&) &, int&>(cl); +        test_b12<int const&(NonCopyable&&) const &, int const&>(cl); +        test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl); +        test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl); +    } +} + +void bullet_three_four_tests() { +    { +        typedef TestClass Fn; +        Fn cl(42); +        test_b34<int&>(cl); +        test_b34<int const&>(static_cast<Fn const&>(cl)); +        test_b34<int volatile&>(static_cast<Fn volatile&>(cl)); +        test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl)); + +        test_b34<int&&>(static_cast<Fn &&>(cl)); +        test_b34<int const&&>(static_cast<Fn const&&>(cl)); +        test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl)); +        test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl)); +    } +    { +        typedef DerivedFromTestClass Fn; +        Fn cl(42); +        test_b34<int&>(cl); +        test_b34<int const&>(static_cast<Fn const&>(cl)); +        test_b34<int volatile&>(static_cast<Fn volatile&>(cl)); +        test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl)); + +        test_b34<int&&>(static_cast<Fn &&>(cl)); +        test_b34<int const&&>(static_cast<Fn const&&>(cl)); +        test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl)); +        test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl)); +    } +    { +        typedef TestClass Fn; +        Fn cl_obj(42); +        Fn* cl = &cl_obj; +        test_b34<int&>(cl); +        test_b34<int const&>(static_cast<Fn const*>(cl)); +        test_b34<int volatile&>(static_cast<Fn volatile*>(cl)); +        test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl)); +    } +    { +        typedef DerivedFromTestClass Fn; +        Fn cl_obj(42); +        Fn* cl = &cl_obj; +        test_b34<int&>(cl); +        test_b34<int const&>(static_cast<Fn const*>(cl)); +        test_b34<int volatile&>(static_cast<Fn volatile*>(cl)); +        test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl)); +    } +} + +void bullet_five_tests() { +    using FooType = int&(NonCopyable&&); +    { +        FooType& fn = foo; +        test_b5<int &>(fn); +    } +    { +        FooType* fn = foo; +        test_b5<int &>(fn); +    } +    { +        typedef TestClass Fn; +        Fn cl(42); +        test_b5<int&>(cl); +        test_b5<int const&>(static_cast<Fn const&>(cl)); +        test_b5<int volatile&>(static_cast<Fn volatile&>(cl)); +        test_b5<int const volatile&>(static_cast<Fn const volatile &>(cl)); + +        test_b5<int&&>(static_cast<Fn &&>(cl)); +        test_b5<int const&&>(static_cast<Fn const&&>(cl)); +        test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl)); +        test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl)); +    } +} + +int main() { +    bullet_one_two_tests(); +    bullet_three_four_tests(); +    bullet_five_tests(); +} diff --git a/test/std/utilities/function.objects/func.memfn/member_data.fail.cpp b/test/std/utilities/function.objects/func.memfn/member_data.fail.cpp new file mode 100644 index 000000000000..5e748c93b9e4 --- /dev/null +++ b/test/std/utilities/function.objects/func.memfn/member_data.fail.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +//                     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<Returnable R, class T> unspecified mem_fn(R T::* pm); + +#include <functional> +#include <cassert> + +struct A +{ +    double data_; +}; + +template <class F> +void +test(F f) +{ +    { +    A a; +    f(a) = 5; +    assert(a.data_ == 5); +    A* ap = &a; +    f(ap) = 6; +    assert(a.data_ == 6); +    const A* cap = ap; +    assert(f(cap) == f(ap)); +    f(cap) = 7; +    } +} + +int main() +{ +    test(std::mem_fn(&A::data_)); +} diff --git a/test/std/utilities/function.objects/func.memfn/member_data.pass.cpp b/test/std/utilities/function.objects/func.memfn/member_data.pass.cpp new file mode 100644 index 000000000000..dff211c60573 --- /dev/null +++ b/test/std/utilities/function.objects/func.memfn/member_data.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +//                     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<Returnable R, class T> unspecified mem_fn(R T::* pm); + +#include <functional> +#include <cassert> + +struct A +{ +    double data_; +}; + +template <class F> +void +test(F f) +{ +    { +    A a; +    f(a) = 5; +    assert(a.data_ == 5); +    A* ap = &a; +    f(ap) = 6; +    assert(a.data_ == 6); +    const A* cap = ap; +    assert(f(cap) == f(ap)); +    const F& cf = f; +    assert(cf(ap) == f(ap)); +    } +} + +int main() +{ +    test(std::mem_fn(&A::data_)); +} diff --git a/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp b/test/std/utilities/function.objects/func.memfn/member_function.pass.cpp new file mode 100644 index 000000000000..4096bd814421 --- /dev/null +++ b/test/std/utilities/function.objects/func.memfn/member_function.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<Returnable R, class T, CopyConstructible... Args> +//   unspecified mem_fn(R (T::* pm)(Args...)); + +#include <functional> +#include <cassert> + +struct A +{ +    char test0() {return 'a';} +    char test1(int) {return 'b';} +    char test2(int, double) {return 'c';} +}; + +template <class F> +void +test0(F f) +{ +    { +    A a; +    assert(f(a) == 'a'); +    A* ap = &a; +    assert(f(ap) == 'a'); +    const F& cf = f; +    assert(cf(ap) == 'a'); +    } +} + +template <class F> +void +test1(F f) +{ +    { +    A a; +    assert(f(a, 1) == 'b'); +    A* ap = &a; +    assert(f(ap, 2) == 'b'); +    const F& cf = f; +    assert(cf(ap, 2) == 'b'); +    } +} + +template <class F> +void +test2(F f) +{ +    { +    A a; +    assert(f(a, 1, 2) == 'c'); +    A* ap = &a; +    assert(f(ap, 2, 3.5) == 'c'); +    const F& cf = f; +    assert(cf(ap, 2, 3.5) == 'c'); +    } +} + +int main() +{ +    test0(std::mem_fn(&A::test0)); +    test1(std::mem_fn(&A::test1)); +    test2(std::mem_fn(&A::test2)); +} diff --git a/test/std/utilities/function.objects/func.memfn/member_function_const.pass.cpp b/test/std/utilities/function.objects/func.memfn/member_function_const.pass.cpp new file mode 100644 index 000000000000..be22443e9542 --- /dev/null +++ b/test/std/utilities/function.objects/func.memfn/member_function_const.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +//                     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<Returnable R, class T, CopyConstructible... Args> +//   unspecified mem_fn(R (T::* pm)(Args...) const); + +#include <functional> +#include <cassert> + +struct A +{ +    char test0() const {return 'a';} +    char test1(int) const {return 'b';} +    char test2(int, double) const {return 'c';} +}; + +template <class F> +void +test0(F f) +{ +    { +    A a; +    assert(f(a) == 'a'); +    A* ap = &a; +    assert(f(ap) == 'a'); +    const A* cap = &a; +    assert(f(cap) == 'a'); +    const F& cf = f; +    assert(cf(ap) == 'a'); +    } +} + +template <class F> +void +test1(F f) +{ +    { +    A a; +    assert(f(a, 1) == 'b'); +    A* ap = &a; +    assert(f(ap, 2) == 'b'); +    const A* cap = &a; +    assert(f(cap, 2) == 'b'); +    const F& cf = f; +    assert(cf(ap, 2) == 'b'); +    } +} + +template <class F> +void +test2(F f) +{ +    { +    A a; +    assert(f(a, 1, 2) == 'c'); +    A* ap = &a; +    assert(f(ap, 2, 3.5) == 'c'); +    const A* cap = &a; +    assert(f(cap, 2, 3.5) == 'c'); +    const F& cf = f; +    assert(cf(ap, 2, 3.5) == 'c'); +    } +} + +int main() +{ +    test0(std::mem_fn(&A::test0)); +    test1(std::mem_fn(&A::test1)); +    test2(std::mem_fn(&A::test2)); +} diff --git a/test/std/utilities/function.objects/func.memfn/member_function_const_volatile.pass.cpp b/test/std/utilities/function.objects/func.memfn/member_function_const_volatile.pass.cpp new file mode 100644 index 000000000000..329ac16a86db --- /dev/null +++ b/test/std/utilities/function.objects/func.memfn/member_function_const_volatile.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +//                     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<Returnable R, class T, CopyConstructible... Args> +//   unspecified mem_fn(R (T::* pm)(Args...) const volatile); + +#include <functional> +#include <cassert> + +struct A +{ +    char test0() const volatile {return 'a';} +    char test1(int) const volatile {return 'b';} +    char test2(int, double) const volatile {return 'c';} +}; + +template <class F> +void +test0(F f) +{ +    { +    A a; +    assert(f(a) == 'a'); +    A* ap = &a; +    assert(f(ap) == 'a'); +    const volatile A* cap = &a; +    assert(f(cap) == 'a'); +    const F& cf = f; +    assert(cf(ap) == 'a'); +    } +} + +template <class F> +void +test1(F f) +{ +    { +    A a; +    assert(f(a, 1) == 'b'); +    A* ap = &a; +    assert(f(ap, 2) == 'b'); +    const volatile A* cap = &a; +    assert(f(cap, 2) == 'b'); +    const F& cf = f; +    assert(cf(ap, 2) == 'b'); +    } +} + +template <class F> +void +test2(F f) +{ +    { +    A a; +    assert(f(a, 1, 2) == 'c'); +    A* ap = &a; +    assert(f(ap, 2, 3.5) == 'c'); +    const volatile A* cap = &a; +    assert(f(cap, 2, 3.5) == 'c'); +    const F& cf = f; +    assert(cf(ap, 2, 3.5) == 'c'); +    } +} + +int main() +{ +    test0(std::mem_fn(&A::test0)); +    test1(std::mem_fn(&A::test1)); +    test2(std::mem_fn(&A::test2)); +} diff --git a/test/std/utilities/function.objects/func.memfn/member_function_volatile.pass.cpp b/test/std/utilities/function.objects/func.memfn/member_function_volatile.pass.cpp new file mode 100644 index 000000000000..743ded9944aa --- /dev/null +++ b/test/std/utilities/function.objects/func.memfn/member_function_volatile.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +//                     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<Returnable R, class T, CopyConstructible... Args> +//   unspecified mem_fn(R (T::* pm)(Args...) volatile); + +#include <functional> +#include <cassert> + +struct A +{ +    char test0() volatile {return 'a';} +    char test1(int) volatile {return 'b';} +    char test2(int, double) volatile {return 'c';} +}; + +template <class F> +void +test0(F f) +{ +    { +    A a; +    assert(f(a) == 'a'); +    A* ap = &a; +    assert(f(ap) == 'a'); +    volatile A* cap = &a; +    assert(f(cap) == 'a'); +    const F& cf = f; +    assert(cf(ap) == 'a'); +    } +} + +template <class F> +void +test1(F f) +{ +    { +    A a; +    assert(f(a, 1) == 'b'); +    A* ap = &a; +    assert(f(ap, 2) == 'b'); +    volatile A* cap = &a; +    assert(f(cap, 2) == 'b'); +    const F& cf = f; +    assert(cf(ap, 2) == 'b'); +    } +} + +template <class F> +void +test2(F f) +{ +    { +    A a; +    assert(f(a, 1, 2) == 'c'); +    A* ap = &a; +    assert(f(ap, 2, 3.5) == 'c'); +    volatile A* cap = &a; +    assert(f(cap, 2, 3.5) == 'c'); +    const F& cf = f; +    assert(cf(ap, 2, 3.5) == 'c'); +    } +} + +int main() +{ +    test0(std::mem_fn(&A::test0)); +    test1(std::mem_fn(&A::test1)); +    test2(std::mem_fn(&A::test2)); +} diff --git a/test/std/utilities/function.objects/func.require/binary_function.pass.cpp b/test/std/utilities/function.objects/func.require/binary_function.pass.cpp new file mode 100644 index 000000000000..fa7afb2e7b9c --- /dev/null +++ b/test/std/utilities/function.objects/func.require/binary_function.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// binary_function + +#include <functional> +#include <type_traits> + +int main() +{ +    typedef std::binary_function<int, short, bool> bf; +    static_assert((std::is_same<bf::first_argument_type, int>::value), ""); +    static_assert((std::is_same<bf::second_argument_type, short>::value), ""); +    static_assert((std::is_same<bf::result_type, bool>::value), ""); +} diff --git a/test/std/utilities/function.objects/func.require/invoke.pass.cpp b/test/std/utilities/function.objects/func.require/invoke.pass.cpp new file mode 100644 index 000000000000..25681630a80c --- /dev/null +++ b/test/std/utilities/function.objects/func.require/invoke.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +// [func.require] + +// INVOKE +#if __cplusplus < 201103L +int main () {}      // no __invoke in C++03 +#else + +#include <type_traits> + +template <typename T, int N> +struct Array +{ +    typedef T type[N]; +}; + +struct Type +{ +    Array<char, 1>::type& f1(); +    Array<char, 2>::type& f2() const; +     +    Array<char, 1>::type& g1()        &; +    Array<char, 2>::type& g2() const  &; +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +    Array<char, 3>::type& g3()       &&; +    Array<char, 4>::type& g4() const &&; +#endif +}; + +int main() +{ +    static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type        >())) == 1, ""); +    static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const  >())) == 2, ""); +     +    static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type       &>())) == 1, ""); +    static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, ""); +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +    static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type      &&>())) == 3, ""); +    static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, ""); +#endif +} +#endif diff --git a/test/std/utilities/function.objects/func.require/unary_function.pass.cpp b/test/std/utilities/function.objects/func.require/unary_function.pass.cpp new file mode 100644 index 000000000000..f14b2d3a2ce5 --- /dev/null +++ b/test/std/utilities/function.objects/func.require/unary_function.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// unary_function + +#include <functional> +#include <type_traits> + +int main() +{ +    typedef std::unary_function<int, bool> uf; +    static_assert((std::is_same<uf::argument_type, int>::value), ""); +    static_assert((std::is_same<uf::result_type, bool>::value), ""); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.badcall/bad_function_call.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.badcall/bad_function_call.pass.cpp new file mode 100644 index 000000000000..357a3b48eae2 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.badcall/bad_function_call.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +// Class bad_function_call + +// class bad_function_call +//     : public exception +// { +// public: +//   // 20.7.16.1.1, constructor: +//   bad_function_call(); +// }; + +#include <functional> +#include <type_traits> + +int main() +{ +    static_assert((std::is_base_of<std::exception, std::bad_function_call>::value), ""); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.badcall/func.wrap.badcall.const/bad_function_call_ctor.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.badcall/func.wrap.badcall.const/bad_function_call_ctor.pass.cpp new file mode 100644 index 000000000000..f5ab9487532f --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.badcall/func.wrap.badcall.const/bad_function_call_ctor.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +// Class bad_function_call + +// bad_function_call(); + +#include <functional> +#include <type_traits> + +int main() +{ +    std::bad_function_call ex; +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp new file mode 100644 index 000000000000..58192c928d58 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp @@ -0,0 +1,123 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template <MoveConstructible  R, MoveConstructible ... ArgTypes> +//   void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&); + + +#include <functional> +#include <cstdlib> +#include <cassert> + +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    explicit A(int j) +    { +        ++count; +        data_[0] = j; +    } + +    A(const A& a) +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = a.data_[i]; +    } + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } + +    int id() const {return data_[0];} +}; + +int A::count = 0; + +int g(int) {return 0;} +int h(int) {return 1;} + +int main() +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = A(1); +    std::function<int(int)> f2 = A(2); +    assert(A::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(2)); +    assert(f1.target<A>()->id() == 1); +    assert(f2.target<A>()->id() == 2); +    swap(f1, f2); +    assert(A::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(2)); +    assert(f1.target<A>()->id() == 2); +    assert(f2.target<A>()->id() == 1); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = A(1); +    std::function<int(int)> f2 = g; +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f1.target<A>()->id() == 1); +    assert(*f2.target<int(*)(int)>() == g); +    swap(f1, f2); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(*f1.target<int(*)(int)>() == g); +    assert(f2.target<A>()->id() == 1); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = g; +    std::function<int(int)> f2 = A(1); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(*f1.target<int(*)(int)>() == g); +    assert(f2.target<A>()->id() == 1); +    swap(f1, f2); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f1.target<A>()->id() == 1); +    assert(*f2.target<int(*)(int)>() == g); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = g; +    std::function<int(int)> f2 = h; +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(*f1.target<int(*)(int)>() == g); +    assert(*f2.target<int(*)(int)>() == h); +    swap(f1, f2); +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(*f1.target<int(*)(int)>() == h); +    assert(*f2.target<int(*)(int)>() == g); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.cap/operator_bool.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.cap/operator_bool.pass.cpp new file mode 100644 index 000000000000..829763f79d82 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.cap/operator_bool.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// explicit operator bool() const + +#include <functional> +#include <cassert> + +int g(int) {return 0;} + +int main() +{ +    { +    std::function<int(int)> f; +    assert(!f); +    f = g; +    assert(f); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp new file mode 100644 index 000000000000..cd86e4cbf8eb --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// function(nullptr_t); + +#include <functional> +#include <cassert> + +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } + +    int foo(int) const {return 1;} +}; + +int A::count = 0; + +int g(int) {return 0;} + +int main() +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = g; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>()); +    assert(f.target<A>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = (int (*)(int))0; +    assert(!f); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    } +    { +    std::function<int(const A*, int)> f = &A::foo; +    assert(f); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int (A::*)(int) const>() != 0); +    } +    { +      std::function<void(int)> f(&g); +      assert(f); +      assert(f.target<int(*)(int)>() != 0); +      f(1); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp new file mode 100644 index 000000000000..11716e7946b0 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class F> +//   requires CopyConstructible<F> && Callable<F, ArgTypes..> +//         && Convertible<Callable<F, ArgTypes...>::result_type +//   operator=(F f); + +#include <functional> +#include <cassert> + +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } + +    int foo(int) const {return 1;} +}; + +int A::count = 0; + +int g(int) {return 0;} + +int main() +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f; +    f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f; +    f = g; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>()); +    assert(f.target<A>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f; +    f = (int (*)(int))0; +    assert(!f); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    } +    { +    std::function<int(const A*, int)> f; +    f = &A::foo; +    assert(f); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int (A::*)(int) const>() != 0); +    } +    { +    std::function<void(int)> f; +    f = &g; +    assert(f); +    assert(f.target<int(*)(int)>() != 0); +    f(1); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp new file mode 100644 index 000000000000..c8f4178a26bd --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class F> function(F); + +// Allow incomplete argument types in the __is_callable check + +#include <functional> + +struct X{ +    typedef std::function<void(X&)> callback_type; +    virtual ~X() {} +private: +    callback_type _cb; +}; + +int main() +{ +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp new file mode 100644 index 000000000000..f97e34d3f2cb --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class A> function(allocator_arg_t, const A&); + +#include <functional> +#include <cassert> + +#include "min_allocator.h" + +int main() +{ +    { +    std::function<int(int)> f(std::allocator_arg, bare_allocator<int>()); +    assert(!f); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp new file mode 100644 index 000000000000..352ecfc602be --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class F, class A> function(allocator_arg_t, const A&, F); + +#include <functional> +#include <cassert> + +#include "min_allocator.h" +#include "test_allocator.h" +#include "count_new.hpp" +#include "../function_types.h" + +class DummyClass {}; + +template <class FuncType, class AllocType> +void test_FunctionObject(AllocType& alloc) +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    FunctionObject target; +    assert(FunctionObject::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    std::function<FuncType> f2(std::allocator_arg, alloc, target); +    assert(FunctionObject::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f2.template target<FunctionObject>()); +    assert(f2.template target<FuncType>() == 0); +    assert(f2.template target<FuncType*>() == 0); +    } +    assert(FunctionObject::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} + + +template <class FuncType, class AllocType> +void test_FreeFunction(AllocType& alloc) +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    FuncType* target = &FreeFunction; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    std::function<FuncType> f2(std::allocator_arg, alloc, target); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.template target<FuncType*>()); +    assert(*f2.template target<FuncType*>() == target); +    assert(f2.template target<FuncType>() == 0); +    assert(f2.template target<DummyClass>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} + +template <class TargetType, class FuncType, class AllocType> +void test_MemFunClass(AllocType& alloc) +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    TargetType target = &MemFunClass::foo; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    std::function<FuncType> f2(std::allocator_arg, alloc, target); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.template target<TargetType>()); +    assert(*f2.template target<TargetType>() == target); +    assert(f2.template target<FuncType*>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} + +template <class Alloc> +void test_for_alloc(Alloc& alloc) { +    test_FunctionObject<int()>(alloc); +    test_FunctionObject<int(int)>(alloc); +    test_FunctionObject<int(int, int)>(alloc); +    test_FunctionObject<int(int, int, int)>(alloc); + +    test_FreeFunction<int()>(alloc); +    test_FreeFunction<int(int)>(alloc); +    test_FreeFunction<int(int, int)>(alloc); +    test_FreeFunction<int(int, int, int)>(alloc); + +    test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc); +    test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc); +    test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc); +} + +int main() +{ +    { +        bare_allocator<DummyClass> bare_alloc; +        test_for_alloc(bare_alloc); +    } +    { +        non_default_test_allocator<DummyClass> non_default_alloc(42); +        test_for_alloc(non_default_alloc); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp new file mode 100644 index 000000000000..371eb98de1a9 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class A> function(allocator_arg_t, const A&, const function&); + + +#include <functional> +#include <cassert> + +#include "min_allocator.h" +#include "test_allocator.h" +#include "count_new.hpp" +#include "../function_types.h" + +class DummyClass {}; + +template <class FuncType, class AllocType> +void test_FunctionObject(AllocType& alloc) +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    // Construct function from FunctionObject. +    std::function<FuncType> f = FunctionObject(); +    assert(FunctionObject::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.template target<FunctionObject>()); +    assert(f.template target<FuncType>() == 0); +    assert(f.template target<FuncType*>() == 0); +    // Copy function with allocator +    std::function<FuncType> f2(std::allocator_arg, alloc, f); +    assert(FunctionObject::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(2)); +    assert(f2.template target<FunctionObject>()); +    assert(f2.template target<FuncType>() == 0); +    assert(f2.template target<FuncType*>() == 0); +    } +    assert(FunctionObject::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} + +template <class FuncType, class AllocType> +void test_FreeFunction(AllocType& alloc) +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    // Construct function from function pointer. +    FuncType* target = &FreeFunction; +    std::function<FuncType> f = target; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.template target<FuncType*>()); +    assert(*f.template target<FuncType*>() == target); +    assert(f.template target<FuncType>() == 0); +    // Copy function with allocator +    std::function<FuncType> f2(std::allocator_arg, alloc, f); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.template target<FuncType*>()); +    assert(*f2.template target<FuncType*>() == target); +    assert(f2.template target<FuncType>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} + +template <class TargetType, class FuncType, class AllocType> +void test_MemFunClass(AllocType& alloc) +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    // Construct function from function pointer. +    TargetType target = &MemFunClass::foo; +    std::function<FuncType> f = target; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.template target<TargetType>()); +    assert(*f.template target<TargetType>() == target); +    assert(f.template target<FuncType*>() == 0); +    // Copy function with allocator +    std::function<FuncType> f2(std::allocator_arg, alloc, f); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.template target<TargetType>()); +    assert(*f2.template target<TargetType>() == target); +    assert(f2.template target<FuncType*>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} + +template <class Alloc> +void test_for_alloc(Alloc& alloc) +{ +    // Large FunctionObject -- Allocation should occur +    test_FunctionObject<int()>(alloc); +    test_FunctionObject<int(int)>(alloc); +    test_FunctionObject<int(int, int)>(alloc); +    test_FunctionObject<int(int, int, int)>(alloc); +    // Free function -- No allocation should occur +    test_FreeFunction<int()>(alloc); +    test_FreeFunction<int(int)>(alloc); +    test_FreeFunction<int(int, int)>(alloc); +    test_FreeFunction<int(int, int, int)>(alloc); +    // Member function -- No allocation should occur. +    test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc); +    test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc); +    test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc); +} + +int main() +{ +  { +    bare_allocator<DummyClass> alloc; +    test_for_alloc(alloc); +  } +  { +    non_default_test_allocator<DummyClass> alloc(42); +    test_for_alloc(alloc); +  } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp new file mode 100644 index 000000000000..2350f92f0f89 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class A> function(allocator_arg_t, const A&, nullptr_t); + +#include <functional> +#include <cassert> + +#include "min_allocator.h" + +int main() +{ +    std::function<int(int)> f(std::allocator_arg, bare_allocator<int>(), nullptr); +    assert(!f); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp new file mode 100644 index 000000000000..aa6b743b5236 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class A> function(allocator_arg_t, const A&, function&&); + +#include <functional> +#include <cassert> + +#include "min_allocator.h" +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } +}; + +int A::count = 0; + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), std::move(f)); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f2.target<A>()); +    assert(f2.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    assert(f.target<int(*)(int)>() == 0); +    } +#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp new file mode 100644 index 000000000000..f603da9dd131 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// function(const function& f); + +#include <functional> +#include <cstdlib> +#include <cassert> + +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } +}; + +int A::count = 0; + +int g(int) {return 0;} + +int main() +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    std::function<int(int)> f2 = f; +    assert(A::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(2)); +    assert(f2.target<A>()); +    assert(f2.target<int(*)(int)>() == 0); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = g; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>()); +    assert(f.target<A>() == 0); +    std::function<int(int)> f2 = f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.target<int(*)(int)>()); +    assert(f2.target<A>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    std::function<int(int)> f2 = f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.target<int(*)(int)>() == 0); +    assert(f2.target<A>() == 0); +    } +    { +    std::function<int(int)> f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    assert(!f); +    std::function<long(int)> g = f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(g.target<long(*)(int)>() == 0); +    assert(g.target<A>() == 0); +    assert(!g); +    } +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    std::function<int(int)> f2 = std::move(f); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f2.target<A>()); +    assert(f2.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    assert(f.target<int(*)(int)>() == 0); +    } +#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp new file mode 100644 index 000000000000..c91eaa2d5674 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// function& operator=(const function& f); + +#include <functional> +#include <cassert> + +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } +}; + +int A::count = 0; + +int g(int) {return 0;} + +int main() +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    std::function<int(int)> f2; +    f2 = f; +    assert(A::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(2)); +    assert(f2.target<A>()); +    assert(f2.target<int(*)(int)>() == 0); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = g; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>()); +    assert(f.target<A>() == 0); +    std::function<int(int)> f2; +    f2 = f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.target<int(*)(int)>()); +    assert(f2.target<A>() == 0); +    } +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    std::function<int(int)> f2; +    f2 = f; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f2.target<int(*)(int)>() == 0); +    assert(f2.target<A>() == 0); +    } +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    std::function<int(int)> f2; +    f2 = std::move(f); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f2.target<A>()); +    assert(f2.target<int(*)(int)>() == 0); +    assert(f.target<A>() == 0); +    assert(f.target<int(*)(int)>() == 0); +    } +#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/default.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/default.pass.cpp new file mode 100644 index 000000000000..83d61b6b2d89 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/default.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// explicit function(); + +#include <functional> +#include <cassert> + +int main() +{ +    std::function<int(int)> f; +    assert(!f); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp new file mode 100644 index 000000000000..7099c45fab81 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R()> + +// template<class F> function(F); + +#define _LIBCPP_HAS_NO_VARIADICS +#include <functional> +#include <cassert> + +int main() +{ +    std::function<void()> f(static_cast<void(*)()>(0)); +    assert(!f); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t.pass.cpp new file mode 100644 index 000000000000..f0d6402d185e --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// function(nullptr_t); + +#include <functional> +#include <cassert> + +int main() +{ +    std::function<int(int)> f(nullptr); +    assert(!f); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp new file mode 100644 index 000000000000..9b2482fb9d54 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.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> + +// class function<R(ArgTypes...)> + +// function& operator=(nullptr_t); + +#include <functional> +#include <cassert> + +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } +}; + +int A::count = 0; + +int g(int) {return 0;} + +int main() +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f.target<A>()); +    f = nullptr; +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<A>() == 0); +    } +    { +    std::function<int(int)> f = g; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>()); +    assert(f.target<A>() == 0); +    f = nullptr; +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(f.target<int(*)(int)>() == 0); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.fail.cpp new file mode 100644 index 000000000000..6dcd2857452c --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.fail.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// R operator()(ArgTypes... args) const + +#include <functional> +#include <cassert> + +// member data pointer:  cv qualifiers should transfer from argument to return type + +struct A_int_1 +{ +    A_int_1() : data_(5) {} + +    int data_; +}; + +void +test_int_1() +{ +    // member data pointer +    { +    int A_int_1::*fp = &A_int_1::data_; +    A_int_1 a; +    std::function<int& (const A_int_1*)> r2(fp); +    const A_int_1* ap = &a; +    assert(r2(ap) == 6); +    r2(ap) = 7; +    assert(r2(ap) == 7); +    } +} + +int main() +{ +    test_int_1(); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp new file mode 100644 index 000000000000..31b80c3323c1 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp @@ -0,0 +1,335 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// R operator()(ArgTypes... args) const + +#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;} +}; + +void +test_void_1() +{ +    int save_count = count; +    // function +    { +    std::function<void (int)> r1(f_void_1); +    int i = 2; +    r1(i); +    assert(count == save_count+2); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)(int) = f_void_1; +    std::function<void (int)> r1(fp); +    int i = 3; +    r1(i); +    assert(count == save_count+3); +    save_count = count; +    } +    // functor +    { +    A_void_1 a0; +    std::function<void (int)> r1(a0); +    int i = 4; +    r1(i); +    assert(count == save_count+4); +    save_count = count; +    } +    // member function pointer +    { +    void (A_void_1::*fp)() = &A_void_1::mem1; +    std::function<void (A_void_1)> r1(fp); +    A_void_1 a; +    r1(a); +    assert(count == save_count+1); +    save_count = count; +    A_void_1* ap = &a; +    std::function<void (A_void_1*)> r2 = fp; +    r2(ap); +    assert(count == save_count+1); +    save_count = count; +    } +    // const member function pointer +    { +    void (A_void_1::*fp)() const = &A_void_1::mem2; +    std::function<void (A_void_1)> r1(fp); +    A_void_1 a; +    r1(a); +    assert(count == save_count+1); +    save_count = count; +    std::function<void (A_void_1*)> r2(fp); +    A_void_1* ap = &a; +    r2(ap); +    assert(count == save_count+1); +    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() +{ +    // function +    { +    std::function<int (int)> r1(f_int_1); +    int i = 2; +    assert(r1(i) == 3); +    } +    // function pointer +    { +    int (*fp)(int) = f_int_1; +    std::function<int (int)> r1(fp); +    int i = 3; +    assert(r1(i) == 4); +    } +    // functor +    { +    A_int_1 a0; +    std::function<int (int)> r1(a0); +    int i = 4; +    assert(r1(i) == 3); +    } +    // member function pointer +    { +    int (A_int_1::*fp)() = &A_int_1::mem1; +    std::function<int (A_int_1)> r1(fp); +    A_int_1 a; +    assert(r1(a) == 3); +    std::function<int (A_int_1*)> r2(fp); +    A_int_1* ap = &a; +    assert(r2(ap) == 3); +    } +    // const member function pointer +    { +    int (A_int_1::*fp)() const = &A_int_1::mem2; +    std::function<int (A_int_1)> r1(fp); +    A_int_1 a; +    assert(r1(a) == 4); +    std::function<int (A_int_1*)> r2(fp); +    A_int_1* ap = &a; +    assert(r2(ap) == 4); +    } +    // member data pointer +    { +    int A_int_1::*fp = &A_int_1::data_; +    std::function<int& (A_int_1&)> r1(fp); +    A_int_1 a; +    assert(r1(a) == 5); +    r1(a) = 6; +    assert(r1(a) == 6); +    std::function<int& (A_int_1*)> r2(fp); +    A_int_1* ap = &a; +    assert(r2(ap) == 6); +    r2(ap) = 7; +    assert(r2(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() +{ +    int save_count = count; +    // function +    { +    std::function<void (int, int)> r1(f_void_2); +    int i = 2; +    int j = 3; +    r1(i, j); +    assert(count == save_count+5); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)(int, int) = f_void_2; +    std::function<void (int, int)> r1(fp); +    int i = 3; +    int j = 4; +    r1(i, j); +    assert(count == save_count+7); +    save_count = count; +    } +    // functor +    { +    A_void_2 a0; +    std::function<void (int, int)> r1(a0); +    int i = 4; +    int j = 5; +    r1(i, j); +    assert(count == save_count+9); +    save_count = count; +    } +    // member function pointer +    { +    void (A_void_2::*fp)(int) = &A_void_2::mem1; +    std::function<void (A_void_2, int)> r1(fp); +    A_void_2 a; +    int i = 3; +    r1(a, i); +    assert(count == save_count+3); +    save_count = count; +    std::function<void (A_void_2*, int)> r2(fp); +    A_void_2* ap = &a; +    r2(ap, i); +    assert(count == save_count+3); +    save_count = count; +    } +    // const member function pointer +    { +    void (A_void_2::*fp)(int) const = &A_void_2::mem2; +    std::function<void (A_void_2, int)> r1(fp); +    A_void_2 a; +    int i = 4; +    r1(a, i); +    assert(count == save_count+4); +    save_count = count; +    std::function<void (A_void_2*, int)> r2(fp); +    A_void_2* ap = &a; +    r2(ap, i); +    assert(count == save_count+4); +    save_count = count; +    } +} + +// 2 arg, return int + +int f_int_2(int i, int j) +{ +    return i+j; +} + +struct A_int_2 +{ +    int operator()(int i, int j) +    { +        return i+j; +    } + +    int mem1(int i) {return i+1;} +    int mem2(int i) const {return i+2;} +}; + +void +testint_2() +{ +    // function +    { +    std::function<int (int, int)> r1(f_int_2); +    int i = 2; +    int j = 3; +    assert(r1(i, j) == i+j); +    } +    // function pointer +    { +    int (*fp)(int, int) = f_int_2; +    std::function<int (int, int)> r1(fp); +    int i = 3; +    int j = 4; +    assert(r1(i, j) == i+j); +    } +    // functor +    { +    A_int_2 a0; +    std::function<int (int, int)> r1(a0); +    int i = 4; +    int j = 5; +    assert(r1(i, j) == i+j); +    } +    // member function pointer +    { +    int(A_int_2::*fp)(int) = &A_int_2::mem1; +    std::function<int (A_int_2, int)> r1(fp); +    A_int_2 a; +    int i = 3; +    assert(r1(a, i) == i+1); +    std::function<int (A_int_2*, int)> r2(fp); +    A_int_2* ap = &a; +    assert(r2(ap, i) == i+1); +    } +    // const member function pointer +    { +    int (A_int_2::*fp)(int) const = &A_int_2::mem2; +    std::function<int (A_int_2, int)> r1(fp); +    A_int_2 a; +    int i = 4; +    assert(r1(a, i) == i+2); +    std::function<int (A_int_2*, int)> r2(fp); +    A_int_2* ap = &a; +    assert(r2(ap, i) == i+2); +    } +} + +int main() +{ +    test_void_1(); +    test_int_1(); +    test_void_2(); +    testint_2(); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_int_0.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_int_0.pass.cpp new file mode 100644 index 000000000000..67b4ec22da8c --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_int_0.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// R operator()(ArgTypes... args) const + +#include <functional> +#include <cassert> + +// 0 args, return int + +int count = 0; + +int f_int_0() +{ +    return 3; +} + +struct A_int_0 +{ +    int operator()() {return 4;} +}; + +void +test_int_0() +{ +    // function +    { +    std::function<int ()> r1(f_int_0); +    assert(r1() == 3); +    } +    // function pointer +    { +    int (*fp)() = f_int_0; +    std::function<int ()> r1(fp); +    assert(r1() == 3); +    } +    // functor +    { +    A_int_0 a0; +    std::function<int ()> r1(a0); +    assert(r1() == 4); +    } +} + +int main() +{ +    test_int_0(); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_no_variadics.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_no_variadics.pass.cpp new file mode 100644 index 000000000000..c0a14fd96fcb --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_no_variadics.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R()> + +// Test that we properly return both values and void for all non-variadic +// overloads of function::operator()(...) + +#define _LIBCPP_HAS_NO_VARIADICS +#include <functional> +#include <cassert> + +int foo0() { return 42; } +int foo1(int) { return 42; } +int foo2(int, int) { return 42; } +int foo3(int, int, int) { return 42; } + +int main() +{ +    { +        std::function<int()> f(&foo0); +        assert(f() == 42); +    } +    { +        std::function<int(int)> f(&foo1); +        assert(f(1) == 42); +    } +    { +        std::function<int(int, int)> f(&foo2); +        assert(f(1, 1) == 42); +    } +    { +        std::function<int(int, int, int)> f(&foo3); +        assert(f(1, 1, 1) == 42); +    } +    { +        std::function<void()> f(&foo0); +        f(); +    } +    { +        std::function<void(int)> f(&foo1); +        f(1); +    } +    { +        std::function<void(int, int)> f(&foo2); +        f(1, 1); +    } +    { +        std::function<void(int, int, int)> f(&foo3); +        f(1, 1, 1); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_void_0.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_void_0.pass.cpp new file mode 100644 index 000000000000..a820cb1b8f38 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_void_0.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// R operator()(ArgTypes... args) const + +#include <functional> +#include <new> +#include <cstdlib> +#include <cassert> + +// 0 args, return void + +int count = 0; + +void f_void_0() +{ +    ++count; +} + +struct A_void_0 +{ +    void operator()() {++count;} +}; + +void +test_void_0() +{ +    int save_count = count; +    // function +    { +    std::function<void ()> r1(f_void_0); +    r1(); +    assert(count == save_count+1); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)() = f_void_0; +    std::function<void ()> r1(fp); +    r1(); +    assert(count == save_count+1); +    save_count = count; +    } +    // functor +    { +    A_void_0 a0; +    std::function<void ()> r1(a0); +    r1(); +    assert(count == save_count+1); +    save_count = count; +    } +} + +int main() +{ +    test_void_0(); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp new file mode 100644 index 000000000000..e9ecfa5539ce --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<class F, class A> void assign(F&&, const A&); + +#include <functional> +#include <cassert> + +#include "test_allocator.h" + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } + +    int foo(int) const {return 1;} +}; + +int A::count = 0; + +int main() +{ +    { +    std::function<int(int)> f; +    f.assign(A(), test_allocator<A>()); +    assert(A::count == 1); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    } +    assert(A::count == 0); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp new file mode 100644 index 000000000000..f94e689b2a6b --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// void swap(function& other); + +#include <functional> +#include <cassert> + +#include "count_new.hpp" + +class A +{ +    int data_[10]; +public: +    static int count; + +    explicit A(int j) +    { +        ++count; +        data_[0] = j; +    } + +    A(const A& a) +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = a.data_[i]; +    } + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } + +    int id() const {return data_[0];} +}; + +int A::count = 0; + +int g(int) {return 0;} +int h(int) {return 1;} + +int main() +{ +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = A(1); +    std::function<int(int)> f2 = A(2); +    assert(A::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(2)); +    assert(f1.target<A>()->id() == 1); +    assert(f2.target<A>()->id() == 2); +    f1.swap(f2); +    assert(A::count == 2); +    assert(globalMemCounter.checkOutstandingNewEq(2)); +    assert(f1.target<A>()->id() == 2); +    assert(f2.target<A>()->id() == 1); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = A(1); +    std::function<int(int)> f2 = g; +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f1.target<A>()->id() == 1); +    assert(*f2.target<int(*)(int)>() == g); +    f1.swap(f2); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(*f1.target<int(*)(int)>() == g); +    assert(f2.target<A>()->id() == 1); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = g; +    std::function<int(int)> f2 = A(1); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(*f1.target<int(*)(int)>() == g); +    assert(f2.target<A>()->id() == 1); +    f1.swap(f2); +    assert(A::count == 1); +    assert(globalMemCounter.checkOutstandingNewEq(1)); +    assert(f1.target<A>()->id() == 1); +    assert(*f2.target<int(*)(int)>() == g); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    { +    std::function<int(int)> f1 = g; +    std::function<int(int)> f2 = h; +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(*f1.target<int(*)(int)>() == g); +    assert(*f2.target<int(*)(int)>() == h); +    f1.swap(f2); +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +    assert(*f1.target<int(*)(int)>() == h); +    assert(*f2.target<int(*)(int)>() == g); +    } +    assert(A::count == 0); +    assert(globalMemCounter.checkOutstandingNewEq(0)); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.nullptr/operator_==.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.nullptr/operator_==.pass.cpp new file mode 100644 index 000000000000..5bca0968702c --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.nullptr/operator_==.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template <MoveConstructible R, MoveConstructible ... ArgTypes> +//   bool operator==(const function<R(ArgTypes...)>&, nullptr_t); +// +// template <MoveConstructible R, MoveConstructible ... ArgTypes> +//   bool operator==(nullptr_t, const function<R(ArgTypes...)>&); +// +// template <MoveConstructible R, MoveConstructible ... ArgTypes> +//   bool operator!=(const function<R(ArgTypes...)>&, nullptr_t); +// +// template <MoveConstructible  R, MoveConstructible ... ArgTypes> +//   bool operator!=(nullptr_t, const function<R(ArgTypes...)>&); + +#include <functional> +#include <cassert> + +int g(int) {return 0;} + +int main() +{ +    { +    std::function<int(int)> f; +    assert(f == nullptr); +    assert(nullptr == f); +    f = g; +    assert(f != nullptr); +    assert(nullptr != f); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.targ/target.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.targ/target.pass.cpp new file mode 100644 index 000000000000..53476a274735 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.targ/target.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// template<typename T> +//   requires Callable<T, ArgTypes...> && Convertible<Callable<T, ArgTypes...>::result_type, R> +//   T* +//   target(); +// template<typename T> +//   requires Callable<T, ArgTypes...> && Convertible<Callable<T, ArgTypes...>::result_type, R> +//   const T* +//   target() const; + +#include <functional> +#include <new> +#include <cstdlib> +#include <cassert> + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } + +    int foo(int) const {return 1;} +}; + +int A::count = 0; + +int g(int) {return 0;} + +int main() +{ +    { +    std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    } +    assert(A::count == 0); +    { +    std::function<int(int)> f = g; +    assert(A::count == 0); +    assert(f.target<int(*)(int)>()); +    assert(f.target<A>() == 0); +    } +    assert(A::count == 0); +    { +    const std::function<int(int)> f = A(); +    assert(A::count == 1); +    assert(f.target<A>()); +    assert(f.target<int(*)(int)>() == 0); +    } +    assert(A::count == 0); +    { +    const std::function<int(int)> f = g; +    assert(A::count == 0); +    assert(f.target<int(*)(int)>()); +    assert(f.target<A>() == 0); +    } +    assert(A::count == 0); +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.targ/target_type.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.targ/target_type.pass.cpp new file mode 100644 index 000000000000..7605e3bf666e --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.targ/target_type.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class function<R(ArgTypes...)> + +// const std::type_info& target_type() const; + +#include <functional> +#include <typeinfo> +#include <cassert> + +class A +{ +    int data_[10]; +public: +    static int count; + +    A() +    { +        ++count; +        for (int i = 0; i < 10; ++i) +            data_[i] = i; +    } + +    A(const A&) {++count;} + +    ~A() {--count;} + +    int operator()(int i) const +    { +        for (int j = 0; j < 10; ++j) +            i += data_[j]; +        return i; +    } + +    int foo(int) const {return 1;} +}; + +int A::count = 0; + +int g(int) {return 0;} + +int main() +{ +    { +    std::function<int(int)> f = A(); +    assert(f.target_type() == typeid(A)); +    } +    { +    std::function<int(int)> f; +    assert(f.target_type() == typeid(void)); +    } +} diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h b/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h new file mode 100644 index 000000000000..55eb80f43ffe --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h @@ -0,0 +1,57 @@ +#ifndef FUNCTION_TYPES_H +#define FUNCTION_TYPES_H + + +class FunctionObject +{ +    int data_[10]; // dummy variable to prevent small object optimization in +                   // std::function +public: +    static int count; + +    FunctionObject() { +        ++count; +        for (int i = 0; i < 10; ++i) data_[i] = i; +    } + +    FunctionObject(const FunctionObject&) {++count;} +    ~FunctionObject() {--count; ((void)data_); } + +    int operator()() const { return 42; } +    int operator()(int i) const { return i; } +    int operator()(int i, int) const { return i; } +    int operator()(int i, int, int) const { return i; } +}; + +int FunctionObject::count = 0; + +class MemFunClass +{ +    int data_[10]; // dummy variable to prevent small object optimization in +                   // std::function +public: +    static int count; + +    MemFunClass() { +        ++count; +        for (int i = 0; i < 10; ++i) data_[i] = 0; +    } + +    MemFunClass(const MemFunClass&) {++count; ((void)data_); } + +    ~MemFunClass() {--count;} + +    int foo() const { return 42; } +    int foo(int i) const { return i; } +    int foo(int i, int) const { return i; } +    int foo(int i, int, int) const { return i; } +}; + +int MemFunClass::count = 0; + +int FreeFunction() { return 42; } +int FreeFunction(int i) {return i;} +int FreeFunction(int i, int) { return i; } +int FreeFunction(int i, int, int) { return i; } + +#endif // FUNCTION_TYPES_H diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp new file mode 100644 index 000000000000..eb4eac65cd2c --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/types.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +//                     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<Returnable R, CopyConstructible... ArgTypes> +// class function<R(ArgTypes...)> { +// public: +//   typedef R result_type; +//   typedef T1 argument_type;          // iff sizeof...(ArgTypes) == 1 and +//                                      // the type in ArgTypes is T1  +//   typedef T1 first_argument_type;    // iff sizeof...(ArgTypes) == 2 and +//                                      // ArgTypes contains T1 and T2 +//   typedef T2 second_argument_type;   // iff sizeof...(ArgTypes) == 2 and +//                                      // ArgTypes contains T1 and T2 +//  ... +//  }; + +#include <functional> +#include <type_traits> + + +template <typename T> +class has_argument_type +{ +    typedef char yes; +    typedef long no; + +    template <typename C> static yes check( typename C::argument_type * ); +    template <typename C> static no  check(...); +public: +    enum { value = sizeof(check<T>(0)) == sizeof(yes) }; +}; + +template <typename T> +class has_first_argument_type +{ +    typedef char yes; +    typedef long no; + +    template <typename C> static yes check( typename C::first_argument_type * ); +    template <typename C> static no  check(...); +public: +    enum { value = sizeof(check<T>(0)) == sizeof(yes) }; +}; + + +template <typename T> +class has_second_argument_type +{ +    typedef char yes; +    typedef long no; + +    template <typename C> static yes check( typename C::second_argument_type *); +    template <typename C> static no  check(...); +public: +    enum { value = sizeof(check<T>(0)) == sizeof(yes) }; +}; + +template <class F, class return_type> +void test_nullary_function () +{ +    static_assert((std::is_same<typename F::result_type, return_type>::value), "" ); +    static_assert((!has_argument_type<F>::value), "" ); +    static_assert((!has_first_argument_type<F>::value), "" ); +    static_assert((!has_second_argument_type<F>::value), "" ); +} + +template <class F, class return_type, class arg_type> +void test_unary_function () +{ +    static_assert((std::is_same<typename F::result_type, return_type>::value), "" ); +    static_assert((std::is_same<typename F::argument_type,  arg_type>::value), "" ); +    static_assert((!has_first_argument_type<F>::value), "" ); +    static_assert((!has_second_argument_type<F>::value), "" ); +} + +template <class F, class return_type, class arg_type1, class arg_type2> +void test_binary_function () +{ +    static_assert((std::is_same<typename F::result_type,        return_type>::value), "" ); +    static_assert((std::is_same<typename F::first_argument_type,  arg_type1>::value), "" ); +    static_assert((std::is_same<typename F::second_argument_type, arg_type2>::value), "" ); +    static_assert((!has_argument_type<F>::value), "" ); +} + +template <class F, class return_type> +void test_other_function () +{ +    static_assert((std::is_same<typename F::result_type, return_type>::value), "" ); +    static_assert((!has_argument_type<F>::value), "" ); +    static_assert((!has_first_argument_type<F>::value), "" ); +    static_assert((!has_second_argument_type<F>::value), "" ); +} + +int main() +{ +    test_nullary_function<std::function<int()>, int>(); +    test_unary_function  <std::function<double(int)>, double, int>(); +    test_binary_function <std::function<double(int, char)>, double, int, char>(); +    test_other_function  <std::function<double(int, char, double)>, double>(); +} diff --git a/test/std/utilities/function.objects/func.wrap/nothing_to_do.pass.cpp b/test/std/utilities/function.objects/func.wrap/nothing_to_do.pass.cpp new file mode 100644 index 000000000000..b58f5c55b643 --- /dev/null +++ b/test/std/utilities/function.objects/func.wrap/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp b/test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp new file mode 100644 index 000000000000..72f9dc20144d --- /dev/null +++ b/test/std/utilities/function.objects/logical.operations/logical_and.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// logical_and + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::logical_and<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(f(36, 36)); +    assert(!f(36, 0)); +    assert(!f(0, 36)); +    assert(!f(0, 0)); +#if _LIBCPP_STD_VER > 11 +    typedef std::logical_and<> F2; +    const F2 f2 = F2(); +    assert( f2(36, 36)); +    assert( f2(36, 36L)); +    assert( f2(36L, 36)); +    assert(!f2(36, 0)); +    assert(!f2(0, 36)); +    assert( f2(36, 36L)); +    assert(!f2(36, 0L)); +    assert(!f2(0, 36L)); +    assert( f2(36L, 36)); +    assert(!f2(36L, 0)); +    assert(!f2(0L, 36)); + +    constexpr bool foo = std::logical_and<int> () (36, 36); +    static_assert ( foo, "" ); + +    constexpr bool bar = std::logical_and<> () (36.0, 36); +    static_assert ( bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp b/test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp new file mode 100644 index 000000000000..8484625a727c --- /dev/null +++ b/test/std/utilities/function.objects/logical.operations/logical_not.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// logical_not + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::logical_not<int> F; +    const F f = F(); +    static_assert((std::is_same<F::argument_type, int>::value), "" ); +    static_assert((std::is_same<F::result_type, bool>::value), "" ); +    assert(!f(36)); +    assert(f(0)); +#if _LIBCPP_STD_VER > 11 +    typedef std::logical_not<> F2; +    const F2 f2 = F2(); +    assert(!f2(36)); +    assert( f2(0)); +    assert(!f2(36L)); +    assert( f2(0L)); + +    constexpr bool foo = std::logical_not<int> () (36); +    static_assert ( !foo, "" ); + +    constexpr bool bar = std::logical_not<> () (36); +    static_assert ( !bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/logical.operations/logical_or.pass.cpp b/test/std/utilities/function.objects/logical.operations/logical_or.pass.cpp new file mode 100644 index 000000000000..7280504403f4 --- /dev/null +++ b/test/std/utilities/function.objects/logical.operations/logical_or.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> + +// logical_or + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::logical_or<int> F; +    const F f = F(); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(f(36, 36)); +    assert(f(36, 0)); +    assert(f(0, 36)); +    assert(!f(0, 0)); +#if _LIBCPP_STD_VER > 11 +    typedef std::logical_or<> F2; +    const F2 f2 = F2(); +    assert( f2(36, 36)); +    assert( f2(36, 36L)); +    assert( f2(36L, 36)); +    assert( f2(36, 0)); +    assert( f2(0, 36)); +    assert( f2(36, 0L)); +    assert( f2(0, 36L)); +    assert(!f2(0, 0)); +    assert(!f2(0, 0L)); +    assert(!f2(0L, 0)); + +    constexpr bool foo = std::logical_or<int> () (36, 36); +    static_assert ( foo, "" ); + +    constexpr bool bar = std::logical_or<> () (36.0, 36); +    static_assert ( bar, "" ); +#endif +} diff --git a/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp b/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp new file mode 100644 index 000000000000..6e3b7a2eee24 --- /dev/null +++ b/test/std/utilities/function.objects/logical.operations/transparent.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +//                     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. +// +//===----------------------------------------------------------------------===// + +#include <functional> +#include <string> + +template <class _Tp> +struct is_transparent +{ +private: +    struct __two {char __lx; char __lxx;}; +    template <class _Up> static __two __test(...); +    template <class _Up> static char __test(typename _Up::is_transparent* = 0); +public: +    static const bool value = sizeof(__test<_Tp>(0)) == 1; +}; + + +int main () { +#if _LIBCPP_STD_VER > 11 + +    static_assert ( !is_transparent<std::logical_and<int>>::value, "" ); +    static_assert ( !is_transparent<std::logical_and<std::string>>::value, "" ); +    static_assert (  is_transparent<std::logical_and<void>>::value, "" ); +    static_assert (  is_transparent<std::logical_and<>>::value, "" ); + +    static_assert ( !is_transparent<std::logical_or<int>>::value, "" ); +    static_assert ( !is_transparent<std::logical_or<std::string>>::value, "" ); +    static_assert (  is_transparent<std::logical_or<void>>::value, "" ); +    static_assert (  is_transparent<std::logical_or<>>::value, "" ); + +    static_assert ( !is_transparent<std::logical_not<int>>::value, "" ); +    static_assert ( !is_transparent<std::logical_not<std::string>>::value, "" ); +    static_assert (  is_transparent<std::logical_not<void>>::value, "" ); +    static_assert (  is_transparent<std::logical_not<>>::value, "" ); +     +#endif + +    return 0; +    } diff --git a/test/std/utilities/function.objects/negators/binary_negate.pass.cpp b/test/std/utilities/function.objects/negators/binary_negate.pass.cpp new file mode 100644 index 000000000000..53ff5b47a3a0 --- /dev/null +++ b/test/std/utilities/function.objects/negators/binary_negate.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// binary_negate + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::binary_negate<std::logical_and<int> > F; +    const F f = F(std::logical_and<int>()); +    static_assert((std::is_same<int, F::first_argument_type>::value), "" ); +    static_assert((std::is_same<int, F::second_argument_type>::value), "" ); +    static_assert((std::is_same<bool, F::result_type>::value), "" ); +    assert(!f(36, 36)); +    assert( f(36, 0)); +    assert( f(0, 36)); +    assert( f(0, 0)); +} diff --git a/test/std/utilities/function.objects/negators/not1.pass.cpp b/test/std/utilities/function.objects/negators/not1.pass.cpp new file mode 100644 index 000000000000..f6ac7a49dc00 --- /dev/null +++ b/test/std/utilities/function.objects/negators/not1.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// not1 + +#include <functional> +#include <cassert> + +int main() +{ +    typedef std::logical_not<int> F; +    assert(std::not1(F())(36)); +    assert(!std::not1(F())(0)); +} diff --git a/test/std/utilities/function.objects/negators/not2.pass.cpp b/test/std/utilities/function.objects/negators/not2.pass.cpp new file mode 100644 index 000000000000..7541753d568e --- /dev/null +++ b/test/std/utilities/function.objects/negators/not2.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// not2 + +#include <functional> +#include <cassert> + +int main() +{ +    typedef std::logical_and<int> F; +    assert(!std::not2(F())(36, 36)); +    assert( std::not2(F())(36, 0)); +    assert( std::not2(F())(0, 36)); +    assert( std::not2(F())(0, 0)); +} diff --git a/test/std/utilities/function.objects/negators/unary_negate.pass.cpp b/test/std/utilities/function.objects/negators/unary_negate.pass.cpp new file mode 100644 index 000000000000..e2498a3b52e2 --- /dev/null +++ b/test/std/utilities/function.objects/negators/unary_negate.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// unary_negate + +#include <functional> +#include <type_traits> +#include <cassert> + +int main() +{ +    typedef std::unary_negate<std::logical_not<int> > F; +    const F f = F(std::logical_not<int>()); +    static_assert((std::is_same<F::argument_type, int>::value), "" ); +    static_assert((std::is_same<F::result_type, bool>::value), "" ); +    assert(f(36)); +    assert(!f(0)); +} diff --git a/test/std/utilities/function.objects/refwrap/binary.pass.cpp b/test/std/utilities/function.objects/refwrap/binary.pass.cpp new file mode 100644 index 000000000000..579e81fe69e6 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/binary.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// check for deriving from binary_function + +#include <functional> +#include <type_traits> + +class functor1 +    : public std::unary_function<int, char> +{ +}; + +class functor2 +    : public std::binary_function<char, int, double> +{ +}; + +class functor3 +    : public std::unary_function<int, int>, +      public std::binary_function<char, int, double> +{ +public: +    typedef float result_type; +}; + +class functor4 +    : public std::unary_function<int, int>, +      public std::binary_function<char, int, double> +{ +public: +}; + +struct C +{ +    typedef int argument_type; +    typedef int result_type; +}; + +int main() +{ +    static_assert((!std::is_base_of<std::binary_function<int, char, int>, +                                    std::reference_wrapper<functor1> >::value), ""); +    static_assert((std::is_base_of<std::binary_function<char, int, double>, +                                   std::reference_wrapper<functor2> >::value), ""); +    static_assert((std::is_base_of<std::binary_function<char, int, double>, +                                   std::reference_wrapper<functor3> >::value), ""); +    static_assert((std::is_base_of<std::binary_function<char, int, double>, +                                   std::reference_wrapper<functor4> >::value), ""); +    static_assert((!std::is_base_of<std::binary_function<int, int, int>, +                                    std::reference_wrapper<C> >::value), ""); +    static_assert((!std::is_base_of<std::binary_function<int, int, float>, +                                    std::reference_wrapper<float ()> >::value), ""); +    static_assert((!std::is_base_of<std::binary_function<int, int, float>, +                                   std::reference_wrapper<float (int)> >::value), ""); +    static_assert((std::is_base_of<std::binary_function<int, int, float>, +                                    std::reference_wrapper<float (int, int)> >::value), ""); +    static_assert((!std::is_base_of<std::binary_function<int, int, float>, +                                    std::reference_wrapper<float(*)()> >::value), ""); +    static_assert((!std::is_base_of<std::binary_function<int, int, float>, +                                   std::reference_wrapper<float(*)(int)> >::value), ""); +    static_assert((std::is_base_of<std::binary_function<int, int, float>, +                                    std::reference_wrapper<float(*)(int, int)> >::value), ""); +    static_assert((!std::is_base_of<std::binary_function<C*, int, float>, +                                   std::reference_wrapper<float(C::*)()> >::value), ""); +    static_assert((std::is_base_of<std::binary_function<C*, int, float>, +                                   std::reference_wrapper<float(C::*)(int)> >::value), ""); +    static_assert((std::is_base_of<std::binary_function<const volatile C*, int, float>, +                                   std::reference_wrapper<float(C::*)(int) const volatile> >::value), ""); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.access/conversion.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.access/conversion.pass.cpp new file mode 100644 index 000000000000..df0b55a5d060 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.access/conversion.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// operator T& () const; + +#include <functional> +#include <cassert> + +class functor1 +    : public std::unary_function<int, char> +{ +}; + +template <class T> +void +test(T& t) +{ +    std::reference_wrapper<T> r(t); +    T& r2 = r; +    assert(&r2 == &t); +} + +void f() {} + +int main() +{ +    void (*fp)() = f; +    test(fp); +    test(f); +    functor1 f1; +    test(f1); +    int i = 0; +    test(i); +    const int j = 0; +    test(j); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp new file mode 100644 index 000000000000..122716a23a8b --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// reference_wrapper& operator=(const reference_wrapper<T>& x); + +#include <functional> +#include <cassert> + +class functor1 +    : public std::unary_function<int, char> +{ +}; + +template <class T> +void +test(T& t) +{ +    std::reference_wrapper<T> r(t); +    T t2 = t; +    std::reference_wrapper<T> r2(t2); +    r2 = r; +    assert(&r2.get() == &t); +} + +void f() {} +void g() {} + +void +test_function() +{ +    std::reference_wrapper<void ()> r(f); +    std::reference_wrapper<void ()> r2(g); +    r2 = r; +    assert(&r2.get() == &f); +} + +int main() +{ +    void (*fp)() = f; +    test(fp); +    test_function(); +    functor1 f1; +    test(f1); +    int i = 0; +    test(i); +    const int j = 0; +    test(j); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.const/copy_ctor.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.const/copy_ctor.pass.cpp new file mode 100644 index 000000000000..721a442d4431 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.const/copy_ctor.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// reference_wrapper(const reference_wrapper<T>& x); + +#include <functional> +#include <cassert> + +class functor1 +    : public std::unary_function<int, char> +{ +}; + +template <class T> +void +test(T& t) +{ +    std::reference_wrapper<T> r(t); +    std::reference_wrapper<T> r2 = r; +    assert(&r2.get() == &t); +} + +void f() {} + +int main() +{ +    void (*fp)() = f; +    test(fp); +    test(f); +    functor1 f1; +    test(f1); +    int i = 0; +    test(i); +    const int j = 0; +    test(j); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp b/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp new file mode 100644 index 000000000000..ba46946aae1b --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.fail.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// reference_wrapper(T&&) = delete; + +#include <functional> +#include <cassert> + +int main() +{ +    std::reference_wrapper<const int> r(3); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp new file mode 100644 index 000000000000..564a3f77433c --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// reference_wrapper(T& t); + +#include <functional> +#include <cassert> + +class functor1 +    : public std::unary_function<int, char> +{ +}; + +template <class T> +void +test(T& t) +{ +    std::reference_wrapper<T> r(t); +    assert(&r.get() == &t); +} + +void f() {} + +int main() +{ +    void (*fp)() = f; +    test(fp); +    test(f); +    functor1 f1; +    test(f1); +    int i = 0; +    test(i); +    const int j = 0; +    test(j); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp new file mode 100644 index 000000000000..f2ffd44e26b7 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_1.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <ObjectType T> reference_wrapper<const T> cref(const T& t); + +#include <functional> +#include <cassert> + +int main() +{ +    int i = 0; +    std::reference_wrapper<const int> r = std::cref(i); +    assert(&r.get() == &i); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp new file mode 100644 index 000000000000..75875264479a --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <ObjectType T> reference_wrapper<const T> cref(reference_wrapper<T> t); + +#include <functional> +#include <cassert> + +int main() +{ +    const int i = 0; +    std::reference_wrapper<const int> r1 = std::cref(i); +    std::reference_wrapper<const int> r2 = std::cref(r1); +    assert(&r2.get() == &i); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp new file mode 100644 index 000000000000..86a5696f48ca --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <ObjectType T> reference_wrapper<T> ref(T& t); + +// Don't allow binding to a temp + +#include <functional> + +struct A {}; + +const A source() {return A();} + +int main() +{ +    std::reference_wrapper<const A> r = std::ref(source()); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp new file mode 100644 index 000000000000..39aa4843a710 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_1.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <ObjectType T> reference_wrapper<T> ref(T& t); + +#include <functional> +#include <cassert> + +int main() +{ +    int i = 0; +    std::reference_wrapper<int> r = std::ref(i); +    assert(&r.get() == &i); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp new file mode 100644 index 000000000000..4033e676f018 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <ObjectType T> reference_wrapper<T> ref(reference_wrapper<T>t); + +#include <functional> +#include <cassert> + +#include "counting_predicates.hpp" + +bool is5 ( int i ) { return i == 5; } + +template <typename T> +bool call_pred ( T pred ) { return pred(5); } + +int main() +{ +    { +    int i = 0; +    std::reference_wrapper<int> r1 = std::ref(i); +    std::reference_wrapper<int> r2 = std::ref(r1); +    assert(&r2.get() == &i); +    } +    { +    unary_counting_predicate<bool(*)(int), int> cp(is5); +    assert(!cp(6)); +    assert(cp.count() == 1); +    assert(call_pred(cp)); +    assert(cp.count() == 1); +    assert(call_pred(std::ref(cp))); +    assert(cp.count() == 2); +    } +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.fail.cpp b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.fail.cpp new file mode 100644 index 000000000000..551562721e3e --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.fail.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <class... ArgTypes> +//   requires Callable<T, ArgTypes&&...> +//   Callable<T, ArgTypes&&...>::result_type +//   operator()(ArgTypes&&... args) const; + +#include <functional> +#include <cassert> + +// member data pointer:  cv qualifiers should transfer from argument to return type + +struct A_int_1 +{ +    A_int_1() : data_(5) {} + +    int data_; +}; + +void +test_int_1() +{ +    // member data pointer +    { +    int A_int_1::*fp = &A_int_1::data_; +    std::reference_wrapper<int A_int_1::*> r1(fp); +    A_int_1 a; +    assert(r1(a) == 5); +    r1(a) = 6; +    assert(r1(a) == 6); +    const A_int_1* ap = &a; +    assert(r1(ap) == 6); +    r1(ap) = 7; +    assert(r1(ap) == 7); +    } +} + +int main() +{ +    test_int_1(); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.pass.cpp new file mode 100644 index 000000000000..a9edf00ee592 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.pass.cpp @@ -0,0 +1,329 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <class... ArgTypes> +//   requires Callable<T, ArgTypes&&...> +//   Callable<T, ArgTypes&&...>::result_type +//   operator()(ArgTypes&&... args) const; + +#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;} +}; + +void +test_void_1() +{ +    int save_count = count; +    // function +    { +    std::reference_wrapper<void (int)> r1(f_void_1); +    int i = 2; +    r1(i); +    assert(count == save_count+2); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)(int) = f_void_1; +    std::reference_wrapper<void (*)(int)> r1(fp); +    int i = 3; +    r1(i); +    assert(count == save_count+3); +    save_count = count; +    } +    // functor +    { +    A_void_1 a0; +    std::reference_wrapper<A_void_1> r1(a0); +    int i = 4; +    r1(i); +    assert(count == save_count+4); +    save_count = count; +    } +    // member function pointer +    { +    void (A_void_1::*fp)() = &A_void_1::mem1; +    std::reference_wrapper<void (A_void_1::*)()> r1(fp); +    A_void_1 a; +    r1(a); +    assert(count == save_count+1); +    save_count = count; +    A_void_1* ap = &a; +    r1(ap); +    assert(count == save_count+1); +    save_count = count; +    } +    // const member function pointer +    { +    void (A_void_1::*fp)() const = &A_void_1::mem2; +    std::reference_wrapper<void (A_void_1::*)() const> r1(fp); +    A_void_1 a; +    r1(a); +    assert(count == save_count+1); +    save_count = count; +    A_void_1* ap = &a; +    r1(ap); +    assert(count == save_count+1); +    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() +{ +    // function +    { +    std::reference_wrapper<int (int)> r1(f_int_1); +    int i = 2; +    assert(r1(i) == 3); +    } +    // function pointer +    { +    int (*fp)(int) = f_int_1; +    std::reference_wrapper<int (*)(int)> r1(fp); +    int i = 3; +    assert(r1(i) == 4); +    } +    // functor +    { +    A_int_1 a0; +    std::reference_wrapper<A_int_1> r1(a0); +    int i = 4; +    assert(r1(i) == 3); +    } +    // member function pointer +    { +    int (A_int_1::*fp)() = &A_int_1::mem1; +    std::reference_wrapper<int (A_int_1::*)()> r1(fp); +    A_int_1 a; +    assert(r1(a) == 3); +    A_int_1* ap = &a; +    assert(r1(ap) == 3); +    } +    // const member function pointer +    { +    int (A_int_1::*fp)() const = &A_int_1::mem2; +    std::reference_wrapper<int (A_int_1::*)() const> r1(fp); +    A_int_1 a; +    assert(r1(a) == 4); +    A_int_1* ap = &a; +    assert(r1(ap) == 4); +    } +    // member data pointer +    { +    int A_int_1::*fp = &A_int_1::data_; +    std::reference_wrapper<int A_int_1::*> r1(fp); +    A_int_1 a; +    assert(r1(a) == 5); +    r1(a) = 6; +    assert(r1(a) == 6); +    A_int_1* ap = &a; +    assert(r1(ap) == 6); +    r1(ap) = 7; +    assert(r1(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() +{ +    int save_count = count; +    // function +    { +    std::reference_wrapper<void (int, int)> r1(f_void_2); +    int i = 2; +    int j = 3; +    r1(i, j); +    assert(count == save_count+5); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)(int, int) = f_void_2; +    std::reference_wrapper<void (*)(int, int)> r1(fp); +    int i = 3; +    int j = 4; +    r1(i, j); +    assert(count == save_count+7); +    save_count = count; +    } +    // functor +    { +    A_void_2 a0; +    std::reference_wrapper<A_void_2> r1(a0); +    int i = 4; +    int j = 5; +    r1(i, j); +    assert(count == save_count+9); +    save_count = count; +    } +    // member function pointer +    { +    void (A_void_2::*fp)(int) = &A_void_2::mem1; +    std::reference_wrapper<void (A_void_2::*)(int)> r1(fp); +    A_void_2 a; +    int i = 3; +    r1(a, i); +    assert(count == save_count+3); +    save_count = count; +    A_void_2* ap = &a; +    r1(ap, i); +    assert(count == save_count+3); +    save_count = count; +    } +    // const member function pointer +    { +    void (A_void_2::*fp)(int) const = &A_void_2::mem2; +    std::reference_wrapper<void (A_void_2::*)(int) const> r1(fp); +    A_void_2 a; +    int i = 4; +    r1(a, i); +    assert(count == save_count+4); +    save_count = count; +    A_void_2* ap = &a; +    r1(ap, i); +    assert(count == save_count+4); +    save_count = count; +    } +} + +// 2 arg, return int + +int f_int_2(int i, int j) +{ +    return i+j; +} + +struct A_int_2 +{ +    int operator()(int i, int j) +    { +        return i+j; +    } + +    int mem1(int i) {return i+1;} +    int mem2(int i) const {return i+2;} +}; + +void +testint_2() +{ +    // function +    { +    std::reference_wrapper<int (int, int)> r1(f_int_2); +    int i = 2; +    int j = 3; +    assert(r1(i, j) == i+j); +    } +    // function pointer +    { +    int (*fp)(int, int) = f_int_2; +    std::reference_wrapper<int (*)(int, int)> r1(fp); +    int i = 3; +    int j = 4; +    assert(r1(i, j) == i+j); +    } +    // functor +    { +    A_int_2 a0; +    std::reference_wrapper<A_int_2> r1(a0); +    int i = 4; +    int j = 5; +    assert(r1(i, j) == i+j); +    } +    // member function pointer +    { +    int(A_int_2::*fp)(int) = &A_int_2::mem1; +    std::reference_wrapper<int (A_int_2::*)(int)> r1(fp); +    A_int_2 a; +    int i = 3; +    assert(r1(a, i) == i+1); +    A_int_2* ap = &a; +    assert(r1(ap, i) == i+1); +    } +    // const member function pointer +    { +    int (A_int_2::*fp)(int) const = &A_int_2::mem2; +    std::reference_wrapper<int (A_int_2::*)(int) const> r1(fp); +    A_int_2 a; +    int i = 4; +    assert(r1(a, i) == i+2); +    A_int_2* ap = &a; +    assert(r1(ap, i) == i+2); +    } +} + +int main() +{ +    test_void_1(); +    test_int_1(); +    test_void_2(); +    testint_2(); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke_int_0.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke_int_0.pass.cpp new file mode 100644 index 000000000000..61357a7fa394 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke_int_0.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <class... ArgTypes> +//   requires Callable<T, ArgTypes&&...> +//   Callable<T, ArgTypes&&...>::result_type +//   operator()(ArgTypes&&... args) const; + +#include <functional> +#include <cassert> + +// 0 args, return int + +int count = 0; + +int f_int_0() +{ +    return 3; +} + +struct A_int_0 +{ +    int operator()() {return 4;} +}; + +void +test_int_0() +{ +    // function +    { +    std::reference_wrapper<int ()> r1(f_int_0); +    assert(r1() == 3); +    } +    // function pointer +    { +    int (*fp)() = f_int_0; +    std::reference_wrapper<int (*)()> r1(fp); +    assert(r1() == 3); +    } +    // functor +    { +    A_int_0 a0; +    std::reference_wrapper<A_int_0> r1(a0); +    assert(r1() == 4); +    } +} + +// 1 arg, return void + +void f_void_1(int i) +{ +    count += i; +} + +struct A_void_1 +{ +    void operator()(int i) +    { +        count += i; +    } +}; + +int main() +{ +    test_int_0(); +} diff --git a/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke_void_0.pass.cpp b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke_void_0.pass.cpp new file mode 100644 index 000000000000..8d700508cdc1 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke_void_0.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// template <class... ArgTypes> +//   requires Callable<T, ArgTypes&&...> +//   Callable<T, ArgTypes&&...>::result_type +//   operator()(ArgTypes&&... args) const; + +#include <functional> +#include <cassert> + +// 0 args, return void + +int count = 0; + +void f_void_0() +{ +    ++count; +} + +struct A_void_0 +{ +    void operator()() {++count;} +}; + +void +test_void_0() +{ +    int save_count = count; +    // function +    { +    std::reference_wrapper<void ()> r1(f_void_0); +    r1(); +    assert(count == save_count+1); +    save_count = count; +    } +    // function pointer +    { +    void (*fp)() = f_void_0; +    std::reference_wrapper<void (*)()> r1(fp); +    r1(); +    assert(count == save_count+1); +    save_count = count; +    } +    // functor +    { +    A_void_0 a0; +    std::reference_wrapper<A_void_0> r1(a0); +    r1(); +    assert(count == save_count+1); +    save_count = count; +    } +} + +int main() +{ +    test_void_0(); +} diff --git a/test/std/utilities/function.objects/refwrap/type.pass.cpp b/test/std/utilities/function.objects/refwrap/type.pass.cpp new file mode 100644 index 000000000000..68e406798145 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/type.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// check for member typedef type + +#include <functional> +#include <type_traits> + +class C {}; + +int main() +{ +    static_assert((std::is_same<std::reference_wrapper<C>::type, +                                                       C>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<void ()>::type, +                                                       void ()>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int* (double*)>::type, +                                                       int* (double*)>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<void(*)()>::type, +                                                       void(*)()>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int*(*)(double*)>::type, +                                                       int*(*)(double*)>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int*(C::*)(double*)>::type, +                                                       int*(C::*)(double*)>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int (C::*)(double*) const volatile>::type, +                                                       int (C::*)(double*) const volatile>::value), ""); +} diff --git a/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp new file mode 100644 index 000000000000..61e0bfa162d8 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/type_properties.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// Test that reference wrapper meets the requirements of TriviallyCopyable, +// CopyConstructible and CopyAssignable. + +#include <functional> +#include <type_traits> +#include <string> + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +class MoveOnly +{ +    MoveOnly(const MoveOnly&); +    MoveOnly& operator=(const MoveOnly&); + +    int data_; +public: +    MoveOnly(int data = 1) : data_(data) {} +    MoveOnly(MoveOnly&& x) +        : data_(x.data_) {x.data_ = 0;} +    MoveOnly& operator=(MoveOnly&& x) +        {data_ = x.data_; x.data_ = 0; return *this;} + +    int get() const {return data_;} +}; +#endif + + +template <class T> +void test() +{ +    typedef std::reference_wrapper<T> Wrap; +    static_assert(std::is_copy_constructible<Wrap>::value, ""); +    static_assert(std::is_copy_assignable<Wrap>::value, ""); +    // Extension up for standardization: See N4151. +    static_assert(std::is_trivially_copyable<Wrap>::value, ""); +} + +int main() +{ +    test<int>(); +    test<double>(); +    test<std::string>();  +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +    test<MoveOnly>();  +#endif +} diff --git a/test/std/utilities/function.objects/refwrap/unary.pass.cpp b/test/std/utilities/function.objects/refwrap/unary.pass.cpp new file mode 100644 index 000000000000..528a8f327d96 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/unary.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// check for deriving from unary_function + +#include <functional> +#include <type_traits> + +class functor1 +    : public std::unary_function<int, char> +{ +}; + +class functor2 +    : public std::binary_function<char, int, double> +{ +}; + +class functor3 +    : public std::unary_function<int, int>, +      public std::binary_function<char, int, double> +{ +public: +    typedef float result_type; +}; + +class functor4 +    : public std::unary_function<int, int>, +      public std::binary_function<char, int, double> +{ +public: +}; + +struct C +{ +    typedef int argument_type; +    typedef int result_type; +}; + +int main() +{ +    static_assert((std::is_base_of<std::unary_function<int, char>, +                                   std::reference_wrapper<functor1> >::value), ""); +    static_assert((!std::is_base_of<std::unary_function<char, int>, +                                    std::reference_wrapper<functor2> >::value), ""); +    static_assert((std::is_base_of<std::unary_function<int, int>, +                                   std::reference_wrapper<functor3> >::value), ""); +    static_assert((std::is_base_of<std::unary_function<int, int>, +                                   std::reference_wrapper<functor4> >::value), ""); +    static_assert((!std::is_base_of<std::unary_function<int, int>, +                                    std::reference_wrapper<C> >::value), ""); +    static_assert((!std::is_base_of<std::unary_function<int, float>, +                                    std::reference_wrapper<float(*)()> >::value), ""); +    static_assert((std::is_base_of<std::unary_function<int, float>, +                                   std::reference_wrapper<float (int)> >::value), ""); +    static_assert((!std::is_base_of<std::unary_function<int, float>, +                                    std::reference_wrapper<float (int, int)> >::value), ""); +    static_assert((std::is_base_of<std::unary_function<int, float>, +                                   std::reference_wrapper<float(*)(int)> >::value), ""); +    static_assert((!std::is_base_of<std::unary_function<int, float>, +                                    std::reference_wrapper<float(*)(int, int)> >::value), ""); +    static_assert((std::is_base_of<std::unary_function<C*, float>, +                                   std::reference_wrapper<float(C::*)()> >::value), ""); +    static_assert((std::is_base_of<std::unary_function<const volatile C*, float>, +                                   std::reference_wrapper<float(C::*)() const volatile> >::value), ""); +    static_assert((!std::is_base_of<std::unary_function<C*, float>, +                                   std::reference_wrapper<float(C::*)(int)> >::value), ""); +} diff --git a/test/std/utilities/function.objects/refwrap/weak_result.pass.cpp b/test/std/utilities/function.objects/refwrap/weak_result.pass.cpp new file mode 100644 index 000000000000..609094dae406 --- /dev/null +++ b/test/std/utilities/function.objects/refwrap/weak_result.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// reference_wrapper + +// has weak result type + +#include <functional> +#include <type_traits> + +class functor1 +    : public std::unary_function<int, char> +{ +}; + +class functor2 +    : public std::binary_function<char, int, double> +{ +}; + +class functor3 +    : public std::unary_function<char, int>, +      public std::binary_function<char, int, double> +{ +public: +    typedef float result_type; +}; + +class functor4 +    : public std::unary_function<char, int>, +      public std::binary_function<char, int, double> +{ +public: +}; + +class C {}; + +template <class T> +struct has_result_type +{ +private: +    struct two {char _; char __;}; +    template <class U> static two test(...); +    template <class U> static char test(typename U::result_type* = 0); +public: +    static const bool value = sizeof(test<T>(0)) == 1; +}; + +int main() +{ +    static_assert((std::is_same<std::reference_wrapper<functor1>::result_type, +                                char>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<functor2>::result_type, +                                double>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<functor3>::result_type, +                                float>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<void()>::result_type, +                                void>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int*(double*)>::result_type, +                                int*>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<void(*)()>::result_type, +                                void>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int*(*)(double*)>::result_type, +                                int*>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int*(C::*)(double*)>::result_type, +                                int*>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<int (C::*)(double*) const volatile>::result_type, +                                int>::value), ""); +    static_assert((std::is_same<std::reference_wrapper<C()>::result_type, +                                C>::value), ""); +    static_assert(has_result_type<std::reference_wrapper<functor3> >::value, ""); +    static_assert(!has_result_type<std::reference_wrapper<functor4> >::value, ""); +    static_assert(!has_result_type<std::reference_wrapper<C> >::value, ""); +} diff --git a/test/std/utilities/function.objects/unord.hash/enum.fail.cpp b/test/std/utilities/function.objects/unord.hash/enum.fail.cpp new file mode 100644 index 000000000000..9e44bfb77817 --- /dev/null +++ b/test/std/utilities/function.objects/unord.hash/enum.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +//  Hashing a struct w/o a defined hash should fail. + +#include <functional> +#include <cassert> +#include <type_traits> + +struct X {}; + +int main() +{ +    X x; +    size_t h = std::hash<X>{} ( x ); +} diff --git a/test/std/utilities/function.objects/unord.hash/enum.pass.cpp b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp new file mode 100644 index 000000000000..bd92a4ac4d2e --- /dev/null +++ b/test/std/utilities/function.objects/unord.hash/enum.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// make sure that we can hash enumeration values +// Not very portable + +#if __cplusplus >= 201402L + +#include <functional> +#include <cassert> +#include <type_traits> +#include <limits> + +enum class Colors { red, orange, yellow, green, blue, indigo, violet }; +enum class Cardinals { zero, one, two, three, five=5 }; +enum class LongColors : short { red, orange, yellow, green, blue, indigo, violet }; +enum class ShortColors : long { red, orange, yellow, green, blue, indigo, violet }; +enum class EightBitColors : uint8_t { red, orange, yellow, green, blue, indigo, violet }; + +enum Fruits { apple, pear, grape, mango, cantaloupe }; + +template <class T> +void +test() +{ +    typedef std::hash<T> H; +    static_assert((std::is_same<typename H::argument_type, T>::value), "" ); +    static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); +    typedef typename std::underlying_type<T>::type under_type; +     +    H h1; +    std::hash<under_type> h2; +    for (int i = 0; i <= 5; ++i) +    { +        T t(static_cast<T> (i)); +        if (sizeof(T) <= sizeof(std::size_t)) +            assert(h1(t) == h2(static_cast<under_type>(i))); +    } +} + +int main() +{ +    test<Cardinals>(); + +    test<Colors>(); +    test<ShortColors>(); +    test<LongColors>(); +    test<EightBitColors>(); + +    test<Fruits>(); +} +#else +int main () {} +#endif diff --git a/test/std/utilities/function.objects/unord.hash/floating.pass.cpp b/test/std/utilities/function.objects/unord.hash/floating.pass.cpp new file mode 100644 index 000000000000..f1f198f23599 --- /dev/null +++ b/test/std/utilities/function.objects/unord.hash/floating.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +//                     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 <class T> +// struct hash +//     : public unary_function<T, size_t> +// { +//     size_t operator()(T val) const; +// }; + +// Not very portable + +#include <functional> +#include <cassert> +#include <type_traits> +#include <limits> +#include <cmath> + +template <class T> +void +test() +{ +    typedef std::hash<T> H; +    static_assert((std::is_same<typename H::argument_type, T>::value), "" ); +    static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); +    H h; + +    std::size_t t0 = h(0.); +    std::size_t tn0 = h(-0.); +    std::size_t tp1 = h(0.1); +    std::size_t t1 = h(1); +    std::size_t tn1 = h(-1); +    std::size_t pinf = h(INFINITY); +    std::size_t ninf = h(-INFINITY); +    assert(t0 == tn0); +    assert(t0 != tp1); +    assert(t0 != t1); +    assert(t0 != tn1); +    assert(t0 != pinf); +    assert(t0 != ninf); + +    assert(tp1 != t1); +    assert(tp1 != tn1); +    assert(tp1 != pinf); +    assert(tp1 != ninf); + +    assert(t1 != tn1); +    assert(t1 != pinf); +    assert(t1 != ninf); + +    assert(tn1 != pinf); +    assert(tn1 != ninf); + +    assert(pinf != ninf); +} + +int main() +{ +    test<float>(); +    test<double>(); +    test<long double>(); +} diff --git a/test/std/utilities/function.objects/unord.hash/integral.pass.cpp b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp new file mode 100644 index 000000000000..7cd9f15e93d1 --- /dev/null +++ b/test/std/utilities/function.objects/unord.hash/integral.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +//                     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 <class T> +// struct hash +//     : public unary_function<T, size_t> +// { +//     size_t operator()(T val) const; +// }; + +// Not very portable + +#include <functional> +#include <cassert> +#include <type_traits> +#include <limits> + +template <class T> +void +test() +{ +    typedef std::hash<T> H; +    static_assert((std::is_same<typename H::argument_type, T>::value), "" ); +    static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); +    H h; + +    for (int i = 0; i <= 5; ++i) +    { +        T t(i); +        if (sizeof(T) <= sizeof(std::size_t)) +            assert(h(t) == t); +    } +} + +int main() +{ +    test<bool>(); +    test<char>(); +    test<signed char>(); +    test<unsigned char>(); +    test<char16_t>(); +    test<char32_t>(); +    test<wchar_t>(); +    test<short>(); +    test<unsigned short>(); +    test<int>(); +    test<unsigned int>(); +    test<long>(); +    test<unsigned long>(); +    test<long long>(); +    test<unsigned long long>(); +} diff --git a/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp b/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp new file mode 100644 index 000000000000..a48394495e2d --- /dev/null +++ b/test/std/utilities/function.objects/unord.hash/pointer.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +//                     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 <class T> +// struct hash +//     : public unary_function<T, size_t> +// { +//     size_t operator()(T val) const; +// }; + +// Not very portable + +#include <functional> +#include <cassert> +#include <type_traits> +#include <limits> + +template <class T> +void +test() +{ +    typedef std::hash<T> H; +    static_assert((std::is_same<typename H::argument_type, T>::value), "" ); +    static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" ); +    H h; + +    typedef typename std::remove_pointer<T>::type type; +    type i; +    type j; +    assert(h(&i) != h(&j)); +} + +int main() +{ +    test<int*>(); +} diff --git a/test/std/utilities/function.objects/version.pass.cpp b/test/std/utilities/function.objects/version.pass.cpp new file mode 100644 index 000000000000..99d731a74543 --- /dev/null +++ b/test/std/utilities/function.objects/version.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +#include <functional> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} | 
