Date: Sat, 27 Apr 2024 01:20:32 -0300
Sometime ago there were some proposals to allow User Defined
Attributes as consteval or constexpr, but among other concerns, it
conflicted with "attributes should not affect the program" and standard
attributes are not "typed", and also not being part of the type of
wherever they are attached. About that, we could change that to
1 - Apply "attributes should not affect the program" only on standard
attributes the statement will become "*standard* attributes should not
affect the program"
2 - Allow consteval UDA´s to be typed, and "affect" the program, I mean, by
being constructed in compile time and anything derived from that, subjected
to "normal" strong typed compile time behavior.
3 - *Not* be part of whatever type/template/declaration that it is being
attached to.
In this spirit I had some thoughts about the subject taking this
path, and giving my 2 cents ( mostly in template cases ) :
1 - It would be useful to reflect a single instance of attribute "my_attr1" for
all instances of X and a different instance of the attribute " my_attr2" for
each X instantiation.
[[ my_attr1{} ]] template<typename T> [[ my_attr2<T>{} ]] struct X {};
X<int> x_int ;
X<float> x_float;
so, if we ask for "attributes_of( type_of(^x_int) )", it should be expanded
as
constexpr auto temp1 = my_attr1{};
constexpr auto temp2 = my_attr2<int>{};
attributes_of( type_of(^x_int) ) == { ^temp1, ^temp2 };
constexpr auto temp3 = my_attr2<float>();
attributes_of( type_of(^x_float) ) == { ^temp1, ^temp3 };
instead of
attributes_of( type_of(^x_int) ) == { my_attr1{} , my_attr2<int>{} };
attributes_of( type_of(^x_float) ) == { my_attr1{} , my_attr2< float >{} };
so, subsequent calls to attributes_of( type_of(^x_int) ) would not
construct other instances of my_attr1 / my_attr2 , right ?
2 - What if my_attr3 does not depend on T ?. Well the same, one my_attr3 to
each instance
[[ my_attr1{} ]] template<typename T> [[ my_attr3{
constexpr_foo_counter() } ]] struct X {};
X<int> x_int ;
X<float> x_float;
constexpr auto temp1 = my_attr1{};
constexpr auto temp2 = my_attr3{ constexpr_foo_counter() };
attributes_of( type_of(^x_int) ) == { ^temp1, ^temp2 };
constexpr auto temp3 = my_attr3{ constexpr_foo_counter() }; // calling
again possibly with different result
attributes_of( type_of(^x_float) ) == { ^temp1, ^temp3 };
3 - Would it be possible to get the instance of my_attr1, without
instantiation of X, also be possible to get the template name "my_attr2"
without instantiating X, just reflecting the template ( not a particular
instance )
[[ my_attr1{} ]] template<typename T> [[ my_attr2<T>{} ]] struct X {};
constexpr auto temp1 = my_attr1{};
attributes_of( ^X ) == { ^temp1, ^my_attr2 };
4 - Specializations should forget all previous attributes.
template<> [[ my_attr4{} ]] struct X<void> {} x_void;
constexpr auto temp1 = my_attr4{};
attributes_of( type_of(^x_void ) ) == { ^temp1 };
Since one can get the "parent" attributes from de template declaration
attributes_of( template_of( type_of(^x_void ) ) ) == attributes_of( ^X );
5 - All standard attributes must belong to a std:: namespace, avoiding
conflict in future proposals.
Thanks
Em qua., 24 de abr. de 2024 às 08:30, Jean-Baptiste Vallon Hoarau via SG7 <
sg7_at_[hidden]> escreveu:
> What Barry was saying is that this cannot work : templates are
> instantiated per type, and the attributes are not part of the type, so the
> information is simply not passed down to the instantiation of the template,
> reflection or not.
>
> Le mer. 24 avr. 2024 à 13:26, Aurelien Cassagnes via SG7 <
> sg7_at_[hidden]> a écrit :
>
>> Barry I understand that right now there is no reasons for it to work, the
>> purpose of this thread is to flesh out what the proposal look like.
>> Gather interest and feedback not share an hypothetical implementation
>> because it doesnt exist yet.
>>
>> Besides seeing interest, the feedback i’m interested is what sections
>> need to be discussed in more detail in the draft for it to become more
>> meaningful
>> thanks.
>>
>> Sent from Gmail Mobile
>>
>>
>> On Sun, Apr 21, 2024 at 1:47 Barry Revzin <barry.revzin_at_[hidden]> wrote:
>>
>>>
>>>
>>> On Fri, Apr 19, 2024, 9:53 PM Aurelien Cassagnes via SG7 <
>>> sg7_at_[hidden]> wrote:
>>>
>>>> Fleshed out the proposal draft and it's available for feedback at
>>>> https://github.com/zebullax/wg21/blob/main/generated/proposal.pdf
>>>>
>>>
>>> How do you expect this to work exactly?
>>>
>>> The type of foo is bool(int), it's not [[nodiscard]] bool(int).
>>> Regardless of the question of reflecting on attributes... logInvoke(foo, 0)
>>> is going to call logInvoke<bool(int), int>. There aren't any attributes
>>> left to reflect on anymore.
>>>
>>> Barry
>>>
>>>> --
>> SG7 mailing list
>> SG7_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>>
> --
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>
Attributes as consteval or constexpr, but among other concerns, it
conflicted with "attributes should not affect the program" and standard
attributes are not "typed", and also not being part of the type of
wherever they are attached. About that, we could change that to
1 - Apply "attributes should not affect the program" only on standard
attributes the statement will become "*standard* attributes should not
affect the program"
2 - Allow consteval UDA´s to be typed, and "affect" the program, I mean, by
being constructed in compile time and anything derived from that, subjected
to "normal" strong typed compile time behavior.
3 - *Not* be part of whatever type/template/declaration that it is being
attached to.
In this spirit I had some thoughts about the subject taking this
path, and giving my 2 cents ( mostly in template cases ) :
1 - It would be useful to reflect a single instance of attribute "my_attr1" for
all instances of X and a different instance of the attribute " my_attr2" for
each X instantiation.
[[ my_attr1{} ]] template<typename T> [[ my_attr2<T>{} ]] struct X {};
X<int> x_int ;
X<float> x_float;
so, if we ask for "attributes_of( type_of(^x_int) )", it should be expanded
as
constexpr auto temp1 = my_attr1{};
constexpr auto temp2 = my_attr2<int>{};
attributes_of( type_of(^x_int) ) == { ^temp1, ^temp2 };
constexpr auto temp3 = my_attr2<float>();
attributes_of( type_of(^x_float) ) == { ^temp1, ^temp3 };
instead of
attributes_of( type_of(^x_int) ) == { my_attr1{} , my_attr2<int>{} };
attributes_of( type_of(^x_float) ) == { my_attr1{} , my_attr2< float >{} };
so, subsequent calls to attributes_of( type_of(^x_int) ) would not
construct other instances of my_attr1 / my_attr2 , right ?
2 - What if my_attr3 does not depend on T ?. Well the same, one my_attr3 to
each instance
[[ my_attr1{} ]] template<typename T> [[ my_attr3{
constexpr_foo_counter() } ]] struct X {};
X<int> x_int ;
X<float> x_float;
constexpr auto temp1 = my_attr1{};
constexpr auto temp2 = my_attr3{ constexpr_foo_counter() };
attributes_of( type_of(^x_int) ) == { ^temp1, ^temp2 };
constexpr auto temp3 = my_attr3{ constexpr_foo_counter() }; // calling
again possibly with different result
attributes_of( type_of(^x_float) ) == { ^temp1, ^temp3 };
3 - Would it be possible to get the instance of my_attr1, without
instantiation of X, also be possible to get the template name "my_attr2"
without instantiating X, just reflecting the template ( not a particular
instance )
[[ my_attr1{} ]] template<typename T> [[ my_attr2<T>{} ]] struct X {};
constexpr auto temp1 = my_attr1{};
attributes_of( ^X ) == { ^temp1, ^my_attr2 };
4 - Specializations should forget all previous attributes.
template<> [[ my_attr4{} ]] struct X<void> {} x_void;
constexpr auto temp1 = my_attr4{};
attributes_of( type_of(^x_void ) ) == { ^temp1 };
Since one can get the "parent" attributes from de template declaration
attributes_of( template_of( type_of(^x_void ) ) ) == attributes_of( ^X );
5 - All standard attributes must belong to a std:: namespace, avoiding
conflict in future proposals.
Thanks
Em qua., 24 de abr. de 2024 às 08:30, Jean-Baptiste Vallon Hoarau via SG7 <
sg7_at_[hidden]> escreveu:
> What Barry was saying is that this cannot work : templates are
> instantiated per type, and the attributes are not part of the type, so the
> information is simply not passed down to the instantiation of the template,
> reflection or not.
>
> Le mer. 24 avr. 2024 à 13:26, Aurelien Cassagnes via SG7 <
> sg7_at_[hidden]> a écrit :
>
>> Barry I understand that right now there is no reasons for it to work, the
>> purpose of this thread is to flesh out what the proposal look like.
>> Gather interest and feedback not share an hypothetical implementation
>> because it doesnt exist yet.
>>
>> Besides seeing interest, the feedback i’m interested is what sections
>> need to be discussed in more detail in the draft for it to become more
>> meaningful
>> thanks.
>>
>> Sent from Gmail Mobile
>>
>>
>> On Sun, Apr 21, 2024 at 1:47 Barry Revzin <barry.revzin_at_[hidden]> wrote:
>>
>>>
>>>
>>> On Fri, Apr 19, 2024, 9:53 PM Aurelien Cassagnes via SG7 <
>>> sg7_at_[hidden]> wrote:
>>>
>>>> Fleshed out the proposal draft and it's available for feedback at
>>>> https://github.com/zebullax/wg21/blob/main/generated/proposal.pdf
>>>>
>>>
>>> How do you expect this to work exactly?
>>>
>>> The type of foo is bool(int), it's not [[nodiscard]] bool(int).
>>> Regardless of the question of reflecting on attributes... logInvoke(foo, 0)
>>> is going to call logInvoke<bool(int), int>. There aren't any attributes
>>> left to reflect on anymore.
>>>
>>> Barry
>>>
>>>> --
>> SG7 mailing list
>> SG7_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>>
> --
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>
Received on 2024-04-27 04:20:47