/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ // Copyright (c) 2006-2008 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.
// Helper functions so that we can call a function a pass it arguments that come // from a Tuple.
namespace details {
// Call the given method on the given object. Arguments are passed by move // semantics from the given tuple. If the tuple has length N, the sequence must // be IndexSequence<0, 1, ..., N-1>. template <size_t... Indices, class ObjT, class Method, typename... Args> void CallMethod(std::index_sequence<Indices...>, ObjT* obj, Method method,
std::tuple<Args...>& arg) {
(obj->*method)(std::move(std::get<Indices>(arg))...);
}
// Same as above, but call a function. template <size_t... Indices, typename Function, typename... Args> void CallFunction(std::index_sequence<Indices...>, Function function,
std::tuple<Args...>& arg) {
(*function)(std::move(std::get<Indices>(arg))...);
}
} // namespace details
// Call a method on the given object. Arguments are passed by move semantics // from the given tuple. template <class ObjT, class Method, typename... Args> void DispatchTupleToMethod(ObjT* obj, Method method, std::tuple<Args...>& arg) {
details::CallMethod(std::index_sequence_for<Args...>{}, obj, method, arg);
}
// Same as above, but call a function. template <typename Function, typename... Args> void DispatchTupleToFunction(Function function, std::tuple<Args...>& arg) {
details::CallFunction(std::index_sequence_for<Args...>{}, function, arg);
}
// General task implementations ------------------------------------------------
private:
T* MOZ_UNSAFE_REF( "The validity of this pointer must be enforced by " "external factors.") obj_;
};
// RunnableMethodTraits -------------------------------------------------------- // // This traits-class is used by RunnableMethod to manage the lifetime of the // callee object. By default, it is assumed that the callee supports AddRef // and Release methods. A particular class can specialize this template to // define other lifetime management. For example, if the callee is known to // live longer than the RunnableMethod object, then a RunnableMethodTraits // struct could be defined with empty RetainCallee and ReleaseCallee methods.
// This allows using the NewRunnableMethod() functions with a const pointer // to the callee object. See the similar support in nsRefPtr for a rationale // of why this is reasonable. template <class T> struct RunnableMethodTraits<const T> { staticvoid RetainCallee(const T* obj) { const_cast<T*>(obj)->AddRef(); } staticvoid ReleaseCallee(const T* obj) { const_cast<T*>(obj)->Release(); }
};
// RunnableMethod and RunnableFunction ----------------------------------------- // // Runnable methods are a type of task that call a function on an object when // they are run. We implement both an object and a set of NewRunnableMethod and // NewRunnableFunction functions for convenience. These functions are // overloaded and will infer the template types, simplifying calling code. // // The template definitions all use the following names: // T - the class type of the object you're supplying // this is not needed for the Static version of the call // Method/Function - the signature of a pointer to the method or function you // want to call // Param - the parameter(s) to the method, possibly packed as a Tuple // A - the first parameter (if any) to the method // B - the second parameter (if any) to the mathod // // Put these all together and you get an object that can call a method whose // signature is: // R T::MyFunction([A[, B]]) // // Usage: // PostTask(NewRunnableMethod(object, &Object::method[, a[, b]]) // PostTask(NewRunnableFunction(&function[, a[, b]])
// RunnableMethod and NewRunnableMethod implementation -------------------------
template <class T, class Method, class Params> class RunnableMethod : public mozilla::CancelableRunnable, public RunnableMethodTraits<T> { public:
RunnableMethod(T* obj, Method meth, Params&& params)
: mozilla::CancelableRunnable("RunnableMethod"),
obj_(obj),
meth_(meth),
params_(std::forward<Params>(params)) {
this->RetainCallee(obj_);
}
~RunnableMethod() { ReleaseCallee(); }
// This is owning because of the RetainCallee and ReleaseCallee calls in the // constructor and destructor.
T* MOZ_OWNING_REF obj_;
Method meth_;
Params params_;
};
namespace dont_add_new_uses_of_this {
// Don't add new uses of this!!!! template <class T, class Method, typename... Args> inline already_AddRefed<mozilla::Runnable> NewRunnableMethod(T* object,
Method method,
Args&&... args) { typedef std::tuple<std::decay_t<Args>...> ArgsTuple;
RefPtr<mozilla::Runnable> t = new RunnableMethod<T, Method, ArgsTuple>(
object, method, std::make_tuple(std::forward<Args>(args)...)); return t.forget();
}
} // namespace dont_add_new_uses_of_this
// RunnableFunction and NewRunnableFunction implementation ---------------------
template <class Function, class Params> class RunnableFunction : public mozilla::CancelableRunnable { public:
RunnableFunction(constchar* name, Function function, Params&& params)
: mozilla::CancelableRunnable(name),
function_(function),
params_(std::forward<Params>(params)) {}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.