brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · 82431bb Raw
305 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++0310 11// <functional>12 13// template<CopyConstructible Fn, CopyConstructible... Types>14//   unspecified bind(Fn, Types...);    // constexpr since C++2015// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types>16//   unspecified bind(Fn, Types...);    // constexpr since C++2017 18#include <stdio.h>19 20#include <functional>21#include <cassert>22 23#include "test_macros.h"24 25int count = 0;26 27// 1 arg, return void28 29void f_void_1(int i)30{31    count += i;32}33 34struct A_void_135{36    void operator()(int i)37    {38        count += i;39    }40 41    void mem1() {++count;}42    void mem2() const {count += 2;}43};44 45void46test_void_1()47{48    using namespace std::placeholders;49    int save_count = count;50    // function51    {52    int i = 2;53    std::bind(f_void_1, _1)(i);54    assert(count == save_count + 2);55    save_count = count;56    }57    {58    int i = 2;59    std::bind(f_void_1, i)();60    assert(count == save_count + 2);61    save_count = count;62    }63    // function pointer64    {65    void (*fp)(int) = f_void_1;66    int i = 3;67    std::bind(fp, _1)(i);68    assert(count == save_count+3);69    save_count = count;70    }71    {72    void (*fp)(int) = f_void_1;73    int i = 3;74    std::bind(fp, i)();75    assert(count == save_count+3);76    save_count = count;77    }78    // functor79    {80    A_void_1 a0;81    int i = 4;82    std::bind(a0, _1)(i);83    assert(count == save_count+4);84    save_count = count;85    }86    {87    A_void_1 a0;88    int i = 4;89    std::bind(a0, i)();90    assert(count == save_count+4);91    save_count = count;92    }93    // member function pointer94    {95    void (A_void_1::*fp)() = &A_void_1::mem1;96    A_void_1 a;97    std::bind(fp, _1)(a);98    assert(count == save_count+1);99    save_count = count;100    A_void_1* ap = &a;101    std::bind(fp, _1)(ap);102    assert(count == save_count+1);103    save_count = count;104    }105    {106    void (A_void_1::*fp)() = &A_void_1::mem1;107    A_void_1 a;108    std::bind(fp, a)();109    assert(count == save_count+1);110    save_count = count;111    A_void_1* ap = &a;112    std::bind(fp, ap)();113    assert(count == save_count+1);114    save_count = count;115    }116    // const member function pointer117    {118    void (A_void_1::*fp)() const = &A_void_1::mem2;119    A_void_1 a;120    std::bind(fp, _1)(a);121    assert(count == save_count+2);122    save_count = count;123    A_void_1* ap = &a;124    std::bind(fp, _1)(ap);125    assert(count == save_count+2);126    save_count = count;127    }128    {129    void (A_void_1::*fp)() const = &A_void_1::mem2;130    A_void_1 a;131    std::bind(fp, a)();132    assert(count == save_count+2);133    save_count = count;134    A_void_1* ap = &a;135    std::bind(fp, ap)();136    assert(count == save_count+2);137    save_count = count;138    }139}140 141// 1 arg, return int142 143TEST_CONSTEXPR_CXX20 int f_int_1(int i) {144    return i + 1;145}146 147struct A_int_1 {148    TEST_CONSTEXPR_CXX20 A_int_1() : data_(5) {}149    TEST_CONSTEXPR_CXX20 int operator()(int i) {150        return i - 1;151    }152 153    TEST_CONSTEXPR_CXX20 int mem1() { return 3; }154    TEST_CONSTEXPR_CXX20 int mem2() const { return 4; }155    int data_;156};157 158TEST_CONSTEXPR_CXX20 bool test_int_1() {159    using namespace std::placeholders;160    // function161    {162    int i = 2;163    assert(std::bind(f_int_1, _1)(i) == 3);164    assert(std::bind(f_int_1, i)() == 3);165    }166    // function pointer167    {168    int (*fp)(int) = f_int_1;169    int i = 3;170    assert(std::bind(fp, _1)(i) == 4);171    assert(std::bind(fp, i)() == 4);172    }173    // functor174    {175    int i = 4;176    assert(std::bind(A_int_1(), _1)(i) == 3);177    assert(std::bind(A_int_1(), i)() == 3);178    }179    // member function pointer180    {181    A_int_1 a;182    assert(std::bind(&A_int_1::mem1, _1)(a) == 3);183    assert(std::bind(&A_int_1::mem1, a)() == 3);184    A_int_1* ap = &a;185    assert(std::bind(&A_int_1::mem1, _1)(ap) == 3);186    assert(std::bind(&A_int_1::mem1, ap)() == 3);187    }188    // const member function pointer189    {190    A_int_1 a;191    assert(std::bind(&A_int_1::mem2, _1)(A_int_1()) == 4);192    assert(std::bind(&A_int_1::mem2, A_int_1())() == 4);193    A_int_1* ap = &a;194    assert(std::bind(&A_int_1::mem2, _1)(ap) == 4);195    assert(std::bind(&A_int_1::mem2, ap)() == 4);196    }197    // member data pointer198    {199    A_int_1 a;200    assert(std::bind(&A_int_1::data_, _1)(a) == 5);201    assert(std::bind(&A_int_1::data_, a)() == 5);202    A_int_1* ap = &a;203    assert(std::bind(&A_int_1::data_, _1)(a) == 5);204    std::bind(&A_int_1::data_, _1)(a) = 6;205    assert(std::bind(&A_int_1::data_, _1)(a) == 6);206    assert(std::bind(&A_int_1::data_, _1)(ap) == 6);207    std::bind(&A_int_1::data_, _1)(ap) = 7;208    assert(std::bind(&A_int_1::data_, _1)(ap) == 7);209    }210 211    return true;212}213 214// 2 arg, return void215 216void f_void_2(int i, int j)217{218    count += i+j;219}220 221struct A_void_2222{223    void operator()(int i, int j)224    {225        count += i+j;226    }227 228    void mem1(int i) {count += i;}229    void mem2(int i) const {count += i;}230};231 232void233test_void_2()234{235    using namespace std::placeholders;236    int save_count = count;237    // function238    {239    int i = 2;240    int j = 3;241    std::bind(f_void_2, _1, _2)(i, j);242    assert(count == save_count+5);243    save_count = count;244    std::bind(f_void_2, i, _1)(j);245    assert(count == save_count+5);246    save_count = count;247    std::bind(f_void_2, i, j)();248    assert(count == save_count+5);249    save_count = count;250    }251    // member function pointer252    {253    int j = 3;254    std::bind(&A_void_2::mem1, _1, _2)(A_void_2(), j);255    assert(count == save_count+3);256    save_count = count;257    std::bind(&A_void_2::mem1, _2, _1)(j, A_void_2());258    assert(count == save_count+3);259    save_count = count;260    }261}262 263struct ConstQualifiedMemberFunction {264    TEST_CONSTEXPR_CXX20 bool foo(unsigned long long) const {265        return true;266    }267};268 269TEST_CONSTEXPR_CXX20 bool test_const_qualified_member() {270    using namespace std;271    using namespace std::placeholders;272    const auto f = bind(&ConstQualifiedMemberFunction::foo, _1, 0UL);273    const ConstQualifiedMemberFunction n = ConstQualifiedMemberFunction{};274    bool b = f(n);275    assert(b);276    return true;277}278 279TEST_CONSTEXPR_CXX20 bool test_many_args() {280    using namespace std::placeholders;281    auto f = [](int& a, char&, float&, long&) -> int& { return a; };282    auto bound = std::bind(f, _4, _3, _2, _1);283    int a = 3; char b = '2'; float c = 1.0f; long d = 0l;284    int& result = bound(d, c, b, a);285    assert(&result == &a);286    return true;287}288 289int main(int, char**) {290    test_void_1();291    test_int_1();292    test_void_2();293    test_const_qualified_member();294    test_many_args();295 296    // The other tests are not constexpr-friendly since they need to use a global variable297#if TEST_STD_VER >= 20298    static_assert(test_int_1());299    static_assert(test_const_qualified_member());300    static_assert(test_many_args());301#endif302 303    return 0;304}305