diff options
author | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-27 01:25:59 +0000 |
---|---|---|
committer | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-27 01:25:59 +0000 |
commit | 054ac754be8bcdecd3f1a39a085f01ef5c5d379a (patch) | |
tree | e713bfa32a32f74e3bb7d93af58e08ced826c075 /base | |
parent | 8cf26423f5e01f1e25b66b126f9bf102b726b8ba (diff) | |
download | chromium_src-054ac754be8bcdecd3f1a39a085f01ef5c5d379a.zip chromium_src-054ac754be8bcdecd3f1a39a085f01ef5c5d379a.tar.gz chromium_src-054ac754be8bcdecd3f1a39a085f01ef5c5d379a.tar.bz2 |
Callback support for __fastcall and __stdcall functions.
Create FunctionTraits specializations that can unwrap function pointers that
are delcared with __fastcall and __stdcall on windows.
Only include these in the Windows build.
BUG=35223
TEST=new unittests
Review URL: http://codereview.chromium.org/6561004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76174 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gypi | 1 | ||||
-rw-r--r-- | base/bind_internal.h | 47 | ||||
-rw-r--r-- | base/bind_internal.h.pump | 11 | ||||
-rw-r--r-- | base/bind_internal_win.h | 128 | ||||
-rw-r--r-- | base/bind_internal_win.h.pump | 52 | ||||
-rw-r--r-- | base/bind_unittest.cc | 21 |
6 files changed, 236 insertions, 24 deletions
diff --git a/base/base.gypi b/base/base.gypi index 13cb1ba..508c4a4 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -39,6 +39,7 @@ 'bind.h', 'bind_helpers.h', 'bind_internal.h', + 'bind_internal_win.h', 'bits.h', 'bzip2_error_handler.cc', 'callback.h', diff --git a/base/bind_internal.h b/base/bind_internal.h index fe3764b..bb5f46f 100644 --- a/base/bind_internal.h +++ b/base/bind_internal.h @@ -14,6 +14,11 @@ #include "base/bind_helpers.h" #include "base/callback_internal.h" #include "base/template_util.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "base/bind_internal_win.h" +#endif namespace base { namespace internal { @@ -67,91 +72,91 @@ struct FunctionTraits; template <typename R> struct FunctionTraits<R(*)()> { typedef R (*NormalizedSig)(); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity 0. template <typename R, typename T> struct FunctionTraits<R(T::*)()> { typedef R (T::*NormalizedSig)(); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity 0. template <typename R, typename T> struct FunctionTraits<R(T::*)() const> { typedef R (T::*NormalizedSig)(); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Function: Arity 1. template <typename R, typename X1> struct FunctionTraits<R(*)(X1)> { typedef R (*NormalizedSig)(X1); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity 1. template <typename R, typename T, typename X1> struct FunctionTraits<R(T::*)(X1)> { typedef R (T::*NormalizedSig)(X1); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity 1. template <typename R, typename T, typename X1> struct FunctionTraits<R(T::*)(X1) const> { typedef R (T::*NormalizedSig)(X1); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Function: Arity 2. template <typename R, typename X1, typename X2> struct FunctionTraits<R(*)(X1, X2)> { typedef R (*NormalizedSig)(X1, X2); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity 2. template <typename R, typename T, typename X1, typename X2> struct FunctionTraits<R(T::*)(X1, X2)> { typedef R (T::*NormalizedSig)(X1, X2); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity 2. template <typename R, typename T, typename X1, typename X2> struct FunctionTraits<R(T::*)(X1, X2) const> { typedef R (T::*NormalizedSig)(X1, X2); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Function: Arity 3. template <typename R, typename X1, typename X2, typename X3> struct FunctionTraits<R(*)(X1, X2, X3)> { typedef R (*NormalizedSig)(X1, X2, X3); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity 3. template <typename R, typename T, typename X1, typename X2, typename X3> struct FunctionTraits<R(T::*)(X1, X2, X3)> { typedef R (T::*NormalizedSig)(X1, X2, X3); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity 3. template <typename R, typename T, typename X1, typename X2, typename X3> struct FunctionTraits<R(T::*)(X1, X2, X3) const> { typedef R (T::*NormalizedSig)(X1, X2, X3); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Function: Arity 4. template <typename R, typename X1, typename X2, typename X3, typename X4> struct FunctionTraits<R(*)(X1, X2, X3, X4)> { typedef R (*NormalizedSig)(X1, X2, X3, X4); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity 4. @@ -159,7 +164,7 @@ template <typename R, typename T, typename X1, typename X2, typename X3, typename X4> struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> { typedef R (T::*NormalizedSig)(X1, X2, X3, X4); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity 4. @@ -167,7 +172,7 @@ template <typename R, typename T, typename X1, typename X2, typename X3, typename X4> struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> { typedef R (T::*NormalizedSig)(X1, X2, X3, X4); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Function: Arity 5. @@ -175,7 +180,7 @@ template <typename R, typename X1, typename X2, typename X3, typename X4, typename X5> struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> { typedef R (*NormalizedSig)(X1, X2, X3, X4, X5); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity 5. @@ -183,7 +188,7 @@ template <typename R, typename T, typename X1, typename X2, typename X3, typename X4, typename X5> struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> { typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity 5. @@ -191,7 +196,7 @@ template <typename R, typename T, typename X1, typename X2, typename X3, typename X4, typename X5> struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> { typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Function: Arity 6. @@ -199,7 +204,7 @@ template <typename R, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6> struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> { typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity 6. @@ -207,7 +212,7 @@ template <typename R, typename T, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6> struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> { typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity 6. @@ -215,7 +220,7 @@ template <typename R, typename T, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6> struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> { typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // InvokerN<> diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump index b1ba2d7..84fb2ef 100644 --- a/base/bind_internal.h.pump +++ b/base/bind_internal.h.pump @@ -18,6 +18,11 @@ $var MAX_ARITY = 6 #include "base/bind_helpers.h" #include "base/callback_internal.h" #include "base/template_util.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "base/bind_internal_win.h" +#endif namespace base { namespace internal { @@ -76,7 +81,7 @@ template <typename R[[]] $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> { typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]); - typedef base::false_type IsMethod; + typedef false_type IsMethod; }; // Method: Arity $(ARITY). @@ -84,7 +89,7 @@ template <typename R, typename T[[]] $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> { typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; // Const Method: Arity $(ARITY). @@ -92,7 +97,7 @@ template <typename R, typename T[[]] $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> { typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); - typedef base::true_type IsMethod; + typedef true_type IsMethod; }; ]] $$for ARITY diff --git a/base/bind_internal_win.h b/base/bind_internal_win.h new file mode 100644 index 0000000..dab8d51 --- /dev/null +++ b/base/bind_internal_win.h @@ -0,0 +1,128 @@ +// This file was GENERATED by command: +// pump.py bind_internal_win.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. + +// Specializations of FunctionTraits<> for Windows specific calling +// conventions. Please see base/bind_internal.h for more info. + +#ifndef BASE_BIND_INTERNAL_WIN_H_ +#define BASE_BIND_INTERNAL_WIN_H_ +#pragma once + +namespace base { +namespace internal { + +template <typename Sig> +struct FunctionTraits; + +// __stdcall Function: Arity 0. +template <typename R> +struct FunctionTraits<R(__stdcall *)()> { + typedef R (*NormalizedSig)(); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity 0. +template <typename R> +struct FunctionTraits<R(__fastcall *)()> { + typedef R (*NormalizedSig)(); + typedef false_type IsMethod; +}; + +// __stdcall Function: Arity 1. +template <typename R, typename X1> +struct FunctionTraits<R(__stdcall *)(X1)> { + typedef R (*NormalizedSig)(X1); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity 1. +template <typename R, typename X1> +struct FunctionTraits<R(__fastcall *)(X1)> { + typedef R (*NormalizedSig)(X1); + typedef false_type IsMethod; +}; + +// __stdcall Function: Arity 2. +template <typename R, typename X1, typename X2> +struct FunctionTraits<R(__stdcall *)(X1, X2)> { + typedef R (*NormalizedSig)(X1, X2); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity 2. +template <typename R, typename X1, typename X2> +struct FunctionTraits<R(__fastcall *)(X1, X2)> { + typedef R (*NormalizedSig)(X1, X2); + typedef false_type IsMethod; +}; + +// __stdcall Function: Arity 3. +template <typename R, typename X1, typename X2, typename X3> +struct FunctionTraits<R(__stdcall *)(X1, X2, X3)> { + typedef R (*NormalizedSig)(X1, X2, X3); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity 3. +template <typename R, typename X1, typename X2, typename X3> +struct FunctionTraits<R(__fastcall *)(X1, X2, X3)> { + typedef R (*NormalizedSig)(X1, X2, X3); + typedef false_type IsMethod; +}; + +// __stdcall Function: Arity 4. +template <typename R, typename X1, typename X2, typename X3, typename X4> +struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4)> { + typedef R (*NormalizedSig)(X1, X2, X3, X4); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity 4. +template <typename R, typename X1, typename X2, typename X3, typename X4> +struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4)> { + typedef R (*NormalizedSig)(X1, X2, X3, X4); + typedef false_type IsMethod; +}; + +// __stdcall Function: Arity 5. +template <typename R, typename X1, typename X2, typename X3, typename X4, + typename X5> +struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5)> { + typedef R (*NormalizedSig)(X1, X2, X3, X4, X5); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity 5. +template <typename R, typename X1, typename X2, typename X3, typename X4, + typename X5> +struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5)> { + typedef R (*NormalizedSig)(X1, X2, X3, X4, X5); + typedef false_type IsMethod; +}; + +// __stdcall Function: Arity 6. +template <typename R, typename X1, typename X2, typename X3, typename X4, + typename X5, typename X6> +struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5, X6)> { + typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity 6. +template <typename R, typename X1, typename X2, typename X3, typename X4, + typename X5, typename X6> +struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5, X6)> { + typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6); + typedef false_type IsMethod; +}; + +} // namespace internal +} // namespace base + +#endif // BASE_BIND_INTERNAL_WIN_H_ diff --git a/base/bind_internal_win.h.pump b/base/bind_internal_win.h.pump new file mode 100644 index 0000000..4d213a3 --- /dev/null +++ b/base/bind_internal_win.h.pump @@ -0,0 +1,52 @@ +$$ This is a pump file for generating file templates. Pump is a python +$$ script that is part of the Google Test suite of utilities. Description +$$ can be found here: +$$ +$$ http://code.google.com/p/googletest/wiki/PumpManual +$$ + +$var MAX_ARITY = 6 + +// 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. + +// Specializations of FunctionTraits<> for Windows specific calling +// conventions. Please see base/bind_internal.h for more info. + +#ifndef BASE_BIND_INTERNAL_WIN_H_ +#define BASE_BIND_INTERNAL_WIN_H_ +#pragma once + +namespace base { +namespace internal { + +template <typename Sig> +struct FunctionTraits; + +$range ARITY 0..MAX_ARITY +$for ARITY [[ +$range ARG 1..ARITY + +// __stdcall Function: Arity $(ARITY). +template <typename R[[]] +$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> +struct FunctionTraits<R(__stdcall *)($for ARG , [[X$(ARG)]])> { + typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]); + typedef false_type IsMethod; +}; + +// __fastcall Function: Arity $(ARITY). +template <typename R[[]] +$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> +struct FunctionTraits<R(__fastcall *)($for ARG , [[X$(ARG)]])> { + typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]); + typedef false_type IsMethod; +}; + +]] $$for ARITY + +} // namespace internal +} // namespace base + +#endif // BASE_BIND_INTERNAL_WIN_H_ diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc index 77eb98a..061808b 100644 --- a/base/bind_unittest.cc +++ b/base/bind_unittest.cc @@ -581,5 +581,26 @@ TEST_F(BindTest, NoCompile) { } +#if defined(OS_WIN) +int __fastcall FastCallFunc(int n) { + return n; +} + +int __stdcall StdCallFunc(int n) { + return n; +} + +// Windows specific calling convention support. +// - Can bind a __fastcall function. +// - Can bind a __stdcall function. +TEST_F(BindTest, WindowsCallingConventions) { + Callback<int(void)> fastcall_cb = Bind(&FastCallFunc, 1); + EXPECT_EQ(1, fastcall_cb.Run()); + + Callback<int(void)> stdcall_cb = Bind(&StdCallFunc, 2); + EXPECT_EQ(2, stdcall_cb.Run()); +} +#endif + } // namespace } // namespace base |