irccd  3.0.3
string_util.hpp
1 /*
2  * string_util.hpp -- string utilities
3  *
4  * Copyright (c) 2013-2019 David Demelier <markand@malikania.fr>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef IRCCD_STRING_UTIL_HPP
20 #define IRCCD_STRING_UTIL_HPP
21 
27 #include "sysconfig.hpp"
28 
29 #include <ctime>
30 #include <initializer_list>
31 #include <limits>
32 #include <optional>
33 #include <sstream>
34 #include <stdexcept>
35 #include <string>
36 #include <string_view>
37 #include <type_traits>
38 #include <unordered_map>
39 #include <vector>
40 
41 namespace irccd {
42 
46 namespace string_util {
47 
48 // {{{ subst
49 
53 enum class subst_flags : unsigned {
54  date = (1 << 0),
55  keywords = (1 << 1),
56  env = (1 << 2),
57  shell = (1 << 3),
58  irc_attrs = (1 << 4),
59  shell_attrs = (1 << 5)
60 };
61 
73 inline auto operator^(subst_flags v1, subst_flags v2) noexcept -> subst_flags
74 {
75  return static_cast<subst_flags>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2));
76 }
77 
85 inline auto operator&(subst_flags v1, subst_flags v2) noexcept -> subst_flags
86 {
87  return static_cast<subst_flags>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2));
88 }
89 
97 inline auto operator|(subst_flags v1, subst_flags v2) noexcept -> subst_flags
98 {
99  return static_cast<subst_flags>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2));
100 }
101 
108 inline auto operator~(subst_flags v) noexcept -> subst_flags
109 {
110  return static_cast<subst_flags>(~static_cast<unsigned>(v));
111 }
112 
120 inline auto operator|=(subst_flags& v1, subst_flags v2) noexcept -> subst_flags&
121 {
122  return v1 = v1 | v2;
123 }
124 
132 inline auto operator&=(subst_flags& v1, subst_flags v2) noexcept -> subst_flags&
133 {
134  return v1 = v1 & v2;
135 }
136 
144 inline auto operator^=(subst_flags& v1, subst_flags v2) noexcept -> subst_flags&
145 {
146  return v1 = v1 ^ v2;
147 }
148 
156 class subst {
157 public:
166  };
167 
171  std::time_t time{std::time(nullptr)};
172 
176  std::unordered_map<std::string, std::string> keywords;
177 };
178 
237 auto format(std::string text, const subst& params = {}) -> std::string;
238 
239 // }}}
240 
241 // {{{ strip
242 
249 auto strip(std::string str) noexcept -> std::string;
250 
251 // }}}
252 
253 // {{{ split
254 
263 auto split(std::string_view list, const std::string& delimiters, int max = -1) -> std::vector<std::string>;
264 
265 // }}}
266 
267 // {{{ join
268 
277 template <typename InputIt, typename DelimType = char>
278 auto join(InputIt first, InputIt last, DelimType delim = ':') -> std::string
279 {
280  std::ostringstream oss;
281 
282  if (first != last) {
283  oss << *first;
284 
285  while (++first != last)
286  oss << delim << *first;
287  }
288 
289  return oss.str();
290 }
291 
299 template <typename Container, typename DelimType = char>
300 auto join(const Container& c, DelimType delim = ':') -> std::string
301 {
302  return join(c.begin(), c.end(), delim);
303 }
304 
312 template <typename T, typename DelimType = char>
313 auto join(std::initializer_list<T> list, DelimType delim = ':') -> std::string
314 {
315  return join(list.begin(), list.end(), delim);
316 }
317 
318 // }}}
319 
320 // {{{ is_identifier
321 
328 auto is_identifier(std::string_view name) noexcept -> bool;
329 
330 // }}}
331 
332 // {{{ is_boolean
333 
341 auto is_boolean(std::string value) noexcept -> bool;
342 
343 // }}}
344 
345 // {{{ to_int
346 
355 template <typename T = int>
356 auto to_int(const std::string& str,
357  T min = std::numeric_limits<T>::min(),
358  T max = std::numeric_limits<T>::max()) noexcept -> std::optional<T>
359 {
360  static_assert(std::is_signed<T>::value, "must be signed");
361 
362  char* end;
363  auto v = std::strtoll(str.c_str(), &end, 10);
364 
365  if (*end != '\0' || v < min || v > max)
366  return std::nullopt;
367 
368  return static_cast<T>(v);
369 }
370 
371 // }}}
372 
373 // {{{ to_uint
374 
384 template <typename T = unsigned>
385 auto to_uint(const std::string& str,
386  T min = std::numeric_limits<T>::min(),
387  T max = std::numeric_limits<T>::max()) noexcept -> std::optional<T>
388 {
389  static_assert(std::is_unsigned<T>::value, "must be unsigned");
390 
391  char* end;
392  auto v = std::strtoull(str.c_str(), &end, 10);
393 
394  if (*end != '\0' || v < min || v > max)
395  return std::nullopt;
396 
397  return static_cast<T>(v);
398 }
399 
400 // }}}
401 
402 } // !string_util
403 
404 } // !irccd
405 
406 #endif // !IRCCD_STRING_UTIL_HPP
irccd::string_util::join
auto join(InputIt first, InputIt last, DelimType delim=':') -> std::string
Definition: string_util.hpp:278
irccd::string_util::is_identifier
auto is_identifier(std::string_view name) noexcept -> bool
irccd::string_util::split
auto split(std::string_view list, const std::string &delimiters, int max=-1) -> std::vector< std::string >
irccd::string_util::subst::time
std::time_t time
Definition: string_util.hpp:171
irccd::string_util::subst_flags::shell_attrs
@ shell_attrs
shell attributes
irccd::string_util::subst
Used for format() function.
Definition: string_util.hpp:156
irccd::string_util::to_uint
auto to_uint(const std::string &str, T min=std::numeric_limits< T >::min(), T max=std::numeric_limits< T >::max()) noexcept -> std::optional< T >
Definition: string_util.hpp:385
irccd::string_util::subst_flags::env
@ env
environment variables
irccd::string_util::subst_flags::irc_attrs
@ irc_attrs
IRC escape codes.
irccd::string_util::to_int
auto to_int(const std::string &str, T min=std::numeric_limits< T >::min(), T max=std::numeric_limits< T >::max()) noexcept -> std::optional< T >
Definition: string_util.hpp:356
irccd::string_util::subst_flags::date
@ date
date templates
irccd::string_util::subst_flags::keywords
@ keywords
keywords
irccd
Parent namespace.
Definition: acceptor.hpp:43
std
Definition: bot.hpp:253
irccd::string_util::subst::keywords
std::unordered_map< std::string, std::string > keywords
Definition: string_util.hpp:176
irccd::string_util::format
auto format(std::string text, const subst &params={}) -> std::string
irccd::string_util::subst_flags::shell
@ shell
command line command
irccd::string_util::subst_flags
subst_flags
Disable or enable some features.
Definition: string_util.hpp:53
irccd::string_util::strip
auto strip(std::string str) noexcept -> std::string
irccd::string_util::subst::flags
subst_flags flags
Definition: string_util.hpp:161
irccd::string_util::is_boolean
auto is_boolean(std::string value) noexcept -> bool