diff options
author | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 22:37:58 +0000 |
---|---|---|
committer | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 22:37:58 +0000 |
commit | ba019acba16af46f1cfcd48f55668d430290f8b6 (patch) | |
tree | cd21c0b816c1ca3952711d416d6c9336208b133b | |
parent | 12c886cdaa29bd2c419bf6c119942378dc7db1ce (diff) | |
download | chromium_src-ba019acba16af46f1cfcd48f55668d430290f8b6.zip chromium_src-ba019acba16af46f1cfcd48f55668d430290f8b6.tar.gz chromium_src-ba019acba16af46f1cfcd48f55668d430290f8b6.tar.bz2 |
Fix is_convertible for windows.
It turns out that if you nest a template inside the initializer list of another template, the namelookup in windows gets all funky. In this case, it couldn't tell that the found name was a function.
Luckily, we could just move the template parameters one level deeper.
BUG=none
TEST=unittests & trybots.
Review URL: http://codereview.chromium.org/6537001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75194 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/template_util.h | 23 | ||||
-rw-r--r-- | base/template_util_unittest.cc | 10 |
2 files changed, 17 insertions, 16 deletions
diff --git a/base/template_util.h b/base/template_util.h index 0408fc6..e48af91 100644 --- a/base/template_util.h +++ b/base/template_util.h @@ -47,8 +47,6 @@ struct NoType { YesType dummy[2]; }; -#if !defined(OS_WIN) - // This class is an implementation detail for is_convertible, and you // don't need to know how it works to use is_convertible. For those // who care: we declare two different functions, one whose argument is @@ -58,15 +56,17 @@ struct NoType { // had called it with an argument of type From. See Alexandrescu's // _Modern C++ Design_ for more details on this sort of trick. -template <typename From, typename To> struct ConvertHelper { + template <typename To> static YesType Test(To); + + template <typename To> static NoType Test(...); + + template <typename From> static From Create(); }; -#endif // !defined(OS_WIN) - // Used to determine if a type is a struct/union/class. Inspired by Boost's // is_class type_trait implementation. struct IsClassHelper { @@ -79,19 +79,18 @@ struct IsClassHelper { } // namespace internal -#if !defined(OS_WIN) - // Inherits from true_type if From is convertible to To, false_type otherwise. +// +// Note that if the type is convertible, this will be a true_type REGARDLESS +// of whether or not the conversion would emit a warning. template <typename From, typename To> struct is_convertible : integral_constant<bool, - sizeof(internal::ConvertHelper<From, To>::Test( - internal::ConvertHelper<From, To>::Create())) - == sizeof(internal::YesType)> { + sizeof(internal::ConvertHelper::Test<To>( + internal::ConvertHelper::Create<From>())) == + sizeof(internal::YesType)> { }; -#endif // !defined(OS_WIN) - template <typename T> struct is_class : integral_constant<bool, diff --git a/base/template_util_unittest.cc b/base/template_util_unittest.cc index 51d4d33..ea5f0ff 100644 --- a/base/template_util_unittest.cc +++ b/base/template_util_unittest.cc @@ -37,10 +37,8 @@ TEST(TemplateUtilTest, IsNonConstReference) { EXPECT_TRUE(is_non_const_reference<int&>::value); } -#if !defined(OS_WIN) -// TODO(ajwong): Why is is_convertible disabled on windows? TEST(TemplateUtilTest, IsConvertible) { - // Extra parents needed to make EXPECT_*'s parsing happy. Otherwise, + // Extra parens needed to make EXPECT_*'s parsing happy. Otherwise, // it sees the equivalent of // // EXPECT_TRUE( (is_convertible < Child), (Parent > ::value)); @@ -48,8 +46,12 @@ TEST(TemplateUtilTest, IsConvertible) { // Silly C++. EXPECT_TRUE( (is_convertible<Child, Parent>::value) ); EXPECT_FALSE( (is_convertible<Parent, Child>::value) ); + EXPECT_FALSE( (is_convertible<Parent, AStruct>::value) ); + + EXPECT_TRUE( (is_convertible<int, double>::value) ); + EXPECT_TRUE( (is_convertible<int*, void*>::value) ); + EXPECT_FALSE( (is_convertible<void*, int*>::value) ); } -#endif // !defined(OS_WIN) TEST(TemplateUtilTest, IsClass) { EXPECT_TRUE(is_class<AStruct>::value); |