| Index: gin/function_template.h
|
| diff --git a/gin/function_template.h b/gin/function_template.h
|
| index 7ba54b5910ef4ffcb032deba86a8490a0fba72ef..05ac4bde62f3af316bde306bc2d01a89b7deec47 100644
|
| --- a/gin/function_template.h
|
| +++ b/gin/function_template.h
|
| @@ -1,16 +1,10 @@
|
| -// This file was GENERATED by command:
|
| -// pump.py function_template.h.pump
|
| -// DO NOT EDIT BY HAND!!!
|
| -
|
| -
|
| +// Copyright 2014 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 GIN_FUNCTION_TEMPLATE_H_
|
| #define GIN_FUNCTION_TEMPLATE_H_
|
|
|
| -// Copyright 2013 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.
|
| -
|
| #include "base/callback.h"
|
| #include "base/logging.h"
|
| #include "gin/arguments.h"
|
| @@ -81,179 +75,32 @@ class CallbackHolder : public CallbackHolderBase {
|
| };
|
|
|
|
|
| -// This set of templates invokes a base::Callback, converts the return type to a
|
| +// This template struct invokes a base::Callback, converts the return type to a
|
| // JavaScript value, and returns that value to script via the provided
|
| // gin::Arguments object.
|
| -//
|
| -// In C++, you can declare the function foo(void), but you can't pass a void
|
| -// expression to foo. As a result, we must specialize the case of Callbacks that
|
| -// have the void return type.
|
| -template<typename R, typename P1 = void, typename P2 = void,
|
| - typename P3 = void, typename P4 = void, typename P5 = void,
|
| - typename P6 = void>
|
| +template <typename R, typename... A>
|
| struct Invoker {
|
| inline static void Go(
|
| Arguments* args,
|
| - const base::Callback<R(P1, P2, P3, P4, P5, P6)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3,
|
| - const P4& a4,
|
| - const P5& a5,
|
| - const P6& a6) {
|
| - args->Return(callback.Run(a1, a2, a3, a4, a5, a6));
|
| - }
|
| -};
|
| -template<typename P1, typename P2, typename P3, typename P4, typename P5,
|
| - typename P6>
|
| -struct Invoker<void, P1, P2, P3, P4, P5, P6> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<void(P1, P2, P3, P4, P5, P6)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3,
|
| - const P4& a4,
|
| - const P5& a5,
|
| - const P6& a6) {
|
| - callback.Run(a1, a2, a3, a4, a5, a6);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1, typename P2, typename P3, typename P4,
|
| - typename P5>
|
| -struct Invoker<R, P1, P2, P3, P4, P5, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<R(P1, P2, P3, P4, P5)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3,
|
| - const P4& a4,
|
| - const P5& a5) {
|
| - args->Return(callback.Run(a1, a2, a3, a4, a5));
|
| - }
|
| -};
|
| -template<typename P1, typename P2, typename P3, typename P4, typename P5>
|
| -struct Invoker<void, P1, P2, P3, P4, P5, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<void(P1, P2, P3, P4, P5)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3,
|
| - const P4& a4,
|
| - const P5& a5) {
|
| - callback.Run(a1, a2, a3, a4, a5);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1, typename P2, typename P3, typename P4>
|
| -struct Invoker<R, P1, P2, P3, P4, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<R(P1, P2, P3, P4)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3,
|
| - const P4& a4) {
|
| - args->Return(callback.Run(a1, a2, a3, a4));
|
| - }
|
| -};
|
| -template<typename P1, typename P2, typename P3, typename P4>
|
| -struct Invoker<void, P1, P2, P3, P4, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<void(P1, P2, P3, P4)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3,
|
| - const P4& a4) {
|
| - callback.Run(a1, a2, a3, a4);
|
| + const base::Callback<R(A...)>& callback,
|
| + const A&... a) {
|
| + args->Return(callback.Run(a...));
|
| }
|
| };
|
|
|
| -template<typename R, typename P1, typename P2, typename P3>
|
| -struct Invoker<R, P1, P2, P3, void, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<R(P1, P2, P3)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3) {
|
| - args->Return(callback.Run(a1, a2, a3));
|
| - }
|
| -};
|
| -template<typename P1, typename P2, typename P3>
|
| -struct Invoker<void, P1, P2, P3, void, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<void(P1, P2, P3)>& callback,
|
| - const P1& a1,
|
| - const P2& a2,
|
| - const P3& a3) {
|
| - callback.Run(a1, a2, a3);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1, typename P2>
|
| -struct Invoker<R, P1, P2, void, void, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<R(P1, P2)>& callback,
|
| - const P1& a1,
|
| - const P2& a2) {
|
| - args->Return(callback.Run(a1, a2));
|
| - }
|
| -};
|
| -template<typename P1, typename P2>
|
| -struct Invoker<void, P1, P2, void, void, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<void(P1, P2)>& callback,
|
| - const P1& a1,
|
| - const P2& a2) {
|
| - callback.Run(a1, a2);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1>
|
| -struct Invoker<R, P1, void, void, void, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<R(P1)>& callback,
|
| - const P1& a1) {
|
| - args->Return(callback.Run(a1));
|
| - }
|
| -};
|
| -template<typename P1>
|
| -struct Invoker<void, P1, void, void, void, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<void(P1)>& callback,
|
| - const P1& a1) {
|
| - callback.Run(a1);
|
| - }
|
| -};
|
| -
|
| -template<typename R>
|
| -struct Invoker<R, void, void, void, void, void, void> {
|
| - inline static void Go(
|
| - Arguments* args,
|
| - const base::Callback<R()>& callback) {
|
| - args->Return(callback.Run());
|
| - }
|
| -};
|
| -template<>
|
| -struct Invoker<void, void, void, void, void, void, void> {
|
| +// In C++, you can declare the function foo(void), but you can't pass a void
|
| +// expression to foo. As a result, we must specialize the case of Callbacks that
|
| +// have the void return type.
|
| +template <typename... A>
|
| +struct Invoker<void, A...> {
|
| inline static void Go(
|
| Arguments* args,
|
| - const base::Callback<void()>& callback) {
|
| - callback.Run();
|
| + const base::Callback<void(A...)>& callback,
|
| + const A&... a) {
|
| + callback.Run(a...);
|
| }
|
| };
|
|
|
| -
|
| template<typename T>
|
| bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
|
| T* result) {
|
| @@ -291,130 +138,12 @@ template<typename Sig>
|
| struct Dispatcher {
|
| };
|
|
|
| -template<typename R>
|
| -struct Dispatcher<R()> {
|
| - static void DispatchToCallback(
|
| - const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| - Arguments args(info);
|
| - v8::Handle<v8::External> v8_holder;
|
| - CHECK(args.GetData(&v8_holder));
|
| - CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
| - v8_holder->Value());
|
| -
|
| - typedef CallbackHolder<R()> HolderT;
|
| - HolderT* holder = static_cast<HolderT*>(holder_base);
|
| -
|
| - Invoker<R>::Go(&args, holder->callback);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1>
|
| -struct Dispatcher<R(P1)> {
|
| - static void DispatchToCallback(
|
| - const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| - Arguments args(info);
|
| - v8::Handle<v8::External> v8_holder;
|
| - CHECK(args.GetData(&v8_holder));
|
| - CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
| - v8_holder->Value());
|
| -
|
| - typedef CallbackHolder<R(P1)> HolderT;
|
| - HolderT* holder = static_cast<HolderT*>(holder_base);
|
| -
|
| - typename CallbackParamTraits<P1>::LocalType a1;
|
| - if (!GetNextArgument(&args, holder->flags, true, &a1)) {
|
| - args.ThrowError();
|
| - return;
|
| - }
|
| -
|
| - Invoker<R, P1>::Go(&args, holder->callback, a1);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1, typename P2>
|
| -struct Dispatcher<R(P1, P2)> {
|
| - static void DispatchToCallback(
|
| - const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| - Arguments args(info);
|
| - v8::Handle<v8::External> v8_holder;
|
| - CHECK(args.GetData(&v8_holder));
|
| - CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
| - v8_holder->Value());
|
| -
|
| - typedef CallbackHolder<R(P1, P2)> HolderT;
|
| - HolderT* holder = static_cast<HolderT*>(holder_base);
|
| -
|
| - typename CallbackParamTraits<P1>::LocalType a1;
|
| - typename CallbackParamTraits<P2>::LocalType a2;
|
| - if (!GetNextArgument(&args, holder->flags, true, &a1) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a2)) {
|
| - args.ThrowError();
|
| - return;
|
| - }
|
| -
|
| - Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1, typename P2, typename P3>
|
| -struct Dispatcher<R(P1, P2, P3)> {
|
| - static void DispatchToCallback(
|
| - const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| - Arguments args(info);
|
| - v8::Handle<v8::External> v8_holder;
|
| - CHECK(args.GetData(&v8_holder));
|
| - CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
| - v8_holder->Value());
|
| -
|
| - typedef CallbackHolder<R(P1, P2, P3)> HolderT;
|
| - HolderT* holder = static_cast<HolderT*>(holder_base);
|
| -
|
| - typename CallbackParamTraits<P1>::LocalType a1;
|
| - typename CallbackParamTraits<P2>::LocalType a2;
|
| - typename CallbackParamTraits<P3>::LocalType a3;
|
| - if (!GetNextArgument(&args, holder->flags, true, &a1) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a2) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a3)) {
|
| - args.ThrowError();
|
| - return;
|
| - }
|
| -
|
| - Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
|
| - }
|
| -};
|
| -
|
| -template<typename R, typename P1, typename P2, typename P3, typename P4>
|
| -struct Dispatcher<R(P1, P2, P3, P4)> {
|
| - static void DispatchToCallback(
|
| - const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| - Arguments args(info);
|
| - v8::Handle<v8::External> v8_holder;
|
| - CHECK(args.GetData(&v8_holder));
|
| - CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
| - v8_holder->Value());
|
| -
|
| - typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
|
| - HolderT* holder = static_cast<HolderT*>(holder_base);
|
| -
|
| - typename CallbackParamTraits<P1>::LocalType a1;
|
| - typename CallbackParamTraits<P2>::LocalType a2;
|
| - typename CallbackParamTraits<P3>::LocalType a3;
|
| - typename CallbackParamTraits<P4>::LocalType a4;
|
| - if (!GetNextArgument(&args, holder->flags, true, &a1) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a2) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a3) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a4)) {
|
| - args.ThrowError();
|
| - return;
|
| - }
|
| -
|
| - Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
|
| - }
|
| -};
|
| +template <typename R, typename... A>
|
| +class Dispatcher<R(A...)> {
|
| + public:
|
| + template <typename T>
|
| + struct TypeTag {};
|
|
|
| -template<typename R, typename P1, typename P2, typename P3, typename P4,
|
| - typename P5>
|
| -struct Dispatcher<R(P1, P2, P3, P4, P5)> {
|
| static void DispatchToCallback(
|
| const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| Arguments args(info);
|
| @@ -423,61 +152,44 @@ struct Dispatcher<R(P1, P2, P3, P4, P5)> {
|
| CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
| v8_holder->Value());
|
|
|
| - typedef CallbackHolder<R(P1, P2, P3, P4, P5)> HolderT;
|
| + typedef CallbackHolder<R(A...)> HolderT;
|
| HolderT* holder = static_cast<HolderT*>(holder_base);
|
| -
|
| - typename CallbackParamTraits<P1>::LocalType a1;
|
| - typename CallbackParamTraits<P2>::LocalType a2;
|
| - typename CallbackParamTraits<P3>::LocalType a3;
|
| - typename CallbackParamTraits<P4>::LocalType a4;
|
| - typename CallbackParamTraits<P5>::LocalType a5;
|
| - if (!GetNextArgument(&args, holder->flags, true, &a1) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a2) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a3) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a4) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a5)) {
|
| - args.ThrowError();
|
| - return;
|
| - }
|
| -
|
| - Invoker<R, P1, P2, P3, P4, P5>::Go(&args, holder->callback, a1, a2, a3, a4,
|
| - a5);
|
| + bool all_arguments_ok = true;
|
| + bool is_first_argument = true;
|
| + InvokeCallback{
|
| + &all_arguments_ok, &args, holder->callback,
|
| + PassNextArgument(
|
| + &all_arguments_ok, &is_first_argument,
|
| + &args, holder->flags,
|
| + TypeTag<typename CallbackParamTraits<A>::LocalType>())...};
|
| }
|
| -};
|
|
|
| -template<typename R, typename P1, typename P2, typename P3, typename P4,
|
| - typename P5, typename P6>
|
| -struct Dispatcher<R(P1, P2, P3, P4, P5, P6)> {
|
| - static void DispatchToCallback(
|
| - const v8::FunctionCallbackInfo<v8::Value>& info) {
|
| - Arguments args(info);
|
| - v8::Handle<v8::External> v8_holder;
|
| - CHECK(args.GetData(&v8_holder));
|
| - CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
|
| - v8_holder->Value());
|
| -
|
| - typedef CallbackHolder<R(P1, P2, P3, P4, P5, P6)> HolderT;
|
| - HolderT* holder = static_cast<HolderT*>(holder_base);
|
| -
|
| - typename CallbackParamTraits<P1>::LocalType a1;
|
| - typename CallbackParamTraits<P2>::LocalType a2;
|
| - typename CallbackParamTraits<P3>::LocalType a3;
|
| - typename CallbackParamTraits<P4>::LocalType a4;
|
| - typename CallbackParamTraits<P5>::LocalType a5;
|
| - typename CallbackParamTraits<P6>::LocalType a6;
|
| - if (!GetNextArgument(&args, holder->flags, true, &a1) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a2) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a3) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a4) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a5) ||
|
| - !GetNextArgument(&args, holder->flags, false, &a6)) {
|
| - args.ThrowError();
|
| - return;
|
| + private:
|
| + template <typename T>
|
| + static T PassNextArgument(bool* all_arguments_ok, bool* is_first,
|
| + Arguments* args, int create_flags, TypeTag<T>) {
|
| + // Short-circuit if getting some previous argument has already failed:
|
| + if (!*all_arguments_ok)
|
| + return T();
|
| +
|
| + T value = T();
|
| + *all_arguments_ok = GetNextArgument(args, create_flags, *is_first, &value);
|
| + *is_first = false;
|
| + return value;
|
| + }
|
| +
|
| + struct InvokeCallback {
|
| + InvokeCallback(bool* all_arguments_ok, Arguments* args,
|
| + const base::Callback<R(A...)>& callback,
|
| + const A&... actual_args) {
|
| + if (!*all_arguments_ok) {;
|
| + args->ThrowError();
|
| + return;
|
| + }
|
| +
|
| + Invoker<R, A...>::Go(args, callback, actual_args...);
|
| }
|
| -
|
| - Invoker<R, P1, P2, P3, P4, P5, P6>::Go(&args, holder->callback, a1, a2, a3,
|
| - a4, a5, a6);
|
| - }
|
| + };
|
| };
|
|
|
| } // namespace internal
|
|
|