xref: /llvm-project/libcxx/test/std/utilities/function.objects/func.bind.partial/bind_back.verify.cpp (revision c8917048e3aa2be03b6588b817730abdbce23c85)
1*c8917048SJakub Mazurkiewicz //===----------------------------------------------------------------------===//
2*c8917048SJakub Mazurkiewicz //
3*c8917048SJakub Mazurkiewicz // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*c8917048SJakub Mazurkiewicz // See https://llvm.org/LICENSE.txt for license information.
5*c8917048SJakub Mazurkiewicz // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*c8917048SJakub Mazurkiewicz //
7*c8917048SJakub Mazurkiewicz //===----------------------------------------------------------------------===//
8*c8917048SJakub Mazurkiewicz 
9*c8917048SJakub Mazurkiewicz // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10*c8917048SJakub Mazurkiewicz 
11*c8917048SJakub Mazurkiewicz // <functional>
12*c8917048SJakub Mazurkiewicz 
13*c8917048SJakub Mazurkiewicz // template<class F, class... Args>
14*c8917048SJakub Mazurkiewicz //   constexpr unspecified bind_back(F&& f, Args&&... args);
15*c8917048SJakub Mazurkiewicz 
16*c8917048SJakub Mazurkiewicz #include <functional>
17*c8917048SJakub Mazurkiewicz 
18*c8917048SJakub Mazurkiewicz #include "types.h"
19*c8917048SJakub Mazurkiewicz 
pass(int n)20*c8917048SJakub Mazurkiewicz constexpr int pass(int n) { return n; }
21*c8917048SJakub Mazurkiewicz 
test()22*c8917048SJakub Mazurkiewicz void test() {
23*c8917048SJakub Mazurkiewicz   { // Test calling constexpr function from non-constexpr `bind_back` result
24*c8917048SJakub Mazurkiewicz     auto f1 = std::bind_back(pass, 1);
25*c8917048SJakub Mazurkiewicz     static_assert(f1() == 1); // expected-error {{static assertion expression is not an integral constant expression}}
26*c8917048SJakub Mazurkiewicz   }
27*c8917048SJakub Mazurkiewicz 
28*c8917048SJakub Mazurkiewicz   { // Test calling `bind_back` with template function
29*c8917048SJakub Mazurkiewicz     auto f1 = std::bind_back(do_nothing, 2);
30*c8917048SJakub Mazurkiewicz     // expected-error@-1 {{no matching function for call to 'bind_back'}}
31*c8917048SJakub Mazurkiewicz   }
32*c8917048SJakub Mazurkiewicz 
33*c8917048SJakub Mazurkiewicz   { // Mandates: is_constructible_v<decay_t<F>, F>
34*c8917048SJakub Mazurkiewicz     struct F {
35*c8917048SJakub Mazurkiewicz       F()         = default;
36*c8917048SJakub Mazurkiewicz       F(const F&) = default;
37*c8917048SJakub Mazurkiewicz       F(F&)       = delete;
38*c8917048SJakub Mazurkiewicz 
39*c8917048SJakub Mazurkiewicz       void operator()() {}
40*c8917048SJakub Mazurkiewicz     };
41*c8917048SJakub Mazurkiewicz 
42*c8917048SJakub Mazurkiewicz     F f;
43*c8917048SJakub Mazurkiewicz     auto f1 = std::bind_back(f);
44*c8917048SJakub Mazurkiewicz     // expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires decay_t<F> to be constructible from F}}
45*c8917048SJakub Mazurkiewicz   }
46*c8917048SJakub Mazurkiewicz 
47*c8917048SJakub Mazurkiewicz   { // Mandates: is_move_constructible_v<decay_t<F>>
48*c8917048SJakub Mazurkiewicz     struct F {
49*c8917048SJakub Mazurkiewicz       F()         = default;
50*c8917048SJakub Mazurkiewicz       F(const F&) = default;
51*c8917048SJakub Mazurkiewicz       F(F&&)      = delete;
52*c8917048SJakub Mazurkiewicz 
53*c8917048SJakub Mazurkiewicz       void operator()() {}
54*c8917048SJakub Mazurkiewicz     };
55*c8917048SJakub Mazurkiewicz 
56*c8917048SJakub Mazurkiewicz     F f;
57*c8917048SJakub Mazurkiewicz     auto f1 = std::bind_back(f);
58*c8917048SJakub Mazurkiewicz     // expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires decay_t<F> to be move constructible}}
59*c8917048SJakub Mazurkiewicz   }
60*c8917048SJakub Mazurkiewicz 
61*c8917048SJakub Mazurkiewicz   { // Mandates: (is_constructible_v<decay_t<Args>, Args> && ...)
62*c8917048SJakub Mazurkiewicz     struct Arg {
63*c8917048SJakub Mazurkiewicz       Arg()           = default;
64*c8917048SJakub Mazurkiewicz       Arg(const Arg&) = default;
65*c8917048SJakub Mazurkiewicz       Arg(Arg&)       = delete;
66*c8917048SJakub Mazurkiewicz     };
67*c8917048SJakub Mazurkiewicz 
68*c8917048SJakub Mazurkiewicz     Arg x;
69*c8917048SJakub Mazurkiewicz     auto f = std::bind_back([](const Arg&) {}, x);
70*c8917048SJakub Mazurkiewicz     // expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires all decay_t<Args> to be constructible from respective Args}}
71*c8917048SJakub Mazurkiewicz     // expected-error@*:* {{no matching constructor for initialization}}
72*c8917048SJakub Mazurkiewicz   }
73*c8917048SJakub Mazurkiewicz 
74*c8917048SJakub Mazurkiewicz   { // Mandates: (is_move_constructible_v<decay_t<Args>> && ...)
75*c8917048SJakub Mazurkiewicz     struct Arg {
76*c8917048SJakub Mazurkiewicz       Arg()           = default;
77*c8917048SJakub Mazurkiewicz       Arg(const Arg&) = default;
78*c8917048SJakub Mazurkiewicz       Arg(Arg&&)      = delete;
79*c8917048SJakub Mazurkiewicz     };
80*c8917048SJakub Mazurkiewicz 
81*c8917048SJakub Mazurkiewicz     Arg x;
82*c8917048SJakub Mazurkiewicz     auto f = std::bind_back([](Arg&) {}, x);
83*c8917048SJakub Mazurkiewicz     // expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires all decay_t<Args> to be move constructible}}
84*c8917048SJakub Mazurkiewicz   }
85*c8917048SJakub Mazurkiewicz }
86