1// This file was GENERATED by command:
2//     pump.py callback_helper.h.pump
3// DO NOT EDIT BY HAND!!!
4
5
6// Copyright 2014 The Chromium Authors. All rights reserved.
7// Use of this source code is governed by a BSD-style license that can be
8// found in the LICENSE file.
9
10#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_HELPER_H_
11#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_HELPER_H_
12
13#include "base/bind.h"
14#include "base/location.h"
15#include "base/logging.h"
16#include "base/sequenced_task_runner.h"
17#include "base/thread_task_runner_handle.h"
18
19// TODO(tzik): Merge this file to media/base/bind_to_current_loop.h.
20
21namespace sync_file_system {
22namespace drive_backend {
23
24namespace internal {
25
26template <typename T>
27typename base::enable_if<
28    base::internal::IsMoveOnlyType<T>::value,
29    base::internal::PassedWrapper<T> >::type
30RebindForward(T& t) {
31  return base::Passed(&t);
32}
33
34template <typename T>
35typename base::enable_if<
36    !base::internal::IsMoveOnlyType<T>::value,
37    T&>::type
38RebindForward(T& t) {
39  return t;
40}
41
42template <typename T>
43class CallbackHolder {
44 public:
45  CallbackHolder(const scoped_refptr<base::SequencedTaskRunner>& task_runner,
46                 const tracked_objects::Location& from_here,
47                 const base::Callback<T>& callback)
48      : task_runner_(task_runner),
49        from_here_(from_here),
50        callback_(new base::Callback<T>(callback)) {
51    DCHECK(task_runner_.get());
52  }
53
54  ~CallbackHolder() {
55    base::Callback<T>* callback = callback_.release();
56    if (!task_runner_->DeleteSoon(from_here_, callback))
57      delete callback;
58  }
59
60  base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }
61  const tracked_objects::Location& from_here() const { return from_here_; }
62  const base::Callback<T>& callback() const { return *callback_; }
63
64 private:
65  scoped_refptr<base::SequencedTaskRunner> task_runner_;
66  const tracked_objects::Location from_here_;
67  scoped_ptr<base::Callback<T> > callback_;
68
69  DISALLOW_COPY_AND_ASSIGN(CallbackHolder);
70};
71
72template <typename>
73struct RelayToTaskRunnerHelper;
74
75template <>
76struct RelayToTaskRunnerHelper<void()> {
77  static void Run(CallbackHolder<void()>* holder) {
78    holder->task_runner()->PostTask(
79        holder->from_here(), base::Bind(holder->callback()));
80  }
81};
82
83template <typename A1>
84struct RelayToTaskRunnerHelper<void(A1)> {
85  static void Run(CallbackHolder<void(A1)>* holder, A1 a1) {
86    holder->task_runner()->PostTask(
87        holder->from_here(), base::Bind(holder->callback(), RebindForward(a1)));
88  }
89};
90
91template <typename A1, typename A2>
92struct RelayToTaskRunnerHelper<void(A1, A2)> {
93  static void Run(CallbackHolder<void(A1, A2)>* holder, A1 a1, A2 a2) {
94    holder->task_runner()->PostTask(
95        holder->from_here(), base::Bind(holder->callback(), RebindForward(a1),
96            RebindForward(a2)));
97  }
98};
99
100template <typename A1, typename A2, typename A3>
101struct RelayToTaskRunnerHelper<void(A1, A2, A3)> {
102  static void Run(CallbackHolder<void(A1, A2, A3)>* holder, A1 a1, A2 a2,
103      A3 a3) {
104    holder->task_runner()->PostTask(
105        holder->from_here(), base::Bind(holder->callback(), RebindForward(a1),
106            RebindForward(a2), RebindForward(a3)));
107  }
108};
109
110template <typename A1, typename A2, typename A3, typename A4>
111struct RelayToTaskRunnerHelper<void(A1, A2, A3, A4)> {
112  static void Run(CallbackHolder<void(A1, A2, A3, A4)>* holder, A1 a1, A2 a2,
113      A3 a3, A4 a4) {
114    holder->task_runner()->PostTask(
115        holder->from_here(), base::Bind(holder->callback(), RebindForward(a1),
116            RebindForward(a2), RebindForward(a3), RebindForward(a4)));
117  }
118};
119
120template <typename A1, typename A2, typename A3, typename A4, typename A5>
121struct RelayToTaskRunnerHelper<void(A1, A2, A3, A4, A5)> {
122  static void Run(CallbackHolder<void(A1, A2, A3, A4, A5)>* holder, A1 a1,
123      A2 a2, A3 a3, A4 a4, A5 a5) {
124    holder->task_runner()->PostTask(
125        holder->from_here(), base::Bind(holder->callback(), RebindForward(a1),
126            RebindForward(a2), RebindForward(a3), RebindForward(a4),
127            RebindForward(a5)));
128  }
129};
130
131template <typename A1, typename A2, typename A3, typename A4, typename A5,
132    typename A6>
133struct RelayToTaskRunnerHelper<void(A1, A2, A3, A4, A5, A6)> {
134  static void Run(CallbackHolder<void(A1, A2, A3, A4, A5, A6)>* holder, A1 a1,
135      A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
136    holder->task_runner()->PostTask(
137        holder->from_here(), base::Bind(holder->callback(), RebindForward(a1),
138            RebindForward(a2), RebindForward(a3), RebindForward(a4),
139            RebindForward(a5), RebindForward(a6)));
140  }
141};
142
143template <typename A1, typename A2, typename A3, typename A4, typename A5,
144    typename A6, typename A7>
145struct RelayToTaskRunnerHelper<void(A1, A2, A3, A4, A5, A6, A7)> {
146  static void Run(CallbackHolder<void(A1, A2, A3, A4, A5, A6, A7)>* holder,
147      A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
148    holder->task_runner()->PostTask(
149        holder->from_here(), base::Bind(holder->callback(), RebindForward(a1),
150            RebindForward(a2), RebindForward(a3), RebindForward(a4),
151            RebindForward(a5), RebindForward(a6), RebindForward(a7)));
152  }
153};
154
155}  // namespace internal
156
157template <typename T>
158base::Callback<T> RelayCallbackToTaskRunner(
159    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
160    const tracked_objects::Location& from_here,
161    const base::Callback<T>& callback) {
162  DCHECK(task_runner->RunsTasksOnCurrentThread());
163
164  if (callback.is_null())
165    return base::Callback<T>();
166
167  return base::Bind(&internal::RelayToTaskRunnerHelper<T>::Run,
168                    base::Owned(new internal::CallbackHolder<T>(
169                        task_runner, from_here, callback)));
170}
171
172template <typename T>
173base::Callback<T> RelayCallbackToCurrentThread(
174    const tracked_objects::Location& from_here,
175    const base::Callback<T>& callback) {
176  return RelayCallbackToTaskRunner(
177      base::ThreadTaskRunnerHandle::Get(),
178      from_here, callback);
179}
180
181}  // namespace drive_backend
182}  // namespace sync_file_system
183
184#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_HELPER_H_
185