constexpr       std::size_t  finder = ( std::size_t )0x0101010101010101ULL;

constexpr       std::size_t  masker = ( std::size_t )0x8080808080808080ULL;


constexpr       std::size_t  has_zero_7bit( const std::size_t n )

{

    return  ( n - finder ) & masker;

}


constexpr       std::size_t  has_zero_8bit( const std::size_t n )

{

    return  has_zero_7bit( n ) & ~n;

}


inline  auto    where_zero( const std::size_t* w )

{

    auto*   p = (const char*)w;

    while( *p++ );

    return  p - 1;

}


template< int bits >

auto            strend_bit( const char* s )

{

    const int  step     = sizeof finder == 4 ? 8 : 4;

    const auto has_zero = bits == 7 ? has_zero_7bit : has_zero_8bit;

    

    if( has_zero( *(std::size_t*)s ) )

        return  where_zero( (std::size_t*)s );


    auto    w = (std::size_t*)( (std::size_t)s & ~std::size_t( sizeof finder - 1 ) ) + 1;


    while( 1 )

    {

        if( has_zero( w[ 0 ] ) ) return  where_zero( w     );

        if( has_zero( w[ 1 ] ) ) return  where_zero( w + 1 );

        if( has_zero( w[ 2 ] ) ) return  where_zero( w + 2 );

        if( has_zero( w[ 3 ] ) ) return  where_zero( w + 3 );

        if( sizeof finder == 4 )

        {

        if( has_zero( w[ 4 ] ) ) return  where_zero( w + 4 );

        if( has_zero( w[ 5 ] ) ) return  where_zero( w + 5 );

        if( has_zero( w[ 6 ] ) ) return  where_zero( w + 6 );

        if( has_zero( w[ 7 ] ) ) return  where_zero( w + 7 );

        }

        w += step;

    }

}


auto            strlen_fast( const char* s )

{

    return  strend_bit< 8 >( strend_bit< 7 >( s ) ) - s;

}


며칠 전에 기본 루프 테스트 해 보고 루프비용 싸진김에

where_zero 를 while 문 돌리는게 inline 화에 더 적합할것 같아서

( code cache 를 적게 소모 )

해 보니 쪼금 더 빨라짐.


gcc strlen 보다 3.98 배 빠름.