@@ -18,26 +18,27 @@ Author: Daniel Poetzl
1818// / in the middle of the string is left unchanged
1919// / \param s: the string to strip
2020// / \return The stripped string
21- std::string strip_string (const std::string & s)
21+ std::string strip_string (std::string_view s)
2222{
2323 auto pred=[](char c){ return std::isspace (c); };
2424
25- std::string ::const_iterator left
26- = std::find_if_not (s.begin (), s.end (), pred);
25+ std::string_view ::const_iterator left =
26+ std::find_if_not (s.begin (), s.end (), pred);
2727 if (left==s.end ())
2828 return " " ;
2929
30- std::string::size_type i= std::distance (s.begin (), left);
30+ std::size_t i = std::distance (s.begin (), left);
3131
32- std::string ::const_reverse_iterator right
33- = std::find_if_not (s.rbegin (), s.rend (), pred);
34- std::string::size_type j= std::distance (right, s.rend ())- 1 ;
32+ std::string_view ::const_reverse_iterator right =
33+ std::find_if_not (s.rbegin (), s.rend (), pred);
34+ std::size_t j = std::distance (right, s.rend ()) - 1 ;
3535
36- return s.substr (i, (j-i+1 ));
36+ // copy happens here; this could return a view in the future
37+ return std::string{s.substr (i, (j - i + 1 ))};
3738}
3839
3940void split_string (
40- const std::string & s,
41+ std::string_view s,
4142 char delim,
4243 std::vector<std::string> &result,
4344 bool strip,
@@ -54,42 +55,48 @@ void split_string(
5455 return ;
5556 }
5657
57- std::string::size_type n= s.length ();
58+ std::size_t n = s.length ();
5859 INVARIANT (n > 0 , " Empty string case should already be handled" );
5960
60- std::string::size_type start= 0 ;
61- std::string::size_type i;
61+ std::size_t start = 0 ;
62+ std::size_t i;
6263
6364 for (i=0 ; i<n; i++)
6465 {
6566 if (s[i]==delim)
6667 {
67- std::string new_s=s.substr (start, i-start);
68+ // result owns std::strings rather than string_views: callers
69+ // routinely pass a temporary as `s` (e.g. some_function()
70+ // returning std::string), so the input may not outlive the
71+ // result.
72+ std::string new_s = std::string{s.substr (start, i - start)};
6873
6974 if (strip)
7075 new_s=strip_string (new_s);
7176
7277 if (!remove_empty || !new_s.empty ())
73- result.push_back (new_s);
78+ result.push_back (std::move ( new_s) );
7479
7580 start=i+1 ;
7681 }
7782 }
7883
79- std::string new_s=s.substr (start, n-start);
84+ // result owns std::strings rather than string_views: see the
85+ // comment above the first push_back in the loop.
86+ std::string new_s = std::string{s.substr (start, n - start)};
8087
8188 if (strip)
8289 new_s=strip_string (new_s);
8390
8491 if (!remove_empty || !new_s.empty ())
85- result.push_back (new_s);
92+ result.push_back (std::move ( new_s) );
8693
8794 if (!remove_empty && result.empty ())
8895 result.push_back (" " );
8996}
9097
9198void split_string (
92- const std::string & s,
99+ std::string_view s,
93100 char delim,
94101 std::string &left,
95102 std::string &right,
@@ -102,31 +109,26 @@ void split_string(
102109
103110 if (result.size () != 2 )
104111 {
105- throw deserialization_exceptiont{" expected string ' " + s +
106- " ' to contain two substrings "
107- " delimited by " +
108- delim + " but has " +
109- std::to_string (result.size ())};
112+ throw deserialization_exceptiont{
113+ " expected string ' " + std::string{s} +
114+ " ' to contain two substrings "
115+ " delimited by " +
116+ delim + " but has " + std::to_string (result.size ())};
110117 }
111118
112119 left=result[0 ];
113120 right=result[1 ];
114121}
115122
116- std::vector<std::string> split_string (
117- const std::string &s,
118- char delim,
119- bool strip,
120- bool remove_empty)
123+ std::vector<std::string>
124+ split_string (std::string_view s, char delim, bool strip, bool remove_empty)
121125{
122126 std::vector<std::string> result;
123127 split_string (s, delim, result, strip, remove_empty);
124128 return result;
125129}
126130
127- std::string trim_from_last_delimiter (
128- const std::string &s,
129- const char delim)
131+ std::string trim_from_last_delimiter (std::string_view s, const char delim)
130132{
131133 std::string result;
132134 const size_t index=s.find_last_of (delim);
@@ -135,7 +137,7 @@ std::string trim_from_last_delimiter(
135137 return result;
136138}
137139
138- std::string escape (const std::string & s)
140+ std::string escape (std::string_view s)
139141{
140142 std::string result;
141143
@@ -150,7 +152,7 @@ std::string escape(const std::string &s)
150152 return result;
151153}
152154
153- std::string escape_non_alnum (const std::string & to_escape)
155+ std::string escape_non_alnum (std::string_view to_escape)
154156{
155157 std::ostringstream escaped;
156158 for (auto &ch : to_escape)
@@ -172,11 +174,12 @@ std::string escape_non_alnum(const std::string &to_escape)
172174 }
173175 return escaped.str ();
174176}
175- std::string capitalize (const std::string &str)
177+
178+ std::string capitalize (std::string_view s)
176179{
177- if (str .empty ())
178- return str ;
179- std::string capitalized = str;
180+ if (s .empty ())
181+ return std::string{} ;
182+ std::string capitalized = std::string{s}; // copy
180183 capitalized[0 ] = toupper (capitalized[0 ]);
181184 return capitalized;
182185}
0 commit comments