1. Table of Contents
2. Changelog
2.1. R6
-
Remove multi-indexed operator[] for conformity reasons with matrices and other data structures
-
Adjust proposed wording
-
Adjust Motivation and Scope
-
Adjust Impact on the Standard
-
Remove
andfirst ( n )
. These will be added in a different paper.last ( n ) -
Removed Design Decisions
-
Added
also to. subview () std :: basic_string_view -
Adjust function name from
toslice () subview ()
2.2. R5
-
Added multi-indexed operator[] for unsafe variant of
std :: string :: slice ( size_t start , size_t end ) -
Adjust proposed wording
2.3. R4
-
Removed
since with the addition of std::stride_view it will no longer be necessary.std :: basic_string :: slice ( size_t start , size_t end , size_t step ) -
Added proposed wording
-
Made functions
,constexpr
andconst
(where applicable)noexcept
2.4. R3
-
Added unit tests to a GitHub project.
2.5. R2
-
now throwsstd :: basic_string :: slice ()
whenstd :: out_of_range
.start >= size ()
2.6. R1
-
Removed default parameter from
.std :: basic_string :: slice ( size_t start , size_t end , size_t step )
3. Motivation and Scope
std :: basic_string
. The introduction of C++20 and C++23 resolved some of these issues by adding the above listed utility functions.I believe we can make string manipulation in C++ even better by adding more of these utility functions to
std :: basic_string
, and one option I always miss, that is present in other programming languages (such as Python), is string-slicing.
Python’s string-slicing is very graceful and easy-to-use, but C++ does not support that syntax.Instead, I propose to add a
subview ()
function to std :: basic_string
and std :: string_view
to emulate string-slicing.I think
. substr ()
can sometimes be a bit cumbersome to use, especially when the substring you’re trying to get is easily gotten via a start and end index, instead of a start and count.. subview ()
will be in function identical to . substr ()
. Its main purpose is for variety in the API for programmers who prefer using start , end
over start , count
.Why would we even want this? Take the following example:
const std :: string { "www.google.com" }; // Subview std :: cout << . subview ( . find ( '.' ) + 1 , . find_last_of ( '.' )) << " \n " ; // Substr size_t start = . find ( '.' ) + 1 ; std :: cout << . substr ( start , . find_last_of ( '.' ) - start ) << " \n " ;
Both do functionally the same thing, but
requires a calculation to get the length and a need to store
since we need it to calculate the length of the substring (although this is not technically necessary, not doing so leads to code duplication), while
can simply pass the same start and just
instead of having to calculate a length.
At the end of the day, this is more about adding to the richness of the API and making the API nicer for some programmers than it is about replacing
or creating entirely new functionality.
4. Impact on the Standard
Since these are only trivial functions requiring no major changes to the language or changes to existing API, the impact of this proposal on the standard is minimal.These functions can already be implemented in the current version of C++23 without any extra changes.
Implementation will be left up to the vendor of course, but since these are trivial functions, we can provide a "template" implementation.
5. Technical Specifications
-
takes 2 parameters:std :: basic_string :: slice ()
andsize_t start
and returns asize_t end
.std :: basic_string_view -
is the starting index (inclusive) of where to start the slice.start -
is thrown whenstd :: out_of_range
.start >= size ()
-
-
is the ending index (exclusive) of where to end the slice.end -
if
thenend > size ()
will be set toend size () -
if
thenend < start
will be set toend start
-
-
These are easily implemented functions and depend on specific vendor-implementation of
and
, but I have provided unit tests and sample implementations here.
6. Proposed Wording
6.1. Addition to < string >
Add the following to 23.4.3.1 basic.string.general:// [...] namespace std { // [...] // [string.ops], string operations // [...] constexpr bool contains ( const charT * x ) const ; constexpr basic_string subview ( size_t start , size_t end ) const ; }
6.2. std :: basic_string :: subview
Add the following subclause to 23.4.3.8 string.ops:-
23.4.3.?:
basic_string :: subview [ string . subview ] -
constexpr basic_string < charT , traits > subview ( size_t start , size_t end ) const ; -
Effects: Determines the effective length
of the string to be returned asxlen
.std :: max ( std :: min ( end , size ()), start )
Returns the characters in the range[ data () + start , data () + xlen ); -
Returns:
basic_string < charT , traits > ( data () + start , end ) -
Throws:
ifout_of_range start >= size ()
-
-
6.3. Addition to < string_view >
Add the following to 23.3.3.1 string.view.template.general:namespace std { // [...] // [string.ops], string operations // [...] constexpr basic_string_view substr ( size_type pos = 0 , size_type n = npos ) const ; // freestanding-deleted constexpr basic_string_view subview ( size_t start , size_t end ) const ; }
6.4. std :: basic_string_view :: subview
Add the following subclause to 23.3.3.8 string.view.ops:-
23.4.3.?:
basic_string_view :: subview [ string . view . subview ] -
constexpr basic_string_view < charT , traits > subview ( size_t start , size_t end ) const ; -
Effects: Determines the effective length
of the string to be returned asxlen
.std :: max ( std :: min ( end , size ()), start )
Returns the characters in the range[ data () + start , data () + xlen ); -
Returns:
basic_string_view < charT , traits > ( data () + start , end ) -
Throws:
ifout_of_range start >= size ()
-
-