<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <div class="moz-cite-prefix">On 24/12/2013 00:29, Marshall Clow
      wrote:<br>
    </div>
    <blockquote
      cite="mid:74EB2108-8EFC-4E04-9CA1-59107B895315@gmail.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      On Dec 23, 2013, at 1:16 PM, Howard Hinnant <<a
        moz-do-not-send="true" href="mailto:howard.hinnant@gmail.com">howard.hinnant@gmail.com</a>>
      wrote:<br>
      <div>
        <blockquote type="cite">
          <div style="font-size: 11px; font-style: normal; font-variant:
            normal; font-weight: normal; letter-spacing: normal;
            line-height: normal; orphans: auto; text-align: start;
            text-indent: 0px; text-transform: none; white-space: normal;
            widows: auto; word-spacing: 0px; -webkit-text-stroke-width:
            0px;"><br>
            Two further questions:<br>
            <br>
            1. Do these keywords come with __has_feature tests (like
            __is_class does)?  If not, they should.<br>
            <br>
            2.  If they do come with __has_feature tests, how about
            libc++ doing the same thing it does for is_class et al.?<br>
            <br>
            #if !__has_feature(is_void)<br>
            <br>
            template <class _Tp> struct __is_void       : public
            false_type {};<br>
            template <>          struct __is_void<void> :
            public true_type {};<br>
            <br>
            #endif  // !__has_feature(is_void)<br>
            <br>
            template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
            is_void<br>
               : public __is_void<typename
            remove_cv<_Tp>::type> {};<br>
            <br>
            That way we don't need major surgery.  We avoid the conflict
            if it exists.  And we take advantage of the compiler
            intrinsic if it exists.</div>
        </blockquote>
        <br>
      </div>
      <div>This sounds good to me, but I think it’ll be a bit more
        involved than that:</div>
      <div><br>
      </div>
      <div>#if !__has_feature(is_void)<br>
      </div>
    </blockquote>
    <br>
    Hi Marshall,<br>
    <br>
    A feature definition was never added for these trait intrinsics
    unfortunately. I'll look into it.<br>
    <br>
    <blockquote
      cite="mid:74EB2108-8EFC-4E04-9CA1-59107B895315@gmail.com"
      type="cite">
      <div><br>
        template <class _Tp> struct __is_void       : public
        false_type {};<br>
        template <>          struct __is_void<void> : public
        true_type {};<br>
        <br>
        template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void<br>
           : public __is_void<typename remove_cv<_Tp>::type>
        {};</div>
    </blockquote>
    <br>
    This would still conflict with the keyword in current clang versions
    and other compilers that don't have a quality __has_feature()
    implementation.<br>
    <br>
    To reiterate, you'll do well to avoid the __is_* prefix entirely
    regardless of whether you can feature-test for individual
    availability of the keywords.<br>
    <br>
    I'll try to illustrate this in a different way, taking clang out of
    the picture for a minute. None of these structures extracted from
    libc++ will compile with MSVC 2013:<br>
    <br>
    <br>
    <code>struct __is_nothrow_constructible {}</code><code>;</code><code><br>
    </code><code>testvc.cpp(8) : error C2332: 'struct' : missing tag
      name</code><code><br>
    </code><code>
    </code><code><br>
    </code><code>struct __is_nothrow_assignable</code><code> {}</code><code>;</code><code><br>
    </code><code>testvc.cpp(8) : error C2332: 'struct' : missing tag
      name</code><code><br>
    </code><code>
    </code><code><br>
    </code><code>struct __is_constructible {}</code><code>;</code><code><br>
    </code><code>testvc.cpp(8) : error C2332: 'struct' : missing tag
      name</code><br>
    <br>
    <br>
    It's a fact of life that there many compiler-defined keywords
    littering the __is_* namespace and most of them are undocumented.
    Trying to use them as identifiers or type names is a parse error.<br>
    <br>
    You /could/ try to continue using the __is_* names that are known
    not to conflict today, but it's a quixotic solution that'll break
    every time a new compiler point-release adds new built-in trait
    primitives.<br>
    <br>
    <br>
    <blockquote
      cite="mid:74EB2108-8EFC-4E04-9CA1-59107B895315@gmail.com"
      type="cite">
      <div><br>
      </div>
      <div>#else</div>
      <div><br>
      </div>
      <div>template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
        is_void</div>
      <div>
        <div>   : public integral_constant<bool, __is_void(typename
          remove_cv<_Tp>::type)>;</div>
        <div><br>
        </div>
      </div>
      <div>#endif  // !__has_feature(is_void)<br>
      </div>
    </blockquote>
    <br>
    This part will work.<br>
    <br>
    I'd actually recommend keeping the production-quality library
    implementations in libc++ instead of switching wholesale to the
    clang intrinsics. Many of our intrinsics are there for compatibility
    and haven't been fully tested in a production environment.<br>
    <br>
    If you just s/__is_/__libcpp_is_/ to avoid the keywords you'll gain
    compatibility with other modern compilers, silence the extension
    warnings and help us set a schedule for removing the GNU
    compatibility hack in the parser.<br>
    <br>
    After that we can start to look at offering optimized type traits by
    coordinating more closely, but it's not the immediate issue at hand.<br>
    <br>
    Alp.<br>
    <br>
    <br>
    <pre class="moz-signature" cols="72">-- 
<a class="moz-txt-link-freetext" href="http://www.nuanti.com">http://www.nuanti.com</a>
the browser experts
</pre>
  </body>
</html>