Skip to content

Commit 9846644

Browse files
committed
Add ends_with_all_of(), ends_with_any_of(), ends_with_none_of()
1 parent 3b4d1f5 commit 9846644

File tree

3 files changed

+106
-6
lines changed

3 files changed

+106
-6
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ The following table presents types, values and simplified, short prototypes of t
126126
|   | bool **starts_with_none_of**(string_view sv, string_view set) | true if string starts with no character of set |
127127
|   |   |   |
128128
|  ends_with | bool **ends_with**(string_view sv, string_view what) | true if string ends with given string |
129+
|   | bool **ends_with_all_of**(string_view sv, string_view set) | true if string ends with all characters of set |
130+
|   | bool **ends_with_any_of**(string_view sv, string_view set) | true if string ends with any character of set |
131+
|   | bool **ends_with_none_of**(string_view sv, string_view set) | true if string ends with no character of set |
129132
|   |   |   |
130133
| **Searching** | size_t **find_first**(string_view sv, string_view what) | position of first occurrence of given string, or npos |
131134
|   | size_t **find_first_of**(string_view sv, string_view set) | position of first occurrence of character in set, or npos |
@@ -239,7 +242,13 @@ contains_all_of: true if string contains all characters of set
239242
contains_any_of: true if string contains any character of set
240243
contains_none_of: true if string contains no character of set
241244
starts_with: true if string starts with substring
245+
starts_with_all_of: true if string starts with all characters of set
246+
starts_with_any_of: true if string starts with any character of set
247+
starts_with_none_of: true if string starts with no character of set
242248
ends_with: true if string ends with substring
249+
ends_with_all_of: true if string ends with all characters of set
250+
ends_with_any_of: true if string ends with any character of set
251+
ends_with_none_of: true if string ends with no character of set
243252
find_first: position of first substring in string
244253
find_last: position of last substring in string
245254
find_first_of: position of first character in string in set

include/nonstd/string.hpp

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,10 +1013,47 @@ string_nodiscard std::size_t find_first( std17::basic_string_view<CharT> text, S
10131013

10141014
// ends_with_all_of()
10151015

1016+
# define string_MK_ENDS_WITH_ALL_OF(CharT) \
1017+
string_nodiscard inline bool \
1018+
ends_with_all_of( std17::basic_string_view<CharT> text, std17::basic_string_view<CharT> set ) \
1019+
{ \
1020+
if ( text.empty() ) \
1021+
return false; \
1022+
\
1023+
std::basic_string<CharT> result; \
1024+
\
1025+
for ( auto it = text.crbegin(); it != text.crend(); ++it ) \
1026+
{ \
1027+
auto const chr = *it; \
1028+
if ( !contains( set, chr ) ) \
1029+
break; \
1030+
if ( !contains( result, chr ) ) \
1031+
result.append( 1, chr ); \
1032+
} \
1033+
return contains_all_of( result, set ); \
1034+
}
1035+
10161036
// ends_with_any_of()
10171037

1038+
# define string_MK_ENDS_WITH_ANY_OF(CharT) \
1039+
string_nodiscard inline bool \
1040+
ends_with_any_of( std17::basic_string_view<CharT> text, std17::basic_string_view<CharT> set ) \
1041+
{ \
1042+
if ( text.empty() ) \
1043+
return false; \
1044+
\
1045+
return contains( set, *text.crbegin() ); \
1046+
}
1047+
10181048
// ends_with_none_of()
10191049

1050+
# define string_MK_ENDS_WITH_NONE_OF(CharT) \
1051+
string_nodiscard inline bool \
1052+
ends_with_none_of( std17::basic_string_view<CharT> text, std17::basic_string_view<CharT> set ) \
1053+
{ \
1054+
return !ends_with_any_of( text, set ); \
1055+
}
1056+
10201057
//
10211058
// Modifiers:
10221059
//
@@ -1879,11 +1916,14 @@ string_MK_CONTAINS_ANY_OF ( char )
18791916
string_MK_CONTAINS_NONE_OF ( char )
18801917
string_MK_STARTS_WITH ( char )
18811918
string_MK_STARTS_WITH_CHAR ( char )
1919+
string_MK_STARTS_WITH_ALL_OF ( char )
18821920
string_MK_STARTS_WITH_ANY_OF ( char )
18831921
string_MK_STARTS_WITH_NONE_OF( char )
1884-
string_MK_STARTS_WITH_ALL_OF ( char )
18851922
string_MK_ENDS_WITH ( char )
18861923
string_MK_ENDS_WITH_CHAR ( char )
1924+
string_MK_ENDS_WITH_ALL_OF ( char )
1925+
string_MK_ENDS_WITH_ANY_OF ( char )
1926+
string_MK_ENDS_WITH_NONE_OF ( char )
18871927
string_MK_ERASE ( char )
18881928
string_MK_ERASE_ALL ( char )
18891929
string_MK_ERASE_FIRST ( char )
@@ -1924,11 +1964,14 @@ string_MK_CONTAINS_ANY_OF ( wchar_t )
19241964
string_MK_CONTAINS_NONE_OF ( wchar_t )
19251965
string_MK_STARTS_WITH ( wchar_t )
19261966
string_MK_STARTS_WITH_CHAR ( wchar_t )
1967+
string_MK_STARTS_WITH_ALL_OF ( wchar_t )
19271968
string_MK_STARTS_WITH_ANY_OF ( wchar_t )
19281969
string_MK_STARTS_WITH_NONE_OF( wchar_t )
1929-
string_MK_STARTS_WITH_ALL_OF ( wchar_t )
19301970
string_MK_ENDS_WITH ( wchar_t )
19311971
string_MK_ENDS_WITH_CHAR ( wchar_t )
1972+
string_MK_ENDS_WITH_ALL_OF ( wchar_t )
1973+
string_MK_ENDS_WITH_ANY_OF ( wchar_t )
1974+
string_MK_ENDS_WITH_NONE_OF ( wchar_t )
19321975
string_MK_FIND_FIRST ( wchar_t )
19331976
string_MK_FIND_FIRST_CHAR ( wchar_t )
19341977
string_MK_FIND_LAST ( wchar_t )
@@ -1977,11 +2020,14 @@ string_MK_CONTAINS_ANY_OF ( char8_t )
19772020
string_MK_CONTAINS_NONE_OF ( char8_t )
19782021
string_MK_STARTS_WITH ( char8_t )
19792022
string_MK_STARTS_WITH_CHAR ( char8_t )
2023+
string_MK_STARTS_WITH_ALL_OF ( char8_t )
19802024
string_MK_STARTS_WITH_ANY_OF ( char8_t )
19812025
string_MK_STARTS_WITH_NONE_OF( char8_t )
1982-
string_MK_STARTS_WITH_ALL_OF ( char8_t )
19832026
string_MK_ENDS_WITH ( char8_t )
19842027
string_MK_ENDS_WITH_CHAR ( char8_t )
2028+
string_MK_ENDS_WITH_ALL_OF ( char8_t )
2029+
string_MK_ENDS_WITH_ANY_OF ( char8_t )
2030+
string_MK_ENDS_WITH_NONE_OF ( char8_t )
19852031
string_MK_FIND_FIRST ( char8_t )
19862032
string_MK_FIND_FIRST_CHAR ( char8_t )
19872033
string_MK_FIND_LAST ( char8_t )
@@ -2030,11 +2076,14 @@ string_MK_CONTAINS_ANY_OF ( char16_t )
20302076
string_MK_CONTAINS_NONE_OF ( char16_t )
20312077
string_MK_STARTS_WITH ( char16_t )
20322078
string_MK_STARTS_WITH_CHAR ( char16_t )
2079+
string_MK_STARTS_WITH_ALL_OF ( char16_t )
20332080
string_MK_STARTS_WITH_ANY_OF ( char16_t )
20342081
string_MK_STARTS_WITH_NONE_OF( char16_t )
2035-
string_MK_STARTS_WITH_ALL_OF ( char16_t )
20362082
string_MK_ENDS_WITH ( char16_t )
20372083
string_MK_ENDS_WITH_CHAR ( char16_t )
2084+
string_MK_ENDS_WITH_ALL_OF ( char16_t )
2085+
string_MK_ENDS_WITH_ANY_OF ( char16_t )
2086+
string_MK_ENDS_WITH_NONE_OF ( char16_t )
20382087
string_MK_FIND_FIRST ( char16_t )
20392088
string_MK_FIND_FIRST_CHAR ( char16_t )
20402089
string_MK_FIND_LAST ( char16_t )
@@ -2083,11 +2132,14 @@ string_MK_CONTAINS_ANY_OF ( char32_t )
20832132
string_MK_CONTAINS_NONE_OF ( char32_t )
20842133
string_MK_STARTS_WITH ( char32_t )
20852134
string_MK_STARTS_WITH_CHAR ( char32_t )
2135+
string_MK_STARTS_WITH_ALL_OF ( char32_t )
20862136
string_MK_STARTS_WITH_ANY_OF ( char32_t )
20872137
string_MK_STARTS_WITH_NONE_OF( char32_t )
2088-
string_MK_STARTS_WITH_ALL_OF ( char32_t )
20892138
string_MK_ENDS_WITH ( char32_t )
20902139
string_MK_ENDS_WITH_CHAR ( char32_t )
2140+
string_MK_ENDS_WITH_ALL_OF ( char32_t )
2141+
string_MK_ENDS_WITH_ANY_OF ( char32_t )
2142+
string_MK_ENDS_WITH_NONE_OF ( char32_t )
20912143
string_MK_FIND_FIRST ( char32_t )
20922144
string_MK_FIND_FIRST_CHAR ( char32_t )
20932145
string_MK_FIND_LAST ( char32_t )
@@ -2136,11 +2188,14 @@ string_MK_SPLIT_LEFT_STRING ( char32_t )
21362188
#undef string_MK_CONTAINS_NONE_OF
21372189
#undef string_MK_STARTS_WITH
21382190
#undef string_MK_STARTS_WITH_CHAR
2191+
#undef string_MK_STARTS_WITH_ALL_OF
21392192
#undef string_MK_STARTS_WITH_ANY_OF
21402193
#undef string_MK_STARTS_WITH_NONE_OF
2141-
#undef string_MK_STARTS_WITH_ALL_OF
21422194
#undef string_MK_ENDS_WITH
21432195
#undef string_MK_ENDS_WITH_CHAR
2196+
#undef string_MK_ENDS_WITH_ALL_OF
2197+
#undef string_MK_ENDS_WITH_ANY_OF
2198+
#undef string_MK_ENDS_WITH_NONE_OF
21442199
#undef string_MK_FIND_FIRST
21452200
#undef string_MK_FIND_FIRST_CHAR
21462201
#undef string_MK_FIND_LAST

test/string.t.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,46 @@ CASE( "ends_with: true if string ends with substring" )
266266

267267
// ends_with_all_of()
268268

269+
CASE( "ends_with_all_of: true if string ends with all characters of set" )
270+
{
271+
EXPECT( ends_with_all_of("abc123mno123xyz", "321zyx") );
272+
EXPECT_NOT( ends_with_all_of("abc123mno123xyz", "321zya") );
273+
274+
EXPECT( ends_with_all_of(std::string("abc123mno123xyz"), std::string("321zyx")) );
275+
EXPECT_NOT( ends_with_all_of(std::string("abc123mno123xyz"), std::string("321zya")) );
276+
277+
EXPECT( ends_with_all_of(std17::string_view("abc123mno123xyz"), std17::string_view("321zyx")) );
278+
EXPECT_NOT( ends_with_all_of(std17::string_view("abc123mno123xyz"), std17::string_view("321zya")) );
279+
}
280+
269281
// ends_with_any_of()
270282

283+
CASE( "ends_with_any_of: true if string ends with any character of set" )
284+
{
285+
EXPECT( ends_with_any_of("abc123mno123xyz", "321zyx") );
286+
EXPECT_NOT( ends_with_any_of("abc123mno123xyz", "789cba") );
287+
288+
EXPECT( ends_with_any_of(std::string("abc123mno123xyz"), std::string("321zyx")) );
289+
EXPECT_NOT( ends_with_any_of(std::string("abc123mno123xyz"), std::string("789cba")) );
290+
291+
EXPECT( ends_with_any_of(std17::string_view("abc123mno123xyz"), std17::string_view("321zyx")) );
292+
EXPECT_NOT( ends_with_any_of(std17::string_view("abc123mno123xyz"), std17::string_view("789cba")) );
293+
}
294+
271295
// ends_with_none_of()
272296

297+
CASE( "ends_with_none_of: true if string ends with no character of set" )
298+
{
299+
EXPECT( ends_with_none_of("abc123mno123xyz", "321cba") );
300+
EXPECT_NOT( ends_with_none_of("abc123mno123xyz", "321cbz") );
301+
302+
EXPECT( ends_with_none_of(std::string("abc123mno123xyz"), std::string("321cba")) );
303+
EXPECT_NOT( ends_with_none_of(std::string("abc123mno123xyz"), std::string("321cbz")) );
304+
305+
EXPECT( ends_with_none_of(std17::string_view("abc123mno123xyz"), std17::string_view("321cba")) );
306+
EXPECT_NOT( ends_with_none_of(std17::string_view("abc123mno123xyz"), std17::string_view("321cbz")) );
307+
}
308+
273309
// find_first():
274310

275311
CASE( "find_first: position of first substring in string" )

0 commit comments

Comments
 (0)