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() {

};

Reply via email to