Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: base/callback.h

Issue 6507029: Callback API Change: is_null, Reset, and Equals (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: grammar Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/bind_unittest.cc ('k') | base/callback.h.pump » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // This file was GENERATED by command: 1 // This file was GENERATED by command:
2 // pump.py callback.h.pump 2 // pump.py callback.h.pump
3 // DO NOT EDIT BY HAND!!! 3 // DO NOT EDIT BY HAND!!!
4 4
5 5
6 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 6 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be 7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. 8 // found in the LICENSE file.
9 9
10 #ifndef BASE_CALLBACK_H_ 10 #ifndef BASE_CALLBACK_H_
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 // - Invoking the return of Bind. Bind(&foo).Run() does not work; 205 // - Invoking the return of Bind. Bind(&foo).Run() does not work;
206 // - Binding arrays to functions that take a non-const pointer. 206 // - Binding arrays to functions that take a non-const pointer.
207 // Example: 207 // Example:
208 // void Foo(const char* ptr); 208 // void Foo(const char* ptr);
209 // void Bar(char* ptr); 209 // void Bar(char* ptr);
210 // Bind(&Foo, "test"); 210 // Bind(&Foo, "test");
211 // Bind(&Bar, "test"); // This fails because ptr is not const. 211 // Bind(&Bar, "test"); // This fails because ptr is not const.
212 212
213 namespace base { 213 namespace base {
214 214
215 namespace internal {
216
217 // Holds the methods that don't require specialization to reduce template bloat.
218 class CallbackBase {
219 protected:
220 // In C++, it is safe to cast function pointers to function pointers of
221 // another type. It is not okay to use void*. We create a InvokeFuncStorage
222 // that that can store our function pointer, and then cast it back to
223 // the original type on usage.
224 typedef void(*InvokeFuncStorage)(void);
225
226 public:
227 explicit CallbackBase(InvokeFuncStorage polymorphic_invoke)
willchan no longer on Chromium 2011/02/17 01:09:57 Can't this be protected? And then you can move all
awong 2011/02/17 02:05:29 Good point. Fixed.
228 : polymorphic_invoke_(polymorphic_invoke) {
229 }
230
231 // Returns true if Callback is empty (doesn't refer to anything).
232 bool is_empty() const {
willchan no longer on Chromium 2011/02/17 01:09:57 Bike shed alert: I prefer empty() to is_empty(). F
awong 2011/02/17 02:05:29 Yeah...now that you mention it, empty() is my pref
233 return invoker_storage_.get() == NULL;
234 }
235
236 // Returns the Callback into an empty state.
237 void reset() {
238 invoker_storage_ = NULL;
239 polymorphic_invoke_ = NULL;
240 }
241
242 bool Equals(const CallbackBase& other) const {
akalin 2011/02/17 01:16:39 Do we really need this? I have a hard time imagin
awong 2011/02/17 02:05:29 I struggled with this...I almost actually wanted t
243 return invoker_storage_.get() == other.invoker_storage_.get() &&
244 polymorphic_invoke_ == other.polymorphic_invoke_;
245 }
246
247 protected:
248 scoped_refptr<InvokerStorageBase> invoker_storage_;
249 InvokeFuncStorage polymorphic_invoke_;
250 };
251
252 } // namespace internal
253
254
215 // First, we forward declare the Callback class template. This informs the 255 // First, we forward declare the Callback class template. This informs the
216 // compiler that the template only has 1 type parameter which is the function 256 // compiler that the template only has 1 type parameter which is the function
217 // signature that the Callback is representing. 257 // signature that the Callback is representing.
218 // 258 //
219 // After this, create template specializations for 0-6 parameters. Note that 259 // After this, create template specializations for 0-6 parameters. Note that
220 // even though the template typelist grows, the specialization still 260 // even though the template typelist grows, the specialization still
221 // only has one type: the function signature. 261 // only has one type: the function signature.
222 template <typename Sig> 262 template <typename Sig>
223 class Callback; 263 class Callback;
224
225 template <typename R> 264 template <typename R>
226 class Callback<R(void)> { 265 class Callback<R(void)> : public internal::CallbackBase {
227 public: 266 public:
228 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*); 267 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*);
229 268
230 Callback() : polymorphic_invoke_(NULL) { } 269 Callback() : CallbackBase(NULL) { }
231 270
232 // We pass InvokerStorageHolder by const ref to avoid incurring an 271 // We pass InvokerStorageHolder by const ref to avoid incurring an
233 // unnecessary AddRef/Unref pair even though we will modify the object. 272 // unnecessary AddRef/Unref pair even though we will modify the object.
234 // We cannot use a normal reference because the compiler will warn 273 // We cannot use a normal reference because the compiler will warn
235 // since this is often used on a return value, which is a temporary. 274 // since this is often used on a return value, which is a temporary.
236 // 275 //
237 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 276 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
238 // return the exact Callback<> type. See base/bind.h for details. 277 // return the exact Callback<> type. See base/bind.h for details.
239 template <typename T> 278 template <typename T>
240 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 279 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
241 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { 280 : CallbackBase(
281 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke)) {
242 invoker_storage_.swap(invoker_holder.invoker_storage_); 282 invoker_storage_.swap(invoker_holder.invoker_storage_);
akalin 2011/02/17 01:16:39 can't you add an InvokerStorageBase param to the C
awong 2011/02/17 02:05:29 Oh...good point.
243 } 283 }
244 284
245 R Run(void) const { 285
246 return polymorphic_invoke_(invoker_storage_.get()); 286 R Run() const {
287 PolymorphicInvoke f =
288 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
289
290 return f(invoker_storage_.get());
247 } 291 }
248
249 private:
250 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
251 PolymorphicInvoke polymorphic_invoke_;
252 }; 292 };
253 293
254 template <typename R, typename A1> 294 template <typename R, typename A1>
255 class Callback<R(A1)> { 295 class Callback<R(A1)> : public internal::CallbackBase {
256 public: 296 public:
257 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&); 297 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&);
258 298
259 Callback() : polymorphic_invoke_(NULL) { } 299 Callback() : CallbackBase(NULL) { }
260 300
261 // We pass InvokerStorageHolder by const ref to avoid incurring an 301 // We pass InvokerStorageHolder by const ref to avoid incurring an
262 // unnecessary AddRef/Unref pair even though we will modify the object. 302 // unnecessary AddRef/Unref pair even though we will modify the object.
263 // We cannot use a normal reference because the compiler will warn 303 // We cannot use a normal reference because the compiler will warn
264 // since this is often used on a return value, which is a temporary. 304 // since this is often used on a return value, which is a temporary.
265 // 305 //
266 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 306 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
267 // return the exact Callback<> type. See base/bind.h for details. 307 // return the exact Callback<> type. See base/bind.h for details.
268 template <typename T> 308 template <typename T>
269 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 309 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
270 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { 310 : CallbackBase(
311 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke)) {
271 invoker_storage_.swap(invoker_holder.invoker_storage_); 312 invoker_storage_.swap(invoker_holder.invoker_storage_);
272 } 313 }
273 314
315
274 R Run(const A1& a1) const { 316 R Run(const A1& a1) const {
275 return polymorphic_invoke_(invoker_storage_.get(), a1); 317 PolymorphicInvoke f =
318 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
319
320 return f(invoker_storage_.get(), a1);
276 } 321 }
277
278 private:
279 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
280 PolymorphicInvoke polymorphic_invoke_;
281 }; 322 };
282 323
283 template <typename R, typename A1, typename A2> 324 template <typename R, typename A1, typename A2>
284 class Callback<R(A1, A2)> { 325 class Callback<R(A1, A2)> : public internal::CallbackBase {
285 public: 326 public:
286 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&, 327 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
287 const A2&); 328 const A2&);
288 329
289 Callback() : polymorphic_invoke_(NULL) { } 330 Callback() : CallbackBase(NULL) { }
290 331
291 // We pass InvokerStorageHolder by const ref to avoid incurring an 332 // We pass InvokerStorageHolder by const ref to avoid incurring an
292 // unnecessary AddRef/Unref pair even though we will modify the object. 333 // unnecessary AddRef/Unref pair even though we will modify the object.
293 // We cannot use a normal reference because the compiler will warn 334 // We cannot use a normal reference because the compiler will warn
294 // since this is often used on a return value, which is a temporary. 335 // since this is often used on a return value, which is a temporary.
295 // 336 //
296 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 337 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
297 // return the exact Callback<> type. See base/bind.h for details. 338 // return the exact Callback<> type. See base/bind.h for details.
298 template <typename T> 339 template <typename T>
299 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 340 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
300 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { 341 : CallbackBase(
342 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke)) {
301 invoker_storage_.swap(invoker_holder.invoker_storage_); 343 invoker_storage_.swap(invoker_holder.invoker_storage_);
302 } 344 }
303 345
346
304 R Run(const A1& a1, 347 R Run(const A1& a1,
305 const A2& a2) const { 348 const A2& a2) const {
306 return polymorphic_invoke_(invoker_storage_.get(), a1, 349 PolymorphicInvoke f =
307 a2); 350 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
351
352 return f(invoker_storage_.get(), a1,
353 a2);
308 } 354 }
309
310 private:
311 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
312 PolymorphicInvoke polymorphic_invoke_;
313 }; 355 };
314 356
315 template <typename R, typename A1, typename A2, typename A3> 357 template <typename R, typename A1, typename A2, typename A3>
316 class Callback<R(A1, A2, A3)> { 358 class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
317 public: 359 public:
318 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&, 360 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
319 const A2&, 361 const A2&,
320 const A3&); 362 const A3&);
321 363
322 Callback() : polymorphic_invoke_(NULL) { } 364 Callback() : CallbackBase(NULL) { }
323 365
324 // We pass InvokerStorageHolder by const ref to avoid incurring an 366 // We pass InvokerStorageHolder by const ref to avoid incurring an
325 // unnecessary AddRef/Unref pair even though we will modify the object. 367 // unnecessary AddRef/Unref pair even though we will modify the object.
326 // We cannot use a normal reference because the compiler will warn 368 // We cannot use a normal reference because the compiler will warn
327 // since this is often used on a return value, which is a temporary. 369 // since this is often used on a return value, which is a temporary.
328 // 370 //
329 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 371 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
330 // return the exact Callback<> type. See base/bind.h for details. 372 // return the exact Callback<> type. See base/bind.h for details.
331 template <typename T> 373 template <typename T>
332 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 374 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
333 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { 375 : CallbackBase(
376 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke)) {
334 invoker_storage_.swap(invoker_holder.invoker_storage_); 377 invoker_storage_.swap(invoker_holder.invoker_storage_);
335 } 378 }
336 379
380
337 R Run(const A1& a1, 381 R Run(const A1& a1,
338 const A2& a2, 382 const A2& a2,
339 const A3& a3) const { 383 const A3& a3) const {
340 return polymorphic_invoke_(invoker_storage_.get(), a1, 384 PolymorphicInvoke f =
341 a2, 385 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
342 a3); 386
387 return f(invoker_storage_.get(), a1,
388 a2,
389 a3);
343 } 390 }
344
345 private:
346 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
347 PolymorphicInvoke polymorphic_invoke_;
348 }; 391 };
349 392
350 template <typename R, typename A1, typename A2, typename A3, typename A4> 393 template <typename R, typename A1, typename A2, typename A3, typename A4>
351 class Callback<R(A1, A2, A3, A4)> { 394 class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
352 public: 395 public:
353 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&, 396 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
354 const A2&, 397 const A2&,
355 const A3&, 398 const A3&,
356 const A4&); 399 const A4&);
357 400
358 Callback() : polymorphic_invoke_(NULL) { } 401 Callback() : CallbackBase(NULL) { }
359 402
360 // We pass InvokerStorageHolder by const ref to avoid incurring an 403 // We pass InvokerStorageHolder by const ref to avoid incurring an
361 // unnecessary AddRef/Unref pair even though we will modify the object. 404 // unnecessary AddRef/Unref pair even though we will modify the object.
362 // We cannot use a normal reference because the compiler will warn 405 // We cannot use a normal reference because the compiler will warn
363 // since this is often used on a return value, which is a temporary. 406 // since this is often used on a return value, which is a temporary.
364 // 407 //
365 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 408 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
366 // return the exact Callback<> type. See base/bind.h for details. 409 // return the exact Callback<> type. See base/bind.h for details.
367 template <typename T> 410 template <typename T>
368 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 411 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
369 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { 412 : CallbackBase(
413 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke)) {
370 invoker_storage_.swap(invoker_holder.invoker_storage_); 414 invoker_storage_.swap(invoker_holder.invoker_storage_);
371 } 415 }
372 416
417
373 R Run(const A1& a1, 418 R Run(const A1& a1,
374 const A2& a2, 419 const A2& a2,
375 const A3& a3, 420 const A3& a3,
376 const A4& a4) const { 421 const A4& a4) const {
377 return polymorphic_invoke_(invoker_storage_.get(), a1, 422 PolymorphicInvoke f =
378 a2, 423 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
379 a3, 424
380 a4); 425 return f(invoker_storage_.get(), a1,
426 a2,
427 a3,
428 a4);
381 } 429 }
382
383 private:
384 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
385 PolymorphicInvoke polymorphic_invoke_;
386 }; 430 };
387 431
388 template <typename R, typename A1, typename A2, typename A3, typename A4, 432 template <typename R, typename A1, typename A2, typename A3, typename A4,
389 typename A5> 433 typename A5>
390 class Callback<R(A1, A2, A3, A4, A5)> { 434 class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
391 public: 435 public:
392 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&, 436 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
393 const A2&, 437 const A2&,
394 const A3&, 438 const A3&,
395 const A4&, 439 const A4&,
396 const A5&); 440 const A5&);
397 441
398 Callback() : polymorphic_invoke_(NULL) { } 442 Callback() : CallbackBase(NULL) { }
399 443
400 // We pass InvokerStorageHolder by const ref to avoid incurring an 444 // We pass InvokerStorageHolder by const ref to avoid incurring an
401 // unnecessary AddRef/Unref pair even though we will modify the object. 445 // unnecessary AddRef/Unref pair even though we will modify the object.
402 // We cannot use a normal reference because the compiler will warn 446 // We cannot use a normal reference because the compiler will warn
403 // since this is often used on a return value, which is a temporary. 447 // since this is often used on a return value, which is a temporary.
404 // 448 //
405 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 449 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
406 // return the exact Callback<> type. See base/bind.h for details. 450 // return the exact Callback<> type. See base/bind.h for details.
407 template <typename T> 451 template <typename T>
408 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 452 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
409 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { 453 : CallbackBase(
454 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke)) {
410 invoker_storage_.swap(invoker_holder.invoker_storage_); 455 invoker_storage_.swap(invoker_holder.invoker_storage_);
411 } 456 }
412 457
458
413 R Run(const A1& a1, 459 R Run(const A1& a1,
414 const A2& a2, 460 const A2& a2,
415 const A3& a3, 461 const A3& a3,
416 const A4& a4, 462 const A4& a4,
417 const A5& a5) const { 463 const A5& a5) const {
418 return polymorphic_invoke_(invoker_storage_.get(), a1, 464 PolymorphicInvoke f =
419 a2, 465 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
420 a3, 466
421 a4, 467 return f(invoker_storage_.get(), a1,
422 a5); 468 a2,
469 a3,
470 a4,
471 a5);
423 } 472 }
424
425 private:
426 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
427 PolymorphicInvoke polymorphic_invoke_;
428 }; 473 };
429 474
430 template <typename R, typename A1, typename A2, typename A3, typename A4, 475 template <typename R, typename A1, typename A2, typename A3, typename A4,
431 typename A5, typename A6> 476 typename A5, typename A6>
432 class Callback<R(A1, A2, A3, A4, A5, A6)> { 477 class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
433 public: 478 public:
434 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&, 479 typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
435 const A2&, 480 const A2&,
436 const A3&, 481 const A3&,
437 const A4&, 482 const A4&,
438 const A5&, 483 const A5&,
439 const A6&); 484 const A6&);
440 485
441 Callback() : polymorphic_invoke_(NULL) { } 486 Callback() : CallbackBase(NULL) { }
442 487
443 // We pass InvokerStorageHolder by const ref to avoid incurring an 488 // We pass InvokerStorageHolder by const ref to avoid incurring an
444 // unnecessary AddRef/Unref pair even though we will modify the object. 489 // unnecessary AddRef/Unref pair even though we will modify the object.
445 // We cannot use a normal reference because the compiler will warn 490 // We cannot use a normal reference because the compiler will warn
446 // since this is often used on a return value, which is a temporary. 491 // since this is often used on a return value, which is a temporary.
447 // 492 //
448 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT 493 // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
449 // return the exact Callback<> type. See base/bind.h for details. 494 // return the exact Callback<> type. See base/bind.h for details.
450 template <typename T> 495 template <typename T>
451 Callback(const internal::InvokerStorageHolder<T>& invoker_holder) 496 Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
452 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) { 497 : CallbackBase(
498 reinterpret_cast<InvokeFuncStorage>(&T::FunctionTraits::DoInvoke)) {
453 invoker_storage_.swap(invoker_holder.invoker_storage_); 499 invoker_storage_.swap(invoker_holder.invoker_storage_);
454 } 500 }
455 501
502
456 R Run(const A1& a1, 503 R Run(const A1& a1,
457 const A2& a2, 504 const A2& a2,
458 const A3& a3, 505 const A3& a3,
459 const A4& a4, 506 const A4& a4,
460 const A5& a5, 507 const A5& a5,
461 const A6& a6) const { 508 const A6& a6) const {
462 return polymorphic_invoke_(invoker_storage_.get(), a1, 509 PolymorphicInvoke f =
463 a2, 510 reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
464 a3, 511
465 a4, 512 return f(invoker_storage_.get(), a1,
466 a5, 513 a2,
467 a6); 514 a3,
515 a4,
516 a5,
517 a6);
468 } 518 }
469
470 private:
471 scoped_refptr<internal::InvokerStorageBase> invoker_storage_;
472 PolymorphicInvoke polymorphic_invoke_;
473 }; 519 };
474 520
475 521
476 // Syntactic sugar to make Callbacks<void(void)> easier to declare since it 522 // Syntactic sugar to make Callbacks<void(void)> easier to declare since it
477 // will be used in a lot of APIs with delayed execution. 523 // will be used in a lot of APIs with delayed execution.
478 typedef Callback<void(void)> Closure; 524 typedef Callback<void(void)> Closure;
479 525
480 } // namespace base 526 } // namespace base
481 527
482 #endif // BASE_CALLBACK_H 528 #endif // BASE_CALLBACK_H
OLDNEW
« no previous file with comments | « base/bind_unittest.cc ('k') | base/callback.h.pump » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698