libzypp  17.31.8
StringV.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_BASE_STRINGV_H
13 #define ZYPP_BASE_STRINGV_H
14 #include <string_view>
15 #ifdef __cpp_lib_string_view
16 
17 #include <zypp-core/base/String.h>
18 #include <zypp-core/base/Regex.h>
19 #include <zypp-core/base/Flags.h>
20 
22 namespace zypp
23 {
24  namespace strv
25  {
26  using regex = str::regex;
27  using smatch = str::smatch;
28 
30  enum class Trim {
31  notrim = 0,
32  left = 1<<0,
33  right = 1<<1,
34  trim = (left|right),
35  };
36 
38 
40  inline constexpr std::string_view blank = " \t";
41 
43  inline std::string_view ltrim( std::string_view str_r, std::string_view chars_r = blank )
44  {
45  if ( str_r.empty() )
46  return str_r;
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() );
50  else if ( pos )
51  str_r.remove_prefix( pos );
52  return str_r;
53  }
54 
56  inline std::string_view rtrim( std::string_view str_r, std::string_view chars_r = blank )
57  {
58  if ( str_r.empty() )
59  return str_r;
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 );
65  return str_r;
66  }
67 
69  inline std::string_view trim( std::string_view str_r, std::string_view chars_r = blank )
70  {
71  if ( str_r.empty() )
72  return str_r;
73  str_r = ltrim( std::move(str_r), chars_r );
74  str_r = rtrim( std::move(str_r), chars_r );
75  return str_r;
76  }
77 
79  inline std::string_view trim( std::string_view str_r, std::string_view chars_r, TrimFlag trim_r )
80  {
81  if ( str_r.empty() || trim_r == Trim::notrim )
82  return str_r;
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 );
87  return str_r;
88  }
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) ); }
92 
94  inline bool hasPrefix( std::string_view str_r, std::string_view prefix_r )
95  { return( ::strncmp( str_r.data(), prefix_r.data(), prefix_r.size() ) == 0 ); }
96 
98  inline bool hasPrefixCI( std::string_view str_r, std::string_view prefix_r )
99  { return( ::strncasecmp( str_r.data(), prefix_r.data(), prefix_r.size() ) == 0 ); }
100 
102  namespace detail
103  {
105  using WordConsumer = std::function<bool(std::string_view,unsigned,bool)>;
106 
122  template <typename Callable, std::enable_if_t<
123  std::is_invocable_r_v<bool,Callable,std::string_view,unsigned,bool>
124  , bool> = true>
125  WordConsumer wordConsumer( Callable && fnc_r )
126  { return std::forward<Callable>(fnc_r); }
128  template <typename Callable, std::enable_if_t<
129  ! std::is_invocable_r_v<bool,Callable,std::string_view,unsigned,bool>
130  && std::is_invocable_r_v<void,Callable,std::string_view,unsigned,bool>
131  , bool> = true>
132  WordConsumer wordConsumer( Callable && fnc_r )
133  { return [&fnc_r](std::string_view a1,unsigned a2,bool a3)->bool { fnc_r(a1,a2,a3); return true; }; }
134 
136  template <typename Callable, std::enable_if_t<
137  std::is_invocable_r_v<bool,Callable,std::string_view,unsigned>
138  , bool> = true>
139  WordConsumer wordConsumer( Callable && fnc_r )
140  { return [&fnc_r](std::string_view a1,unsigned a2,bool)->bool { return fnc_r(a1,a2); }; }
142  template <typename Callable, std::enable_if_t<
143  ! std::is_invocable_r_v<bool,Callable,std::string_view,unsigned>
144  && std::is_invocable_r_v<void,Callable,std::string_view,unsigned>
145  , bool> = true>
146  WordConsumer wordConsumer( Callable && fnc_r )
147  { return [&fnc_r](std::string_view a1,unsigned a2,bool)->bool { fnc_r(a1,a2); return true; }; }
148 
150  template <typename Callable, std::enable_if_t<
151  std::is_invocable_r_v<bool,Callable,std::string_view>
152  , bool> = true>
153  WordConsumer wordConsumer( Callable && fnc_r )
154  { return [&fnc_r](std::string_view a1,unsigned,bool)->bool { return fnc_r(a1); }; }
156  template <typename Callable, std::enable_if_t<
157  ! std::is_invocable_r_v<bool,Callable,std::string_view>
158  && std::is_invocable_r_v<void,Callable,std::string_view>
159  , bool> = true>
160  WordConsumer wordConsumer( Callable && fnc_r )
161  { return [&fnc_r](std::string_view a1,unsigned,bool)->bool { fnc_r(a1); return true; }; }
162 
164  template <typename Callable, std::enable_if_t<
165  std::is_invocable_r_v<bool,Callable>
166  , bool> = true>
167  WordConsumer wordConsumer( Callable && fnc_r )
168  { return [&fnc_r](std::string_view,unsigned,bool)->bool { return fnc_r(); }; }
170  template <typename Callable, std::enable_if_t<
171  ! std::is_invocable_r_v<bool,Callable>
172  && std::is_invocable_r_v<void,Callable>
173  , bool> = true>
174  WordConsumer wordConsumer( Callable && fnc_r )
175  { return [&fnc_r](std::string_view,unsigned,bool)->bool { fnc_r(); return true; }; }
177 
179  unsigned _split( std::string_view line_r, std::string_view sep_r, Trim trim_r, WordConsumer && fnc_r );
180 
182  unsigned _splitRx( const std::string & line_r, const regex & rx_r, WordConsumer && fnc_r );
183 
184  } // namespace detail
186 
207  template <typename Callable = detail::WordConsumer>
208  unsigned splitRx( const std::string & line_r, const regex & rx_r, Callable && fnc_r = Callable() )
209  { return detail::_splitRx( line_r, rx_r, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
210 
211 
272  template <typename Callable = detail::WordConsumer>
273  unsigned split( std::string_view line_r, std::string_view sep_r, Trim trim_r, Callable && fnc_r = Callable() )
274  { return detail::_split( line_r, sep_r, trim_r, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
275 
277  template <typename Callable = detail::WordConsumer>
278  inline unsigned split( std::string_view line_r, std::string_view sep_r, Callable && fnc_r = Callable() )
279  { return detail::_split( line_r, sep_r, Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
280 
282  template <typename Callable = detail::WordConsumer>
283  inline unsigned split( std::string_view line_r, Callable && fnc_r = Callable() )
284  { return detail::_split( line_r, std::string_view(), Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
285 
286  inline std::string_view asStringView( const char * t )
287  { return t == nullptr ? std::string_view() : t; }
288 
289  } // namespace strv
290 } // namespace zypp
292 #endif // __cpp_lib_string_view
293 #endif // ZYPP_BASE_STRINGV_H
bool hasPrefixCI(const C_Str &str_r, const C_Str &prefix_r)
Definition: String.h:1030
Trim
To define how to trim.
Definition: String.h:496
std::string ltrim(const std::string &s)
Definition: String.h:506
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.
Definition: String.h:531
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:223
#define ZYPP_DECLARE_FLAGS_AND_OPERATORS(Name, Enum)
Definition: Flags.h:189
std::string rtrim(const std::string &s)
Definition: String.h:511
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1027