[M94 Dev][Tizen] Fix for errors for generating ninja files
[platform/framework/web/chromium-efl.git] / base / bind_unittest.nc
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.
4
5 // This is a "No Compile Test" suite.
6 // http://dev.chromium.org/developers/testing/no-compile-tests
7
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/macros.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/test/bind.h"
15
16 namespace base {
17
18 // Do not put everything inside an anonymous namespace.  If you do, many of the
19 // helper function declarations will generate unused definition warnings.
20
21 static const int kParentValue = 1;
22 static const int kChildValue = 2;
23
24 class NoRef {
25  public:
26   void VoidMethod0() {}
27   void VoidConstMethod0() const {}
28   int IntMethod0() { return 1; }
29 };
30
31 class HasRef : public NoRef, public base::RefCounted<HasRef> {
32 };
33
34 class Parent {
35  public:
36   void AddRef() const {}
37   void Release() const {}
38   virtual void VirtualSet() { value = kParentValue; }
39   void NonVirtualSet() { value = kParentValue; }
40   int value;
41 };
42
43 class Child : public Parent {
44  public:
45   virtual void VirtualSet() { value = kChildValue; }
46   void NonVirtualSet() { value = kChildValue; }
47 };
48
49 class NoRefParent {
50  public:
51   virtual void VirtualSet() { value = kParentValue; }
52   void NonVirtualSet() { value = kParentValue; }
53   int value;
54 };
55
56 class NoRefChild : public NoRefParent {
57   virtual void VirtualSet() { value = kChildValue; }
58   void NonVirtualSet() { value = kChildValue; }
59 };
60
61 template <typename T>
62 T PolymorphicIdentity(T t) {
63   return t;
64 }
65
66 int UnwrapParentRef(Parent& p) {
67   return p.value;
68 }
69
70 template <typename T>
71 void VoidPolymorphic1(T t) {
72 }
73
74 void TakesMoveOnly(std::unique_ptr<int>) {
75 }
76
77 void TakesIntRef(int& ref) {}
78
79 struct NonEmptyFunctor {
80   int x;
81   void operator()() const {}
82 };
83
84 #if defined(NCTEST_METHOD_ON_CONST_OBJECT)  // [r"static_assert failed.+?BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kCanBeForwardedToBoundFunctor.+?Type mismatch between bound argument and bound functor's parameter\."]
85
86 // Method bound to const-object.
87 //
88 // Only const methods should be allowed to work with const objects.
89 void WontCompile() {
90   HasRef has_ref;
91   const HasRef* const_has_ref_ptr_ = &has_ref;
92   RepeatingCallback<void()> method_to_const_cb =
93       BindRepeating(&HasRef::VoidMethod0, const_has_ref_ptr_);
94   method_to_const_cb.Run();
95 }
96
97 #elif defined(NCTEST_METHOD_BIND_NEEDS_REFCOUNTED_OBJECT)  // [r"fatal error: static_assert failed due to requirement '!std::is_pointer<base::NoRef *>::value || IsRefCountedType<base::NoRef, void>::value' \"Receivers may not be raw pointers. If using a raw pointer here is safe and has no lifetime concerns, use base::Unretained() and document why it's safe.\""]
98
99
100 // Method bound to non-refcounted object.
101 //
102 // We require refcounts unless you have Unretained().
103 void WontCompile() {
104   NoRef no_ref;
105   RepeatingCallback<void()> no_ref_cb =
106       BindRepeating(&NoRef::VoidMethod0, &no_ref);
107   no_ref_cb.Run();
108 }
109
110 #elif defined(NCTEST_CONST_METHOD_NEEDS_REFCOUNTED_OBJECT)  // [r"fatal error: static_assert failed due to requirement '!std::is_pointer<base::NoRef *>::value || IsRefCountedType<base::NoRef, void>::value' \"Receivers may not be raw pointers. If using a raw pointer here is safe and has no lifetime concerns, use base::Unretained() and document why it's safe.\""]
111
112 // Const Method bound to non-refcounted object.
113 //
114 // We require refcounts unless you have Unretained().
115 void WontCompile() {
116   NoRef no_ref;
117   RepeatingCallback<void()> no_ref_const_cb =
118       BindRepeating(&NoRef::VoidConstMethod0, &no_ref);
119   no_ref_const_cb.Run();
120 }
121
122 #elif defined(NCTEST_CONST_POINTER)  // [r"static_assert failed.+?BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kCanBeForwardedToBoundFunctor.+?Type mismatch between bound argument and bound functor's parameter\."]
123 // Const argument used with non-const pointer parameter of same type.
124 //
125 // This is just a const-correctness check.
126 void WontCompile() {
127   const NoRef* const_no_ref_ptr;
128   RepeatingCallback<NoRef*()> pointer_same_cb =
129       BindRepeating(&PolymorphicIdentity<NoRef*>, const_no_ref_ptr);
130   pointer_same_cb.Run();
131 }
132
133 #elif defined(NCTEST_CONST_POINTER_SUBTYPE)  // [r"static_assert failed.+?BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kCanBeForwardedToBoundFunctor.+?Type mismatch between bound argument and bound functor's parameter\."]
134
135 // Const argument used with non-const pointer parameter of super type.
136 //
137 // This is just a const-correctness check.
138 void WontCompile() {
139   const NoRefChild* const_child_ptr;
140   RepeatingCallback<NoRefParent*()> pointer_super_cb =
141     BindRepeating(&PolymorphicIdentity<NoRefParent*>, const_child_ptr);
142   pointer_super_cb.Run();
143 }
144
145 #elif defined(DISABLED_NCTEST_DISALLOW_NON_CONST_REF_PARAM)  // [r"fatal error: no member named 'AddRef' in 'base::NoRef'"]
146 // TODO(dcheng): I think there's a type safety promotion issue here where we can
147 // pass a const ref to a non const-ref function, or vice versa accidentally. Or
148 // we make a copy accidentally. Check.
149
150 // Functions with reference parameters, unsupported.
151 //
152 // First, non-const reference parameters are disallowed by the Google
153 // style guide. Second, since we are doing argument forwarding it becomes
154 // very tricky to avoid copies, maintain const correctness, and not
155 // accidentally have the function be modifying a temporary, or a copy.
156 void WontCompile() {
157   Parent p;
158   RepeatingCallback<int(Parent&)> ref_arg_cb = BindRepeating(&UnwrapParentRef);
159   ref_arg_cb.Run(p);
160 }
161
162 #elif defined(NCTEST_BIND_ONCE_WITH_NON_CONST_REF_PARAM)  // [r"static_assert failed due to requirement 'BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kNonConstRefParamMustBeWrapped' \"Bound argument for non-const reference parameter must be wrapped in std::ref\(\) or base::OwnedRef\(\).\""]
163
164 // Binding functions with reference parameters requires `std::ref()` or
165 // 'base::OwnedRef()`.
166 void WontCompile() {
167   int v = 1;
168   auto cb = BindOnce(&TakesIntRef, v);
169 }
170
171 #elif defined(NCTEST_BIND_REPEATING_WITH_NON_CONST_REF_PARAM)  // [r"static_assert failed due to requirement 'BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kNonConstRefParamMustBeWrapped' \"Bound argument for non-const reference parameter must be wrapped in std::ref\(\) or base::OwnedRef\(\).\""]
172
173 // Binding functions with reference parameters requires `std::ref()` or
174 // 'base::OwnedRef()`.
175 void WontCompile() {
176   int v = 1;
177   auto cb = BindRepeating(&TakesIntRef, v);
178 }
179
180 #elif defined(NCTEST_NON_CONST_REF_PARAM_WRONG_TYPE)  // [r"static_assert failed due to requirement 'BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kCanBeForwardedToBoundFunctor' \"Type mismatch between bound argument and bound functor's parameter.\""]
181
182 // If the argument and parameter types mismatch then the compile error should be
183 // the generic type mismatch error.
184 void WontCompile() {
185   float f = 1.0f;
186   auto cb = BindOnce(&TakesIntRef, f);
187 }
188
189 #elif defined(NCTEST_NON_CONST_REF_PARAM_WRONG_TYPE_AND_WRAPPED)  // [r"static_assert failed due to requirement 'BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kCanBeForwardedToBoundFunctor' \"Type mismatch between bound argument and bound functor's parameter.\""]
190
191 // If the argument and parameter types mismatch then the compile error should be
192 // the generic type mismatch error even if the argument is wrapped in
193 // base::OwnedRef().
194 void WontCompile() {
195   float f = 1.0f;
196   auto cb = BindOnce(&TakesIntRef, base::OwnedRef(f));
197 }
198
199 #elif defined(NCTEST_NO_IMPLICIT_ARRAY_PTR_CONVERSION)  // [r"fatal error: static_assert failed due to requirement '!std::is_array<base::HasRef \[10\]>::value' \"First bound argument to a method cannot be an array.\""]
200
201 // A method should not be bindable with an array of objects.
202 //
203 // This is likely not wanted behavior. We specifically check for it though
204 // because it is possible, depending on how you implement prebinding, to
205 // implicitly convert an array type to a pointer type.
206 void WontCompile() {
207   HasRef p[10];
208   RepeatingCallback<void()> method_bound_to_array_cb =
209       BindRepeating(&HasRef::VoidMethod0, p);
210   method_bound_to_array_cb.Run();
211 }
212
213 #elif defined(NCTEST_NO_RVALUE_RAW_PTR_FOR_REFCOUNTED_TYPES)  // [r"fatal error: static_assert failed due to requirement '!HasRefCountedTypeAsRawPtr<base::HasRef \*>::value' \"A parameter is a refcounted type and needs scoped_refptr.\""]
214
215 // Refcounted types should not be bound as a raw pointer.
216 void WontCompile() {
217   HasRef for_raw_ptr;
218   int a;
219   RepeatingCallback<void()> ref_count_as_raw_ptr_a =
220       BindRepeating(&VoidPolymorphic1<int*>, &a);
221   RepeatingCallback<void()> ref_count_as_raw_ptr =
222       BindRepeating(&VoidPolymorphic1<HasRef*>, &for_raw_ptr);
223 }
224
225 #elif defined(NCTEST_NO_LVALUE_RAW_PTR_FOR_REFCOUNTED_TYPES)  // [r"fatal error: static_assert failed due to requirement '!HasRefCountedTypeAsRawPtr<base::HasRef \*>::value' \"A parameter is a refcounted type and needs scoped_refptr.\""]
226
227 // Refcounted types should not be bound as a raw pointer.
228 void WontCompile() {
229   HasRef* for_raw_ptr = nullptr;
230   RepeatingCallback<void()> ref_count_as_raw_ptr =
231       BindRepeating(&VoidPolymorphic1<HasRef*>, for_raw_ptr);
232 }
233
234 #elif defined(NCTEST_NO_RVALUE_CONST_RAW_PTR_FOR_REFCOUNTED_TYPES)  // [r"fatal error: static_assert failed due to requirement '!HasRefCountedTypeAsRawPtr<const base::HasRef \*>::value' \"A parameter is a refcounted type and needs scoped_refptr.\""]
235
236 // Refcounted types should not be bound as a raw pointer.
237 void WontCompile() {
238   const HasRef for_raw_ptr;
239   RepeatingCallback<void()> ref_count_as_raw_ptr =
240       BindRepeating(&VoidPolymorphic1<const HasRef*>, &for_raw_ptr);
241 }
242
243 #elif defined(NCTEST_NO_LVALUE_CONST_RAW_PTR_FOR_REFCOUNTED_TYPES)  // [r"fatal error: static_assert failed due to requirement '!HasRefCountedTypeAsRawPtr<const base::HasRef \*>::value' \"A parameter is a refcounted type and needs scoped_refptr.\""]
244
245 // Refcounted types should not be bound as a raw pointer.
246 void WontCompile() {
247   const HasRef* for_raw_ptr = nullptr;
248   RepeatingCallback<void()> ref_count_as_raw_ptr =
249       BindRepeating(&VoidPolymorphic1<const HasRef*>, for_raw_ptr);
250 }
251
252 #elif defined(NCTEST_WEAKPTR_BIND_MUST_RETURN_VOID)  // [r"fatal error: static_assert failed due to requirement 'std::is_void<int>::value' \"weak_ptrs can only bind to methods without return values\""]
253
254 // WeakPtrs cannot be bound to methods with return types.
255 void WontCompile() {
256   NoRef no_ref;
257   WeakPtrFactory<NoRef> weak_factory(&no_ref);
258   RepeatingCallback<int()> weak_ptr_with_non_void_return_type =
259       BindRepeating(&NoRef::IntMethod0, weak_factory.GetWeakPtr());
260   weak_ptr_with_non_void_return_type.Run();
261 }
262
263 #elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES)  // [r"fatal error: no viable conversion from 'RepeatingCallback<internal::MakeUnboundRunType<void \(\*\)\(int\)>>' to 'RepeatingCallback<void \(\)>'"]
264
265 // Bind result cannot be assigned to Callbacks with a mismatching type.
266 void WontCompile() {
267   RepeatingClosure callback_mismatches_bind_type =
268       BindRepeating(&VoidPolymorphic1<int>);
269 }
270
271 #elif defined(NCTEST_DISALLOW_CAPTURING_LAMBDA)  // [r"fatal error: implicit instantiation of undefined template 'base::internal::FunctorTraits<\(lambda at (\.\./)+base/bind_unittest.nc:[0-9]+:[0-9]+\)>'"]
272
273 void WontCompile() {
274   int i = 0, j = 0;
275   BindOnce([i,&j]() {j = i;});
276 }
277
278 #elif defined(NCTEST_DISALLOW_ONCECALLBACK_RUN_ON_LVALUE)  // [r"fatal error: static_assert failed due to requirement '!sizeof \(\*this\)' \"OnceCallback::Run\(\) may only be invoked on a non-const rvalue, i\.e\. std::move\(callback\).Run\(\).\""]
279
280 void WontCompile() {
281   OnceClosure cb = BindOnce([] {});
282   cb.Run();
283 }
284
285 #elif defined(NCTEST_DISALLOW_ONCECALLBACK_RUN_ON_CONST_LVALUE)  // [r"fatal error: static_assert failed due to requirement '!sizeof \(\*this\)' \"OnceCallback::Run\(\) may only be invoked on a non-const rvalue, i\.e\. std::move\(callback\).Run\(\).\""]
286
287 void WontCompile() {
288   const OnceClosure cb = BindOnce([] {});
289   cb.Run();
290 }
291
292 #elif defined(NCTEST_DISALLOW_ONCECALLBACK_RUN_ON_CONST_RVALUE)  // [r"fatal error: static_assert failed due to requirement '!sizeof \(\*this\)' \"OnceCallback::Run\(\) may only be invoked on a non-const rvalue, i\.e\. std::move\(callback\).Run\(\).\""]
293
294 void WontCompile() {
295   const OnceClosure cb = BindOnce([] {});
296   std::move(cb).Run();
297 }
298
299 #elif defined(NCTEST_DISALLOW_BIND_ONCECALLBACK)  // [r"fatal error: static_assert failed due to requirement '!base::internal::IsOnceCallback<base::OnceCallback<void \(int\)> ?>\(\)' \"BindRepeating cannot bind OnceCallback. Use BindOnce with std::move\(\).\""]
300
301 void WontCompile() {
302   BindRepeating(BindOnce([](int) {}), 42);
303 }
304
305 #elif defined(NCTEST_DISALLOW_BINDONCE_LVALUE_ONCECALLBACK)  // [r"fatal error: static_assert failed due to requirement '!internal::IsOnceCallback<std::decay_t<OnceCallback<void (int)> &> >() || (std::is_rvalue_reference<OnceCallback<void (int)> &>() && !std::is_const<std::remove_reference_t<OnceCallback<void (int)> &> >())' \"BindOnce requires non-const rvalue for OnceCallback binding. I.e.: base::BindOnce(std::move(callback)).\""]
306 void WontCompile() {
307   auto cb = BindOnce([](int) {});
308   BindOnce(cb, 42);
309 }
310
311 #elif defined(NCTEST_DISALLOW_BINDONCE_RVALUE_CONST_ONCECALLBACK)  // [r"fatal error: static_assert failed due to requirement '!internal::IsOnceCallback<std::decay_t<const OnceCallback<void (int)> > >() || (std::is_rvalue_reference<const OnceCallback<void (int)> &&>() && !std::is_const<std::remove_reference_t<const OnceCallback<void (int)> > >())' \"BindOnce requires non-const rvalue for OnceCallback binding. I.e.: base::BindOnce(std::move(callback)).\""]
312
313 void WontCompile() {
314   const auto cb = BindOnce([](int) {});
315   BindOnce(std::move(cb), 42);
316 }
317
318 #elif defined(NCTEST_BINDONCE_MOVEONLY_TYPE_BY_VALUE)  // [r"static_assert failed.+?BindArgument<0>::BoundAs<.+?>::StoredAs<.+?>::kMoveOnlyTypeMustUseStdMove.+?Attempting to bind a move-only type\. Use std::move\(\) to transfer ownership to the created callback\."]
319
320 void WontCompile() {
321   std::unique_ptr<int> x;
322   BindOnce(&TakesMoveOnly, x);
323 }
324
325 #elif defined(NCTEST_BIND_MOVEONLY_TYPE_BY_VALUE)  // [r"static_assert failed.+?BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kMoveOnlyTypeMustUseBasePassed.+?base::BindRepeating\(\) argument is a move-only type\. Use base::Passed\(\) instead of std::move\(\) to transfer ownership from the callback to the bound functor\."]
326
327 void WontCompile() {
328   std::unique_ptr<int> x;
329   BindRepeating(&TakesMoveOnly, x);
330 }
331
332 #elif defined(NCTEST_BIND_MOVEONLY_TYPE_WITH_STDMOVE)  // [r"static_assert failed.+?BindArgument<0>::ForwardedAs<.+?>::ToParamWithType<.+?>::kMoveOnlyTypeMustUseBasePassed.+?base::BindRepeating\(\) argument is a move-only type\. Use base::Passed\(\) instead of std::move\(\) to transfer ownership from the callback to the bound functor\."]
333
334 void WontCompile() {
335   std::unique_ptr<int> x;
336   BindRepeating(&TakesMoveOnly, std::move(x));
337 }
338
339 #elif defined(NCTEST_BIND_NON_EMPTY_FUNCTOR)  // [r"fatal error: implicit instantiation of undefined template 'base::internal::FunctorTraits<base::NonEmptyFunctor>'"]
340
341 void WontCompile() {
342   BindRepeating(NonEmptyFunctor());
343 }
344
345 #elif defined(NCTEST_DISALLOW_BINDLAMBDAFORTESTING_LVALUE_MUTABLE_LAMBDA)  // [r"BindLambdaForTesting requires non-const rvalue for mutable lambda binding\. I\.e\.: base::BindLambdaForTesting\(std::move\(lambda\)\)."]
346 void WontCompile() {
347   int foo = 42;
348   auto mutable_lambda = [&]() mutable {};
349   BindLambdaForTesting(mutable_lambda);
350 }
351
352 #elif defined(NCTEST_DISALLOW_BINDLAMBDAFORTESTING_RVALUE_CONST_MUTABLE_LAMBDA)  // [r"BindLambdaForTesting requires non-const rvalue for mutable lambda binding\. I\.e\.: base::BindLambdaForTesting\(std::move\(lambda\)\)."]
353
354 void WontCompile() {
355   int foo = 42;
356   const auto mutable_lambda = [&]() mutable {};
357   BindLambdaForTesting(std::move(mutable_lambda));
358 }
359
360 #elif defined(NCTEST_BIND_UNCOPYABLE_AND_UNMOVABLE_TYPE)  // [r"static_assert failed.+?BindArgument<0>::BoundAs<.+?>::StoredAs<.+?>::kBindArgumentCanBeCaptured.+?Cannot capture argument: is the argument copyable or movable\?"]
361
362 void WontCompile() {
363   struct UncopyableUnmovable {
364     UncopyableUnmovable() = default;
365     UncopyableUnmovable(const UncopyableUnmovable&) = delete;
366     UncopyableUnmovable& operator=(const UncopyableUnmovable&) = delete;
367   };
368
369   UncopyableUnmovable u;
370   BindOnce([] (const UncopyableUnmovable&) {}, u);
371 }
372
373 #elif defined(NCTEST_BIND_ONCE_WITH_PASSED)  // [r"static_assert failed.+?Use std::move\(\) instead of base::Passed\(\) with base::BindOnce\(\)"]
374
375 void WontCompile() {
376   std::unique_ptr<int> x;
377   BindOnce([] (std::unique_ptr<int>) {}, Passed(&x));
378 }
379
380 #endif
381
382 }  // namespace base