Skip to content

Commit

Permalink
Refine rfind implementations and add related test.
Browse files Browse the repository at this point in the history
Improved the `rfind` function for better performance and correctness, including enhanced handling of character and substring searches. Updated `rfind` to include optimized logic for specific cases, such as using `memrchr` when applicable. Added a new test case to validate the updated `rfind` functionality.
  • Loading branch information
beached committed Jan 4, 2025
1 parent fc71705 commit 7275a13
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
41 changes: 32 additions & 9 deletions include/daw/daw_string_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -1743,8 +1743,9 @@ namespace daw {
return static_cast<std::size_t>( static_cast<CharT const *>( r ) -
first );
} else if constexpr( sizeof( CharT ) == 2 ) {
void const *r = std::wmemchr( const_cast<wchar_t const *>( first ),
static_cast<wchar_t>( c ), sz );
void const *r =
std::wmemchr( reinterpet_cast<wchar_t const *>( first ),
static_cast<wchar_t>( c ), sz );
if( r == nullptr ) {
return npos;
}
Expand Down Expand Up @@ -1852,10 +1853,11 @@ namespace daw {
if( v.empty( ) ) {
return pos;
}

do {
if( sv2_details::compare( m_first +
static_cast<std::ptrdiff_t>( pos ),
v.begin( ), v.size( ) ) == 0 ) {
if( sv2_details::compare(
std::next( m_first, static_cast<std::ptrdiff_t>( pos ) ),
v.begin( ), v.size( ) ) == 0 ) {
return pos;
}
} while( pos-- > 0 );
Expand All @@ -1868,8 +1870,8 @@ namespace daw {
/// @param pos starting position
/// @param count size of substring
/// @returns starting position of substring or npos if not found
[[nodiscard]] constexpr size_type rfind( const_pointer s, size_type pos,
size_type count ) const {
[[nodiscard]] DAW_ATTRIB_FLATTEN constexpr size_type
rfind( const_pointer s, size_type pos, size_type count ) const {
return rfind( basic_string_view<CharT, BoundsType>( s, count ), pos );
}

Expand All @@ -1880,8 +1882,29 @@ namespace daw {
/// @returns position of found character or npos
[[nodiscard]] constexpr size_type rfind( CharT c,
size_type pos = npos ) const {
return rfind(
basic_string_view<CharT, BoundsType>( std::addressof( c ), 1 ), pos );
if( empty( ) ) {
return npos;
}
pos = ( std::min )( { pos, size( ) - 1 } );
#if defined( _GNU_SOURCE ) and defined( DAW_HAS_CONSTEVAL )
if constexpr( sizeof( CharT ) == 1 ) {
if( not DAW_IS_CONSTANT_EVALUATED( ) ) {
void const *r = memrchr( m_first, static_cast<char>( c ), pos );
if( r == nullptr ) {
return npos;
}
return static_cast<size_type>( static_cast<CharT const *>( r ) -
m_first );
}
}
#endif

do {
if( m_first[static_cast<std::ptrdiff_t>( pos )] == c ) {
return pos;
}
} while( pos-- > 0 );
return npos;
}

/// @brief find the last position of character in [data( ) + pos, data( )
Expand Down
7 changes: 7 additions & 0 deletions tests/daw_string_view2_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,12 @@ namespace daw {
daw_expecting( 16U, pos_sv );
}

void daw_rfind_test_004( ) {
daw::sv2::string_view const sv = "This is a string";
auto pos_sv = sv.rfind( 's' );
daw_expecting( 10U, pos_sv );
}

void daw_find_test_001( ) {
daw::sv2::string_view const sv = "This is a string";
auto pos_sv = sv.find( "is" );
Expand Down Expand Up @@ -1787,6 +1793,7 @@ int main( )
daw::daw_rfind_test_001( );
daw::daw_rfind_test_002( );
daw::daw_rfind_test_003( );
daw::daw_rfind_test_004( );
daw::daw_find_test_001( );
daw::daw_find_test_002( );
daw::daw_find_test_003( );
Expand Down

0 comments on commit 7275a13

Please sign in to comment.