libzypp  17.31.31
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/APIConfig.h>
18 #include <zypp-core/base/String.h>
19 #include <zypp-core/base/Regex.h>
20 #include <zypp-core/base/Flags.h>
21 
23 namespace zypp
24 {
25  namespace strv
26  {
27  using regex = str::regex;
28  using smatch = str::smatch;
29 
31  enum class Trim {
32  notrim = 0,
33  left = 1<<0,
34  right = 1<<1,
35  trim = (left|right),
36  };
37 
39 
41  inline constexpr std::string_view blank = " \t";
42 
44  inline std::string_view ltrim( std::string_view str_r, std::string_view chars_r = blank )
45  {
46  if ( str_r.empty() )
47  return str_r;
48  auto pos = str_r.find_first_not_of( chars_r );
49  if ( pos == str_r.npos )
50  str_r.remove_prefix( str_r.size() );
51  else if ( pos )
52  str_r.remove_prefix( pos );
53  return str_r;
54  }
55 
57  inline std::string_view rtrim( std::string_view str_r, std::string_view chars_r = blank )
58  {
59  if ( str_r.empty() )
60  return str_r;
61  auto pos = str_r.find_last_not_of( chars_r );
62  if ( pos == str_r.npos )
63  str_r.remove_suffix( str_r.size() );
64  else if ( (pos = str_r.size()-1-pos) )
65  str_r.remove_suffix( pos );
66  return str_r;
67  }
68 
70  inline std::string_view trim( std::string_view str_r, std::string_view chars_r = blank )
71  {
72  if ( str_r.empty() )
73  return str_r;
74  str_r = ltrim( std::move(str_r), chars_r );
75  str_r = rtrim( std::move(str_r), chars_r );
76  return str_r;
77  }
78 
80  inline std::string_view trim( std::string_view str_r, std::string_view chars_r, TrimFlag trim_r )
81  {
82  if ( str_r.empty() || trim_r == Trim::notrim )
83  return str_r;
84  if ( trim_r.testFlag( Trim::left ) )
85  str_r = ltrim( std::move(str_r), chars_r );
86  if ( trim_r.testFlag( Trim::right ) )
87  str_r = rtrim( std::move(str_r), chars_r );
88  return str_r;
89  }
91  inline std::string_view trim( std::string_view str_r, TrimFlag trim_r )
92  { return trim( std::move(str_r), blank, std::move(trim_r) ); }
93 
95  inline bool hasPrefix( std::string_view str_r, std::string_view prefix_r )
96  { return( ::strncmp( str_r.data(), prefix_r.data(), prefix_r.size() ) == 0 ); }
97 
99  inline bool hasPrefixCI( std::string_view str_r, std::string_view prefix_r )
100  { return( ::strncasecmp( str_r.data(), prefix_r.data(), prefix_r.size() ) == 0 ); }
101 
103  namespace detail
104  {
106  using WordConsumer = std::function<bool(std::string_view,unsigned,bool)>;
107 
123  template <typename Callable, std::enable_if_t<
124  std::is_invocable_r_v<bool,Callable,std::string_view,unsigned,bool>
125  , bool> = true>
126  WordConsumer wordConsumer( Callable && fnc_r )
127  { return std::forward<Callable>(fnc_r); }
129  template <typename Callable, std::enable_if_t<
130  ! std::is_invocable_r_v<bool,Callable,std::string_view,unsigned,bool>
131  && std::is_invocable_r_v<void,Callable,std::string_view,unsigned,bool>
132  , bool> = true>
133  WordConsumer wordConsumer( Callable && fnc_r )
134  { return [&fnc_r](std::string_view a1,unsigned a2,bool a3)->bool { fnc_r(a1,a2,a3); return true; }; }
135 
137  template <typename Callable, std::enable_if_t<
138  std::is_invocable_r_v<bool,Callable,std::string_view,unsigned>
139  , bool> = true>
140  WordConsumer wordConsumer( Callable && fnc_r )
141  { return [&fnc_r](std::string_view a1,unsigned a2,bool)->bool { return fnc_r(a1,a2); }; }
143  template <typename Callable, std::enable_if_t<
144  ! std::is_invocable_r_v<bool,Callable,std::string_view,unsigned>
145  && std::is_invocable_r_v<void,Callable,std::string_view,unsigned>
146  , bool> = true>
147  WordConsumer wordConsumer( Callable && fnc_r )
148  { return [&fnc_r](std::string_view a1,unsigned a2,bool)->bool { fnc_r(a1,a2); return true; }; }
149 
151  template <typename Callable, std::enable_if_t<
152  std::is_invocable_r_v<bool,Callable,std::string_view>
153  , bool> = true>
154  WordConsumer wordConsumer( Callable && fnc_r )
155  { return [&fnc_r](std::string_view a1,unsigned,bool)->bool { return fnc_r(a1); }; }
157  template <typename Callable, std::enable_if_t<
158  ! std::is_invocable_r_v<bool,Callable,std::string_view>
159  && std::is_invocable_r_v<void,Callable,std::string_view>
160  , bool> = true>
161  WordConsumer wordConsumer( Callable && fnc_r )
162  { return [&fnc_r](std::string_view a1,unsigned,bool)->bool { fnc_r(a1); return true; }; }
163 
165  template <typename Callable, std::enable_if_t<
166  std::is_invocable_r_v<bool,Callable>
167  , bool> = true>
168  WordConsumer wordConsumer( Callable && fnc_r )
169  { return [&fnc_r](std::string_view,unsigned,bool)->bool { return fnc_r(); }; }
171  template <typename Callable, std::enable_if_t<
172  ! std::is_invocable_r_v<bool,Callable>
173  && std::is_invocable_r_v<void,Callable>
174  , bool> = true>
175  WordConsumer wordConsumer( Callable && fnc_r )
176  { return [&fnc_r](std::string_view,unsigned,bool)->bool { fnc_r(); return true; }; }
178 
180  unsigned _split( std::string_view line_r, std::string_view sep_r, Trim trim_r, WordConsumer && fnc_r );
181 
183  unsigned _splitRx( std::string_view line_r, const regex & rx_r, WordConsumer && fnc_r );
184 #if LEGACY(1722)
185  unsigned _splitRx( const std::string & line_r, const regex & rx_r, WordConsumer && fnc_r );
186 #endif
187  } // namespace detail
189 
210  template <typename Callable = detail::WordConsumer>
211  unsigned splitRx( std::string_view line_r, const regex & rx_r, Callable && fnc_r = Callable() )
212  { return detail::_splitRx( line_r, rx_r, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
213 
214 
275  template <typename Callable = detail::WordConsumer>
276  unsigned split( std::string_view line_r, std::string_view sep_r, Trim trim_r, Callable && fnc_r = Callable() )
277  { return detail::_split( line_r, sep_r, trim_r, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
278 
280  template <typename Callable = detail::WordConsumer>
281  inline unsigned split( std::string_view line_r, std::string_view sep_r, Callable && fnc_r = Callable() )
282  { return detail::_split( line_r, sep_r, Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
283 
285  template <typename Callable = detail::WordConsumer>
286  inline unsigned split( std::string_view line_r, Callable && fnc_r = Callable() )
287  { return detail::_split( line_r, std::string_view(), Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
288 
289  inline std::string_view asStringView( const char * t )
290  { return t == nullptr ? std::string_view() : t; }
291 
292  } // namespace strv
293 } // namespace zypp
295 #endif // __cpp_lib_string_view
296 #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
Provides API related macros.
#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