// Copyright (c) 2006-2008 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_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ #define BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ #pragma once #include "base/ref_counted.h" #include "base/tuple.h" // It is dangerous to post a task with a raw pointer argument to a function // that expects a scoped_refptr<>. The compiler will happily accept the // situation, but it will not attempt to increase the refcount until the task // runs. Callers expecting the argument to be refcounted up at post time are // in for a nasty surprise! Example: http://crbug.com/27191 // The following set of traits are designed to generate a compile error // whenever this antipattern is attempted. template struct ExpectsScopedRefptrButGetsRawPtr { enum { value = 0 }; }; template struct ExpectsScopedRefptrButGetsRawPtr, B*> { enum { value = 1 }; }; template struct FunctionUsesScopedRefptrCorrectly { enum { value = 1 }; }; template struct FunctionUsesScopedRefptrCorrectly > { enum { value = !ExpectsScopedRefptrButGetsRawPtr::value }; }; template struct FunctionUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct FunctionUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct FunctionUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct FunctionUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct FunctionUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct FunctionUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct MethodUsesScopedRefptrCorrectly { enum { value = 1 }; }; template struct MethodUsesScopedRefptrCorrectly > { enum { value = !ExpectsScopedRefptrButGetsRawPtr::value }; }; template struct MethodUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct MethodUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct MethodUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct MethodUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct MethodUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; template struct MethodUsesScopedRefptrCorrectly > { enum { value = !(ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value || ExpectsScopedRefptrButGetsRawPtr::value) }; }; #endif // BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_