summaryrefslogtreecommitdiffstats
path: root/base/bind.h
blob: f023308eb55ec7421fcfac90200c276fc126dfcf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// This file was GENERATED by command:
//     pump.py bind.h.pump
// DO NOT EDIT BY HAND!!!



// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_BIND_H_
#define BASE_BIND_H_
#pragma once

#include "base/bind_internal.h"
#include "base/callback_internal.h"

// See base/callback.h for how to use these functions.
//
// IMPLEMENTATION NOTE
// Though Bind()'s result is meant to be stored in a Callback<> type, it
// cannot actually return the exact type without requiring a large amount
// of extra template specializations. The problem is that in order to
// discern the correct specialization of Callback<>, Bind would need to
// unwrap the function signature to determine the signature's arity, and
// whether or not it is a method.
//
// Each unique combination of (arity, function_type, num_prebound) where
// function_type is one of {function, method, const_method} would require
// one specialization.  We eventually have to do a similar number of
// specializations anyways in the implementation (see the FunctionTraitsN,
// classes).  However, it is avoidable in Bind if we return the result
// via an indirection like we do below.

namespace base {

template <typename Sig>
internal::InvokerStorageHolder<internal::InvokerStorage0<Sig> >
Bind(Sig f) {
  return internal::MakeInvokerStorageHolder(
      new internal::InvokerStorage0<Sig>(f));
}

template <typename Sig, typename P1>
internal::InvokerStorageHolder<internal::InvokerStorage1<Sig,P1> >
Bind(Sig f, const P1& p1) {
  return internal::MakeInvokerStorageHolder(
      new internal::InvokerStorage1<Sig, P1>(
          f, p1));
}

template <typename Sig, typename P1, typename P2>
internal::InvokerStorageHolder<internal::InvokerStorage2<Sig,P1, P2> >
Bind(Sig f, const P1& p1, const P2& p2) {
  return internal::MakeInvokerStorageHolder(
      new internal::InvokerStorage2<Sig, P1, P2>(
          f, p1, p2));
}

template <typename Sig, typename P1, typename P2, typename P3>
internal::InvokerStorageHolder<internal::InvokerStorage3<Sig,P1, P2, P3> >
Bind(Sig f, const P1& p1, const P2& p2, const P3& p3) {
  return internal::MakeInvokerStorageHolder(
      new internal::InvokerStorage3<Sig, P1, P2, P3>(
          f, p1, p2, p3));
}

template <typename Sig, typename P1, typename P2, typename P3, typename P4>
internal::InvokerStorageHolder<internal::InvokerStorage4<Sig,P1, P2, P3, P4> >
Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
  return internal::MakeInvokerStorageHolder(
      new internal::InvokerStorage4<Sig, P1, P2, P3, P4>(
          f, p1, p2, p3, p4));
}

template <typename Sig, typename P1, typename P2, typename P3, typename P4,
    typename P5>
internal::InvokerStorageHolder<internal::InvokerStorage5<Sig,P1, P2, P3, P4,
    P5> >
Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
    const P5& p5) {
  return internal::MakeInvokerStorageHolder(
      new internal::InvokerStorage5<Sig, P1, P2, P3, P4, P5>(
          f, p1, p2, p3, p4, p5));
}

template <typename Sig, typename P1, typename P2, typename P3, typename P4,
    typename P5, typename P6>
internal::InvokerStorageHolder<internal::InvokerStorage6<Sig,P1, P2, P3, P4,
    P5, P6> >
Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
    const P5& p5, const P6& p6) {
  return internal::MakeInvokerStorageHolder(
      new internal::InvokerStorage6<Sig, P1, P2, P3, P4, P5, P6>(
          f, p1, p2, p3, p4, p5, p6));
}

// Specializations to allow binding all the free arguments in a
// pre-existing base::Callback<>. This does not give full support for
// currying, but is significantly simpler and addresses the use case
// where a base::Callback<> needs to be invoked on another context/thread.
template <typename Sig, typename P1>
base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1) {
  return base::Bind(&internal::BindMoreFunc1<Sig, P1>, callback, p1);
}

template <typename Sig, typename P1, typename P2>
base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
    const P2& p2) {
  return base::Bind(&internal::BindMoreFunc2<Sig, P1, P2>, callback, p1, p2);
}

template <typename Sig, typename P1, typename P2, typename P3>
base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
    const P2& p2, const P3& p3) {
  return base::Bind(&internal::BindMoreFunc3<Sig, P1, P2, P3>, callback, p1,
      p2, p3);
}

template <typename Sig, typename P1, typename P2, typename P3, typename P4>
base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
    const P2& p2, const P3& p3, const P4& p4) {
  return base::Bind(&internal::BindMoreFunc4<Sig, P1, P2, P3, P4>, callback,
      p1, p2, p3, p4);
}

template <typename Sig, typename P1, typename P2, typename P3, typename P4,
    typename P5>
base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
    const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
  return base::Bind(&internal::BindMoreFunc5<Sig, P1, P2, P3, P4, P5>,
      callback, p1, p2, p3, p4, p5);
}

template <typename Sig, typename P1, typename P2, typename P3, typename P4,
    typename P5, typename P6>
base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
    const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
  return base::Bind(&internal::BindMoreFunc6<Sig, P1, P2, P3, P4, P5, P6>,
      callback, p1, p2, p3, p4, p5, p6);
}

}  // namespace base

#endif  // BASE_BIND_H_