[PATCH] Libc++ Windows fixes

Not sure this is worth mentioning, but since error C2516 is defined as (http://msdn.microsoft.com/en-us/library/4d8f5kf3(v=VS.100).aspx) "The class is derived from a type name defined by a typedef statement.", so for example naively changing the second variant of common_type in the test case you posted to connect.microsoft.com to

  template <class _Tp>
    struct common_type<_Tp, void, void>
    {
    public:
        _Tp && type;
    };

makes the test case compile under VS2010 for me. (probably breaking any intended functionality completely) In any case I get "error C2371: 'size_t' : redefinition; different basic types" from the test case, so maybe reducing it a bit can improve upon the miniscule chance of it being fixed...? You have my vote anyway.

/PL

Not sure this is worth mentioning, but since error C2516 is defined as
(http://msdn.microsoft.com/en-us/library/4d8f5kf3%28v=VS.100%29.aspx)
“The class is derived from a type name defined by a typedef statement.”,
so for example naively changing the second variant of common_type in the
test case you posted to connect.microsoft.com to

template
struct common_type<_Tp, void, void>
{
public:
_Tp && type;
};

makes the test case compile under VS2010 for me. (probably breaking any
intended functionality completely) In any case I get “error C2371:
‘size_t’ : redefinition; different basic types” from the test case, so
maybe reducing it a bit can improve upon the miniscule chance of it
being fixed…? You have my vote anyway.

I compiled for 64-bit, it’s preprocessed source code, so that’s the reason. Anyhow, you’re probably right. I’ll try to reduce it more when I find the time.

Howard, is this (the start of) a viable workaround?

Ruben

I don't really see how. common_type<T>::type must be a type, not an object. It seems strange that VS2010 is letting you derive from an object but not a type.

You might try this:

template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value>
struct __is_assignable_imp
    : public decltype(__is_assignable_test(declval<_Tp>(), declval<_Arg>()))
        {};

I.e. remove the common_type wrapper around decltype. However this will have to be #ifdef'd as clang chokes on it:

type_traits:1185:13: error: expected class name
            decltype((__is_assignable_test(declval<_Tp>(), declval<_Arg>())))
            ^
1 error generated.

I actually don't know /why/ clang doesn't like this as [class.derived]/p1 appears to allow it (looks like a clang bug to me).

Howard

Please file a bug.

-Eli

http://llvm.org/bugs/show_bug.cgi?id=11216

Howard

2011/10/23 Howard Hinnant <hhinnant@apple.com>

Not sure this is worth mentioning, but since error C2516 is defined as
(http://msdn.microsoft.com/en-us/library/4d8f5kf3%28v=VS.100%29.aspx)
“The class is derived from a type name defined by a typedef statement.”,
so for example naively changing the second variant of common_type in the
test case you posted to connect.microsoft.com to

template
struct common_type<_Tp, void, void>
{
public:
_Tp && type;
};

makes the test case compile under VS2010 for me. (probably breaking any
intended functionality completely) In any case I get “error C2371:
‘size_t’ : redefinition; different basic types” from the test case, so
maybe reducing it a bit can improve upon the miniscule chance of it
being fixed…? You have my vote anyway.

I compiled for 64-bit, it’s preprocessed source code, so that’s the reason. Anyhow, you’re probably right. I’ll try to reduce it more when I find the time.

Howard, is this (the start of) a viable workaround?

I don’t really see how. common_type::type must be a type, not an object. It seems strange that VS2010 is letting you derive from an object but not a type.

You might try this:

template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value>
struct __is_assignable_imp
: public decltype(__is_assignable_test(declval<_Tp>(), declval<_Arg>()))
{};

This shows me this error, signaling that decltype is buggy as I suspected:

testcase.cpp(90) : error C2062: type ‘’ unexpected
testcase.cpp(90) : see reference to class template instantiation ‘std::__is_assignable_imp<_Tp,_Arg,__formal>’ being compiled

Which only makes the problem worse… I googled this (although seemingly unrelated), suggesting adding a std::identity to accomodate this bug, and this, suggesting an intermediate typedef to work around the bug (although I don’t see this being possible in this case…

Ruben

We removed std::identity<T> late in the C++11 cycle because common_type<T> is the same thing and we were having backwards compatibility problems with extensions named identity.

Howard