Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/nonstd/string_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,8 @@ class basic_string_view
nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
{
return assert( v.size() == 0 || v.data() != nssv_nullptr )
, pos >= size()
, v.empty() && pos <= size() ? pos
: pos >= size()
? npos : to_pos(
#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
detail::search( substr(pos), v )
Expand Down
59 changes: 59 additions & 0 deletions test/string-view.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,65 @@ CASE( "string_view: Allows to search for a C-string substring, starting at posit
EXPECT( sv.find("world", 7 ) == string_view::npos );
}

CASE( "string_view: Finds empty substrings through size() via find()" )
{
string_view views[] = { string_view(), string_view(""), string_view("abc") };

for ( size_type i = 0; i < sizeof( views ) / sizeof( views[0] ); ++i )
{
string_view sv = views[i];
size_type positions[] = { 0, sv.size() / 2, sv.size(), sv.size() + 1, string_view::npos };

for ( size_type j = 0; j < sizeof( positions ) / sizeof( positions[0] ); ++j )
{
size_type pos = positions[j];
size_type expected = pos <= sv.size() ? pos : string_view::npos;

EXPECT( sv.find( string_view(), pos ) == expected );
EXPECT( sv.find( string_view(""), pos ) == expected );
EXPECT( sv.find( "", pos ) == expected );
EXPECT( sv.find( "ignored", pos, 0 ) == expected );
}
}
}

CASE( "string_view: Does not find nonempty substrings at or past size() via find()" )
{
string_view sv("abc");

EXPECT( sv.find( string_view("c"), sv.size() ) == string_view::npos );
EXPECT( sv.find( "c", sv.size() ) == string_view::npos );
EXPECT( sv.find( "c", sv.size(), 1 ) == string_view::npos );
EXPECT( sv.find( 'c', sv.size() ) == string_view::npos );
EXPECT( sv.find( "c", sv.size() + 1 ) == string_view::npos );
EXPECT( sv.find( "c", string_view::npos ) == string_view::npos );
}

CASE( "string_view: Finds empty wide substrings at size() via find()" )
{
nonstd::wstring_view sv(L"abc", 3);

EXPECT( nonstd::wstring_view().find( nonstd::wstring_view() ) == size_type( 0 ) );
EXPECT( sv.find( nonstd::wstring_view(), sv.size() ) == sv.size() );
EXPECT( sv.find( L"", sv.size() ) == sv.size() );
EXPECT( sv.find( L"ignored", sv.size(), 0 ) == sv.size() );
EXPECT( sv.find( L"", sv.size() + 1 ) == nonstd::wstring_view::npos );
}

CASE( "string_view: Allows to constexpr-find empty substrings via find() (C++14)" )
{
#if nssv_STD_SV_OR( nssv_HAVE_CONSTEXPR_14 )
static_assert( string_view().find( string_view() ) == 0, "" );
static_assert( string_view( "abc" ).find( string_view(), 3 ) == 3, "" );
static_assert( string_view( "abc" ).find( "", 3 ) == 3, "" );
static_assert( string_view( "abc" ).find( "ignored", 3, 0 ) == 3, "" );
static_assert( string_view( "abc" ).find( "", 4 ) == string_view::npos, "" );
static_assert( string_view( "abc" ).find( "", string_view::npos ) == string_view::npos, "" );
#else
EXPECT( !!"C++14 constexpr is not available (no C++14)" );
#endif
}

CASE( "string_view: Allows to search backwards for a string_view substring, starting at position pos (default: npos) via rfind(), (1)" )
{
char hello[] = "hello world";
Expand Down
Loading