gempyre  1.7.1
gempyre_utils.h
Go to the documentation of this file.
1 #ifndef UTILS_H
2 #define UTILS_H
3 
4 #include <ctime>
5 #include <chrono>
6 #include <vector>
7 #include <map>
8 #include <sstream>
9 #include <fstream>
10 #include <optional>
11 #include <variant>
12 #include <functional>
13 #include <algorithm>
14 #include <future>
15 #include <limits>
16 #include <iomanip>
17 #include <any>
18 #include <string_view>
19 
33 #define GEMPYREUTILSDEBUG(x) GempyreUtils::log(Utils::LogLevel::Debug, x, __FILE__, __LINE__)
36 #define gempyre_utils_assert(b) (b || GempyreUtils::do_fatal("Panic!", nullptr, __FILE__, __LINE__))
38 #define gempyre_utils_assert_x(b, x) (b || GempyreUtils::do_fatal(x, nullptr, __FILE__, __LINE__))
40 #define gempyre_utils_assert_x_f(b, x, f) (b || GempyreUtils::do_fatal(x, f, __FILE__, __LINE__))
42 #define gempyre_utils_fatal(x) GempyreUtils::do_fatal(x, nullptr, __FILE__, __LINE__)
44 #define gempyre_utils_fatal_f(x, f) GempyreUtils::do_fatal(x, f, __FILE__, __LINE__)
46 #define gempyre_utils_auto_clean(p, f) std::unique_ptr<std::remove_pointer<decltype(p)>::type, decltype(&f)> _ ## p (p, &f)
48 #define gempyre_utils_auto_close(p, f) GempyreUtils::_Close<std::decay_t<decltype(p)>, decltype(&f)> _ ## p (p, &f)
49 
51 
52 #ifdef WINDOWS_EXPORT
53  #define UTILS_EX __declspec(dllexport)
54 #else
55  #define UTILS_EX
56 #endif
57 
58 #ifdef _MSC_VER
59 using SSIZE_T = long long;
60 #else
61 using SSIZE_T = ssize_t;
62 #endif
63 
64 
66 
67 namespace GempyreUtils {
71 enum class LogLevel : int {
72  None,
73  Fatal,
74  Error,
75  Warning,
76  Info,
77  Debug,
79  };
80 
82 class LogWriter {
83 public:
87  virtual ~LogWriter();
88  LogWriter(const GempyreUtils::LogWriter&) = delete;
89  LogWriter& operator=(const GempyreUtils::LogWriter&) = delete;
93  virtual std::string header(LogLevel logLevel);
94 
99  virtual bool do_write(const char* buffer, size_t count) = 0;
101  virtual bool has_ansi() const;
102 private:
103  LogWriter* m_previousLogWriter{nullptr};
104 };
105 
107 class UTILS_EX FileLogWriter : public LogWriter {
108 public:
109  FileLogWriter(std::string_view path);
110 protected:
111  bool do_write(const char* buffer, size_t count) override;
112 protected:
113  std::ofstream m_file;
114 };
115 
116 class UTILS_EX StreamLogWriter : public LogWriter {
117 public:
118  StreamLogWriter(std::ostream& os);
119 protected:
120  bool do_write(const char* buffer, size_t count) override;
121 protected:
122  std::ostream& m_os;
123 };
125 
128 UTILS_EX void set_log_level(LogLevel level);
129 
132 UTILS_EX LogLevel log_level();
133 
137 UTILS_EX std::string to_str(LogLevel log_level);
138 
140 UTILS_EX std::ostream log_stream(LogLevel logLevel);
141 
142 template <typename T, typename ...Args>
143 inline void log_line(LogLevel level, std::ostream& os, const T& e, Args... args) {
144  os << e << " ";
145  log_line(level, os, args...);
146 }
147 
148 
149 UTILS_EX void process_exit(int);
150 
151 template<typename T>
152 inline void log_line(LogLevel level, std::ostream& os, const T& e) {
153  os << e << std::endl;
154  if(level == LogLevel::Fatal) {
155  process_exit(99);
156  }
157 }
159 
164 template <typename T, typename ...Args>
165 inline void log(LogLevel level, const T& e, Args... args) {
166  if(level <= log_level()) {
167  auto os = log_stream(level);
168  log_line(level, os, e, args...);
169  }
170 }
171 
173 template <LogLevel level, typename T, typename ...Args>
174 inline void write_log(const T& e, Args... args) {
175  log(level, e, args...);
176 }
178 
180 template <typename T, typename ...Args>
181 inline void log_debug(const T& e, Args... args) {
182  write_log<LogLevel::Debug, T, Args...>(e, args...);
183 }
184 
185 
187 inline bool do_fatal(std::string_view txt, std::function<void()> f, const char* file, int line) {
188  if(f) f();
189  log(LogLevel::Fatal, txt, "at", file, "line:", line);
190  return false;
191 }
193 
194 
195 #ifdef _MSC_VER
196 #define __PRETTY_FUNCTION__ __FUNCSIG__
197 #endif
198 
200 #define GEM_DEBUG(...) GempyreUtils::log(GempyreUtils::LogLevel::Debug, __PRETTY_FUNCTION__, __VA_ARGS__)
202 }
203 
204 
205 
206 
210 namespace GempyreUtils {
211 
213 //Helper for C memory management
214 template <typename T, typename A>
215 class _Close {
216 public:
217  _Close(T ref, A&& f) : t(ref), d(f) {}
218  ~_Close() {(void) this->d(this->t);}
219  _Close(_Close&& other) = default;
220  _Close& operator=(_Close&& other) = default;
221  _Close(const _Close& other) = delete;
222  _Close& operator=(const _Close& other) = delete;
223 private:
224  T t;
225  A d;
226 };
228 
229 
231 UTILS_EX void init();
232 UTILS_EX std::string current_time_string();
233 UTILS_EX std::string last_error();
235 
237 template<typename E>
238 struct ErrorValue {
239  ErrorValue(E&& e) : err{e} {}
240  ErrorValue(const E& e) : err{e} {}
241  E err;
242  };
244 
248 // internal for Result
249 template <typename E> struct Error {
251  using value_type = E;
253  E error;
254 };
256 template <typename R, typename E = std::string>
257 struct Result : private std::variant<R, Error<E>> {
259  using Err = Error<E>;
262  using value_type = R;
264  using error_type = E;
267  constexpr Result(R&& r) : std::variant<R, Err>{r} {}
270  constexpr Result(Err&& e) : std::variant<R, Err>{e} {} // use makeError
273  constexpr Result(const R& r) : std::variant<R, Err>{r} {}
276  constexpr Result(const Err& e) : std::variant<R,Err>{e} {}
280  constexpr Result& operator=(R&& r) {*this = std::move(r); return *this;}
284  constexpr Result& operator=(Err&& e) {*this = std::move(e); return *this;}
288  constexpr Result& operator=(const R& r) {*this = r; return *this;}
292  constexpr Result& operator=(const Err &e) {*this = e; return *this;}
294  constexpr operator bool() const {return std::get_if<R>(this);}
296  constexpr operator std::optional<R>() const {return has_value() ? std::make_optional<R>(value()) : std::nullopt;}
298  constexpr bool has_value() const {return operator bool();}
300  constexpr const R& value() const {return std::get<R>(*this);}
302  constexpr const E& error() const {return std::get<Err>(*this).error;}
304  constexpr R& value() {return std::get<R>(*this);}
306  constexpr R& operator *() {return std::get<R>(*this);}
308  constexpr const R& operator *() const {return std::get<R>(*this);}
310  constexpr R* operator ->() {return &std::get<R>(*this);}
312  constexpr const R* operator ->() const {return &std::get<R>(*this);}
316  constexpr static auto make_error(const E& e) {return Result<R, E>{Error<E>{e}};}
320  constexpr static auto make_error(E&& e) {return Result<R, E>{Error<E>{e}};}
323  constexpr static auto make_error() {return Result<R, E>{Error<E>{}};}
326  constexpr static auto ok() {return Result<R, E>{R{}};}
327 };
328 
330 template <typename R, typename E>
331 constexpr inline bool operator==(const Result<R, E>& a, const Result<R, E>& b) {return Result<R, E>::ParentType::operator==(a, b);}
333 template <typename R, typename E>
334 constexpr inline bool operator!=(const Result<R, E>& a, const Result<R, E>& b) {return !operator==(a, b);}
335 
338 
344 template<typename T, typename... A>
346  std::stringstream str;
347  (str << ... << a); //str << ... << a;
348  return Result<T, std::string>::make_error(str.str());
349 }
350 
358 UTILS_EX std::string qq(std::string_view s);
359 
363 UTILS_EX std::string chop(std::string_view s);
364 
369 UTILS_EX std::string chop(std::string_view s, std::string_view chopped);
370 
376 UTILS_EX std::string substitute(std::string_view str, std::string_view substring, std::string_view substitution);
377 
381 UTILS_EX std::string remove_spaces(std::string_view str);
382 
384 template <typename T>
385 T convert(std::string_view source) {
386  std::istringstream ss(std::string{source});
387  typename std::remove_const<T>::type v{};
388  ss.operator>>(v); //overloads have similar conversions MSVC19
389  return v;
390 }
391 
396 inline
397 std::string_view right(std::string_view str, size_t p) {
398  return str.substr(str.length() - p);
399 }
400 
401 template <>
402 inline std::string convert<std::string>(std::string_view source)
403 {
404  return std::string{source};
405 }
407 
412 template <typename T>
413 std::optional<T> parse(std::string_view source) {
414  std::istringstream ss(std::string{source});
415  T v;
416  static_cast<std::istream&>(ss) >> v; //MSVC said it would be otherwise ambiguous
417  return !ss.fail() ? std::make_optional(v) : std::nullopt;
418 }
419 
423 template <class T>
424 std::string to_low(const T& str) {
425  std::string n;
426  std::transform(std::begin(str), std::end(str), std::back_inserter(n),
427  [](auto c){return std::tolower(c);});
428  return n;
429 }
430 
431 
435 template <class T>
436 std::string to_upper(const T& str) {
437  std::string n;
438  std::transform(std::begin(str), std::end(str), std::back_inserter(n),
439  [](auto c){return std::toupper(c);});
440  return n;
441 }
442 
443 
447 inline std::string_view ltrim(std::string_view str) {
448  const auto begin = std::find_if(str.begin(), str.end(), [](auto ch) {
449  return (ch > ' ');
450  });
451  return str.substr(static_cast<std::string_view::size_type>(
452  std::distance(str.begin(), begin)));
453 }
454 
458 inline std::string_view rtrim(std::string_view str) {
459  const auto end = std::find_if(str.rbegin(), str.rend(), [](auto ch) {
460  return (ch > ' ');
461  });
462  return str.substr(0, static_cast<std::string_view::size_type>(
463  std::distance(end, str.rend())));
464 }
465 
469 inline std::string_view trim(std::string_view str) {
470  return ltrim(rtrim(str));
471 }
472 
473 
474 
478  template< typename T >
479  std::string to_hex(T ival) {
480  std::stringstream stream;
481  stream << std::setfill('0') << std::setw(sizeof(T) * 2)
482  << std::hex << ival;
483  return stream.str();
484  }
485 
486 
491 UTILS_EX int levenshtein_distance(std::string_view s1, std::string_view s2);
492 
496 UTILS_EX bool is_valid_utf8(std::string_view str);
497 
503 template<typename C, typename T>
504 std::optional<T> at(const C& container, std::string_view s, unsigned index = 0) {
505  const auto range = container.equal_range(s);
506  const auto it = std::next(range.first, index);
507  return (std::distance(range.first, it) < std::distance(range.first, range.second)) ?
508  std::make_optional(it->second) : std::nullopt;
509 }
510 
511 template<typename C, typename T>
512 T at_or(const C& container, std::string_view s, const T& defaultValue, unsigned index = 0) {
513  const auto v = at<C, T>(container, s, index);
514  return v.has_value() ? *v : defaultValue;
515 }
517 
523 template <class Container = std::vector<std::string>>
524 Container split(std::string_view str, const char splitChar = ' ') {
525  Container con;
526  std::istringstream iss(std::string{str});
527  for(std::string token; iss.good() && std::getline(iss, token, splitChar);) {
528  con.insert(con.end(), convert<typename Container::value_type>(token));
529  }
530  return con;
531 }
532 
534 template <typename IT>
535 inline constexpr std::string_view make_string_view(IT begin, IT end)
536 {
537  return (begin == end) ? std::string_view{nullptr} : std::string_view{&*begin, std::distance(begin, end)};
538 }
540 
546 template <class T, typename K = typename T::key_type>
547 std::vector<K> keys(const T& map) {
548  std::vector<K> ks; ks.resize(map.size());
549  std::transform(map.begin(), map.end(), ks.begin(), [](const auto& p) {return p.first;});
550  return ks;
551 }
552 
554  template<typename V>
555  struct DefaultJoiner {
556  auto operator()(const V& v) const {return v;}
557  };
559 
561 template <class IT, typename In, typename Out>
562 [[deprecated("See join with Callable")]] std::string join(const IT& begin,
563  const IT& end,
564  std::string_view joinChar = "",
565  const std::function<Out (const In&)>& f = [](const In& k)->Out{return k;}) {
566  std::string s;
567  std::ostringstream iss(s);
568  if(begin != end) {
569  for(auto it = begin;;) {
570  iss << f(*it);
571  if(!(++it != end)) break;
572  if(!joinChar.empty())
573  iss << joinChar;
574  }
575  }
576  return iss.str();
577 }
578 
579 template <class T, typename In, typename Out>
580 [[deprecated("See join with Callable")]] std::string join(const T& t,
581  std::string_view joinChar = "",
582  const std::function<Out (const In&)>& f = [](const In& v)->Out{return v;}) {
583  return join(t.begin(), t.end(), joinChar, f);
584 }
585 
586 template <class IT, typename In, typename Out, typename = std::enable_if_t<std::is_pointer<IT>::value>>
587 [[deprecated("See join with Callable")]] std::string join(const IT begin,
588  const IT end,
589  std::string_view joinChar = "",
590  const std::function<Out (const In&)>& f = [](const In& k)->Out{return k;}) {
591  std::string s;
592  std::ostringstream iss(s);
593  if(begin != end) {
594  for(auto it = begin;;) {
595  iss << f(*it);
596  if(!(++it != end)) break;
597  if(!joinChar.empty())
598  iss << joinChar;
599  }
600  }
601  return iss.str();
602 }
603 
605 
614 template <typename IT, typename Callable = DefaultJoiner<typename IT::value_type>,
615  typename = std::enable_if_t<!std::is_pointer<IT>::value>>
616 std::string join(const IT& begin,
617  const IT& end,
618  std::string_view joinChar = "",
619  const Callable& f = Callable{}) {
620  std::string s;
621  std::ostringstream iss(s);
622  if(begin != end) {
623  for(auto it = begin;;) {
624  iss << f(*it);
625  if(!(++it != end)) break;
626  if(!joinChar.empty())
627  iss << joinChar;
628  }
629  }
630  return iss.str();
631 }
632 
642  typename = std::enable_if_t<std::is_pointer<IT>::value>>
643 std::string join(const IT begin,
644  const IT end,
645  std::string_view joinChar = "",
646  const Callable& f = Callable{}) {
647  std::string s;
648  std::ostringstream iss(s);
649  if(begin != end) {
650  for(auto it = begin;;) {
651  iss << f(*it);
652  if(!(++it != end)) break;
653  if(!joinChar.empty())
654  iss << joinChar;
655  }
656  }
657  return iss.str();
658 }
659 
667 template <typename T, typename Callable = DefaultJoiner<typename T::value_type>>
668 std::string join(const T& t,
669  std::string_view joinChar = "",
670  const Callable& f = Callable{}) {
671  return join(std::begin(t), std::end(t), joinChar, f);
672 }
673 
675 template <typename T>
676 T merge(const T& b1, const T& b2) {
677  T bytes(b1.size() + b2.size());
678  auto begin = bytes.begin();
679  std::copy(b1.begin(), b1.end(), begin);
680  std::advance(begin, std::distance(b1.begin(), b1.end()));
681  std::copy(b2.begin(), b2.end(), begin);
682  return bytes;
683  }
684 
685 // I just wonder why copy instead of move hence not public
686 template <typename T, typename ...Arg>
687 T merge(const T& b1, const T& b2, Arg ...args) {
688  T bytes(b1.size() + b2.size());
689  auto begin = bytes.begin();
690  std::copy(b1.begin(), b1.end(), begin);
691  std::advance(begin, std::distance(b1.begin(), b1.end()));
692  std::copy(b2.begin(), b2.end(), begin);
693  return merge(bytes, args...);
694 }
696 
698 template <typename IT> IT advanced(IT it, int distance) {
699  std::advance(it, distance);
700  return it;
701 }
702 
703 template <typename K, typename V >
705 std::optional<V> get_value(const std::multimap<K, V>& map, const K& key, int index = 0)
706 {
707  const auto range = map.equal_range(key);
708  return std::distance(range.first, range.second) > index ?
709  std::make_optional((advanced(range.first, index))->second) : std::nullopt;
710 }
711 
712 
713  /*
714  * Misc Utils
715  */
716 
718 
719 class expiror;
720 [[nodiscard]]
721 UTILS_EX std::shared_ptr<expiror> wait_expire(std::chrono::seconds s, const std::function<void ()>& onExpire);
722 class expiror {
723 public:
724  ~expiror() {m_f.wait();}
725 private:
726  expiror() = default;
727  expiror(std::future<void>&& f) : m_f(std::move(f)) {}
728  std::future<void> m_f{};
729  friend std::shared_ptr<GempyreUtils::expiror> GempyreUtils::wait_expire(std::chrono::seconds s, const std::function<void ()>& onExpire);
730 };
731 
733 
738 UTILS_EX std::string hexify(std::string_view src, std::string_view pat);
739 
743 UTILS_EX std::string unhexify(std::string_view src);
744 
746 enum class OS {OtherOs, MacOs, WinOs, LinuxOs, AndroidOs, RaspberryOs};
747 
749 UTILS_EX OS current_os();
750 
752 UTILS_EX std::string html_file_launch_cmd();
754 
755 
757 enum AddressType : unsigned {Ipv4 = 0x1, Ipv6 = 0x2};
761 UTILS_EX std::vector<std::string> ip_addresses(unsigned addressType);
762 
763 
768 enum class PathStyle {Native, Unix, Win};
769 
771 UTILS_EX std::string get_link(std::string_view fname);
773 UTILS_EX bool is_dir(std::string_view fname);
775 UTILS_EX std::string working_dir();
777 UTILS_EX std::string home_dir();
779 UTILS_EX std::string root_dir();
781 UTILS_EX std::string abs_path(std::string_view rpath);
787 UTILS_EX std::string path_pop(std::string_view filename, int steps = 1, PathStyle path_style = PathStyle::Native);
789 UTILS_EX std::vector<std::string> entries(std::string_view dirname);
790 
792 [[deprecated("use entries")]]
793 inline std::vector<std::string> directory(std::string_view dirname) {return entries(dirname);}
795 
800 UTILS_EX std::optional<std::string> read_process(std::string_view processName, const std::vector<std::string>& params);
802 UTILS_EX std::string base_name(std::string_view filename, PathStyle path_style = PathStyle::Native);
804 UTILS_EX std::tuple<std::string, std::string> split_name(std::string_view filename, PathStyle path_style = PathStyle::Native);
806 UTILS_EX std::string temp_name();
808 UTILS_EX std::string host_name();
810 UTILS_EX std::optional<std::string> system_env(std::string_view env);
812 UTILS_EX bool is_hidden_entry(std::string_view filename);
814 UTILS_EX bool is_executable(std::string_view filename);
816 UTILS_EX SSIZE_T file_size(std::string_view filename);
818 UTILS_EX bool rename(std::string_view of, std::string_view nf);
820 UTILS_EX void remove_file(std::string_view filename);
822 UTILS_EX bool file_exists(std::string_view filename);
824 UTILS_EX std::optional<std::string> which(std::string_view filename);
826 UTILS_EX std::string push_path(std::string_view path, std::string_view name);
828 template<class ...NAME>
829 std::string push_path(std::string_view path, std::string_view name, NAME...names) {
830  return push_path(push_path(path, name), names...);
831 }
832 
834 UTILS_EX int execute(std::string_view prog, const std::vector<std::string_view>& parameters);
835 
837 template<class ...PARAM>
838 UTILS_EX int execute(std::string_view prog, PARAM...parameters) {
839  std::vector<std::string_view> parameter_list{parameters...};
840  return execute(prog, parameter_list);
841 }
842 
843 
844 
845 
850 template <class T>
851 std::string write_to_temp(const T& data) {
852  const auto name = GempyreUtils::temp_name();
853  std::ofstream out(name, std::ios::out | std::ios::binary);
854  std::ostreambuf_iterator<typename T::value_type> iter(out);
855  std::copy(data.begin(), data.end(), iter);
856  return name;
857 }
858 
864 template <class T>
865 std::vector<T> slurp(std::string_view file, const size_t max = std::numeric_limits<size_t>::max()) {
866  std::vector<T> vec;
868  std::ifstream stream(std::string{file}, std::ios::in | std::ios::binary | std::ios::ate);
869  if(!stream.is_open()) {
870  log(LogLevel::Error, "Cannot open file", qq(file));
871  return vec;
872  }
873  const auto size = std::min(max, static_cast<size_t>(stream.tellg()));
874  if(size <= 0) {
875  return vec;
876  }
877  vec.resize(size / sizeof (T), 0);
878  stream.seekg(std::ios_base::beg);
879  auto ptr = reinterpret_cast<char*>(vec.data());
880  stream.read(ptr, static_cast<std::streamsize>(size));
881  return vec;
882  }
883 
886 UTILS_EX std::string slurp(std::string_view file, const size_t max = std::numeric_limits<size_t>::max());
887 
889 enum class JsonMode {Compact, Pretty};
892 // or container type std::vector, std::unordered_map or std::map containing other values.
896 UTILS_EX Result<std::string> to_json_string(const std::any& any, JsonMode mode = JsonMode::Compact);
897 
899 enum class MapType {Map, UnorderedMap};
904 UTILS_EX Result<std::any> json_to_any(std::string_view str, MapType map_type = MapType::UnorderedMap);
905 
907 using JsonType = std::variant<
908 int,
909 double,
910 bool,
911 std::string,
912 std::nullptr_t,
913 std::vector<std::any>,
914 std::map<std::string, std::any>,
915 std::unordered_map<std::string, std::any>
916 >;
924 UTILS_EX ResultTrue set_json_value(std::any& any, std::string_view path, JsonType&& value);
925 
930 UTILS_EX ResultTrue remove_json_value(std::any& any, std::string_view path);
931 
936 UTILS_EX Result<JsonType> get_json_value(const std::any& any, std::string_view path);
937 
943 UTILS_EX ResultTrue make_json_path(std::any& any, std::string_view path,
944  const std::function<JsonType (std::string_view, std::string_view)>& f = [](auto, auto name) {
945  return (GempyreUtils::parse<int>(name)) ?
946  GempyreUtils::JsonType{std::vector<std::any>{}} :
947  GempyreUtils::JsonType{std::unordered_map<std::string, std::any>{}};});
948 
950 UTILS_EX bool is_available(int port);
951 
953 UTILS_EX std::string base64_encode(const unsigned char* bytes, size_t sz);
955 UTILS_EX std::string base64_encode(const std::vector<uint8_t> & vec);
957 UTILS_EX std::string base64_encode(std::string_view str);
959 UTILS_EX std::vector<uint8_t> base64_decode(std::string_view data);
960 
961 
963 enum class ArgType{
964  NO_ARG,
965  REQ_ARG,
966  OPT_ARG
967  };
968 
970 using ParamList = std::vector<std::string>;
971 
973 using Options = std::multimap<std::string, std::string>;
974 
976 using Params = std::tuple<ParamList, Options>;
977 
983 UTILS_EX Params parse_args(int argc, char* argv[], const std::initializer_list<std::tuple<std::string, char, ArgType>>& args);
984 
991 template <typename T>
992 T option_or(const Options& opts, std::string_view key, const T& default_value) {
993  const auto it = opts.find(std::string{key});
994  if(it == opts.end())
995  return default_value;
996  const auto parsed = parse<T>(it->second);
997  return parsed ? parsed.value() : default_value;
998 }
999 
1000 
1001 }
1002 
1003 
1004 
1005 #endif // UTILS_H
Parent class for LogWriters.
Definition: gempyre_utils.h:82
virtual bool do_write(const char *buffer, size_t count)=0
Implement write to the medium.
virtual std::string header(LogLevel logLevel)
header of class, called before every line, default just returns a timestamp and loglevel string.
LogWriter()
Constructor.
virtual ~LogWriter()
Destructor.
virtual bool has_ansi() const
override to return true if this write supports ANSI colors, default just return false
UTILS_EX Result< std::string > to_json_string(const std::any &any, JsonMode mode=JsonMode::Compact)
Convert any type to json string, if possible.
std::tuple< ParamList, Options > Params
a tuple containing ParamList and Options. Used for parse_params.
Definition: gempyre_utils.h:976
UTILS_EX SSIZE_T file_size(std::string_view filename)
File size.
std::optional< V > get_value(const std::multimap< K, V > &map, const K &key, int index=0)
Get a value from a multimap, especially helper for Parameter Options.
Definition: gempyre_utils.h:705
UTILS_EX std::string chop(std::string_view s)
remove newline from end of string
UTILS_EX std::string get_link(std::string_view fname)
Get symbolic link source.
std::vector< T > slurp(std::string_view file, const size_t max=std::numeric_limits< size_t >::max())
Read a file data in one read.
Definition: gempyre_utils.h:865
std::optional< T > parse(std::string_view source)
parse string to value
Definition: gempyre_utils.h:413
UTILS_EX int levenshtein_distance(std::string_view s1, std::string_view s2)
Get a levenshtein distance of strings.
UTILS_EX std::string qq(std::string_view s)
make quoted
UTILS_EX std::string to_str(LogLevel log_level)
Log Level to string.
UTILS_EX std::optional< std::string > read_process(std::string_view processName, const std::vector< std::string > &params)
Read stdout from the process - wait process to end.
UTILS_EX bool file_exists(std::string_view filename)
Test if file with name exits.
UTILS_EX std::string unhexify(std::string_view src)
un hexify hexified string
UTILS_EX Result< std::any > json_to_any(std::string_view str, MapType map_type=MapType::UnorderedMap)
Concert json string to any type.
UTILS_EX std::string remove_spaces(std::string_view str)
remove
constexpr bool operator!=(const Result< R, E > &a, const Result< R, E > &b)
defined if underlaying types defines required operators
Definition: gempyre_utils.h:334
PathStyle
Definition: gempyre_utils.h:768
UTILS_EX std::string push_path(std::string_view path, std::string_view name)
push name to path
std::string_view rtrim(std::string_view str)
trim from right
Definition: gempyre_utils.h:458
UTILS_EX std::string path_pop(std::string_view filename, int steps=1, PathStyle path_style=PathStyle::Native)
Remove elements from path.
UTILS_EX Result< JsonType > get_json_value(const std::any &any, std::string_view path)
Return a value from path.
UTILS_EX std::string home_dir()
Current source dir.
UTILS_EX LogLevel log_level()
Get current log level.
UTILS_EX std::string root_dir()
Current root dir - 'C:\' or '/'.
std::string write_to_temp(const T &data)
Write data to temp file.
Definition: gempyre_utils.h:851
UTILS_EX std::string temp_name()
Generate unique name (prefer std::filesystem if available)
void log_debug(const T &e, Args... args)
Write a debug log.
Definition: gempyre_utils.h:181
UTILS_EX bool rename(std::string_view of, std::string_view nf)
Rename a file.
AddressType
address type
Definition: gempyre_utils.h:757
std::multimap< std::string, std::string > Options
string - string value pairs of options. Used for parse_params.
Definition: gempyre_utils.h:973
UTILS_EX void remove_file(std::string_view filename)
Delete file.
UTILS_EX ResultTrue remove_json_value(std::any &any, std::string_view path)
UTILS_EX std::string substitute(std::string_view str, std::string_view substring, std::string_view substitution)
replace a substrings from a string
UTILS_EX std::string working_dir()
Current source dir.
UTILS_EX std::string abs_path(std::string_view rpath)
Absolute path.
UTILS_EX OS current_os()
Get.
constexpr bool operator==(const Result< R, E > &a, const Result< R, E > &b)
defined if underlaying types defines required operators
Definition: gempyre_utils.h:331
UTILS_EX bool is_executable(std::string_view filename)
is executable
UTILS_EX std::vector< uint8_t > base64_decode(std::string_view data)
Base64 decode.
void log(LogLevel level, const T &e, Args... args)
Write a log line.
Definition: gempyre_utils.h:165
UTILS_EX Params parse_args(int argc, char *argv[], const std::initializer_list< std::tuple< std::string, char, ArgType >> &args)
parse arguments
UTILS_EX ResultTrue set_json_value(std::any &any, std::string_view path, JsonType &&value)
Modifies a given data.
UTILS_EX bool is_valid_utf8(std::string_view str)
Test if a given string is a valid UTF-8 string.
std::string to_low(const T &str)
make lower case string
Definition: gempyre_utils.h:424
UTILS_EX bool is_dir(std::string_view fname)
Is dir.
UTILS_EX std::optional< std::string > which(std::string_view filename)
Try to find a executable from PATH.
IT advanced(IT it, int distance)
Const version of std::advance.
Definition: gempyre_utils.h:698
UTILS_EX ResultTrue make_json_path(std::any &any, std::string_view path, const std::function< JsonType(std::string_view, std::string_view)> &f=[](auto, auto name) { return(GempyreUtils::parse< int >(name)) ? GempyreUtils::JsonType{std::vector< std::any >{}} :GempyreUtils::JsonType{std::unordered_map< std::string, std::any >{}};})
ensure that json path exits
MapType
Json dictionary conversion.
Definition: gempyre_utils.h:899
std::vector< std::string > ParamList
string vector of parameters. Used for parse_params.
Definition: gempyre_utils.h:970
UTILS_EX std::string base_name(std::string_view filename, PathStyle path_style=PathStyle::Native)
Base name.
Result< T, std::string > make_error(A &&... a)
Definition: gempyre_utils.h:345
std::string to_hex(T ival)
Hex presentation of the value.
Definition: gempyre_utils.h:479
ArgType
Option Argument type for parse_args.
Definition: gempyre_utils.h:963
@ REQ_ARG
Option does not have an argument.
@ OPT_ARG
Option has an argument.
T option_or(const Options &opts, std::string_view key, const T &default_value)
get option as type
Definition: gempyre_utils.h:992
std::string_view trim(std::string_view str)
trim from left and right
Definition: gempyre_utils.h:469
UTILS_EX int execute(std::string_view prog, const std::vector< std::string_view > &parameters)
Execute a program.
UTILS_EX std::optional< std::string > system_env(std::string_view env)
Read environment value.
UTILS_EX std::vector< std::string > entries(std::string_view dirname)
Directory entries.
std::string join(const IT &begin, const IT &end, std::string_view joinChar="", const Callable &f=Callable{})
Join container values, try 1st if compiler can deduct types.
Definition: gempyre_utils.h:616
JsonMode
How json represented as a string.
Definition: gempyre_utils.h:889
UTILS_EX std::vector< std::string > ip_addresses(unsigned addressType)
Try to resolve own ipaddresses.
UTILS_EX bool is_hidden_entry(std::string_view filename)
Is entry hidden.
std::string_view ltrim(std::string_view str)
trim from left
Definition: gempyre_utils.h:447
OS
OS id.
Definition: gempyre_utils.h:746
UTILS_EX bool is_available(int port)
Check if port is free.
UTILS_EX std::string host_name()
Machine host name.
UTILS_EX std::string base64_encode(const unsigned char *bytes, size_t sz)
Base64 encode.
UTILS_EX std::tuple< std::string, std::string > split_name(std::string_view filename, PathStyle path_style=PathStyle::Native)
Name and extension.
Container split(std::string_view str, const char splitChar=' ')
Split sting to container.
Definition: gempyre_utils.h:524
UTILS_EX void set_log_level(LogLevel level)
Set current log level.
LogLevel
The LogLevel enum.
Definition: gempyre_utils.h:71
@ Warning
Something is wrong, Default.
@ Info
At least developer should be worried.
@ Debug_Trace
What is going on.
@ Fatal
All logs disabled.
@ Debug
Something developer should know.
UTILS_EX std::string hexify(std::string_view src, std::string_view pat)
URL hexify string.
std::vector< K > keys(const T &map)
Get keys from map.
Definition: gempyre_utils.h:547
std::string to_upper(const T &str)
make upper case string
Definition: gempyre_utils.h:436
std::variant< int, double, bool, std::string, std::nullptr_t, std::vector< std::any >, std::map< std::string, std::any >, std::unordered_map< std::string, std::any > > JsonType
Json Type.
Definition: gempyre_utils.h:916
Gempyre::dataT type
pixel type
Definition: gempyre_bitmap.h:36
Result is used like optional, but contains a fail reasoning.
Definition: gempyre_utils.h:249
E value_type
std compatibility
Definition: gempyre_utils.h:251
E error
error value
Definition: gempyre_utils.h:253
similar as std::optional, but with error info (not 100% same, add delta if needed).
Definition: gempyre_utils.h:257
constexpr Result(Err &&e)
Definition: gempyre_utils.h:270
constexpr const R & value() const
get value if available
Definition: gempyre_utils.h:300
constexpr static auto ok()
helper to make valid value, valid only if result has a default constructor
Definition: gempyre_utils.h:326
constexpr Result(const Err &e)
Definition: gempyre_utils.h:276
constexpr Result(R &&r)
Definition: gempyre_utils.h:267
constexpr Result & operator=(const R &r)
Definition: gempyre_utils.h:288
constexpr static auto make_error(E &&e)
helper to make error value
Definition: gempyre_utils.h:320
constexpr bool has_value() const
true is has value
Definition: gempyre_utils.h:298
constexpr R & value()
get value if available
Definition: gempyre_utils.h:304
E error_type
std compatibility
Definition: gempyre_utils.h:264
constexpr Result(const R &r)
Definition: gempyre_utils.h:273
constexpr static auto make_error(const E &e)
helper to make error value
Definition: gempyre_utils.h:316
R value_type
std compatibility
Definition: gempyre_utils.h:262
constexpr const E & error() const
get error if not value
Definition: gempyre_utils.h:302
constexpr static auto make_error()
helper to make error value, valid only if error has a default constructor
Definition: gempyre_utils.h:323
constexpr R * operator->()
get pointer to value
Definition: gempyre_utils.h:310
constexpr Result & operator=(Err &&e)
Definition: gempyre_utils.h:284
constexpr Result & operator=(R &&r)
Definition: gempyre_utils.h:280
constexpr R & operator*()
get ref to value
Definition: gempyre_utils.h:306
constexpr Result & operator=(const Err &e)
Definition: gempyre_utils.h:292