Index: base/prebind.h.pump |
diff --git a/base/prebind.h.pump b/base/prebind.h.pump |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cfb27dbd08362bf5030c8d7f0720c334e52de7a8 |
--- /dev/null |
+++ b/base/prebind.h.pump |
@@ -0,0 +1,225 @@ |
+$$ 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 |
+$$ |
+// 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. |
+ |
+#ifndef BASE_PREBIND_H_ |
+#define BASE_PREBIND_H_ |
+ |
+#include "base/uber_callback.h" |
+ |
+namespace base { |
+ |
+namespace internal { |
+// These classes are argument wrappers that affect the refcounting, and storage |
+// semantics for prebound arguments. |
+ |
+template <typename T> |
+class UnretainedWrapper { |
+ public: |
+ explicit UnretainedWrapper(T* o) : obj_(o) {} |
+ T* get() { return obj_; } |
+ private: |
+ T* obj_; |
+}; |
+ |
+template <typename T> |
+class ConstRefWrapper { |
+ public: |
+ explicit ConstRefWrapper(const T& o) : ptr_(&o) {} |
+ const T* get() { return ptr_; } |
+ private: |
+ const T* ptr_; |
+}; |
+ |
+// Unwrap for the wrappers above. |
+template <typename T> |
+T Unwrap(T o) { return o; } |
+ |
+template <typename T> |
+T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); } |
+ |
+template <typename T> |
+const T* Unwrap(ConstRefWrapper<T> const_ref) { return const_ref.get(); } |
+ |
+// Optional Refcounting. |
+ |
+template <bool ref, typename O> |
+struct MaybeRefcount; |
+ |
+template <typename O> |
+struct MaybeRefcount<false, O> { |
+ static void AddRef(const O&) {} |
+ static void Release(const O&) {} |
+}; |
+ |
+template <typename O> |
+struct MaybeRefcount<true, UnretainedWrapper<O> > { |
+ static void AddRef(const UnretainedWrapper<O>&) {} |
+ static void Release(const UnretainedWrapper<O>&) {} |
+}; |
+ |
+template <typename O> |
+struct MaybeRefcount<true, ConstRefWrapper<O> > { |
+ static void AddRef(ConstRefWrapper<O> o) { o.get()->AddRef(); } |
+ static void Release(ConstRefWrapper<O> o) { o.get()->Release(); } |
+}; |
+ |
+template <typename O> |
+struct MaybeRefcount<true, O* > { |
+ static void AddRef(O* o) { o->AddRef(); } |
+ static void Release(O* o) { o->Release(); } |
+}; |
+ |
+// The method by which a function is invoked is determined by 3 different |
+// dimensions: |
+// |
+// 1) The type of function (normal, method, const-method) |
+// 2) The arity of the function |
+// 3) The number of bound parameters. |
+// |
+// The FunctionTraitsN classes unwrap the function signature type to |
+// specialize based on the first two dimensions. The N in FunctionTraitsN |
+// specifies the 3rd dimension. |
+ |
+$var MAX_ARITY = 6 |
+ |
+$range PREBOUND 1..MAX_ARITY |
+$for PREBOUND [[ |
+ |
+template <typename StorageType, typename Sig> |
+struct FunctionTraits$(PREBOUND); |
+ |
+$range ARITY 1..MAX_ARITY |
+$for ARITY [[ |
+ |
+$var UNBOUND = ARITY - PREBOUND |
+$if UNBOUND >= 0 [[ |
+ |
+$$ Variables for function traits generation. |
+$range ARG 1..ARITY |
+$range BOUND_ARG 1..PREBOUND |
+$range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY |
+ |
+$$ Variables for method traits generation. We are always short one arity since |
+$$ the first bound parameter is the object. |
+$var M_ARITY = ARITY - 1 |
+$range M_ARG 1..M_ARITY |
+$range M_BOUND_ARG 2..PREBOUND |
+$range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY |
+ |
+// Function: Arity $(ARITY) -> $(UNBOUND). |
+template <typename StorageType, typename R, $for ARG , [[typename X$(ARG)]]> |
+struct FunctionTraits$(PREBOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> { |
+ static const bool kShouldRef = false; |
+ static R DoInvoke(InvokerStorageBase* base[[]] |
+$if UNBOUND != 0 [[, ]] $for UNBOUND_ARG , [[X$(UNBOUND_ARG) x$(UNBOUND_ARG)]]) { |
+ StorageType* invoker = static_cast<StorageType*>(base); |
+ return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]] |
+$if UNBOUND > 0 [[, ]] $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]); |
+ } |
+}; |
+ |
+// Method: Arity $(M_ARITY) -> $(UNBOUND). |
+template <typename StorageType, typename R, typename T[[]] |
+$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> |
+struct FunctionTraits$(PREBOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> { |
+ static const bool kShouldRef = true; |
+ static R DoInvoke(InvokerStorageBase* base[[]] |
+$if UNBOUND > 0 [[, ]] $for M_UNBOUND_ARG , [[X$(M_UNBOUND_ARG) x$(M_UNBOUND_ARG)]]) { |
+ StorageType* invoker = static_cast<StorageType*>(base); |
+ return (Unwrap(invoker->p1_)->*invoker->f_)([[]] |
+$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] |
+$if UNBOUND > 0 [[$if PREBOUND > 1 [[, ]]]][[]] |
+$for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); |
+ } |
+}; |
+ |
+// Const Method: Arity $(M_ARITY) -> $(UNBOUND). |
+template <typename StorageType, typename R, typename T[[]] |
+$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> |
+struct FunctionTraits$(PREBOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]]) const> { |
+ static const bool kShouldRef = true; |
+ static R DoInvoke(InvokerStorageBase* base[[]] |
+$if UNBOUND > 0 [[, ]] $for M_UNBOUND_ARG , [[X$(M_UNBOUND_ARG) x$(M_UNBOUND_ARG)]]) { |
+ StorageType* invoker = static_cast<StorageType*>(base); |
+ return (Unwrap(invoker->p1_)->*invoker->f_)([[]] |
+$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] |
+$if UNBOUND > 0 [[$if PREBOUND > 1 [[, ]]]][[]] |
+$for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); |
+ } |
+}; |
+ |
+]] $$ if UNBOUND |
+]] $$ for ARITY |
+]] $$ for PREBOUND |
+ |
+ |
+// These are the actual storage classes for the invokers. |
+ |
+$for PREBOUND [[ |
+$range BOUND_ARG 1..PREBOUND |
+ |
+template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> |
+class InvokerStorage$(PREBOUND) : public InvokerStorageBase { |
+ public: |
+ typedef InvokerStorage$(PREBOUND) StorageType; |
+ typedef FunctionTraits$(PREBOUND)<StorageType, Sig> FunctionTraits; |
+ |
+ InvokerStorage$(PREBOUND)(Sig f, [[]] |
+$for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) |
+ : f_(f), $for BOUND_ARG , [[p$(BOUND_ARG)_(p$(BOUND_ARG))]] { |
+ MaybeRefcount<FunctionTraits::kShouldRef, P1>::AddRef(p1_); |
+ } |
+ |
+ virtual ~InvokerStorage$(PREBOUND)() { |
+ MaybeRefcount<FunctionTraits::kShouldRef, P1>::Release(p1_); |
+ } |
+ |
+ Sig f_; |
+ |
+$for BOUND_ARG [[ |
+ P$(BOUND_ARG) p$(BOUND_ARG)_; |
+ |
+]] |
+}; |
+ |
+]] $$ for PREBOUND |
+ |
+} // namespace internal |
+ |
+ |
+$for PREBOUND [[ |
+$range BOUND_ARG 1..PREBOUND |
+ |
+template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> |
+InvokerStorageHolder<internal::InvokerStorage$(PREBOUND)<Sig, [[]] |
+$for BOUND_ARG , [[P$(BOUND_ARG)]]> > |
+Prebind(Sig f, $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) { |
+ return MakeInvokerStorageHolder( |
+ new internal::InvokerStorage$(PREBOUND)<Sig, [[]] |
+$for BOUND_ARG , [[P$(BOUND_ARG)]]>( |
+ f, [[]] $for BOUND_ARG , [[p$(BOUND_ARG)]])); |
+} |
+ |
+]] $$ for PREBOUND |
+ |
+template <typename T> |
+inline internal::UnretainedWrapper<T> Unretained(T* o) { |
+ return internal::UnretainedWrapper<T>(o); |
+} |
+ |
+template <typename T> |
+inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
+ return internal::ConstRefWrapper<T>(o); |
+} |
+ |
+ |
+} // namespace base |
+ |
+#endif // BASE_PREBIND_H_ |