Commit 3c828c63 authored by hiroshige's avatar hiroshige Committed by Commit bot

Use std::is_convertible in EnsurePtrConvertibleArgDecl

This is to make EnsurePtrConvertibleArgDecl(T, const T) to fail
for https://codereview.chromium.org/2220543002.

This CL also adds unit tests for EnsurePtrConvertibleArgDecl.

BUG=

Review-Url: https://codereview.chromium.org/2220443004
Cr-Commit-Position: refs/heads/master@{#418638}
parent 851a481a
...@@ -218,23 +218,23 @@ struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> { ...@@ -218,23 +218,23 @@ struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
// Here, we use a template specialization for same type case to allow incomplete // Here, we use a template specialization for same type case to allow incomplete
// types. // types.
template <typename T, typename U> struct IsBaseOf { template <typename T, typename U> struct IsConvertible {
static const bool value = std::is_base_of<T, U>::value; static const bool value = std::is_convertible<T, U>::value;
}; };
template <typename T> struct IsBaseOf<T, T> { template <typename T> struct IsConvertible<T, T> {
static const bool value = true; static const bool value = true;
}; };
#define EnsurePtrConvertibleArgDecl(From, To) \ #define EnsurePtrConvertibleArgDecl(From, To) \
typename std::enable_if<WTF::IsBaseOf<To, From>::value>::type* = nullptr typename std::enable_if<WTF::IsConvertible<From*, To*>::value>::type* = nullptr
#define EnsurePtrConvertibleArgDefn(From, To) \ #define EnsurePtrConvertibleArgDefn(From, To) \
typename std::enable_if<WTF::IsBaseOf<To, From>::value>::type* typename std::enable_if<WTF::IsConvertible<From*, To*>::value>::type*
#else #else
#define EnsurePtrConvertibleArgDecl(From, To) \ #define EnsurePtrConvertibleArgDecl(From, To) \
typename std::enable_if<std::is_base_of<To, From>::value>::type* = nullptr typename std::enable_if<std::is_convertible<From*, To*>::value>::type* = nullptr
#define EnsurePtrConvertibleArgDefn(From, To) \ #define EnsurePtrConvertibleArgDefn(From, To) \
typename std::enable_if<std::is_base_of<To, From>::value>::type* typename std::enable_if<std::is_convertible<From*, To*>::value>::type*
#endif #endif
} // namespace WTF } // namespace WTF
......
...@@ -180,6 +180,42 @@ static_assert(!IsTriviallyDefaultConstructible<DefaultConstructorDeleted>::value ...@@ -180,6 +180,42 @@ static_assert(!IsTriviallyDefaultConstructible<DefaultConstructorDeleted>::value
static_assert(!IsTriviallyDestructible<DestructorDeleted>::value, static_assert(!IsTriviallyDestructible<DestructorDeleted>::value,
"DestructorDeleted must not be trivially destructible."); "DestructorDeleted must not be trivially destructible.");
template<typename T>
class Wrapper
{
public:
template<typename U>
Wrapper(const Wrapper<U>&, EnsurePtrConvertibleArgDecl(U, T))
{
}
};
class ForwardDeclarationOnlyClass;
static_assert(std::is_convertible<Wrapper<TestDerivedClass>, Wrapper<TestDerivedClass>>::value,
"EnsurePtrConvertibleArgDecl<T, T> should pass");
static_assert(std::is_convertible<Wrapper<TestDerivedClass>, Wrapper<const TestDerivedClass>>::value,
"EnsurePtrConvertibleArgDecl<T, const T> should pass");
static_assert(!std::is_convertible<Wrapper<const TestDerivedClass>, Wrapper<TestDerivedClass>>::value,
"EnsurePtrConvertibleArgDecl<const T, T> should not pass");
static_assert(std::is_convertible<Wrapper<ForwardDeclarationOnlyClass>, Wrapper<ForwardDeclarationOnlyClass>>::value,
"EnsurePtrConvertibleArgDecl<T, T> should pass if T is not a complete type");
static_assert(std::is_convertible<Wrapper<ForwardDeclarationOnlyClass>, Wrapper<const ForwardDeclarationOnlyClass>>::value,
"EnsurePtrConvertibleArgDecl<T, const T> should pass if T is not a complete type");
static_assert(!std::is_convertible<Wrapper<const ForwardDeclarationOnlyClass>, Wrapper<ForwardDeclarationOnlyClass>>::value,
"EnsurePtrConvertibleArgDecl<const T, T> should not pass if T is not a complete type");
static_assert(std::is_convertible<Wrapper<TestDerivedClass>, Wrapper<TestBaseClass<int>>>::value,
"EnsurePtrConvertibleArgDecl<U, T> should pass if U is a subclass of T");
static_assert(!std::is_convertible<Wrapper<TestBaseClass<int>>, Wrapper<TestDerivedClass>>::value,
"EnsurePtrConvertibleArgDecl<U, T> should not pass if U is a base class of T");
} // anonymous namespace } // anonymous namespace
} // namespace WTF } // namespace WTF
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment