12 #ifndef ZYPP_BASE_STRINGV_H 13 #define ZYPP_BASE_STRINGV_H 14 #include <string_view> 15 #ifdef __cpp_lib_string_view 17 #include <zypp-core/base/String.h> 18 #include <zypp-core/base/Regex.h> 19 #include <zypp-core/base/Flags.h> 26 using regex = str::regex;
27 using smatch = str::smatch;
40 inline constexpr std::string_view blank =
" \t";
43 inline std::string_view
ltrim( std::string_view str_r, std::string_view chars_r = blank )
47 auto pos = str_r.find_first_not_of( chars_r );
48 if ( pos == str_r.npos )
49 str_r.remove_prefix( str_r.size() );
51 str_r.remove_prefix( pos );
56 inline std::string_view
rtrim( std::string_view str_r, std::string_view chars_r = blank )
60 auto pos = str_r.find_last_not_of( chars_r );
61 if ( pos == str_r.npos )
62 str_r.remove_suffix( str_r.size() );
63 else if ( (pos = str_r.size()-1-pos) )
64 str_r.remove_suffix( pos );
69 inline std::string_view
trim( std::string_view str_r, std::string_view chars_r = blank )
73 str_r =
ltrim( std::move(str_r), chars_r );
74 str_r =
rtrim( std::move(str_r), chars_r );
79 inline std::string_view
trim( std::string_view str_r, std::string_view chars_r, TrimFlag trim_r )
81 if ( str_r.empty() || trim_r == Trim::notrim )
83 if ( trim_r.testFlag( Trim::left ) )
84 str_r =
ltrim( std::move(str_r), chars_r );
85 if ( trim_r.testFlag( Trim::right ) )
86 str_r =
rtrim( std::move(str_r), chars_r );
90 inline std::string_view
trim( std::string_view str_r, TrimFlag trim_r )
91 {
return trim( std::move(str_r), blank, std::move(trim_r) ); }
97 using WordConsumer = std::function<bool(std::string_view,unsigned,bool)>;
114 template <
typename Callable, std::enable_if_t<
115 std::is_invocable_r_v<bool,Callable,std::string_view,unsigned,bool>
117 WordConsumer wordConsumer( Callable && fnc_r )
118 {
return std::forward<Callable>(fnc_r); }
120 template <
typename Callable, std::enable_if_t<
121 ! std::is_invocable_r_v<bool,Callable,std::string_view,unsigned,bool>
122 && std::is_invocable_r_v<void,Callable,std::string_view,unsigned,bool>
124 WordConsumer wordConsumer( Callable && fnc_r )
125 {
return [&fnc_r](std::string_view a1,
unsigned a2,
bool a3)->
bool { fnc_r(a1,a2,a3);
return true; }; }
128 template <
typename Callable, std::enable_if_t<
129 std::is_invocable_r_v<bool,Callable,std::string_view,unsigned>
131 WordConsumer wordConsumer( Callable && fnc_r )
132 {
return [&fnc_r](std::string_view a1,
unsigned a2,
bool)->
bool {
return fnc_r(a1,a2); }; }
134 template <
typename Callable, std::enable_if_t<
135 ! std::is_invocable_r_v<bool,Callable,std::string_view,unsigned>
136 && std::is_invocable_r_v<void,Callable,std::string_view,unsigned>
138 WordConsumer wordConsumer( Callable && fnc_r )
139 {
return [&fnc_r](std::string_view a1,
unsigned a2,
bool)->
bool { fnc_r(a1,a2);
return true; }; }
142 template <
typename Callable, std::enable_if_t<
143 std::is_invocable_r_v<bool,Callable,std::string_view>
145 WordConsumer wordConsumer( Callable && fnc_r )
146 {
return [&fnc_r](std::string_view a1,unsigned,
bool)->
bool {
return fnc_r(a1); }; }
148 template <
typename Callable, std::enable_if_t<
149 ! std::is_invocable_r_v<bool,Callable,std::string_view>
150 && std::is_invocable_r_v<void,Callable,std::string_view>
152 WordConsumer wordConsumer( Callable && fnc_r )
153 {
return [&fnc_r](std::string_view a1,unsigned,
bool)->
bool { fnc_r(a1);
return true; }; }
156 template <
typename Callable, std::enable_if_t<
157 std::is_invocable_r_v<bool,Callable>
159 WordConsumer wordConsumer( Callable && fnc_r )
160 {
return [&fnc_r](std::string_view,unsigned,
bool)->
bool {
return fnc_r(); }; }
162 template <
typename Callable, std::enable_if_t<
163 ! std::is_invocable_r_v<bool,Callable>
164 && std::is_invocable_r_v<void,Callable>
166 WordConsumer wordConsumer( Callable && fnc_r )
167 {
return [&fnc_r](std::string_view,unsigned,
bool)->
bool { fnc_r();
return true; }; }
171 unsigned _split( std::string_view line_r, std::string_view sep_r,
Trim trim_r, WordConsumer && fnc_r );
174 unsigned _splitRx(
const std::string & line_r,
const regex & rx_r, WordConsumer && fnc_r );
199 template <
typename Callable = detail::WordConsumer>
200 unsigned splitRx(
const std::string & line_r,
const regex & rx_r, Callable && fnc_r = Callable() )
201 {
return detail::_splitRx( line_r, rx_r, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
264 template <
typename Callable = detail::WordConsumer>
265 unsigned split( std::string_view line_r, std::string_view sep_r,
Trim trim_r, Callable && fnc_r = Callable() )
266 {
return detail::_split( line_r, sep_r, trim_r, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
269 template <
typename Callable = detail::WordConsumer>
270 inline unsigned split( std::string_view line_r, std::string_view sep_r, Callable && fnc_r = Callable() )
271 {
return detail::_split( line_r, sep_r, Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
274 template <
typename Callable = detail::WordConsumer>
275 inline unsigned split( std::string_view line_r, Callable && fnc_r = Callable() )
276 {
return detail::_split( line_r, std::string_view(), Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
278 inline std::string_view asStringView(
const char * t )
279 {
return t ==
nullptr ? std::string_view() : t; }
284 #endif // __cpp_lib_string_view 285 #endif // ZYPP_BASE_STRINGV_H Trim
To define how to trim.
std::string ltrim(const std::string &s)
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, const Trim trim_r=NO_TRIM)
Split line_r into words.
std::string trim(const std::string &s, const Trim trim_r)
#define ZYPP_DECLARE_FLAGS_AND_OPERATORS(Name, Enum)
std::string rtrim(const std::string &s)
Easy-to use interface to the ZYPP dependency resolver.