Updating trunk VERSION from 935.0 to 936.0
[chromium-blink-merge.git] / base / callback_internal.h
blob4f0736f0eb6ae4556c52396bc9b6f7a39a918daf
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This file contains utility functions and classes that help the
6 // implementation, and management of the Callback objects.
8 #ifndef BASE_CALLBACK_INTERNAL_H_
9 #define BASE_CALLBACK_INTERNAL_H_
10 #pragma once
12 #include <stddef.h>
14 #include "base/base_export.h"
15 #include "base/memory/ref_counted.h"
17 namespace base {
18 namespace internal {
20 // InvokerStorageBase is used to provide an opaque handle that the Callback
21 // class can use to represent a function object with bound arguments. It
22 // behaves as an existential type that is used by a corresponding
23 // DoInvoke function to perform the function execution. This allows
24 // us to shield the Callback class from the types of the bound argument via
25 // "type erasure."
26 class InvokerStorageBase : public RefCountedThreadSafe<InvokerStorageBase> {
27 protected:
28 friend class RefCountedThreadSafe<InvokerStorageBase>;
29 virtual ~InvokerStorageBase() {}
32 // This structure exists purely to pass the returned |invoker_storage_| from
33 // Bind() to Callback while avoiding an extra AddRef/Release() pair.
35 // To do this, the constructor of Callback<> must take a const-ref. The
36 // reference must be to a const object otherwise the compiler will emit a
37 // warning about taking a reference to a temporary.
39 // Unfortunately, this means that the internal |invoker_storage_| field must
40 // be made mutable.
41 template <typename T>
42 struct InvokerStorageHolder {
43 explicit InvokerStorageHolder(T* invoker_storage)
44 : invoker_storage_(invoker_storage) {
47 mutable scoped_refptr<InvokerStorageBase> invoker_storage_;
50 template <typename T>
51 InvokerStorageHolder<T> MakeInvokerStorageHolder(T* o) {
52 return InvokerStorageHolder<T>(o);
55 // Holds the Callback methods that don't require specialization to reduce
56 // template bloat.
57 class BASE_EXPORT CallbackBase {
58 public:
59 // Returns true if Callback is null (doesn't refer to anything).
60 bool is_null() const;
62 // Returns the Callback into an uninitialized state.
63 void Reset();
65 protected:
66 // In C++, it is safe to cast function pointers to function pointers of
67 // another type. It is not okay to use void*. We create a InvokeFuncStorage
68 // that that can store our function pointer, and then cast it back to
69 // the original type on usage.
70 typedef void(*InvokeFuncStorage)(void);
72 // Returns true if this callback equals |other|. |other| may be null.
73 bool Equals(const CallbackBase& other) const;
75 CallbackBase(InvokeFuncStorage polymorphic_invoke,
76 scoped_refptr<InvokerStorageBase>* invoker_storage);
78 // Force the destructor to be instantiated inside this translation unit so
79 // that our subclasses will not get inlined versions. Avoids more template
80 // bloat.
81 ~CallbackBase();
83 scoped_refptr<InvokerStorageBase> invoker_storage_;
84 InvokeFuncStorage polymorphic_invoke_;
87 // This is a typetraits object that's used to take an argument type, and
88 // extract a suitable type for storing and forwarding arguments.
90 // In particular, it strips off references, and converts arrays to
91 // pointers for storage; and it avoids accidentally trying to create a
92 // "reference of a reference" if the argument is a reference type.
94 // This array type becomes an issue for storage because we are passing bound
95 // parameters by const reference. In this case, we end up passing an actual
96 // array type in the initializer list which C++ does not allow. This will
97 // break passing of C-string literals.
98 template <typename T>
99 struct ParamTraits {
100 typedef const T& ForwardType;
101 typedef T StorageType;
104 // The Storage should almost be impossible to trigger unless someone manually
105 // specifies type of the bind parameters. However, in case they do,
106 // this will guard against us accidentally storing a reference parameter.
108 // The ForwardType should only be used for unbound arguments.
109 template <typename T>
110 struct ParamTraits<T&> {
111 typedef T& ForwardType;
112 typedef T StorageType;
115 // Note that for array types, we implicitly add a const in the conversion. This
116 // means that it is not possible to bind array arguments to functions that take
117 // a non-const pointer. Trying to specialize the template based on a "const
118 // T[n]" does not seem to match correctly, so we are stuck with this
119 // restriction.
120 template <typename T, size_t n>
121 struct ParamTraits<T[n]> {
122 typedef const T* ForwardType;
123 typedef const T* StorageType;
126 // See comment for ParamTraits<T[n]>.
127 template <typename T>
128 struct ParamTraits<T[]> {
129 typedef const T* ForwardType;
130 typedef const T* StorageType;
133 } // namespace internal
134 } // namespace base
136 #endif // BASE_CALLBACK_INTERNAL_H_