https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119008
Bug ID: 119008
Summary: for token(>): compiler can NOT distinguish
close-template-block(>) from operator(>):
Product: gcc
Version: 14.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: terryinzaghi at 163 dot com
Target Milestone: ---
the full code here:
https://godbolt.org/z/KPjhWGGxa
----------------------------------------------------
BREIF:
/* GT > example can work: using paren (...) to wrap the gt-op > */
template<typename TagT, typename... MemberTs> concept
concept_is_good_write_order2 = ordered_window2_step1_conjunction_verify_v<
[]<typename T, std::size_t I,typename NexT, std::size_t NexI>(
std::type_identity<T>, value_identity<I>,
std::type_identity<NexT>,value_identity<NexI>
)->bool {
//...
if constexpr ( (sizeof(T) > sizeof(NexT)) ) {
//================ WORK
return true;
} else if constexpr ( sizeof(T) == sizeof(NexT) ) {
return(alignof(T) >= alignof(NexT));
} else {
return false;
}
//...
},
MemberTs...
>() && !std::is_same_v<TagT,void>;
/* GT > example can NOT work!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
template<typename TagT, typename... MemberTs> concept
BAD_concept_is_good_write_order = ordered_window2_step1_conjunction_verify_v<
[]<typename T, std::size_t I,typename NexT, std::size_t NexI>(
std::type_identity<T>, value_identity<I>,
std::type_identity<NexT>,value_identity<NexI>
)->bool {
//...
if constexpr ( sizeof(T) > sizeof(NexT)) {
//================ FAIL <source>:107:40: error: expected ')' before '>' token
return true;
} else if constexpr ( sizeof(T) == sizeof(NexT) ) {
return(alignof(T) >= alignof(NexT));
} else {
return false;
}
//...
},
MemberTs...
>() && !std::is_same_v<TagT,void>;
FOR LT(<), ITS OK, NOT need paren(...):
/* COMPARE with LT: < */
template<typename TagT, typename... MemberTs> concept TEST_LT =
ordered_window2_step1_conjunction_verify_v<
[]<typename T, std::size_t I,typename NexT, std::size_t NexI>(
std::type_identity<T>, value_identity<I>,
std::type_identity<NexT>,value_identity<NexI>
)->bool {
//...
if constexpr ( sizeof(T) < sizeof(NexT)) {
//------------WORK: <
return true;
} else if constexpr ( sizeof(T) == sizeof(NexT) ) {
return(alignof(T) >= alignof(NexT));
} else {
return false;
}
//...
},
MemberTs...
>() && !std::is_same_v<TagT,void>;
----------------------------------------------------
FULL CODE:
#include <cstdint>
#include <concepts>
#include <type_traits>
/*
PREPARE CODE:
these struct and functions implement are NOT important,
they just to make this example can be compiled
*/
template<auto V> struct value_identity { static constexpr auto value = V;};
template<typename T> struct type_identity { using type = T;}; //
for clang , gcc just use std::type_identity
template<
auto VerifyLmbd,
std::size_t I,
typename T0,
typename T1,
typename... UnhandledTs
> static constexpr bool __ordered_window2_step1_conjunction_verify_f() {
constexpr bool Cond = VerifyLmbd(type_identity<T0>{}, value_identity<I>{},
type_identity<T1>{}, value_identity<I+1>{});
if constexpr(Cond) {
if constexpr(sizeof...(UnhandledTs) ==0) {
return true;
} else {
return(__ordered_window2_step1_conjunction_verify_f<VerifyLmbd,I+1,T1,UnhandledTs...>());
}
} else {
return false;
}
};
template<
auto VerifyLmbd,
typename T,
typename... UnhandledTs
> static constexpr bool _ordered_window2_step1_conjunction_verify_f() {
if constexpr(sizeof...(UnhandledTs) ==0) {
return true;
} else {
return(__ordered_window2_step1_conjunction_verify_f<VerifyLmbd,0,T,UnhandledTs...>());
}
};
template<
auto VerifyLmbd, // [] -- window count 2 : prev , current;
iter advance step 1 ;
// <
// typename EleT0, size_t Index0,
// typename EleT1, size_t Index1,
// >(
// std::type_identity<EleT0>,
value_identity<Index0>,
// std::type_identity<EleT1>,
value_identity<Index1>,
// ) -> bool
typename... UnhandledTs
> requires(sizeof...(UnhandledTs) >0)
static constexpr bool ordered_window2_step1_conjunction_verify_v
=_ordered_window2_step1_conjunction_verify_f<VerifyLmbd,UnhandledTs...>();
/* GT > : example can work: using a variable */
template<typename TagT, typename... MemberTs> concept
concept_is_good_write_order = ordered_window2_step1_conjunction_verify_v<
[]<typename T, std::size_t I,typename NexT, std::size_t NexI>(
std::type_identity<T>, value_identity<I>,
std::type_identity<NexT>,value_identity<NexI>
)->bool {
constexpr bool CondGt = (sizeof(T) > sizeof(NexT)) ;
//...
if constexpr ( CondGt ) {
//================ WORK
return true;
} else if constexpr ( sizeof(T) == sizeof(NexT) ) {
return(alignof(T) >= alignof(NexT));
} else {
return false;
}
//...
},
MemberTs...
>() && !std::is_same_v<TagT,void>;
/* GT > example can work: using paren (...) to wrap the gt-op > */
template<typename TagT, typename... MemberTs> concept
concept_is_good_write_order2 = ordered_window2_step1_conjunction_verify_v<
[]<typename T, std::size_t I,typename NexT, std::size_t NexI>(
std::type_identity<T>, value_identity<I>,
std::type_identity<NexT>,value_identity<NexI>
)->bool {
//...
if constexpr ( (sizeof(T) > sizeof(NexT)) ) {
//================ WORK
return true;
} else if constexpr ( sizeof(T) == sizeof(NexT) ) {
return(alignof(T) >= alignof(NexT));
} else {
return false;
}
//...
},
MemberTs...
>() && !std::is_same_v<TagT,void>;
/* GT > example can NOT work!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
template<typename TagT, typename... MemberTs> concept
BAD_concept_is_good_write_order = ordered_window2_step1_conjunction_verify_v<
[]<typename T, std::size_t I,typename NexT, std::size_t NexI>(
std::type_identity<T>, value_identity<I>,
std::type_identity<NexT>,value_identity<NexI>
)->bool {
//...
if constexpr ( sizeof(T) > sizeof(NexT)) {
//================ FAIL <source>:107:40: error: expected ')' before '>' token
return true;
} else if constexpr ( sizeof(T) == sizeof(NexT) ) {
return(alignof(T) >= alignof(NexT));
} else {
return false;
}
//...
},
MemberTs...
>() && !std::is_same_v<TagT,void>;
/* COMPARE with LT: < */
template<typename TagT, typename... MemberTs> concept TEST_LT =
ordered_window2_step1_conjunction_verify_v<
[]<typename T, std::size_t I,typename NexT, std::size_t NexI>(
std::type_identity<T>, value_identity<I>,
std::type_identity<NexT>,value_identity<NexI>
)->bool {
//...
if constexpr ( sizeof(T) < sizeof(NexT)) {
//------------WORK: <
return true;
} else if constexpr ( sizeof(T) == sizeof(NexT) ) {
return(alignof(T) >= alignof(NexT));
} else {
return false;
}
//...
},
MemberTs...
>() && !std::is_same_v<TagT,void>;
int main() {
};