[Bug c++/100157] Support `__type_pack_element` like Clang

2023-04-26 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Jonathan Wakely  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED
   Target Milestone|13.2|14.0

--- Comment #14 from Jonathan Wakely  ---
Done for GCC 14

[Bug c++/100157] Support `__type_pack_element` like Clang

2023-04-26 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|13.0|13.2

--- Comment #13 from Richard Biener  ---
GCC 13.1 is being released, retargeting bugs to GCC 13.2.

[Bug c++/100157] Support `__type_pack_element` like Clang

2023-04-19 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #12 from CVS Commits  ---
The master branch has been updated by Patrick Palka :

https://gcc.gnu.org/g:58b7dbf865b146a4e65dbda9be6df78f212c03b6

commit r14-92-g58b7dbf865b146a4e65dbda9be6df78f212c03b6
Author: Patrick Palka 
Date:   Wed Apr 19 15:36:34 2023 -0400

c++: Define built-in for std::tuple_element [PR100157]

This adds a new built-in to replace the recursive class template
instantiations done by traits such as std::tuple_element and
std::variant_alternative.  The purpose is to select the Nth type from a
list of types, e.g. __type_pack_element<1, char, int, float> is int.
We implement it as a special kind of TRAIT_TYPE.

For a pathological example tuple_element_t<1000, tuple<2000 types...>>
the compilation time is reduced by more than 90% and the memory used by
the compiler is reduced by 97%.  In realistic examples the gains will be
much smaller, but still relevant.

Unlike the other built-in traits, __type_pack_element uses template-id
syntax instead of call syntax and is SFINAE-enabled, matching Clang's
implementation.  And like the other built-in traits, it's not mangleable
so we can't use it directly in function signatures.

N.B. Clang seems to implement __type_pack_element as a first-class
template that can e.g. be used as a template-template argument.  For
simplicity we implement it in a more ad-hoc way.

Co-authored-by: Jonathan Wakely 

PR c++/100157

gcc/cp/ChangeLog:

* cp-trait.def (TYPE_PACK_ELEMENT): Define.
* cp-tree.h (finish_trait_type): Add complain parameter.
* cxx-pretty-print.cc (pp_cxx_trait): Handle
CPTK_TYPE_PACK_ELEMENT.
* parser.cc (cp_parser_constant_expression): Document default
arguments.
(cp_parser_trait): Handle CPTK_TYPE_PACK_ELEMENT.  Pass
tf_warning_or_error to finish_trait_type.
* pt.cc (tsubst) : Handle non-type first
argument.  Pass complain to finish_trait_type.
* semantics.cc (finish_type_pack_element): Define.
(finish_trait_type): Add complain parameter.  Handle
CPTK_TYPE_PACK_ELEMENT.
* tree.cc (strip_typedefs): Handle non-type first argument.
Pass tf_warning_or_error to finish_trait_type.
* typeck.cc (structural_comptypes) : Use
cp_tree_equal instead of same_type_p for the first argument.

libstdc++-v3/ChangeLog:

* include/bits/utility.h (_Nth_type): Conditionally define in
terms of __type_pack_element if available.
* testsuite/20_util/tuple/element_access/get_neg.cc: Prune
additional errors from the new built-in.

gcc/testsuite/ChangeLog:

* g++.dg/ext/type_pack_element1.C: New test.
* g++.dg/ext/type_pack_element2.C: New test.
* g++.dg/ext/type_pack_element3.C: New test.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-11-29 Thread pdimov at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Peter Dimov  changed:

   What|Removed |Added

 CC||pdimov at gmail dot com

--- Comment #11 from Peter Dimov  ---
Just import mp11 wholesale and use mp_at_c and mp_find :-)

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #10 from Jonathan Wakely  ---
FWIW std::tuple_element_t<1000, tuple> takes 97% less
memory and takes 80% less time with my patch. I just need to fix a problem with
debuginfo generation.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #9 from Vittorio Romeo  ---
(In reply to Jonathan Wakely from comment #8)
> (In reply to Vittorio Romeo from comment #6)
> > worthwhile to keep the same name as Clang for compatibility,
> 
> No, that's not an option. Clang's is a built-in template, GCC's can't be (it
> would require considerable internal reworking to support that).
> 
> That's also why we have __integer_pack(N)... instead of __make_integer_seq<>.
> 
> Since GCC's built-in has to use different syntax, it would be a disaster to
> use the same name.
> 
> #if __has_builtin(__type_pack_element)
> // now what? is it a template or a function?
> #endif

Got it, I didn't realize that they had to be wildly different. I guess that as
long as a library developer can wrap either under a portable macro, it should
be fine.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #8 from Jonathan Wakely  ---
(In reply to Vittorio Romeo from comment #6)
> worthwhile to keep the same name as Clang for compatibility,

No, that's not an option. Clang's is a built-in template, GCC's can't be (it
would require considerable internal reworking to support that).

That's also why we have __integer_pack(N)... instead of __make_integer_seq<>.

Since GCC's built-in has to use different syntax, it would be a disaster to use
the same name.

#if __has_builtin(__type_pack_element)
// now what? is it a template or a function?
#endif

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #7 from Jonathan Wakely  ---
(In reply to m.cencora from comment #5)
> Yeah, __is_same builtin beats custom unique-id comparisons, but it is
> available only since gcc-10 so unavailable for me.

GCC has had __is_same_as since 6.1 though. Much later, __is_same was added as
another spelling for it (PR 92271).

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread vittorio.romeo at outlook dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #6 from Vittorio Romeo  ---
Thank you, Jonathan, for looking into this. I feel like it might be worthwhile
to keep the same name as Clang for compatibility, or maybe talk to some Clang
developers and see if there can be an agreement on naming and design that works
for both compilers -- would be nice to have something that works for both GCC
and Clang in the same way.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread m.cencora at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #5 from m.cencora at gmail dot com ---
Yeah, __is_same builtin beats custom unique-id comparisons, but it is available
only since gcc-10 so unavailable for me.

Recently I discovered this one (only works for unique types), and it is twice
as fast as __is_same in my scenarios (I guess mainly due to memoization):

template 
struct indexed_type
{
   unsigned idx;
};

template 
struct indexed_type_list : indexed_type...
{
   constexpr indexed_type_list(unsigned i = 0)
 : indexed_type{i++}...
   {}
};

template 
constexpr indexed_type_list indexed_type_list_instance;


template 
constexpr auto index_of =
static_cast>(indexed_type_list_instance).idx;

Anyway, thanks for working on this topic!

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #4 from Jonathan Wakely  ---
(In reply to Jonathan Wakely from comment #3)
> I would prefer a pair of similar names involving "type at index" and "index
> of type" or something like that. Or "index to type" and "tpe to index".

Another option I considered is to just use the same name and make the same
built-in support both cases. If the first argument is an integer, return a
type, if the first argument is a type, return an integer. But that's a bit
subtle, and is complicated by wanting the boolean flag for the type-to-index
case.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #3 from Jonathan Wakely  ---
(In reply to m.cencora from comment #2)
> Please consider also adding a builtin for fetching index of type in type
> list.

I am already considering it and it's one of the reasons I don't like the name
"type pack element". That name isn't easily extensible to the reverse case.

I would prefer a pair of similar names involving "type at index" and "index of
type" or something like that. Or "index to type" and "tpe to index".

> While there are some easy implementations (like following), they are still
> not very performant.

The uses in the standard library also require an error if the type occurs more
than once, which yours doesn't check. I intend to add a built-in that supports
both cases with a boolean flag to say whether to fail if the type is repeated.

FWIW I think __find_uniq_type_in_pack() in libstdc++'s  scales
better than yours (and checks for uniqueness).

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-30 Thread m.cencora at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

m.cencora at gmail dot com changed:

   What|Removed |Added

 CC||m.cencora at gmail dot com

--- Comment #2 from m.cencora at gmail dot com ---
Please consider also adding a builtin for fetching index of type in type list.
While there are some easy implementations (like following), they are still not
very performant.

template 
constexpr auto uniqId()
{
return __PRETTY_FUNCTION__;
}

template 
constexpr unsigned index_of_impl(U needle, const U ()[N])
{
for (unsigned i = 0u; i != N; ++i)
{
if (haystack[i] == needle)
{
return i;
}
}
return -1;
}

template 
constexpr auto index_of_v = index_of_impl(uniqId, { uniqId...});

using T1 = float;
using T2 = int;
struct A;
struct B;

auto c = index_of_v;

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-29 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

--- Comment #1 from Jonathan Wakely  ---
GCC doesn't support template-like built-ins, but I have a patch to add a
function-like __builtin_type_pack_element(N, T...) instead. I don't like the
name "type pack element" much though. To me that doesn't really suggest
selecting an element by its index.

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-29 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Jonathan Wakely  changed:

   What|Removed |Added

   Target Milestone|--- |13.0

[Bug c++/100157] Support `__type_pack_element` like Clang

2022-06-29 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Jonathan Wakely  changed:

   What|Removed |Added

   Last reconfirmed||2022-06-29
 Status|UNCONFIRMED |ASSIGNED
 Ever confirmed|0   |1
   Assignee|unassigned at gcc dot gnu.org  |redi at gcc dot gnu.org

[Bug c++/100157] Support `__type_pack_element` like Clang

2021-04-21 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100157

Richard Biener  changed:

   What|Removed |Added

Version|unknown |12.0
   Severity|normal  |enhancement