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 #include "base/callback.h"
7 #include "base/memory/ref_counted.h"
11 // Do not put everything inside an anonymous namespace. If you do, many of the
12 // helper function declarations will generate unused definition warnings unless
13 // unused definition warnings.
15 static const int kParentValue = 1;
16 static const int kChildValue = 2;
21 void VoidConstMethod0() const {}
22 int IntMethod0() { return 1; }
25 class HasRef : public NoRef, public base::RefCounted<HasRef> {
30 void AddRef(void) const {}
31 void Release(void) const {}
32 virtual void VirtualSet() { value = kParentValue; }
33 void NonVirtualSet() { value = kParentValue; }
37 class Child : public Parent {
39 virtual void VirtualSet() { value = kChildValue; }
40 void NonVirtualSet() { value = kChildValue; }
45 virtual void VirtualSet() { value = kParentValue; }
46 void NonVirtualSet() { value = kParentValue; }
50 class NoRefChild : public NoRefParent {
51 virtual void VirtualSet() { value = kChildValue; }
52 void NonVirtualSet() { value = kChildValue; }
56 T PolymorphicIdentity(T t) {
60 int UnwrapParentRef(Parent& p) {
65 void VoidPolymorphic1(T t) {
68 #if defined(NCTEST_METHOD_ON_CONST_OBJECT) // [r"invalid conversion from 'const base::NoRef\*' to 'base::NoRef\*'"]
70 // Method bound to const-object.
72 // Only const methods should be allowed to work with const objects.
75 const HasRef* const_has_ref_ptr_ = &has_ref;
76 Callback<void(void)> method_to_const_cb =
77 Bind(&HasRef::VoidMethod0, const_has_ref_ptr_);
78 method_to_const_cb.Run();
81 #elif defined(NCTEST_METHOD_BIND_NEEDS_REFCOUNTED_OBJECT) // [r"has no member named 'AddRef'"]
83 // Method bound to non-refcounted object.
85 // We require refcounts unless you have Unretained().
88 Callback<void(void)> no_ref_cb =
89 Bind(&NoRef::VoidMethod0, &no_ref);
93 #elif defined(NCTEST_CONST_METHOD_NEEDS_REFCOUNTED_OBJECT) // [r"has no member named 'AddRef'"]
95 // Const Method bound to non-refcounted object.
97 // We require refcounts unless you have Unretained().
100 Callback<void(void)> no_ref_const_cb =
101 Bind(&NoRef::VoidConstMethod0, &no_ref);
102 no_ref_const_cb.Run();
105 #elif defined(NCTEST_CONST_POINTER) // [r"invalid conversion from 'const base::NoRef\*' to 'base::NoRef\*'"]
107 // Const argument used with non-const pointer parameter of same type.
109 // This is just a const-correctness check.
111 const NoRef* const_no_ref_ptr;
112 Callback<NoRef*(void)> pointer_same_cb =
113 Bind(&PolymorphicIdentity<NoRef*>, const_no_ref_ptr);
114 pointer_same_cb.Run();
117 #elif defined(NCTEST_CONST_POINTER_SUBTYPE) // [r"'const base::NoRefParent\*' to 'base::NoRefParent\*'"]
119 // Const argument used with non-const pointer parameter of super type.
121 // This is just a const-correctness check.
123 const NoRefChild* const_child_ptr;
124 Callback<NoRefParent*(void)> pointer_super_cb =
125 Bind(&PolymorphicIdentity<NoRefParent*>, const_child_ptr);
126 pointer_super_cb.Run();
129 #elif defined(DISABLED_NCTEST_DISALLOW_NON_CONST_REF_PARAM) // [r"badstring"]
130 // I think there's a type safety promotion issue here where we can pass a const
131 // ref to a non const-ref function, or vice versa accidentally. Or we make a
132 // copy accidentally. Check.
134 // Functions with reference parameters, unsupported.
136 // First, non-const reference parameters are disallowed by the Google
137 // style guide. Second, since we are doing argument forwarding it becomes
138 // very tricky to avoid copies, maintain const correctness, and not
139 // accidentally have the function be modifying a temporary, or a copy.
142 Callback<int(Parent&)> ref_arg_cb = Bind(&UnwrapParentRef);
146 #elif defined(NCTEST_DISALLOW_BIND_TO_NON_CONST_REF_PARAM) // [r"size of array is negative"]
148 // Binding functions with reference parameters, unsupported.
150 // See comment in NCTEST_DISALLOW_NON_CONST_REF_PARAM
153 Callback<int(void)> ref_cb = Bind(&UnwrapParentRef, p);
157 #elif defined(NCTEST_NO_IMPLICIT_ARRAY_PTR_CONVERSION) // [r"size of array is negative"]
159 // A method should not be bindable with an array of objects.
161 // This is likely not wanted behavior. We specifically check for it though
162 // because it is possible, depending on how you implement prebinding, to
163 // implicitly convert an array type to a pointer type.
166 Callback<void(void)> method_bound_to_array_cb =
167 Bind(&HasRef::VoidMethod0, p);
168 method_bound_to_array_cb.Run();
171 #elif defined(NCTEST_NO_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"size of array is negative"]
173 // Refcounted types should not be bound as a raw pointer.
177 Callback<void(void)> ref_count_as_raw_ptr_a =
178 Bind(&VoidPolymorphic1<int*>, &a);
179 Callback<void(void)> ref_count_as_raw_ptr =
180 Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr);
183 #elif defined(NCTEST_WEAKPTR_BIND_MUST_RETURN_VOID) // [r"size of array is negative"]
185 // WeakPtrs cannot be bound to methods with return types.
188 WeakPtrFactory<NoRef> weak_factory(&no_ref);
189 Callback<int(void)> weak_ptr_with_non_void_return_type =
190 Bind(&NoRef::IntMethod0, weak_factory.GetWeakPtr());
191 weak_ptr_with_non_void_return_type.Run();
194 #elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES) // [r"conversion from 'base::Callback<void\(int\)>' to non-scalar type"]
196 // Bind result cannot be assigned to Callbacks with a mismatching type.
198 Closure callback_mismatches_bind_type = Bind(&VoidPolymorphic1<int>);