summaryrefslogtreecommitdiffstats
path: root/google_apis/drive/task_util.h
blob: 358c280b469439603e9946615999e969e81376c0 (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
// Copyright (c) 2012 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 GOOGLE_APIS_DRIVE_TASK_UTIL_H_
#define GOOGLE_APIS_DRIVE_TASK_UTIL_H_

#include "base/bind.h"
#include "base/message_loop/message_loop_proxy.h"

namespace google_apis {

// Runs task on a thread on which |task_runner| may run tasks.
void RunTaskOnThread(scoped_refptr<base::SequencedTaskRunner> task_runner,
                     const base::Closure& task);

namespace internal {

// Implementation of the composed callback, whose signature is |Sig|.
template<typename Sig> struct ComposedCallback;

// ComposedCallback with no argument.
template<>
struct ComposedCallback<void()> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Closure& callback) {
    runner.Run(callback);
  }
};

// ComposedCallback with one argument.
template<typename T1>
struct ComposedCallback<void(T1)> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Callback<void(T1)>& callback,
      T1 arg1) {
    runner.Run(base::Bind(callback, arg1));
  }
};

// ComposedCallback with two arguments.
template<typename T1, typename T2>
struct ComposedCallback<void(T1, T2)> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Callback<void(T1, T2)>& callback,
      T1 arg1, T2 arg2) {
    runner.Run(base::Bind(callback, arg1, arg2));
  }
};

// ComposedCallback with two arguments, and the last one is scoped_ptr.
template<typename T1, typename T2, typename D2>
struct ComposedCallback<void(T1, scoped_ptr<T2, D2>)> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Callback<void(T1, scoped_ptr<T2, D2>)>& callback,
      T1 arg1, scoped_ptr<T2, D2> arg2) {
    runner.Run(base::Bind(callback, arg1, base::Passed(&arg2)));
  }
};

// ComposedCallback with three arguments.
template<typename T1, typename T2, typename T3>
struct ComposedCallback<void(T1, T2, T3)> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Callback<void(T1, T2, T3)>& callback,
      T1 arg1, T2 arg2, T3 arg3) {
    runner.Run(base::Bind(callback, arg1, arg2, arg3));
  }
};

// ComposedCallback with three arguments, and the last one is scoped_ptr.
template<typename T1, typename T2, typename T3, typename D3>
struct ComposedCallback<void(T1, T2, scoped_ptr<T3, D3>)> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Callback<void(T1, T2, scoped_ptr<T3, D3>)>& callback,
      T1 arg1, T2 arg2, scoped_ptr<T3, D3> arg3) {
    runner.Run(base::Bind(callback, arg1, arg2, base::Passed(&arg3)));
  }
};

// ComposedCallback with four arguments.
template<typename T1, typename T2, typename T3, typename T4>
struct ComposedCallback<void(T1, T2, T3, T4)> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Callback<void(T1, T2, T3, T4)>& callback,
      T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
    runner.Run(base::Bind(callback, arg1, arg2, arg3, arg4));
  }
};

// ComposedCallback with four arguments, and the second one is scoped_ptr.
template<typename T1, typename T2, typename D2, typename T3, typename T4>
struct ComposedCallback<void(T1, scoped_ptr<T2, D2>, T3, T4)> {
  static void Run(
      const base::Callback<void(const base::Closure&)>& runner,
      const base::Callback<void(T1, scoped_ptr<T2, D2>, T3, T4)>& callback,
      T1 arg1, scoped_ptr<T2, D2> arg2, T3 arg3, T4 arg4) {
    runner.Run(base::Bind(callback, arg1, base::Passed(&arg2), arg3, arg4));
  }
};

}  // namespace internal

// Returns callback that takes arguments (arg1, arg2, ...), create a closure
// by binding them to |callback|, and runs |runner| with the closure.
// I.e. the returned callback works as follows:
//   runner.Run(Bind(callback, arg1, arg2, ...))
template<typename CallbackType>
CallbackType CreateComposedCallback(
    const base::Callback<void(const base::Closure&)>& runner,
    const CallbackType& callback) {
  DCHECK(!runner.is_null());
  DCHECK(!callback.is_null());
  return base::Bind(
      &internal::ComposedCallback<typename CallbackType::RunType>::Run,
      runner, callback);
}

// Returns callback which runs the given |callback| on the current thread.
template<typename CallbackType>
CallbackType CreateRelayCallback(const CallbackType& callback) {
  return CreateComposedCallback(
      base::Bind(&RunTaskOnThread, base::MessageLoopProxy::current()),
      callback);
}

}  // namespace google_apis

#endif  // GOOGLE_APIS_DRIVE_TASK_UTIL_H_