<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, May 1, 2014 at 10:36 PM, Alp Toker <span dir="ltr"><<a href="mailto:alp@nuanti.com" target="_blank">alp@nuanti.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class=""><br>
On 02/05/2014 05:34, Richard Smith wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
IIRC there were concerns that __has_feature might not be the right place to be surfacing these traits.<br>
</blockquote>
<br></div>
Right, I took some notes back when I was looking into this and my findings were:<br>
<br>
__has_feature() is intended for standardised language features and it's prominently user-facing so not really appropriate for trait primitives whether or not they're feature-complete. Once an alternative is found we should phase those out.<br>

<br>
__has_extension() also suffers from being user-facing, but perhaps less so.<br>
<br>
__has_builtin() would let us automatically list all built-in trait primitives and I did some work to support that but it wasn't clear what value this adds so I've put that aside.<br>
<br>
Observation: There's no need to list "compatibility-only" or poorly defined trait primitives in any detection macro because they only exist for compatibility with MSVC and GCC which use without checking, with the possible exception of Embarcadero(?).<br>

<br>
As you see this is a bit of a tangle. As a way forward the viable options to provide a feature test for _quality_ type trait primitives could be one of:<br>
<br>
a) A new __has_primitive()<br>
b) Shoehorning into __has_extension() but naming the features more clearly as primitives: e.g. __has_extension(primitive_is_<u></u>constructible)</blockquote><div><br></div><div>Another option is recommending people use __is_identifier, which already works for this purpose (because we treat these tokens as keywords), but I'd be against that one since we can't mark a trait as unavailable when it's in a not-fully-working state.</div>
<div><br></div><div>One advantage of sticking with __has_feature or __has_extension is that we don't immediately gain a legacy deprecated interface to support and be unhappy about =) Here's what our documentation says:</div>
<div><br></div><div>"For type trait __X, __has_extension(X) indicates the presence of the type trait primitive in the compiler."<br></div><div><br></div><div>We could stick with that, using the is_ prefix as our indicator that the extension is a type trait (and adding these and any further type traits only to __has_extension and not to __has_feature).</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

Some of the traits don't work in general (and support just enough to get through the MS headers); I don't recall exactly which ones, though, and I think it was more than just __is_*_destructible. Alp, do you recall? (Maybe it was the __is_nothrow_* ones?)<br>

</blockquote>
<br></div>
Many of the _is_ ones are sketchy. I cooked up some tests to compare them against GCC and while compatibility was good, overall usefulness wasn't clear and some of the results were sketchy. I'll see if I can dig this up but the results may be lost (wish we had a wiki to throw stuff like this).<br>

<br>
Meanwhile our tests for the trait primitives have inconsistent coverage and fixing them would be a lot of work. Fortunately the libc++ test suite has great coverage and it might be possible to reuse that work..<br>
<br>
Marshall, do you think a strategically placed static_assert() could be added somewhere in your type trait tests to compare answers from the clang builtin type trait primitives against your quality library implementations?<div class="">
<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
Do we advertise support for the __has_* ones? We should stop doing that if we do -- they're fundamentally broken and pretty much useless (they exist to support libstdc++ and give wrong answers in some cases for GCC compatibility). Eventually I would ilke to make them synonyms for the correct traits, but I'm concerned that people might be relying on the GCC bugs that we emulate for them.<br>

</blockquote>
<br></div>
My understanding of the Embarcadero usage is that they _DO_ use the feature detection macros. If this is indeed the case (they should comment, do we have a contact?) then removing them from __has_feature() is tantamount to removing them completely. I'm not at all opposed to that but it should be done after we get the facts from the original authors.<br>
</blockquote><div><br></div><div>I'm not sure whether we're talking about the same traits. Just to make sure, I mean __has_trivial_* and __has_nothrow_* (which GCC added a few years ago based on the then-C++0x type traits proposal, which got reworked substantially before C++11).</div>
<div><br></div><div>I don't have any particular views on the __is_lvalue_expr, __is_rvalue_expr, __is_same, __is_convertible, __array_* Embarcadero traits (except that the names array_rank and array_extent are icky :-) ).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Alp.<div class=""><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
<br>
On Thu, May 1, 2014 at 7:48 AM, Marshall Clow <<a href="mailto:mclow.lists@gmail.com" target="_blank">mclow.lists@gmail.com</a> <mailto:<a href="mailto:mclow.lists@gmail.com" target="_blank">mclow.lists@gmail.com</a>><u></u>> wrote:<br>

<br>
    Recently, reading llvm/tools/clang/docs/<u></u>LanguageExtensions.rst, I<br>
    saw a list of type_trait primitives<br>
    supported by clang.<br>
<br>
    One of them caught my eye: __is_nothrow_constructible  — that<br>
    could be handy for use in libc++.<br>
<br>
    So I ran a quick test:<br>
<br>
            __is_nothrow_constructible(<u></u>int)<br>
    and it returned true.<br>
<br>
    Then I tried:<br>
            __has_feature(is_nothrow_<u></u>constructible)<br>
    and it returned false.<br>
<br>
    Well, that’s not useful to me; I need to be able to tell when I<br>
    can use that feature.<br>
    So I whipped up a program to test all of the type_traits listed in<br>
    that file (attached),<br>
    and to see if I can check (using __has_feature) whether or not<br>
    they are implemented.<br>
<br>
    Turns out that __has_feature returns false for the following type<br>
    traits:<br>
<br>
            __has_feature(is_interface_<u></u>class) = 0<br>
            __has_feature(is_destructible) = 0<br>
            __has_feature(is_nothrow_<u></u>destructible) = 0<br>
            __has_feature(is_nothrow_<u></u>assignable) = 0<br>
            __has_feature(is_nothrow_<u></u>constructible) = 0<br>
<br>
    __is_interface_class is a MS extension; so that’s fine.<br>
    __is_destructible and __is_nothrow_destructible are described as<br>
    “partially implemented”, and attempts to use them fail.<br>
<br>
    On the other hand:<br>
            __is_nothrow_constructible(<u></u>int) returns 1<br>
            __is_nothrow_assignable(int&, int) returns 1<br>
<br>
    So these two seem to work (for at least one case)<br>
    It seems to me that we should have feature tests for these type<br>
    traits if we expect people to use them<br>
<br>
    So, I’d like to see<br>
            __has_feature(is_nothrow_<u></u>constructible)<br>
    and     __has_feature(is_nothrow_<u></u>assignable)<br>
<br>
    return 1<br>
<br>
<br>
    — Marshall<br>
<br>
<br>
<br>
</blockquote>
<br></div></div><span class=""><font color="#888888">
-- <br>
<a href="http://www.nuanti.com" target="_blank">http://www.nuanti.com</a><br>
the browser experts<br>
<br>
</font></span></blockquote></div><br></div></div>