zupply.hpp
1 /* Doxygen main page */
28 #ifndef _ZUPPLY_ZUPPLY_HPP_
29 #define _ZUPPLY_ZUPPLY_HPP_
30 
32 // Require C++ 11 features
34 #if ((defined(_MSC_VER) && _MSC_VER >= 1800) || __cplusplus >= 201103L)
35 // VC++ defined an older version of __cplusplus, but it should work later than vc12
36 #else
37 #error C++11 required, add -std=c++11 to CFLAG.
38 #endif
39 
40 #ifdef _MSC_VER
41 
42 // Disable silly security warnings
43 //#ifndef _CRT_SECURE_NO_WARNINGS
44 //#define _CRT_SECURE_NO_WARNINGS
45 //#endif
46 
47 // Define __func__ macro
48 #ifndef __func__
49 #define __func__ __FUNCTION__
50 #endif
51 
52 // Define NDEBUG in Release Mode, ensure assert() disabled.
53 #if (!defined(_DEBUG) && !defined(NDEBUG))
54 #define NDEBUG
55 #endif
56 
57 #if _MSC_VER < 1900
58 #define ZUPPLY_NOEXCEPT throw()
59 #endif
60 
61 #endif
62 
63 #ifndef ZUPPLY_NOEXCEPT
64 #define ZUPPLY_NOEXCEPT noexcept
65 #endif
66 
67 // Optional header only mode, not done.
68 #ifdef ZUPPLY_HEADER_ONLY
69 #define ZUPPLY_EXPORT inline
70 #else
71 #define ZUPPLY_EXPORT
72 #endif
73 
74 #include <string>
75 #include <exception>
76 #include <fstream>
77 #include <utility>
78 #include <iostream>
79 #include <vector>
80 #include <locale>
81 #include <ctime>
82 #include <chrono>
83 #include <thread>
84 #include <mutex>
85 #include <atomic>
86 #include <map>
87 #include <unordered_map>
88 #include <memory>
89 #include <type_traits>
90 #include <sstream>
91 #include <iomanip>
92 #include <algorithm>
93 #include <functional>
94 #include <climits>
95 #include <cassert>
96 #include <cstring>
97 
98 
103 namespace zz
104 {
110  namespace consts
111  {
112  static const char* kExceptionPrefixGeneral = "[Zupply Exception] ";
113  static const char* kExceptionPrefixLogic = "[Zupply Exception->Logic] ";
114  static const char* kExceptionPrefixArgument = "[Zupply Exception->Logic->Argument] ";
115  static const char* kExceptionPrefixRuntime = "[Zupply Exception->Runtime] ";
116  static const char* kExceptionPrefixIO = "[Zupply Exception->Runtime->IO] ";
117  static const char* kExceptionPrefixCast = "[Zupply Exception->Runtime->Cast] ";
118  static const char* kExceptionPrefixMemory = "[Zupply Exception->Runtime->Memory] ";
119  static const char* kExceptionPrefixStrictWarn = "[Zupply Exception->StrictWarn] ";
120  }
121 
128  {
129  public:
130  UnCopyable() {};
131  // no copy constructor
132  UnCopyable(const UnCopyable&) = delete;
133  // no assignment
134  UnCopyable& operator=(const UnCopyable&) = delete;
135  };
136 
142  class UnMovable
143  {
144  public:
145  UnMovable() {};
146  // no copy constructor
147  UnMovable(const UnMovable&) = delete;
148  // no copy operator
149  UnMovable& operator=(const UnMovable&) = delete;
150  // no move constructor
151  UnMovable(UnMovable&&) = delete;
152  // no move operator
153  UnMovable& operator=(UnMovable&&) = delete;
154  };
155 
161  class Exception : public std::exception
162  {
163  public:
164  explicit Exception(const char* message, const char* prefix = consts::kExceptionPrefixGeneral)
165  {
166  message_ = std::string(prefix) + message;
167  };
168  explicit Exception(const std::string message, const char* prefix = consts::kExceptionPrefixGeneral)
169  {
170  message_ = std::string(prefix) + message;
171  };
172  virtual ~Exception() ZUPPLY_NOEXCEPT{};
173 
174  const char* what() const ZUPPLY_NOEXCEPT{ return message_.c_str(); };
175  private:
176  std::string message_;
177  };
178 
184  class LogicException : public Exception
185  {
186  public:
187  explicit LogicException(const char *message) : Exception(message, consts::kExceptionPrefixLogic){};
188  explicit LogicException(const std::string &message) : Exception(message, consts::kExceptionPrefixLogic){};
189  };
190 
196  class ArgException : public Exception
197  {
198  public:
199  explicit ArgException(const char *message) : Exception(message, consts::kExceptionPrefixArgument){};
200  explicit ArgException(const std::string &message) : Exception(message, consts::kExceptionPrefixArgument){};
201  };
202 
209  {
210  public:
211  explicit RuntimeException(const char *message) : Exception(message, consts::kExceptionPrefixRuntime){};
212  explicit RuntimeException(const std::string &message) : Exception(message, consts::kExceptionPrefixRuntime){};
213  };
214 
220  class CastException : public Exception
221  {
222  public:
223  explicit CastException(const char *message) : Exception(message, consts::kExceptionPrefixCast){};
224  explicit CastException(const std::string &message) : Exception(message, consts::kExceptionPrefixCast){};
225  };
226 
232  class IOException : public Exception
233  {
234  public:
235  explicit IOException(const char *message) : Exception(message, consts::kExceptionPrefixIO){};
236  explicit IOException(const std::string &message) : Exception(message, consts::kExceptionPrefixIO){};
237  };
238 
244  class MemException : public Exception
245  {
246  public:
247  explicit MemException(const char *message) : Exception(message, consts::kExceptionPrefixMemory){};
248  explicit MemException(const std::string &message) : Exception(message, consts::kExceptionPrefixMemory){};
249  };
250 
256  class WarnException : public Exception
257  {
258  public:
259  explicit WarnException(const char *message) : Exception(message, consts::kExceptionPrefixStrictWarn){};
260  explicit WarnException(const std::string &message) : Exception(message, consts::kExceptionPrefixStrictWarn){};
261  };
262 
268  template<typename _Tp> class Size_
269  {
270  public:
271  typedef _Tp value_type;
272 
276  Size_();
277 
283  Size_(_Tp width, _Tp height);
284 
289  Size_(const Size_& sz);
290 
295  Size_& operator = (const Size_& sz);
296 
302  bool operator==(const Size_& other);
303 
309  bool operator!=(const Size_& other);
310 
315  _Tp area() const;
316 
320  template<typename _Tp2> operator Size_<_Tp2>() const;
321 
322  _Tp width, height; // the width and the height
323  };
328 
333 
338 
342  using Size = Size_<int>;
343 
344  template<typename _Tp> class Rect_;
351  template<typename _Tp> class Point_
352  {
353  public:
354  typedef _Tp value_type;
355 
359  Point_();
360 
366  Point_(_Tp _x, _Tp _y);
367 
372  Point_(const Point_& pt);
373 
379  Point_& operator = (const Point_& pt);
380 
384  template<typename _Tp2> operator Point_<_Tp2>() const;
385 
391  _Tp dot(const Point_& pt) const;
392 
398  double ddot(const Point_& pt) const;
404  double cross(const Point_& pt) const;
410  bool inside(const Rect_<_Tp>& r) const;
411 
412  _Tp x, y;
413  };
414 
419 
424 
429 
433  typedef Point2i Point;
434 
438  typedef std::vector<Point> Vecpts;
439 
445  template<typename _Tp> class Rect_
446  {
447  public:
448  typedef _Tp value_type;
449 
453  Rect_();
454 
462  Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
463 
468  Rect_(const Rect_& r);
469 
475  Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
476 
482  Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
483 
489  Rect_& operator = (const Rect_& r);
490 
495  Point_<_Tp> tl() const;
496 
501  Point_<_Tp> br() const;
502 
507  Size_<_Tp> size() const;
508 
513  _Tp area() const;
514 
518  template<typename _Tp2> operator Rect_<_Tp2>() const;
519 
525  bool contains(const Point_<_Tp>& pt) const;
526 
527  _Tp x, y, width, height;
528  };
529 
534 
539 
544 
548  typedef Rect2i Rect;
549 
550  namespace detail
551  {
556  template<typename _Tp> class ImageBase
557  {
558  public:
559  typedef _Tp value_type;
560 
564  ImageBase();
565 
572  ImageBase(int rows, int cols, int channels);
573 
579  ImageBase(const ImageBase& other);
580 
585  ImageBase(ImageBase&& other);
586 
587 
588  virtual ~ImageBase();
589 
596  void create(int rows, int cols, int channels);
597 
601  void release();
602 
608  ImageBase& operator= (const ImageBase& other);
609 
615  ImageBase& operator= (ImageBase&& other);
616 
624  _Tp& operator() (int row, int col, int channel = 0);
625 
633  const _Tp& operator() (int row, int col, int channel = 0) const;
634 
638  template <typename _Tp2> operator ImageBase<_Tp2>() const;
639 
644  bool empty() const;
645 
650  int rows() const;
651 
656  int cols() const;
657 
662  int channels() const;
663 
672  _Tp at(int row, int col, int channel = 0) const;
673 
681  _Tp* ptr(int offset = 0) const;
682 
692  _Tp* ptr(int row, int col, int channel = 0) const;
693 
702  void import(_Tp* data, int rows, int cols, int channels);
703 
712  void import(std::vector<_Tp> data, int rows, int cols, int channels);
713 
719  std::vector<_Tp> export_raw() const;
720 
724  template <typename _Tp2> std::vector<_Tp2>& export_raw(std::vector<_Tp2>& out) const;
725 
733  void crop(int r0, int c0, int r1, int c1);
734 
740  void crop(Point p0, Point p1);
741 
746  void crop(Rect rect);
747 
748  protected:
749  void range_check(long long pos) const;
750  void range_check(int row, int col, int channel) const;
751  void detach();
752 
753  int rows_;
754  int cols_;
755  int channels_;
756  std::shared_ptr<std::vector<_Tp>> data_;
757 
758  };
759  } // namespace zz::detail
760 
766  class Image : public detail::ImageBase<unsigned char>
767  {
768  public:
772  Image() : ImageBase() {};
773 
780  Image(int rows, int cols, int channels) : ImageBase(rows, cols, channels) {};
781 
786  Image(const char* filename);
787 
792  void load(const char* filename);
793 
799  void save(const char* filename, int quality = 80) const;
800 
805  void resize(Size sz);
806 
812  void resize(int width, int height);
813 
818  void resize(double ratio);
819  };
820 
825  class ImageHdr : public detail::ImageBase<float>
826  {
827  public:
831  ImageHdr() : ImageBase() {};
832 
839  ImageHdr(int rows, int cols, int channels) : ImageBase(rows, cols, channels) {};
840 
845  ImageHdr(const char* filename);
846 
852  ImageHdr(const Image& from, float range = 1.0f);
853 
858  void load(const char* filename);
859 
864  void save_hdr(const char* filename) const;
865 
871  Image to_normal(float range = 1.0f) const;
872 
878  void from_normal(const Image& from, float range = 1.0f);
879 
884  void resize(Size sz);
885 
891  void resize(int width, int height);
892 
897  void resize(double ratio);
898  };
899 
900 
905  namespace math
906  {
907  using std::min;
908  using std::max;
909  using std::abs;
910 
920  template<class T> inline const T clip(const T& value, const T& low, const T& high)
921  {
922  // fool proof max/min values
923  T h = (std::max)(low, high);
924  T l = (std::min)(low, high);
925  return (std::max)((std::min)(value, h), l);
926  }
927 
932  template <unsigned long B, unsigned long E>
933  struct Pow
934  {
935  static const unsigned long result = B * Pow<B, E - 1>::result;
936  };
937 
938  template <unsigned long B>
939  struct Pow<B, 0>
940  {
941  static const unsigned long result = 1;
942  };
943 
944 
951  inline int round(double value)
952  {
953 #if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) && 0
954  __m128d t = _mm_set_sd(value);
955  return _mm_cvtsd_si32(t);
956 #elif defined _MSC_VER && defined _M_IX86
957  int t;
958  __asm
959  {
960  fld value;
961  fistp t;
962  }
963  return t;
964 #elif defined _MSC_VER && defined _M_ARM && defined HAVE_TEGRA_OPTIMIZATION
965  TEGRA_ROUND(value);
966 #elif defined CV_ICC || defined __GNUC__
967 # ifdef HAVE_TEGRA_OPTIMIZATION
968  TEGRA_ROUND(value);
969 # else
970  return (int)lrint(value);
971 # endif
972 #else
973  double intpart, fractpart;
974  fractpart = modf(value, &intpart);
975  if ((fabs(fractpart) != 0.5) || ((((int)intpart) % 2) != 0))
976  return (int)(value + (value >= 0 ? 0.5 : -0.5));
977  else
978  return (int)intpart;
979 #endif
980  }
981 
982  } // namespace math
983 
988  namespace misc
989  {
994  template<typename T>
995  inline void unused(const T&) {}
996 
997  namespace detail
998  {
999  // To allow ADL with custom begin/end
1000  using std::begin;
1001  using std::end;
1002 
1003  template <typename T>
1004  auto is_iterable_impl(int)
1005  -> decltype (
1006  begin(std::declval<T&>()) != end(std::declval<T&>()), // begin/end and operator !=
1007  ++std::declval<decltype(begin(std::declval<T&>()))&>(), // operator ++
1008  *begin(std::declval<T&>()), // operator*
1009  std::true_type{});
1010 
1011  template <typename T>
1012  std::false_type is_iterable_impl(...);
1013 
1014  }
1015 
1016  template <typename T>
1017  using is_iterable = decltype(detail::is_iterable_impl<T>(0));
1018 
1022  class Callback
1023  {
1024  public:
1025  Callback(std::function<void()> f) : f_(f) { f_(); }
1026  private:
1027  std::function<void()> f_;
1028  };
1029  } // namespace misc
1030 
1035  namespace cds
1036  {
1037  inline void nop_pause()
1038  {
1039 #if (defined _MSC_VER) && (defined _M_IX86 || defined _M_X64) && 0
1040  __asm volatile("pause" ::: "memory");
1041 #endif
1042  }
1043 
1050  {
1051  public:
1052  void lock() {}
1053  void unlock() {}
1054  bool try_lock() { return true; }
1055  };
1056 
1063  {
1064  public:
1065  SpinLock(){ flag_.clear(); }
1066  inline void lock()
1067  {
1068  while (flag_.test_and_set(std::memory_order_acquire))
1069  {
1070  nop_pause(); // no op or use architecture pause
1071  }
1072  }
1073 
1074  inline void unlock()
1075  {
1076  flag_.clear(std::memory_order_release);
1077  }
1078 
1079  inline bool try_lock()
1080  {
1081  return !flag_.test_and_set(std::memory_order_acquire);
1082  }
1083  private:
1084  std::atomic_flag flag_;
1085  };
1086 
1087  class RWLockable;
1088 
1089  class RWLock {
1090  friend class RWLockable;
1091 
1092  public:
1093  enum class LockType {
1094  none,
1095  read,
1096  write
1097  };
1098 
1099  private:
1100  RWLockable * lockable_;
1101  LockType lockType_;
1102 
1103  RWLock(RWLockable * const lockable, bool const exclusive);
1104  RWLock();
1105 
1106  public:
1107  RWLock(RWLock&& rhs);
1108  RWLock& operator =(RWLock&& rhs);
1109  ~RWLock();
1110 
1111  void unlock();
1112  LockType get_lock_type() const;
1113  };
1114 
1115  class RWLockable {
1116  friend RWLock::~RWLock();
1117 
1118  private:
1119  class Counters {
1120  private:
1121  uint16_t read_;
1122  uint8_t writeClaim_;
1123  uint8_t writeDone_;
1124  public:
1125  bool is_waiting_for_write() const;
1126  bool is_waiting_for_read() const;
1127  bool is_my_turn_to_write(Counters const & claim) const;
1128 
1129  bool want_to_read(Counters * buf) const;
1130  bool want_to_write(Counters * buf) const;
1131  Counters done_reading() const;
1132  Counters done_writing() const;
1133  };
1134 
1135  std::atomic<Counters> counters_;
1136 
1137  void unlock_read();
1138  void unlock_write();
1139 
1140  public:
1141  RWLock lock_for_read();
1142  RWLock lock_for_write();
1143  bool is_lock_free() const;
1144  };
1145 
1146  namespace lockfree
1147  {
1148  template <typename Key, typename Value> class UnorderedMap : public UnMovable
1149  {
1150  public:
1151  using MapType = std::unordered_map<Key, Value>;
1152  using MapPairType = std::pair<Key, Value>;
1153 
1154  UnorderedMap() {}
1155 
1156  bool is_lock_free() const
1157  {
1158  return lockable_.is_lock_free();
1159  }
1160 
1161  bool contains(const Key& key)
1162  {
1163  auto lock = lockable_.lock_for_read();
1164  return map_.count(key) > 0;
1165  }
1166 
1167  bool get(const Key& key, Value& dst)
1168  {
1169  auto lock = lockable_.lock_for_read();
1170  if (map_.count(key) > 0)
1171  {
1172  dst = map_[key];
1173  return true;
1174  }
1175  return false;
1176  }
1177 
1178  MapType snapshot()
1179  {
1180  auto lock = lockable_.lock_for_read();
1181  return map_;
1182  }
1183 
1184  bool insert(const Key& key, const Value& value)
1185  {
1186  if (contains(key)) return false;
1187  auto lock = lockable_.lock_for_write();
1188  map_[key] = value;
1189  return true;
1190  }
1191 
1192  bool insert(const MapPairType& pair)
1193  {
1194  return insert(pair.first, pair.second);
1195  }
1196 
1197  void replace(const Key& key, const Value& value)
1198  {
1199  auto lock = lockable_.lock_for_write();
1200  map_[key] = value;
1201  }
1202 
1203  void replace(const MapPairType& pair)
1204  {
1205  replace(pair.first, pair.second);
1206  }
1207 
1208  void erase(const Key& key)
1209  {
1210  auto lock = lockable_.lock_for_write();
1211  map_.erase(key);
1212  }
1213 
1214  void clear()
1215  {
1216  auto lock = lockable_.lock_for_write();
1217  map_.clear();
1218  }
1219 
1220  //template <typename Function>
1221  //void for_each(std::function<Function> functor)
1222  //{
1223  // auto lock = lockable_.lock_for_read();
1224  // std::for_each(map_.begin(), map_.end(), functor);
1225  //}
1226 
1227  private:
1228 
1229  RWLockable lockable_;
1230  MapType map_;
1231  };
1232 
1233  template <typename T> class NonTrivialContainer : public UnMovable
1234  {
1235  public:
1236  NonTrivialContainer() {}
1237 
1238  bool is_lock_free() const
1239  {
1240  return lockable_.is_lock_free();
1241  }
1242 
1243  T get()
1244  {
1245  auto lock = lockable_.lock_for_read();
1246  return obj_;
1247  }
1248 
1249  void set(const T& t)
1250  {
1251  //std::lock_guard<std::mutex> lock(mutex_);
1252  auto lock = lockable_.lock_for_write();
1253  obj_ = t;
1254  }
1255 
1256  private:
1257  T obj_;
1258  RWLockable lockable_;
1259 
1260  };
1261  }
1262 
1263  namespace lockbased
1264  {
1265  template <typename Key, typename Value> class UnorderedMap : public UnMovable
1266  {
1267  public:
1268  using MapType = std::unordered_map<Key, Value>;
1269  using MapPairType = std::pair<Key, Value>;
1270 
1271  UnorderedMap() {}
1272 
1273  bool is_lock_free() const
1274  {
1275  return false;
1276  }
1277 
1278  bool contains(const Key& key)
1279  {
1280  std::lock_guard<std::mutex> lock(mutex_);
1281  return map_.count(key) > 0;
1282  }
1283 
1284  bool get(const Key& key, Value& dst)
1285  {
1286  std::lock_guard<std::mutex> lock(mutex_);
1287  if (map_.count(key) > 0)
1288  {
1289  dst = map_[key];
1290  return true;
1291  }
1292  return false;
1293  }
1294 
1295  MapType snapshot()
1296  {
1297  std::lock_guard<std::mutex> lock(mutex_);
1298  return map_;
1299  }
1300 
1301  bool insert(const Key& key, const Value& value)
1302  {
1303  if (contains(key)) return false;
1304  std::lock_guard<std::mutex> lock(mutex_);
1305  map_[key] = value;
1306  return true;
1307  }
1308 
1309  bool insert(const MapPairType& pair)
1310  {
1311  return insert(pair.first, pair.second);
1312  }
1313 
1314  void replace(const Key& key, const Value& value)
1315  {
1316  std::lock_guard<std::mutex> lock(mutex_);
1317  map_[key] = value;
1318  }
1319 
1320  void replace(const MapPairType& pair)
1321  {
1322  replace(pair.first, pair.second);
1323  }
1324 
1325  void erase(const Key& key)
1326  {
1327  std::lock_guard<std::mutex> lock(mutex_);
1328  map_.erase(key);
1329  }
1330 
1331  void clear()
1332  {
1333  std::lock_guard<std::mutex> lock(mutex_);
1334  map_.clear();
1335  }
1336 
1337  //template <typename Function>
1338  //void for_each(std::function<Function> functor)
1339  //{
1340  // auto lock = lockable_.lock_for_read();
1341  // std::for_each(map_.begin(), map_.end(), functor);
1342  //}
1343 
1344  private:
1345 
1346  std::mutex mutex_;
1347  MapType map_;
1348  };
1349 
1350  template <typename T> class NonTrivialContainer : public UnMovable
1351  {
1352  public:
1353  NonTrivialContainer() {}
1354 
1355  bool is_lock_free() const
1356  {
1357  return false;
1358  }
1359 
1360  T get()
1361  {
1362  std::lock_guard<std::mutex> lock(mutex_);
1363  return obj_;
1364  }
1365 
1366  void set(const T& t)
1367  {
1368  std::lock_guard<std::mutex> lock(mutex_);
1369  obj_ = t;
1370  }
1371 
1372  private:
1373  T obj_;
1374  std::mutex mutex_;
1375 
1376  };
1377  }
1378 
1380  // * \brief AtomicUnorderedMap Template atomic unordered_map<>
1381  // * AtomicUnorderedMap is lock-free, however, modification will create copies.
1382  // * Thus this structure is good for read-many write-rare purposes.
1383  // */
1384  //template <typename Key, typename Value> class AtomicUnorderedMap
1385  //{
1386  // using MapType = std::unordered_map<Key, Value>;
1387  // using MapPtr = std::shared_ptr<MapType>;
1388  //public:
1389  // AtomicUnorderedMap()
1390  // {
1391  // mapPtr_ = std::make_shared<MapType>();
1392  // }
1393 
1394  // /*!
1395  // * \brief Get shared_ptr of unorderd_map instance
1396  // * \return Shared_ptr of unordered_map
1397  // */
1398  // MapPtr get()
1399  // {
1400  // return std::atomic_load(&mapPtr_);
1401  // }
1402 
1403  // /*!
1404  // * \brief Insert key-value pair to the map
1405  // * \param key
1406  // * \param value
1407  // * \return True on success
1408  // */
1409  // bool insert(const Key& key, const Value& value)
1410  // {
1411  // MapPtr p = std::atomic_load(&mapPtr_);
1412  // MapPtr copy;
1413  // do
1414  // {
1415  // if ((*p).count(key) > 0) return false;
1416  // copy = std::make_shared<MapType>(*p);
1417  // (*copy).insert({ key, value });
1418  // } while (!std::atomic_compare_exchange_weak(&mapPtr_, &p, std::move(copy)));
1419  // return true;
1420  // }
1421 
1422  // /*!
1423  // * \brief Erase according to key
1424  // * \param key
1425  // * \return True on success
1426  // */
1427  // bool erase(const Key& key)
1428  // {
1429  // MapPtr p = std::atomic_load(&mapPtr_);
1430  // MapPtr copy;
1431  // do
1432  // {
1433  // if ((*p).count(key) <= 0) return false;
1434  // copy = std::make_shared<MapType>(*p);
1435  // (*copy).erase(key);
1436  // } while (!std::atomic_compare_exchange_weak(&mapPtr_, &p, std::move(copy)));
1437  // return true;
1438  // }
1439 
1440  // /*!
1441  // * \brief Clear all
1442  // */
1443  // void clear()
1444  // {
1445  // MapPtr p = atomic_load(&mapPtr_);
1446  // auto copy = std::make_shared<MapType>();
1447  // do
1448  // {
1449  // ; // do clear when possible does not require old status
1450  // } while (!std::atomic_compare_exchange_weak(&mapPtr_, &p, std::move(copy)));
1451  // }
1452 
1453  //private:
1454  // std::shared_ptr<MapType> mapPtr_;
1455  //};
1456 
1458  // * \brief AtomicNonTrivial Template lock-free class
1459  // * AtomicNonTrivial is lock-free, however, modification will create copies.
1460  // * Thus this structure is good for read-many write-rare purposes.
1461  // */
1462  //template <typename T> class AtomicNonTrivial
1463  //{
1464  //public:
1465  // AtomicNonTrivial()
1466  // {
1467  // ptr_ = std::make_shared<T>();
1468  // }
1469 
1470  // /*!
1471  // * \brief Get shared_ptr to instance
1472  // * \return Shared_ptr to instance
1473  // */
1474  // std::shared_ptr<T> get()
1475  // {
1476  // return std::atomic_load(&ptr_);
1477  // }
1478 
1479  // /*!
1480  // * \brief Set to new value
1481  // * \param val
1482  // * This operation will make a copy which is only visible for future get()
1483  // */
1484  // void set(const T& val)
1485  // {
1486  // std::shared_ptr<T> copy = std::make_shared<T>(val);
1487  // std::atomic_store(&ptr_, copy);
1488  // }
1489 
1490  //private:
1491  // std::shared_ptr<T> ptr_;
1492  //};
1493 
1494 
1495  // namespace gc
1496  // {
1497  // class HPRecord
1498  // {
1499  // public:
1500  // void* pHazard_; //!< can be used by the thread that acquire it
1501  // HPRecord* pNext_;
1502  // static HPRecord* head() { return pHead_; }
1503  //
1504  // static HPRecord* acquire()
1505  // {
1506  // // try to reuse a retired hp record
1507  // HPRecord* p = pHead_;
1508  // bool inactive(false);
1509  //
1510  // for (; p; p = p->pNext_)
1511  // {
1512  // if (p->active_ || (!p->active_.compare_exchange_weak(inactive, true)))
1513  // {
1514  // continue;
1515  // }
1516  // return p; // got one!
1517  // }
1518  // // increment the list length by adding one
1519  // int oldLen;
1520  // do
1521  // {
1522  // oldLen = listLen_;
1523  // } while (!listLen_.compare_exchange_weak(oldLen, oldLen + 1));
1524  // // allocate a new one
1525  // p = new HPRecord;
1526  // p->active_.store(true);
1527  // p->pHazard_ = nullptr;
1528  // // push it to the front
1529  // HPRecord* old = nullptr;
1530  // do
1531  // {
1532  // old = pHead_;
1533  // p->pNext_ = old;
1534  // } while (!pHead_.compare_exchange_weak(old, p));
1535  //
1536  // return p; // return acquired pointer
1537  // }
1538  //
1539  // static void release(HPRecord* p)
1540  // {
1541  // p->pHazard_ = nullptr;
1542  // p->active_.store(false);
1543  // }
1544  //
1545  // private:
1546  // std::atomic<bool> active_;
1547  // static std::atomic<HPRecord*> pHead_; //!< global header of the hazard pointer list
1548  // static std::atomic<int> listLen_; //!< length of the list
1549  // };
1550  //
1551  // template <typename T> void garbage_collection(std::vector<T*> rlist)
1552  // {
1553  // // stage 1: scan hazard ponter list
1554  // // collecting all non-null pointers
1555  // std::vector<void*> hp;
1556  // HPRecord* head = HPRecord::head();
1557  // while (head)
1558  // {
1559  // void *p = head->pHazard_;
1560  // if (p) hp.push_back(p);
1561  // head = head->pNext_;
1562  // }
1563  // // stage 2: sort the hazard pointers
1564  // std::sort(hp.begin(), hp.end(), std::less<void*>());
1565  // // stage 3: search for null
1566  // std::vector<T*>::iterator iter = rlist.begin();
1567  // while (iter != rlist.end())
1568  // {
1569  // if (!std::binary_search(hp.begin(), hp.end(), *iter))
1570  // {
1571  // delete *iter; // safely reclaim this memory
1572  // if (&*iter != rlist.back())
1573  // {
1574  // *iter = rlist.back();
1575  // }
1576  // rlist.pop_back();
1577  // }
1578  // else
1579  // {
1580  // ++iter;
1581  // }
1582  // }
1583  // }
1584  //
1585  // } // namespace gc
1586  //
1587  // namespace consts
1588  // {
1589  // static const unsigned kGarbageCollectionThreshold = 4;
1590  // }
1591  //
1592  // template <typename K, typename V> class WRRMUMap
1593  // {
1594  // public:
1595  //
1596  // private:
1597  // using MapType = std::unordered_map<K, V>;
1598  //
1599  // static void retire(MapType* old)
1600  // {
1601  // // put old map into retire list
1602  // rlist_.push_back(old);
1603  // if (rlist_.size() >= consts::kGarbageCollectionThreshold)
1604  // {
1605  // gc::garbage_collection(rlist_);
1606  // }
1607  // }
1608  //#if _MSC_VER
1609  // static __declspec(thread) std::vector<MapType*> rlist_;
1610  //#else
1611  // static thread_local std::vector<MapType*> rlist_;
1612  //#endif
1613  // MapType* pMap_;
1614  // };
1615 
1616 
1617  } // namespace cds
1618 
1619 
1624  namespace os
1625  {
1633  int system(const char *const command, const char *const module_name = 0);
1634 
1640  std::size_t thread_id();
1641 
1646  int is_atty();
1647 
1654  std::tm localtime(std::time_t t);
1655 
1662  std::tm gmtime(std::time_t t);
1663 
1669  std::wstring utf8_to_wstring(std::string &u8str);
1670 
1676  std::string wstring_to_utf8(std::wstring &wstr);
1677 
1684  bool path_exists(std::string path, bool considerFile = true);
1685 
1691  bool is_file(std::string path);
1692 
1698  bool is_directory(std::string path);
1699 
1707  void fstream_open(std::fstream &stream, std::string filename, std::ios::openmode openmode);
1708 
1716  void ifstream_open(std::ifstream &stream, std::string filename, std::ios::openmode openmode);
1717 
1724  bool rename(std::string oldName, std::string newName);
1725 
1733  bool copyfile(std::string src, std::string dst, bool replaceDst = false);
1734 
1742  bool movefile(std::string src, std::string dst, bool replaceDst = false);
1743 
1750  bool remove_all(std::string path);
1751 
1759  bool remove_dir(std::string root, bool recursive = true);
1760 
1767  bool remove_file(std::string path);
1768 
1773  std::string last_error();
1774 
1779  std::string endl();
1780 
1785  std::string path_delim();
1786 
1791  std::string current_working_directory();
1792 
1798  std::string absolute_path(std::string reletivePath);
1799 
1806  std::vector<std::string> path_split(std::string path);
1807 
1816  bool path_identical(std::string first, std::string second, bool forceCaseSensitve = false);
1817 
1826  std::string path_join(std::vector<std::string> elems);
1827 
1833  std::string path_split_filename(std::string path);
1834 
1840  std::string path_split_directory(std::string path);
1841 
1847  std::string path_split_basename(std::string path);
1848 
1854  std::string path_split_extension(std::string path);
1855 
1865  std::string path_append_basename(std::string origPath, std::string whatToAppend);
1866 
1873  bool create_directory(std::string path);
1874 
1882  bool create_directory_recursive(std::string path);
1883 
1889  std::vector<std::string> list_directory(std::string root);
1890 
1895  Size console_size();
1896 
1897  } // namespace os
1898 
1903  namespace time
1904  {
1910  class DateTime
1911  {
1912  public:
1913  DateTime();
1914  virtual ~DateTime() = default;
1915 
1919  void to_local_time();
1920 
1924  void to_utc_time();
1925 
1932  std::string to_string(const char *format = "%y-%m-%d %H:%M:%S.%frac");
1933 
1938  static DateTime local_time();
1939 
1944  static DateTime utc_time();
1945 
1946  private:
1947  std::time_t timeStamp_;
1948  int fraction_;
1949  std::string fractionStr_;
1950  struct std::tm calendar_;
1951 
1952  };
1953 
1959  class Timer
1960  {
1961  public:
1962  Timer();
1966  void reset();
1967 
1971  void pause();
1972 
1976  void resume();
1977 
1982  std::size_t elapsed_ns();
1983 
1988  std::string elapsed_ns_str();
1989 
1994  std::size_t elapsed_us();
1995 
2000  std::string elapsed_us_str();
2001 
2006  std::size_t elapsed_ms();
2007 
2012  std::string elapsed_ms_str();
2013 
2018  std::size_t elapsed_sec();
2019 
2024  std::string elapsed_sec_str();
2025 
2030  double elapsed_sec_double();
2031 
2038  std::string to_string(const char *format = "[%ms ms]");
2039 
2040  private:
2041  std::chrono::steady_clock::time_point timeStamp_;
2042  std::size_t elapsed_;
2043  bool paused_;
2044  };
2045 
2053  inline void sleep(int milliseconds)
2054  {
2055  if (milliseconds > 0)
2056  {
2057  std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
2058  }
2059  }
2060 
2061  } // namespace time
2062 
2067  namespace fs
2068  {
2069  namespace consts
2070  {
2071  static const int kDefaultFileOpenRetryTimes = 5;
2072  static const int kDefaultFileOpenRetryInterval = 10;
2073  }
2074 
2078  class Path
2079  {
2080  public:
2081  Path(std::string path, bool isAbsolute = false);
2082 
2087  bool empty() const;
2088 
2093  bool exist() const;
2094 
2099  bool is_file() const;
2100 
2105  bool is_dir() const;
2106 
2111  std::string abs_path() const;
2112 
2117  std::string relative_path() const;
2118 
2124  std::string relative_path(std::string root) const;
2125 
2131  std::string filename() const;
2132 
2133  private:
2134  std::string abspath_;
2135  };
2136 
2141  {
2142  public:
2143  using iterator = std::vector<Path>::iterator;
2144  using const_iterator = std::vector<Path>::const_iterator;
2145 
2151  Directory(std::string root, bool recursive = false);
2152 
2159  Directory(std::string root, const std::string pattern, bool recursive = false);
2160 
2167  Directory(std::string root, const std::vector<std::string> patternList, bool recursive);
2168 
2175  Directory(std::string root, const std::vector<const char*> patternList, bool recursive);
2176 
2181  iterator begin() { return paths_.begin(); }
2182 
2187  iterator end() { return paths_.end(); }
2188 
2193  const_iterator cbegin() const { return paths_.cbegin(); }
2194 
2199  const_iterator cend() const { return paths_.cend(); }
2200 
2205  std::size_t size() const { return paths_.size(); }
2206 
2211  bool is_recursive() const;
2212 
2217  std::string root() const;
2218 
2223  void filter(const std::string pattern);
2224 
2229  void filter(const std::vector<const char*> patternList);
2230 
2235  void filter(const std::vector<std::string> patternList);
2236 
2240  void reset();
2241 
2246  std::vector<Path> to_list() const;
2247 
2248  private:
2249  void resolve();
2250 
2251  bool recursive_;
2252  Path root_;
2253  std::vector<Path> paths_;
2254  };
2255 
2261  class FileEditor : private UnCopyable
2262  {
2263  public:
2264  FileEditor() = default;
2265 
2273  FileEditor(std::string filename, bool truncateOrNot = false,
2274  int retryTimes = consts::kDefaultFileOpenRetryTimes,
2275  int retryInterval = consts::kDefaultFileOpenRetryInterval);
2276 
2284  //FileEditor(FileEditor&& other);
2285 
2286  virtual ~FileEditor() { this->close(); }
2287 
2288  // No move operator
2289  FileEditor& operator=(FileEditor&&) = delete;
2290 
2294  template <typename T>
2295  FileEditor& operator<<(T what) { stream_ << what; return *this; }
2296 
2301  std::string filename() const { return filename_; }
2302 
2311  bool open(std::string filename, bool truncateOrNot = false,
2312  int retryTimes = consts::kDefaultFileOpenRetryTimes,
2313  int retryInterval = consts::kDefaultFileOpenRetryInterval);
2314 
2323  bool open(const char* filename, bool truncateOrNot = false,
2324  int retryTimes = consts::kDefaultFileOpenRetryTimes,
2325  int retryInterval = consts::kDefaultFileOpenRetryInterval);
2326 
2332  bool open(bool truncateOrNot = false);
2333 
2339  bool reopen(bool truncateOrNot = true);
2340 
2344  void close();
2345 
2350  bool is_valid() const { return !filename_.empty(); }
2351 
2356  bool is_open() const { return stream_.is_open(); }
2357 
2361  void flush() { stream_.flush(); }
2362  private:
2363 
2364  bool try_open(int retryTime, int retryInterval, bool truncateOrNot = false);
2365  void check_valid() { if (!this->is_valid()) throw RuntimeException("Invalid File Editor!"); }
2366 
2367  std::string filename_;
2368  std::fstream stream_;
2369  std::streampos readPos_;
2370  std::streampos writePos_;
2371  };
2372 
2378  class FileReader : private UnCopyable
2379  {
2380  public:
2381  FileReader() = delete;
2382 
2389  FileReader(std::string filename, int retryTimes = consts::kDefaultFileOpenRetryTimes,
2390  int retryInterval = consts::kDefaultFileOpenRetryInterval);
2391 
2396  //FileReader(FileReader&& other);
2397 
2402  std::string filename() const { return filename_; }
2403 
2408  bool is_open() const { return istream_.is_open(); }
2409 
2414  bool is_valid() const { return !filename_.empty(); }
2415 
2419  void close() { istream_.close(); }
2420 
2425  std::size_t file_size();
2426 
2431  std::size_t count_lines();
2432 
2438  std::string next_line(bool trimWhiteSpaces = false);
2439 
2446  int goto_line(int n);
2447 
2448  private:
2449  bool open();
2450  bool try_open(int retryTime, int retryInterval);
2451  void check_valid(){ if (!this->is_valid()) throw RuntimeException("Invalid File Reader!"); }
2452  std::string filename_;
2453  std::ifstream istream_;
2454  };
2455 
2461  std::size_t get_file_size(std::string filename);
2462 
2463  } //namespace fs
2464 
2465 
2470  namespace fmt
2471  {
2472  namespace consts
2473  {
2474  static const std::string kFormatSpecifierPlaceHolder = std::string("{}");
2475  }
2476 
2477  namespace detail
2478  {
2479  template<class Facet>
2480  struct DeletableFacet : Facet
2481  {
2482  template<class ...Args>
2483  DeletableFacet(Args&& ...args) : Facet(std::forward<Args>(args)...) {}
2484  ~DeletableFacet() {}
2485  };
2486  } // namespace detail
2487 
2494  inline std::string int_to_zero_pad_str(int num, int length)
2495  {
2496  std::ostringstream ss;
2497  ss << std::setw(length) << std::setfill('0') << num;
2498  return ss.str();
2499  }
2500 
2506  bool is_digit(char c);
2507 
2515  bool wild_card_match(const char* str, const char* pattern);
2516 
2523  bool starts_with(const std::string& str, const std::string& start);
2524 
2531  bool ends_with(const std::string& str, const std::string& end);
2532 
2540  std::string& replace_all(std::string& str, const std::string& replaceWhat, const std::string& replaceWith);
2541 
2549  std::string& replace_all(std::string& str, char replaceWhat, char replaceWith);
2550 
2559  bool str_equals(const char* s1, const char* s2);
2560 
2566  std::string ltrim(std::string str);
2567 
2573  std::string rtrim(std::string str);
2574 
2580  std::string trim(std::string str);
2581 
2589  std::string lstrip(std::string str, std::string what);
2590 
2598  std::string rstrip(std::string str, std::string what);
2599 
2606  std::string lskip(std::string str, std::string delim);
2607 
2614  std::string rskip(std::string str, std::string delim);
2615 
2622  std::string rskip_all(std::string str, std::string delim);
2623 
2630  std::vector<std::string> split(const std::string s, char delim = ' ');
2631 
2639  std::vector<std::string> split(const std::string s, std::string delim);
2640 
2647  std::vector<std::string> split_multi_delims(const std::string s, std::string delims);
2648 
2654  std::vector<std::string> split_whitespace(const std::string s);
2655 
2662  std::pair<std::string, std::string> split_first_occurance(const std::string s, char delim);
2663 
2670  std::string join(std::vector<std::string> elems, char delim);
2671 
2678  std::vector<std::string>& erase_empty(std::vector<std::string>& vec);
2679 
2687  void replace_first_with_escape(std::string &str, const std::string &replaceWhat, const std::string &replaceWith);
2688 
2696  void replace_all_with_escape(std::string &str, const std::string &replaceWhat, const std::string &replaceWith);
2697 
2705  void replace_sequential_with_escape(std::string &str, const std::string &replaceWhat, const std::vector<std::string> &replaceWith);
2706 
2713  std::string to_lower_ascii(std::string mixed);
2714 
2721  std::string to_upper_ascii(std::string mixed);
2722 
2728  std::u16string utf8_to_utf16(std::string u8str);
2729 
2735  std::string utf16_to_utf8(std::u16string u16str);
2736 
2742  std::u32string utf8_to_utf32(std::string u8str);
2743 
2749  std::string utf32_to_utf8(std::u32string u32str);
2750 
2757  template<typename Arg>
2758  inline void format_string(std::string &fmt, const Arg &last)
2759  {
2760  std::stringstream ss;
2761  ss << last;
2762  replace_first_with_escape(fmt, consts::kFormatSpecifierPlaceHolder, ss.str());
2763  }
2764 
2772  template<typename Arg, typename... Args>
2773  inline void format_string(std::string &fmt, const Arg& current, const Args&... more)
2774  {
2775  std::stringstream ss;
2776  ss << current;
2777  replace_first_with_escape(fmt, consts::kFormatSpecifierPlaceHolder, ss.str());
2778  format_string(fmt, more...);
2779  }
2780 
2781  } // namespace fmt
2782 
2787  namespace cfg
2788  {
2792  class Value
2793  {
2794  public:
2798  Value(){}
2799 
2804  Value(const char* cstr) : str_(cstr) {}
2805 
2810  Value(std::string str) : str_(str) {}
2811 
2816  Value(const Value& other) : str_(other.str_) {}
2817 
2822  std::string str() const { return str_; }
2823 
2828  bool empty() const { return str_.empty(); }
2829 
2833  void clear() { str_.clear(); }
2834 
2840  bool operator== (const Value& other) { return str_ == other.str_; }
2841 
2847  Value& operator= (const Value& other) { str_ = other.str_; return *this; }
2848 
2854  template <typename T> std::string store(T t);
2855 
2861  template <typename T> std::string store(std::vector<T> t);
2862 
2868  template <typename T> T load(T& t);
2869 
2875  template <typename T> std::vector<T> load(std::vector<T>& t);
2876 
2883  //template <> bool load(bool& b);
2884 
2889  template <typename T> T load() { T t; return load(t); }
2890 
2891  private:
2892  std::string str_;
2893  };
2894 
2899  struct CfgLevel
2900  {
2901  CfgLevel() : parent(nullptr), depth(0) {}
2902  CfgLevel(CfgLevel* p, std::size_t d) : parent(p), depth(d) {}
2903 
2904  using value_map_t = std::map<std::string, Value>;
2905  using section_map_t = std::map<std::string, CfgLevel>;
2906 
2907  value_map_t values;
2908  section_map_t sections;
2909  std::string prefix;
2910  CfgLevel* parent;
2911  size_t depth;
2912 
2913  Value operator[](const std::string& name) { return values[name]; }
2914  CfgLevel& operator()(const std::string& name) { return sections[name]; }
2915  std::string to_string()
2916  {
2917  std::string ret;
2918  for (auto v : values)
2919  {
2920  ret += prefix + v.first + " = " + v.second.str() + "\n";
2921  }
2922  for (auto s : sections)
2923  {
2924  ret += s.second.to_string();
2925  }
2926  return ret;
2927  }
2928  };
2929 
2934  {
2935  public:
2940  CfgParser(std::string filename);
2941 
2946  CfgParser(std::istream& s) : pstream_(&s), ln_(0) { parse(root_); }
2947 
2952  CfgLevel& root() { return root_; }
2953 
2959  Value operator[](const std::string& name) { return root_.values[name]; }
2960 
2966  CfgLevel& operator()(const std::string& name) { return root_.sections[name]; }
2967 
2968  private:
2969  void parse(CfgLevel& lvl);
2970  CfgLevel* parse_section(std::string sline, CfgLevel *lvl);
2971  CfgLevel* parse_key_section(std::string& vline, CfgLevel *lvl);
2972  std::string split_key_value(std::string& line);
2973  void error_handler(std::string msg);
2974 
2975  CfgLevel root_;
2976  std::ifstream stream_;
2977  std::istream *pstream_;
2978  std::string line_;
2979  std::size_t ln_;
2980  };
2981 
2986  {
2987  friend class ArgParser;
2988  public:
2989 
2995  ArgOption(char shortKey, std::string longKey);
2996 
3001  ArgOption(char shortKey);
3002 
3007  ArgOption(std::string longKey);
3008 
3015  ArgOption& call(std::function<void()> todo);
3016 
3026  ArgOption& call(std::function<void()> todo, std::function<void()> otherwise);
3027 
3034  ArgOption& set_help(std::string helpInfo);
3035 
3043  ArgOption& require(bool require = true);
3044 
3051  ArgOption& set_once(bool onlyOnce = true);
3052 
3059  ArgOption& set_type(std::string type);
3060 
3067  ArgOption& set_min(int minCount);
3068 
3075  ArgOption& set_max(int maxCount);
3076 
3081  Value get_value();
3082 
3087  int get_count();
3088 
3089  private:
3090  std::string get_help();
3091  std::string get_short_help();
3092 
3093  char shortKey_;
3094  std::string longKey_;
3095  std::string type_;
3096  std::string help_;
3097  std::string default_;
3098  bool required_;
3099  int min_;
3100  int max_;
3101  int size_;
3102  bool once_;
3103  int count_;
3104  Value val_;
3105  std::vector<std::function<void()>> callback_;
3106  std::vector<std::function<void()>> othercall_;
3107  };
3108 
3114  {
3115  public:
3119  ArgParser();
3120 
3125  void add_info(std::string info);
3126 
3135  ArgOption& add_opt(char shortKey, std::string longKey);
3136 
3142  ArgOption& add_opt(char shortKey);
3143 
3149  ArgOption& add_opt(std::string longKey);
3150 
3166  template <typename T> ArgOption& add_opt_value(char shortKey, std::string longKey,
3167  T& dst, T defaultValue, std::string help = "", std::string type = "", int min = 1, int max = 1);
3168 
3178  ArgOption& add_opt_flag(char shortKey, std::string longKey, std::string help = "", bool* dst = nullptr);
3179 
3187  void add_opt_help(char shortKey, std::string longKey, std::string help = "print this help and exit");
3188 
3196  void add_opt_version(char shortKey, std::string longKey, std::string version, std::string help = "print version and exit");
3197 
3202  std::string version() const { return info_[1]; }
3203 
3210  void parse(int argc, char** argv, bool ignoreUnknown = false);
3211 
3216  std::size_t count_error() { return errors_.size(); }
3217 
3223  int count(char shortKey);
3224 
3230  int count(std::string longKey);
3231 
3236  std::string get_error();
3237 
3242  std::string get_help();
3243 
3249  Value operator[](const std::string& longKey);
3250 
3256  Value operator[](const char shortKey);
3257 
3262  std::vector<Value> arguments() const;
3263 
3264  private:
3265  //using ArgOptIter = std::vector<ArgOption>::iterator;
3266  enum class Type { SHORT_KEY, LONG_KEY, ARGUMENT, INVALID };
3267  using ArgQueue = std::vector<std::pair<std::string, Type>>;
3268 
3269  ArgOption& add_opt_internal(char shortKey, std::string longKey);
3270  void register_keys(char shortKey, std::string longKey, std::size_t pos);
3271  Type check_type(std::string str);
3272  ArgQueue pretty_arguments(int argc, char** argv);
3273  void error_option(std::string opt, std::string msg = "");
3274  void parse_option(ArgOption* ptr);
3275  void parse_value(ArgOption* ptr, const std::string& value);
3276 
3277  std::vector<ArgOption> options_;
3278  std::unordered_map<char, std::size_t> shortKeys_;
3279  std::unordered_map<std::string, std::size_t> longKeys_;
3280  std::vector<Value> args_;
3281  std::vector<std::string> errors_;
3282  std::vector<std::string> info_;
3283  };
3284 
3285 
3286  // implementations in cfg:: namespace
3287 
3288  template <typename T> inline std::string Value::store(T t)
3289  {
3290  std::ostringstream oss;
3291  oss << t;
3292  str_ = oss.str();
3293  return str_;
3294  }
3295 
3296  template <typename T> inline std::string Value::store(std::vector<T> t)
3297  {
3298  std::ostringstream oss;
3299  for (auto e : t)
3300  {
3301  oss << e << " ";
3302  }
3303  str_ = oss.str();
3304  return str_;
3305  }
3306 
3307  template <typename T> inline T Value::load(T& t)
3308  {
3309  std::istringstream iss(str_);
3310  iss >> t;
3311  return t;
3312  }
3313 
3314  template <> inline bool Value::load(bool& b)
3315  {
3316  b = false;
3317  std::string lowered = fmt::to_lower_ascii(str_);
3318  std::istringstream iss(lowered);
3319  iss >> std::boolalpha >> b;
3320  return b;
3321  }
3322 
3323  template <typename T> inline std::vector<T> Value::load(std::vector<T>& t)
3324  {
3325  std::istringstream iss(str_);
3326  t.clear();
3327  T val;
3328  std::string dummy;
3329  while (iss >> val || !iss.eof())
3330  {
3331  if (iss.fail())
3332  {
3333  iss.clear();
3334  iss >> dummy;
3335  continue;
3336  }
3337  t.push_back(val);
3338  }
3339  return t;
3340  }
3341 
3342  template <typename T> inline ArgOption& ArgParser::add_opt_value(char shortKey, std::string longKey,
3343  T& dst, T defaultValue, std::string help, std::string type, int min, int max)
3344  {
3345  dst = defaultValue;
3346  Value dfltValue;
3347  dfltValue.store(defaultValue);
3348  auto pos = options_.size();
3349  auto& opt = add_opt(shortKey, longKey).call([&, pos] {options_[pos].get_value().load(dst); });
3350  opt.default_ = dfltValue.str();
3351  return opt.set_help(help).set_type(type).set_min(min).set_max(max);
3352  }
3353 
3354  } // namespace cfg
3355 
3360  namespace log
3361  {
3362  // \cond
3363 
3364  namespace detail
3365  {
3366  void zupply_internal_warn(std::string msg);
3367  void zupply_internal_error(std::string msg);
3368 
3369  class ScopedRedirect
3370  {
3371  public:
3372  ScopedRedirect(std::ostream &orig) : backup_(orig)
3373  {
3374  old = orig.rdbuf(buffer_.rdbuf());
3375  }
3376 
3377  ~ScopedRedirect()
3378  {
3379  backup_.rdbuf(old);
3380  backup_ << buffer_.str();
3381  }
3382 
3383  private:
3384  ScopedRedirect(const ScopedRedirect&);
3385  ScopedRedirect& operator=(const ScopedRedirect&);
3386 
3387  std::ostream &backup_;
3388  std::streambuf *old;
3389  std::ostringstream buffer_;
3390  };
3391  }
3392 
3393  // \endcond
3394 
3399  class ProgBar
3400  {
3401  public:
3407  ProgBar(unsigned range = 100, std::string info = "");
3408 
3412  ~ProgBar();
3413 
3418  void step(unsigned size = 1);
3419 
3425  void stop();
3426 
3427  private:
3428  void start();
3429  void bg_work();
3430  void draw();
3431  void calc_rate(unsigned size);
3432 
3433  std::string info_;
3434  unsigned range_;
3435  std::atomic<unsigned> pos_;
3436  std::thread worker_;
3437  std::atomic_bool running_;
3438  std::streambuf *oldCout_;
3439  std::streambuf *oldCerr_;
3440  std::ostream ss_;
3441  std::ostringstream buffer_;
3442  char rate_[10];
3443  time::Timer timer_;
3444  };
3445 
3446  // \cond
3447  typedef enum LogLevelEnum
3448  {
3449  trace = 0,
3450  debug = 1,
3451  info = 2,
3452  warn = 3,
3453  error = 4,
3454  fatal = 5,
3455  off = 6,
3456  sentinel = 63
3457  }LogLevels;
3458 
3459  namespace consts
3460  {
3461  static const char *kLevelNames[] { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF"};
3462  static const char *kShortLevelNames[] { "T", "D", "I", "W", "E", "F", "O"};
3463  static const char *kZupplyInternalLoggerName = "zupply";
3464  static const int kAsyncQueueSize = 4096;
3465 
3466  static const char *kSinkDatetimeSpecifier = "%datetime";
3467  static const char *kSinkLoggerNameSpecifier = "%logger";
3468  static const char *kSinkThreadSpecifier = "%thread";
3469  static const char *kSinkLevelSpecifier = "%level";
3470  static const char *kSinkLevelShortSpecifier = "%lvl";
3471  static const char *kSinkMessageSpecifier = "%msg";
3472  static const char *kStdoutSinkName = "stdout";
3473  static const char *kStderrSinkName = "stderr";
3474  static const char *kSimplefileSinkType = "simplefile";
3475  static const char *kRotatefileSinkType = "rotatefile";
3476  static const char *kOstreamSinkType = "ostream";
3477  static const char *kDefaultLoggerFormat = "[%datetime][T%thread][%logger][%level] %msg";
3478  static const char *kDefaultLoggerDatetimeFormat = "%y-%m-%d %H:%M:%S.%frac";
3479 
3480  // config file formats
3481  static const char *KConfigGlobalSectionSpecifier = "global";
3482  static const char *KConfigLoggerSectionSpecifier = "loggers";
3483  static const char *KConfigSinkSectionSpecifier = "sinks";
3484  static const char *kConfigFormatSpecifier = "format";
3485  static const char *kConfigLevelsSpecifier = "levels";
3486  static const char *kConfigDateTimeFormatSpecifier = "datetime_format";
3487  static const char *kConfigSinkListSpecifier = "sink_list";
3488  static const char *kConfigSinkTypeSpecifier = "type";
3489  static const char *kConfigSinkFilenameSpecifier = "filename";
3490  }
3491 
3492  // forward declaration
3493  namespace detail
3494  {
3495  struct LogMessage;
3496  class LineLogger;
3497  class SinkInterface;
3498  } // namespace detail
3499  typedef std::shared_ptr<detail::SinkInterface> SinkPtr;
3500 
3501  inline bool level_should_log(int levelMask, LogLevels lvl)
3502  {
3503  return (LogLevels::sentinel & levelMask & (1 << lvl)) > 0;
3504  }
3505 
3506  std::string level_mask_to_string(int levelMask);
3507 
3508  LogLevels level_from_str(std::string level);
3509 
3510  int level_mask_from_string(std::string levels);
3511 
3512  // \endcond
3513 
3519  {
3520  public:
3526  static LogConfig& instance();
3527 
3532  static void set_default_format(std::string format);
3533 
3538  static void set_default_datetime_format(std::string dateFormat);
3539 
3544  static void set_default_sink_list(std::vector<std::string> list);
3545 
3552  static void set_default_level_mask(int levelMask);
3553 
3558  std::vector<std::string> sink_list();
3559 
3564  void set_sink_list(std::vector<std::string> &list);
3565 
3570  int log_level_mask();
3571 
3576  void set_log_level_mask(int newMask);
3577 
3582  std::string format();
3583 
3588  void set_format(std::string newFormat);
3589 
3594  std::string datetime_format();
3595 
3600  void set_datetime_format(std::string newDatetimeFormat);
3601 
3602  private:
3603  LogConfig();
3604 
3606  std::atomic_int logLevelMask_;
3609  };
3610 
3617  {
3618  public:
3623  Logger(std::string name) : name_(name)
3624  {
3625  levelMask_ = LogConfig::instance().log_level_mask();
3626  }
3627 
3633  Logger(std::string name, int levelMask) : name_(name)
3634  {
3635  levelMask_ = levelMask;
3636  }
3637 
3638  // logger.info(format string, arg1, arg2, arg3, ...) call style
3644  template <typename... Args> detail::LineLogger trace(const char* fmt, const Args&... args);
3645 
3651  template <typename... Args> detail::LineLogger debug(const char* fmt, const Args&... args);
3652 
3658  template <typename... Args> detail::LineLogger info(const char* fmt, const Args&... args);
3659 
3665  template <typename... Args> detail::LineLogger warn(const char* fmt, const Args&... args);
3666 
3672  template <typename... Args> detail::LineLogger error(const char* fmt, const Args&... args);
3673 
3679  template <typename... Args> detail::LineLogger fatal(const char* fmt, const Args&... args);
3680 
3681 
3682  // logger.info(msg) << ".." call style
3688  template <typename T> detail::LineLogger trace(const T& msg);
3689 
3695  template <typename T> detail::LineLogger debug(const T& msg);
3696 
3702  template <typename T> detail::LineLogger info(const T& msg);
3703 
3709  template <typename T> detail::LineLogger warn(const T& msg);
3710 
3716  template <typename T> detail::LineLogger error(const T& msg);
3717 
3723  template <typename T> detail::LineLogger fatal(const T& msg);
3724 
3725 
3726  // logger.info() << ".." call style
3727 
3732  detail::LineLogger trace();
3733 
3738  detail::LineLogger debug();
3739 
3744  detail::LineLogger info();
3745 
3750  detail::LineLogger warn();
3751 
3756  detail::LineLogger error();
3757 
3762  detail::LineLogger fatal();
3763 
3764  //const LogLevels level() const
3765  //{
3766  // return static_cast<LogLevels>(level_.load(std::memory_order_relaxed));
3767  //}
3768 
3773  void set_level_mask(int levelMask)
3774  {
3775  levelMask_ = levelMask & LogLevels::sentinel;
3776  }
3777 
3783  bool should_log(LogLevels msgLevel) const
3784  {
3785  return level_should_log(levelMask_, msgLevel);
3786  }
3787 
3792  std::string name() const { return name_; };
3793 
3799  std::string to_string();
3800 
3806  SinkPtr get_sink(std::string name);
3807 
3812  void attach_sink(SinkPtr sink);
3813 
3818  void detach_sink(SinkPtr sink);
3819 
3823  void detach_all_sinks();
3824 
3829  void attach_sink_list(std::vector<std::string> &sinkList);
3830 
3835  void attach_console();
3836 
3841  void detach_console();
3842 
3843  private:
3844 
3845  friend detail::LineLogger;
3846 
3847  detail::LineLogger log_if_enabled(LogLevels lvl);
3848 
3849  template <typename... Args>
3850  detail::LineLogger log_if_enabled(LogLevels lvl, const char* fmt, const Args&... args);
3851 
3852  template<typename T>
3853  detail::LineLogger log_if_enabled(LogLevels lvl, const T& msg);
3854 
3855  void log_msg(detail::LogMessage msg);
3856 
3857  std::string name_;
3858  std::atomic_int levelMask_;
3860  };
3861  typedef std::shared_ptr<Logger> LoggerPtr;
3862 
3863 
3864  // \cond
3865  namespace detail
3866  {
3867  template<typename T>
3868  class mpmc_bounded_queue
3869  {
3870  public:
3871 
3872  using item_type = T;
3873  mpmc_bounded_queue(size_t buffer_size)
3874  : buffer_(new cell_t[buffer_size]),
3875  buffer_mask_(buffer_size - 1)
3876  {
3877  //queue size must be power of two
3878  if (!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0)))
3879  throw ArgException("async logger queue size must be power of two");
3880 
3881  for (size_t i = 0; i != buffer_size; i += 1)
3882  buffer_[i].sequence_.store(i, std::memory_order_relaxed);
3883  enqueue_pos_.store(0, std::memory_order_relaxed);
3884  dequeue_pos_.store(0, std::memory_order_relaxed);
3885  }
3886 
3887  ~mpmc_bounded_queue()
3888  {
3889  delete[] buffer_;
3890  }
3891 
3892 
3893  bool enqueue(T&& data)
3894  {
3895  cell_t* cell;
3896  size_t pos = enqueue_pos_.load(std::memory_order_relaxed);
3897  for (;;)
3898  {
3899  cell = &buffer_[pos & buffer_mask_];
3900  size_t seq = cell->sequence_.load(std::memory_order_acquire);
3901  intptr_t dif = (intptr_t)seq - (intptr_t)pos;
3902  if (dif == 0)
3903  {
3904  if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
3905  break;
3906  }
3907  else if (dif < 0)
3908  {
3909  return false;
3910  }
3911  else
3912  {
3913  pos = enqueue_pos_.load(std::memory_order_relaxed);
3914  }
3915  }
3916  cell->data_ = std::move(data);
3917  cell->sequence_.store(pos + 1, std::memory_order_release);
3918  return true;
3919  }
3920 
3921  bool dequeue(T& data)
3922  {
3923  cell_t* cell;
3924  size_t pos = dequeue_pos_.load(std::memory_order_relaxed);
3925  for (;;)
3926  {
3927  cell = &buffer_[pos & buffer_mask_];
3928  size_t seq =
3929  cell->sequence_.load(std::memory_order_acquire);
3930  intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1);
3931  if (dif == 0)
3932  {
3933  if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
3934  break;
3935  }
3936  else if (dif < 0)
3937  return false;
3938  else
3939  pos = dequeue_pos_.load(std::memory_order_relaxed);
3940  }
3941  data = std::move(cell->data_);
3942  cell->sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release);
3943  return true;
3944  }
3945 
3946  private:
3947  struct cell_t
3948  {
3949  std::atomic<size_t> sequence_;
3950  T data_;
3951  };
3952 
3953  static size_t const cacheline_size = 64;
3954  typedef char cacheline_pad_t[cacheline_size];
3955 
3956  cacheline_pad_t pad0_;
3957  cell_t* const buffer_;
3958  size_t const buffer_mask_;
3959  cacheline_pad_t pad1_;
3960  std::atomic<size_t> enqueue_pos_;
3961  cacheline_pad_t pad2_;
3962  std::atomic<size_t> dequeue_pos_;
3963  cacheline_pad_t pad3_;
3964 
3965  mpmc_bounded_queue(mpmc_bounded_queue const&);
3966  void operator = (mpmc_bounded_queue const&);
3967  };
3968 
3969  struct LogMessage
3970  {
3971  std::string loggerName_;
3972  LogLevels level_;
3973  time::DateTime dateTime_;
3974  size_t threadId_;
3975  std::string buffer_;
3976  };
3977 
3978  class LineLogger : private UnCopyable
3979  {
3980  public:
3981  LineLogger(Logger* callbacker, LogLevels lvl, bool enable) :callbackLogger_(callbacker), enabled_(enable)
3982  {
3983  msg_.level_ = lvl;
3984  }
3985 
3986  LineLogger(LineLogger&& other) :
3987  callbackLogger_(other.callbackLogger_),
3988  msg_(std::move(other.msg_)),
3989  enabled_(other.enabled_)
3990  {
3991  other.disable();
3992  }
3993 
3994  ~LineLogger()
3995  {
3996  if (enabled_)
3997  {
3998  msg_.loggerName_ = callbackLogger_->name();
3999  msg_.dateTime_ = time::DateTime::local_time();
4000  msg_.threadId_ = os::thread_id();
4001  callbackLogger_->log_msg(msg_);
4002  }
4003  }
4004 
4005  LineLogger& operator=(LineLogger&&) = delete;
4006 
4007  void write(const char* what)
4008  {
4009  if (enabled_)
4010  msg_.buffer_ += what;
4011  }
4012 
4013  template <typename... Args>
4014  void write(const char* fmt, const Args&... args)
4015  {
4016  if (!enabled_) return;
4017  std::string buf(fmt);
4018  fmt::format_string(buf, args...);
4019  msg_.buffer_ += buf;
4020  }
4021 
4022 
4023  LineLogger& operator<<(const char* what)
4024  {
4025  if (enabled_) msg_.buffer_ += what;
4026  return *this;
4027  }
4028 
4029  LineLogger& operator<<(const std::string& what)
4030  {
4031  if (enabled_) msg_.buffer_ += what;
4032  return *this;
4033  }
4034 
4035  template<typename T>
4036  LineLogger& operator<<(const T& what)
4037  {
4038  if (enabled_)
4039  {
4040  std::ostringstream oss;
4041  oss << std::dec << what;
4042  msg_.buffer_ += oss.str();
4043  }
4044  return *this;
4045  }
4046 
4047  void disable()
4048  {
4049  enabled_ = false;
4050  }
4051 
4052  bool is_enabled() const
4053  {
4054  return enabled_;
4055  }
4056  private:
4057  Logger *callbackLogger_;
4058  LogMessage msg_;
4059  bool enabled_;
4060  };
4061 
4062  class SinkInterface
4063  {
4064  public:
4065  virtual ~SinkInterface() {};
4066  virtual void log(const LogMessage& msg) = 0;
4067  virtual void flush() = 0;
4068  virtual std::string name() const = 0;
4069  virtual std::string to_string() const = 0;
4070  virtual void set_level_mask(int levelMask) = 0;
4071  virtual void set_format(const std::string &fmt) = 0;
4072  };
4073 
4074  // Due to a bug in VC12, thread join in static object dtor
4075  // will cause deadlock. TODO: implement async sink when
4076  // VS2015 ready.
4077  class AsyncSink : public SinkInterface, private UnCopyable
4078  {
4079 
4080  };
4081 
4082  class Sink : public SinkInterface, private UnCopyable
4083  {
4084  public:
4085  Sink()
4086  {
4087  levelMask_ = 0x3F & LogConfig::instance().log_level_mask();
4088  set_format(LogConfig::instance().format());
4089  };
4090 
4091  virtual ~Sink() {};
4092 
4093  void log(const LogMessage& msg) override
4094  {
4095  if (!level_should_log(levelMask_, msg.level_)) return;
4096  std::string finalMessage = format_message(msg);
4097  // mutex for multi-thread race, actually vc++ and gnu++ are ok without lock
4098  // but this behavior is not guanranteed, and libc++ will have corrupt output
4099  std::lock_guard<std::mutex> lock(mutex_);
4100  sink_it(finalMessage);
4101  }
4102 
4103  void set_level_mask(int levelMask) override
4104  {
4105  levelMask_ = levelMask & LogLevels::sentinel;
4106  }
4107 
4108  int level_mask() const
4109  {
4110  return levelMask_;
4111  }
4112 
4113  void set_format(const std::string &format) override
4114  {
4115  format_.set(format);
4116  }
4117 
4118  virtual void sink_it(const std::string &finalMsg) = 0;
4119 
4120  private:
4121  std::string format_message(const LogMessage &msg)
4122  {
4123  std::string ret(format_.get());
4124  auto dt = msg.dateTime_;
4125  fmt::replace_all_with_escape(ret, consts::kSinkDatetimeSpecifier, dt.to_string(LogConfig::instance().datetime_format().c_str()));
4126  fmt::replace_all_with_escape(ret, consts::kSinkLoggerNameSpecifier, msg.loggerName_);
4127  fmt::replace_all_with_escape(ret, consts::kSinkThreadSpecifier, std::to_string(msg.threadId_));
4128  fmt::replace_all_with_escape(ret, consts::kSinkLevelSpecifier, consts::kLevelNames[msg.level_]);
4129  fmt::replace_all_with_escape(ret, consts::kSinkLevelShortSpecifier, consts::kShortLevelNames[msg.level_]);
4130  fmt::replace_all_with_escape(ret, consts::kSinkMessageSpecifier, msg.buffer_);
4131  // make sure new line
4132  if (!fmt::ends_with(ret, "\n")) ret += os::endl();
4133  return ret;
4134  }
4135 
4136  std::atomic_int levelMask_;
4137  std::mutex mutex_;
4138  cds::lockbased::NonTrivialContainer<std::string> format_;
4139  };
4140 
4141  class SimpleFileSink : public Sink
4142  {
4143  public:
4144  SimpleFileSink(const std::string filename, bool truncate) :fileEditor_(filename, truncate)
4145  {
4146  }
4147 
4148  void flush() override
4149  {
4150  fileEditor_.flush();
4151  }
4152 
4153  void sink_it(const std::string &finalMsg) override
4154  {
4155  fileEditor_ << finalMsg;
4156  }
4157 
4158  std::string name() const override
4159  {
4160  return fileEditor_.filename();
4161  }
4162 
4163  std::string to_string() const override
4164  {
4165  return "SimpleFileSink->" + name() + " " + level_mask_to_string(level_mask());
4166  }
4167 
4168  private:
4169  fs::FileEditor fileEditor_;
4170  };
4171 
4172  class RotateFileSink : public Sink
4173  {
4174  public:
4175  RotateFileSink(const std::string filename, std::size_t maxSizeInByte, bool backup);
4176 
4177  void flush() override
4178  {
4179  fileEditor_.flush();
4180  }
4181 
4182  void sink_it(const std::string &finalMsg) override
4183  {
4184  currentSize_ += finalMsg.length();
4185  if (currentSize_ > maxSizeInByte_)
4186  {
4187  rotate();
4188  }
4189  fileEditor_ << finalMsg;
4190  }
4191 
4192  std::string name() const override
4193  {
4194  return fileEditor_.filename();
4195  }
4196 
4197  std::string to_string() const override
4198  {
4199  return "RotateFileSink->" + name() + " " + level_mask_to_string(level_mask());
4200  }
4201 
4202  private:
4203  void back_up(std::string oldFile);
4204  void rotate();
4205 
4206  fs::FileEditor fileEditor_;
4207  std::mutex mutex_;
4208  std::size_t maxSizeInByte_;
4209  std::atomic<std::size_t> currentSize_;
4210  bool backup_;
4211  };
4212 
4213  class OStreamSink : public Sink
4214  {
4215  public:
4216  explicit OStreamSink(std::ostream& os, const char *name, bool forceFlush = false)
4217  :ostream_(os), name_(name), forceFlush_(forceFlush)
4218  {
4219  }
4220 
4221  std::string name() const override
4222  {
4223  return name_;
4224  }
4225 
4226  std::string to_string() const override
4227  {
4228  return "OStreamSink->" + name() + " " + level_mask_to_string(level_mask());
4229  }
4230 
4231  private:
4232  void sink_it(const std::string &finalMsg) override
4233  {
4234  ostream_ << finalMsg;
4235  if (forceFlush_) ostream_.flush();
4236  }
4237 
4238  void flush() override
4239  {
4240  ostream_.flush();
4241  }
4242 
4243  std::ostream& ostream_;
4244  std::string name_;
4245  bool forceFlush_;
4246  };
4247 
4248  class StdoutSink : public OStreamSink
4249  {
4250  public:
4251  StdoutSink() : OStreamSink(std::cout, consts::kStdoutSinkName, true)
4252  {
4253  // stdout by design should not receive warning and error message
4254  // so add cout and cerr together and filter by level is a better idea
4255  set_level_mask(0x07 & LogConfig::instance().log_level_mask());
4256  }
4257  static std::shared_ptr<StdoutSink> instance()
4258  {
4259  static std::shared_ptr<StdoutSink> instance = std::make_shared<StdoutSink>();
4260  return instance;
4261  }
4262 
4263  std::string to_string() const override
4264  {
4265  return "StdoutSink->" + name() + " " + level_mask_to_string(level_mask());
4266  }
4267  };
4268 
4269  class StderrSink : public OStreamSink
4270  {
4271  public:
4272  StderrSink() : OStreamSink(std::cerr, consts::kStderrSinkName, true)
4273  {
4274  // stderr by design should only log error/warning msg
4275  set_level_mask(0x38 & LogConfig::instance().log_level_mask());
4276  }
4277  static std::shared_ptr<StderrSink> instance()
4278  {
4279  static std::shared_ptr<StderrSink> instance = std::make_shared<StderrSink>();
4280  return instance;
4281  }
4282 
4283  std::string to_string() const override
4284  {
4285  return "StderrSink->" + name() + " " + level_mask_to_string(level_mask());
4286  }
4287  };
4288 
4289  class LoggerRegistry : UnMovable
4290  {
4291  public:
4292  static LoggerRegistry& instance();
4293  LoggerPtr create(const std::string &name);
4294  LoggerPtr ensure_get(std::string &name);
4295  LoggerPtr get(std::string &name);
4296  std::vector<LoggerPtr> get_all();
4297  void drop(const std::string &name);
4298  void drop_all();
4299  void lock();
4300  void unlock();
4301  bool is_locked() const;
4302 
4303  private:
4304  LoggerRegistry(){ lock_ = false; }
4305 
4306  LoggerPtr new_registry(const std::string &name);
4307 
4308  cds::lockbased::UnorderedMap<std::string, LoggerPtr> loggers_;
4309  std::atomic_bool lock_;
4310  };
4311  } // namespace detail
4312 
4313  inline detail::LineLogger Logger::log_if_enabled(LogLevels lvl)
4314  {
4315  detail::LineLogger l(this, lvl, should_log(lvl));
4316  return l;
4317  }
4318 
4319  template <typename... Args>
4320  inline detail::LineLogger Logger::log_if_enabled(LogLevels lvl, const char* fmt, const Args&... args)
4321  {
4322  detail::LineLogger l(this, lvl, should_log(lvl));
4323  l.write(fmt, args...);
4324  return l;
4325  }
4326 
4327  template<typename T>
4328  inline detail::LineLogger Logger::log_if_enabled(LogLevels lvl, const T& msg)
4329  {
4330  detail::LineLogger l(this, lvl, should_log(lvl));
4331  l.write(msg);
4332  return l;
4333  }
4334 
4335  // logger.info(format string, arg1, arg2, arg3, ...) call style
4336  template <typename... Args>
4337  inline detail::LineLogger Logger::trace(const char* fmt, const Args&... args)
4338  {
4339  return log_if_enabled(LogLevels::trace, fmt, args...);
4340  }
4341  template <typename... Args>
4342  inline detail::LineLogger Logger::debug(const char* fmt, const Args&... args)
4343  {
4344  return log_if_enabled(LogLevels::debug, fmt, args...);
4345  }
4346  template <typename... Args>
4347  inline detail::LineLogger Logger::info(const char* fmt, const Args&... args)
4348  {
4349  return log_if_enabled(LogLevels::info, fmt, args...);
4350  }
4351  template <typename... Args>
4352  inline detail::LineLogger Logger::warn(const char* fmt, const Args&... args)
4353  {
4354  return log_if_enabled(LogLevels::warn, fmt, args...);
4355  }
4356  template <typename... Args>
4357  inline detail::LineLogger Logger::error(const char* fmt, const Args&... args)
4358  {
4359  return log_if_enabled(LogLevels::error, fmt, args...);
4360  }
4361  template <typename... Args>
4362  inline detail::LineLogger Logger::fatal(const char* fmt, const Args&... args)
4363  {
4364  return log_if_enabled(LogLevels::fatal, fmt, args...);
4365  }
4366 
4367 
4368  // logger.info(msg) << ".." call style
4369  template <typename T>
4370  inline detail::LineLogger Logger::trace(const T& msg)
4371  {
4372  return log_if_enabled(LogLevels::trace, msg);
4373  }
4374  template <typename T>
4375  inline detail::LineLogger Logger::debug(const T& msg)
4376  {
4377  return log_if_enabled(LogLevels::debug, msg);
4378  }
4379  template <typename T>
4380  inline detail::LineLogger Logger::info(const T& msg)
4381  {
4382  return log_if_enabled(LogLevels::info, msg);
4383  }
4384  template <typename T>
4385  inline detail::LineLogger Logger::warn(const T& msg)
4386  {
4387  return log_if_enabled(LogLevels::warn, msg);
4388  }
4389  template <typename T>
4390  inline detail::LineLogger Logger::error(const T& msg)
4391  {
4392  return log_if_enabled(LogLevels::error, msg);
4393  }
4394  template <typename T>
4395  inline detail::LineLogger Logger::fatal(const T& msg)
4396  {
4397  return log_if_enabled(LogLevels::fatal, msg);
4398  }
4399 
4400  // \endcond
4401 
4408  LoggerPtr get_logger(std::string name, bool createIfNotExists = true);
4409 
4414  SinkPtr new_stdout_sink();
4415 
4420  SinkPtr new_stderr_sink();
4421 
4427  SinkPtr get_sink(std::string name);
4428 
4433  void dump_loggers(std::ostream &out = std::cout);
4434 
4442  SinkPtr new_ostream_sink(std::ostream &stream, std::string name, bool forceFlush = false);
4443 
4450  SinkPtr new_simple_file_sink(std::string filename, bool truncate = false);
4451 
4459  SinkPtr new_rotate_file_sink(std::string filename, std::size_t maxSizeInByte = 4194304, bool backupOld = false);
4460 
4465  void lock_loggers();
4466 
4471  void unlock_loggers();
4472 
4477  void drop_logger(std::string name);
4478 
4482  void drop_all_loggers();
4483 
4488  void drop_sink(std::string name);
4489 
4490  // \cond
4491  namespace detail
4492  {
4493  void sink_list_revise(std::vector<std::string> &list, std::map<std::string, std::string> &map);
4494 
4495  void config_loggers_from_section(cfg::CfgLevel::section_map_t &section, std::map<std::string, std::string> &map);
4496 
4497  LoggerPtr get_hidden_logger();
4498 
4499  std::map<std::string, std::string> config_sinks_from_section(cfg::CfgLevel::section_map_t &section);
4500 
4501 
4502  void zupply_internal_warn(std::string msg);
4503 
4504  void zupply_internal_error(std::string msg);
4505 
4506  void config_from_parser(cfg::CfgParser& parser);
4507  } // namespace detail
4508  // \endcond
4509 
4514  void config_from_file(std::string cfgFilename);
4515 
4520  void config_from_stringstream(std::stringstream& ss);
4521  } // namespace log
4522 
4523  // \cond
4526 
4527  template<typename _Tp> static inline _Tp saturate_cast(unsigned char v) { return _Tp(v); }
4528  template<typename _Tp> static inline _Tp saturate_cast(char v) { return _Tp(v); }
4529  template<typename _Tp> static inline _Tp saturate_cast(unsigned short v) { return _Tp(v); }
4530  template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
4531  template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
4532  template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
4533  template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
4534  template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
4535 
4536  template<> inline unsigned char saturate_cast<unsigned char>(char v) { return (unsigned char)(std::max)((int)v, 0); }
4537  template<> inline unsigned char saturate_cast<unsigned char>(unsigned char v) { return (unsigned char)(std::min)((unsigned)v, (unsigned)UCHAR_MAX); }
4538  template<> inline unsigned char saturate_cast<unsigned char>(int v) { return (unsigned char)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
4539  template<> inline unsigned char saturate_cast<unsigned char>(short v) { return saturate_cast<unsigned char>((int)v); }
4540  template<> inline unsigned char saturate_cast<unsigned char>(unsigned v) { return (unsigned char)(std::min)(v, (unsigned)UCHAR_MAX); }
4541  template<> inline unsigned char saturate_cast<unsigned char>(float v) { int iv = math::round(v); return saturate_cast<unsigned char>(iv); }
4542  template<> inline unsigned char saturate_cast<unsigned char>(double v) { int iv = math::round(v); return saturate_cast<unsigned char>(iv); }
4543 
4544  template<> inline char saturate_cast<char>(unsigned char v) { return (char)(std::min)((int)v, SCHAR_MAX); }
4545  template<> inline char saturate_cast<char>(unsigned short v) { return (char)(std::min)((unsigned)v, (unsigned)SCHAR_MAX); }
4546  template<> inline char saturate_cast<char>(int v) { return (char)((unsigned)(v - SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); }
4547  template<> inline char saturate_cast<char>(short v) { return saturate_cast<char>((int)v); }
4548  template<> inline char saturate_cast<char>(unsigned int v) { return (char)(std::min)(v, (unsigned)SCHAR_MAX); }
4549  template<> inline char saturate_cast<char>(float v) { int iv = math::round(v); return saturate_cast<char>(iv); }
4550  template<> inline char saturate_cast<char>(double v) { int iv = math::round(v); return saturate_cast<char>(iv); }
4551 
4552  template<> inline unsigned short saturate_cast<unsigned short>(char v) { return (unsigned short)(std::max)((int)v, 0); }
4553  template<> inline unsigned short saturate_cast<unsigned short>(short v) { return (unsigned short)(std::max)((int)v, 0); }
4554  template<> inline unsigned short saturate_cast<unsigned short>(int v) { return (unsigned short)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
4555  template<> inline unsigned short saturate_cast<unsigned short>(unsigned v) { return (unsigned short)(std::min)(v, (unsigned)USHRT_MAX); }
4556  template<> inline unsigned short saturate_cast<unsigned short>(float v) { int iv = math::round(v); return saturate_cast<unsigned short>(iv); }
4557  template<> inline unsigned short saturate_cast<unsigned short>(double v) { int iv = math::round(v); return saturate_cast<unsigned short>(iv); }
4558 
4559  template<> inline short saturate_cast<short>(unsigned short v) { return (short)(std::min)((int)v, SHRT_MAX); }
4560  template<> inline short saturate_cast<short>(int v) { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); }
4561  template<> inline short saturate_cast<short>(unsigned v) { return (short)(std::min)(v, (unsigned)SHRT_MAX); }
4562  template<> inline short saturate_cast<short>(float v) { int iv = math::round(v); return saturate_cast<short>(iv); }
4563  template<> inline short saturate_cast<short>(double v) { int iv = math::round(v); return saturate_cast<short>(iv); }
4564 
4565  template<> inline int saturate_cast<int>(float v) { return math::round(v); }
4566  template<> inline int saturate_cast<int>(double v) { return math::round(v); }
4567 
4568  // we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
4569  template<> inline unsigned saturate_cast<unsigned>(float v) { return (unsigned)math::round(v); }
4570  template<> inline unsigned saturate_cast<unsigned>(double v) { return (unsigned)math::round(v); }
4571 
4573  template<typename _Tp> inline
4575  : width(0), height(0) {}
4576 
4577  template<typename _Tp> inline
4578  Size_<_Tp>::Size_(_Tp _width, _Tp _height)
4579  : width(_width), height(_height) {}
4580 
4581  template<typename _Tp> inline
4582  Size_<_Tp>::Size_(const Size_& sz)
4583  : width(sz.width), height(sz.height) {}
4584 
4585  template<typename _Tp> template<typename _Tp2> inline
4586  Size_<_Tp>::operator Size_<_Tp2>() const
4587  {
4588  return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
4589  }
4590 
4591  template<typename _Tp> inline
4592  Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz)
4593  {
4594  width = sz.width; height = sz.height;
4595  return *this;
4596  }
4597 
4598  template<typename _Tp> inline
4599  bool Size_<_Tp>::operator == (const Size_<_Tp>& sz)
4600  {
4601  return (width == sz.width) && (height == sz.height);
4602  }
4603 
4604  template<typename _Tp> inline
4605  bool Size_<_Tp>::operator != (const Size_<_Tp>& sz)
4606  {
4607  return (width != sz.width) || (height != sz.height);
4608  }
4609 
4610  template<typename _Tp> inline
4611  _Tp Size_<_Tp>::area() const
4612  {
4613  return width * height;
4614  }
4615 
4616  template<typename _Tp> static inline
4617  Size_<_Tp>& operator *= (Size_<_Tp>& a, _Tp b)
4618  {
4619  a.width *= b;
4620  a.height *= b;
4621  return a;
4622  }
4623 
4624  template<typename _Tp> static inline
4625  Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
4626  {
4627  Size_<_Tp> tmp(a);
4628  tmp *= b;
4629  return tmp;
4630  }
4631 
4632  template<typename _Tp> static inline
4633  Size_<_Tp>& operator /= (Size_<_Tp>& a, _Tp b)
4634  {
4635  a.width /= b;
4636  a.height /= b;
4637  return a;
4638  }
4639 
4640  template<typename _Tp> static inline
4641  Size_<_Tp> operator / (const Size_<_Tp>& a, _Tp b)
4642  {
4643  Size_<_Tp> tmp(a);
4644  tmp /= b;
4645  return tmp;
4646  }
4647 
4648  template<typename _Tp> static inline
4649  Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
4650  {
4651  a.width += b.width;
4652  a.height += b.height;
4653  return a;
4654  }
4655 
4656  template<typename _Tp> static inline
4657  Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
4658  {
4659  Size_<_Tp> tmp(a);
4660  tmp += b;
4661  return tmp;
4662  }
4663 
4664  template<typename _Tp> static inline
4665  Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
4666  {
4667  a.width -= b.width;
4668  a.height -= b.height;
4669  return a;
4670  }
4671 
4672  template<typename _Tp> static inline
4673  Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
4674  {
4675  Size_<_Tp> tmp(a);
4676  tmp -= b;
4677  return tmp;
4678  }
4679 
4680  template<typename _Tp> static inline
4681  bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
4682  {
4683  return a.width == b.width && a.height == b.height;
4684  }
4685 
4686  template<typename _Tp> static inline
4687  bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
4688  {
4689  return !(a == b);
4690  }
4691 
4693  template<typename _Tp> inline
4695  : x(0), y(0) {}
4696 
4697  template<typename _Tp> inline
4698  Point_<_Tp>::Point_(_Tp _x, _Tp _y)
4699  : x(_x), y(_y) {}
4700 
4701  template<typename _Tp> inline
4702  Point_<_Tp>::Point_(const Point_& pt)
4703  : x(pt.x), y(pt.y) {}
4704 
4706  template<typename _Tp> inline
4707  Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
4708  {
4709  x = pt.x; y = pt.y;
4710  return *this;
4711  }
4712 
4713  template<typename _Tp> template<typename _Tp2> inline
4714  Point_<_Tp>::operator Point_<_Tp2>() const
4715  {
4716  return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y));
4717  }
4718 
4719  template<typename _Tp> static inline
4720  Point_<_Tp>& operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
4721  {
4722  a.x += b.x;
4723  a.y += b.y;
4724  return a;
4725  }
4726 
4727  template<typename _Tp> static inline
4728  Point_<_Tp>& operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
4729  {
4730  a.x -= b.x;
4731  a.y -= b.y;
4732  return a;
4733  }
4734 
4735  template<typename _Tp> static inline
4736  Point_<_Tp>& operator *= (Point_<_Tp>& a, int b)
4737  {
4738  a.x = saturate_cast<_Tp>(a.x * b);
4739  a.y = saturate_cast<_Tp>(a.y * b);
4740  return a;
4741  }
4742 
4743  template<typename _Tp> static inline
4744  Point_<_Tp>& operator *= (Point_<_Tp>& a, float b)
4745  {
4746  a.x = saturate_cast<_Tp>(a.x * b);
4747  a.y = saturate_cast<_Tp>(a.y * b);
4748  return a;
4749  }
4750 
4751  template<typename _Tp> static inline
4752  Point_<_Tp>& operator *= (Point_<_Tp>& a, double b)
4753  {
4754  a.x = saturate_cast<_Tp>(a.x * b);
4755  a.y = saturate_cast<_Tp>(a.y * b);
4756  return a;
4757  }
4758 
4759  template<typename _Tp> static inline
4760  Point_<_Tp>& operator /= (Point_<_Tp>& a, int b)
4761  {
4762  a.x = saturate_cast<_Tp>(a.x / b);
4763  a.y = saturate_cast<_Tp>(a.y / b);
4764  return a;
4765  }
4766 
4767  template<typename _Tp> static inline
4768  Point_<_Tp>& operator /= (Point_<_Tp>& a, float b)
4769  {
4770  a.x = saturate_cast<_Tp>(a.x / b);
4771  a.y = saturate_cast<_Tp>(a.y / b);
4772  return a;
4773  }
4774 
4775  template<typename _Tp> static inline
4776  Point_<_Tp>& operator /= (Point_<_Tp>& a, double b)
4777  {
4778  a.x = saturate_cast<_Tp>(a.x / b);
4779  a.y = saturate_cast<_Tp>(a.y / b);
4780  return a;
4781  }
4782 
4783  template<typename _Tp> static inline
4784  bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
4785  {
4786  return a.x == b.x && a.y == b.y;
4787  }
4788 
4789  template<typename _Tp> static inline
4790  bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
4791  {
4792  return a.x != b.x || a.y != b.y;
4793  }
4794 
4795  template<typename _Tp> static inline
4796  Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
4797  {
4798  return Point_<_Tp>(saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y));
4799  }
4800 
4801  template<typename _Tp> static inline
4802  Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
4803  {
4804  return Point_<_Tp>(saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y));
4805  }
4806 
4807  template<typename _Tp> static inline
4808  Point_<_Tp> operator - (const Point_<_Tp>& a)
4809  {
4810  return Point_<_Tp>(saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y));
4811  }
4812 
4813  template<typename _Tp> static inline
4814  Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
4815  {
4816  return Point_<_Tp>(saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b));
4817  }
4818 
4819  template<typename _Tp> static inline
4820  Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
4821  {
4822  return Point_<_Tp>(saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a));
4823  }
4824 
4825  template<typename _Tp> static inline
4826  Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
4827  {
4828  return Point_<_Tp>(saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b));
4829  }
4830 
4831  template<typename _Tp> static inline
4832  Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
4833  {
4834  return Point_<_Tp>(saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a));
4835  }
4836 
4837  template<typename _Tp> static inline
4838  Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
4839  {
4840  return Point_<_Tp>(saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b));
4841  }
4842 
4843  template<typename _Tp> static inline
4844  Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
4845  {
4846  return Point_<_Tp>(saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a));
4847  }
4848 
4849 
4850  template<typename _Tp> static inline
4851  Point_<_Tp> operator / (const Point_<_Tp>& a, int b)
4852  {
4853  Point_<_Tp> tmp(a);
4854  tmp /= b;
4855  return tmp;
4856  }
4857 
4858  template<typename _Tp> static inline
4859  Point_<_Tp> operator / (const Point_<_Tp>& a, float b)
4860  {
4861  Point_<_Tp> tmp(a);
4862  tmp /= b;
4863  return tmp;
4864  }
4865 
4866  template<typename _Tp> static inline
4867  Point_<_Tp> operator / (const Point_<_Tp>& a, double b)
4868  {
4869  Point_<_Tp> tmp(a);
4870  tmp /= b;
4871  return tmp;
4872  }
4873 
4874  template<typename _Tp> inline
4875  _Tp Point_<_Tp>::dot(const Point_& pt) const
4876  {
4877  return saturate_cast<_Tp>(x*pt.x + y*pt.y);
4878  }
4879 
4880  template<typename _Tp> inline
4881  double Point_<_Tp>::ddot(const Point_& pt) const
4882  {
4883  return (double)x*pt.x + (double)y*pt.y;
4884  }
4885 
4886  template<typename _Tp> inline
4887  double Point_<_Tp>::cross(const Point_& pt) const
4888  {
4889  return (double)x*pt.y - (double)y*pt.x;
4890  }
4891 
4892  template<typename _Tp> inline bool
4893  Point_<_Tp>::inside(const Rect_<_Tp>& r) const
4894  {
4895  return r.contains(*this);
4896  }
4897 
4899 
4900  template<typename _Tp> inline
4902  : x(0), y(0), width(0), height(0) {}
4903 
4904  template<typename _Tp> inline
4905  Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)
4906  : x(_x), y(_y), width(_width), height(_height) {}
4907 
4908  template<typename _Tp> inline
4909  Rect_<_Tp>::Rect_(const Rect_<_Tp>& r)
4910  : x(r.x), y(r.y), width(r.width), height(r.height) {}
4911 
4912  template<typename _Tp> inline
4913  Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz)
4914  : x(org.x), y(org.y), width(sz.width), height(sz.height) {}
4915 
4916  template<typename _Tp> inline
4917  Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
4918  {
4919  x = (std::min)(pt1.x, pt2.x);
4920  y = (std::min)(pt1.y, pt2.y);
4921  width = (std::max)(pt1.x, pt2.x) - x;
4922  height = (std::max)(pt1.y, pt2.y) - y;
4923  }
4924 
4925  template<typename _Tp> inline
4926  Rect_<_Tp>& Rect_<_Tp>::operator = (const Rect_<_Tp>& r)
4927  {
4928  x = r.x;
4929  y = r.y;
4930  width = r.width;
4931  height = r.height;
4932  return *this;
4933  }
4934 
4935  template<typename _Tp> inline
4936  Point_<_Tp> Rect_<_Tp>::tl() const
4937  {
4938  return Point_<_Tp>(x, y);
4939  }
4940 
4941  template<typename _Tp> inline
4942  Point_<_Tp> Rect_<_Tp>::br() const
4943  {
4944  return Point_<_Tp>(x + width, y + height);
4945  }
4946 
4947  template<typename _Tp> inline
4948  Size_<_Tp> Rect_<_Tp>::size() const
4949  {
4950  return Size_<_Tp>(width, height);
4951  }
4952 
4953  template<typename _Tp> inline
4954  _Tp Rect_<_Tp>::area() const
4955  {
4956  return width * height;
4957  }
4958 
4959  template<typename _Tp> template<typename _Tp2> inline
4960  Rect_<_Tp>::operator Rect_<_Tp2>() const
4961  {
4962  return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height));
4963  }
4964 
4965  template<typename _Tp> inline
4966  bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const
4967  {
4968  return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height;
4969  }
4970 
4971 
4972  template<typename _Tp> static inline
4973  Rect_<_Tp>& operator += (Rect_<_Tp>& a, const Point_<_Tp>& b)
4974  {
4975  a.x += b.x;
4976  a.y += b.y;
4977  return a;
4978  }
4979 
4980  template<typename _Tp> static inline
4981  Rect_<_Tp>& operator -= (Rect_<_Tp>& a, const Point_<_Tp>& b)
4982  {
4983  a.x -= b.x;
4984  a.y -= b.y;
4985  return a;
4986  }
4987 
4988  template<typename _Tp> static inline
4989  Rect_<_Tp>& operator += (Rect_<_Tp>& a, const Size_<_Tp>& b)
4990  {
4991  a.width += b.width;
4992  a.height += b.height;
4993  return a;
4994  }
4995 
4996  template<typename _Tp> static inline
4997  Rect_<_Tp>& operator -= (Rect_<_Tp>& a, const Size_<_Tp>& b)
4998  {
4999  a.width -= b.width;
5000  a.height -= b.height;
5001  return a;
5002  }
5003 
5004  template<typename _Tp> static inline
5005  Rect_<_Tp>& operator &= (Rect_<_Tp>& a, const Rect_<_Tp>& b)
5006  {
5007  _Tp x1 = (std::max)(a.x, b.x);
5008  _Tp y1 = (std::max)(a.y, b.y);
5009  a.width = (std::min)(a.x + a.width, b.x + b.width) - x1;
5010  a.height = (std::min)(a.y + a.height, b.y + b.height) - y1;
5011  a.x = x1;
5012  a.y = y1;
5013  if (a.width <= 0 || a.height <= 0)
5014  a = Rect();
5015  return a;
5016  }
5017 
5018  template<typename _Tp> static inline
5019  Rect_<_Tp>& operator |= (Rect_<_Tp>& a, const Rect_<_Tp>& b)
5020  {
5021  _Tp x1 = (std::min)(a.x, b.x);
5022  _Tp y1 = (std::min)(a.y, b.y);
5023  a.width = (std::max)(a.x + a.width, b.x + b.width) - x1;
5024  a.height = (std::max)(a.y + a.height, b.y + b.height) - y1;
5025  a.x = x1;
5026  a.y = y1;
5027  return a;
5028  }
5029 
5030  template<typename _Tp> static inline
5031  bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
5032  {
5033  return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
5034  }
5035 
5036  template<typename _Tp> static inline
5037  bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
5038  {
5039  return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
5040  }
5041 
5042  template<typename _Tp> static inline
5043  Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
5044  {
5045  return Rect_<_Tp>(a.x + b.x, a.y + b.y, a.width, a.height);
5046  }
5047 
5048  template<typename _Tp> static inline
5049  Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
5050  {
5051  return Rect_<_Tp>(a.x - b.x, a.y - b.y, a.width, a.height);
5052  }
5053 
5054  template<typename _Tp> static inline
5055  Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
5056  {
5057  return Rect_<_Tp>(a.x, a.y, a.width + b.width, a.height + b.height);
5058  }
5059 
5060  template<typename _Tp> static inline
5061  Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
5062  {
5063  Rect_<_Tp> c = a;
5064  return c &= b;
5065  }
5066 
5067  template<typename _Tp> static inline
5068  Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
5069  {
5070  Rect_<_Tp> c = a;
5071  return c |= b;
5072  }
5073 
5074  namespace detail
5075  {
5077  template<typename _Tp> inline
5078  ImageBase<_Tp>::ImageBase()
5079  :rows_(0), cols_(0), channels_(0), data_(nullptr)
5080  {
5081  }
5082 
5083  template<typename _Tp> inline
5084  ImageBase<_Tp>::ImageBase(int rows, int cols, int channels)
5085  {
5086  create(rows, cols, channels);
5087  }
5088 
5089  template<typename _Tp> inline
5090  ImageBase<_Tp>::ImageBase(const ImageBase& other)
5091  {
5092  rows_ = other.rows_;
5093  cols_ = other.cols_;
5094  channels_ = other.channels_;
5095  data_ = other.data_; // shallow copy
5096  }
5097 
5098  template<typename _Tp> template<typename _Tp2> inline
5099  ImageBase<_Tp>::operator ImageBase<_Tp2>() const
5100  {
5101  ImageBase<_Tp2> tmp(rows_, cols_, channels_);
5102  _Tp2* p = tmp.ptr(0);
5103  _Tp* p_ = ptr(0);
5104  for (long i = 0; i < rows_ * cols_ * channels_; ++i)
5105  {
5106  *p = saturate_cast<_Tp>(*p_);
5107  ++p;
5108  ++p_;
5109  }
5110  return tmp;
5111  }
5112 
5113  template<typename _Tp> inline
5114  ImageBase<_Tp>::ImageBase(ImageBase&& other)
5115  {
5116  rows_ = other.rows_;
5117  cols_ = other.cols_;
5118  channels_ = other.channels_;
5119  data_ = other.data_; // shallow copy
5120  other.release();
5121  }
5122 
5123  template<typename _Tp> inline
5124  ImageBase<_Tp>::~ImageBase()
5125  {
5126  release();
5127  }
5128 
5129  template<typename _Tp> inline
5130  void ImageBase<_Tp>::create(int rows, int cols, int channels)
5131  {
5132  assert(rows > 0 && cols > 0 && channels > 0);
5133  rows_ = rows;
5134  cols_ = cols;
5135  channels_ = channels;
5136  data_ = std::make_shared<std::vector<_Tp>>(rows * cols * channels);
5137  }
5138 
5139  template<typename _Tp> inline
5140  void ImageBase<_Tp>::release()
5141  {
5142  rows_ = 0;
5143  cols_ = 0;
5144  channels_ = 0;
5145  data_ = nullptr;
5146  }
5147 
5148  template<typename _Tp> inline
5149  ImageBase<_Tp>& ImageBase<_Tp>::operator= (const ImageBase<_Tp>& other)
5150  {
5151  rows_ = other.rows_;
5152  cols_ = other.cols_;
5153  channels_ = other.channels_;
5154  data_ = other.data_; // shallow copy
5155  return *this;
5156  }
5157 
5158  template<typename _Tp> inline
5159  ImageBase<_Tp>& ImageBase<_Tp>::operator= (ImageBase<_Tp>&& other)
5160  {
5161  rows_ = other.rows_;
5162  cols_ = other.cols_;
5163  channels_ = other.channels_;
5164  data_ = other.data_; // shallow copy
5165  other.release();
5166  return *this;
5167  }
5168 
5169  template<typename _Tp> inline
5170  _Tp& ImageBase<_Tp>::operator() (int row, int col, int channel)
5171  {
5172  detach();
5173  long pos = row * cols_ * channels_ + col * channels_ + channel;
5174  range_check(row, col, channel);
5175  return (*data_)[pos];
5176  }
5177 
5178  template<typename _Tp> inline
5179  const _Tp& ImageBase<_Tp>::operator() (int row, int col, int channel) const
5180  {
5181  detach();
5182  long pos = row * cols_ * channels_ + col * channels_ + channel;
5183  range_check(row, col, channel);
5184  return (*data_)[pos];
5185  }
5186 
5187  template<typename _Tp> inline
5188  bool ImageBase<_Tp>::empty() const
5189  {
5190  return (rows_ < 1 || cols_ < 1 || channels_ < 1 || (!data_));
5191  }
5192 
5193  template<typename _Tp> inline
5194  int ImageBase<_Tp>::rows() const
5195  {
5196  return rows_;
5197  }
5198 
5199  template<typename _Tp> inline
5200  int ImageBase<_Tp>::cols() const
5201  {
5202  return cols_;
5203  }
5204 
5205  template<typename _Tp> inline
5206  int ImageBase<_Tp>::channels() const
5207  {
5208  return channels_;
5209  }
5210 
5211  template<typename _Tp> inline
5212  void ImageBase<_Tp>::range_check(long long pos) const
5213  {
5214  assert(pos >= 0);
5215  if (empty()) throw RuntimeException("Accessing emtpy image!");
5216  if (pos >= rows_ * cols_ * channels_) throw RuntimeException("Access out of range!");
5217  }
5218 
5219  template<typename _Tp> inline
5220  void ImageBase<_Tp>::range_check(int row, int col, int channel) const
5221  {
5222  assert(row >= 0 && col >= 0 && channel >= 0);
5223  if (empty()) throw RuntimeException("Accessing emtpy image!");
5224  if (row >= rows_ || col >= cols_ || channel >= channels_) throw RuntimeException("Access out of range!");
5225  }
5226 
5227  template<typename _Tp> inline
5228  _Tp ImageBase<_Tp>::at(int row, int col, int channel) const
5229  {
5230  range_check(row, col, channel);
5231  long pos = row * cols_ * channels_ + col * channels_ + channel;
5232  return (*data_)[pos];
5233  }
5234 
5235  template<typename _Tp> inline
5236  _Tp* ImageBase<_Tp>::ptr(int offset) const
5237  {
5238  range_check(offset);
5239  return (*data_).data() + offset;
5240  }
5241 
5242  template<typename _Tp> inline
5243  _Tp* ImageBase<_Tp>::ptr(int row, int col, int channel) const
5244  {
5245  range_check(row, col, channel);
5246  long pos = row * cols_ * channels_ + col * channels_ + channel;
5247  return (*data_).data() + pos;
5248  }
5249 
5250  template<typename _Tp> inline
5251  void ImageBase<_Tp>::import(_Tp* data, int rows, int cols, int channels)
5252  {
5253  assert(rows > 0 && cols > 0 && channels > 0 && "import size should be positive");
5254  create(rows, cols, channels);
5255  std::memcpy((*data_).data(), data, sizeof(_Tp)* rows * cols * channels);
5256  }
5257 
5258  template<typename _Tp> inline
5259  void ImageBase<_Tp>::import(std::vector<_Tp> data, int rows, int cols, int channels)
5260  {
5261  assert(rows > 0 && cols > 0 && channels > 0 && data.size() >= rows * cols * channels);
5262  create(rows, cols, channels);
5263  std::memcpy((*data_).data(), data.data(), sizeof(_Tp)* rows * cols * channels);
5264  }
5265 
5266  template<typename _Tp> inline
5267  std::vector<_Tp> ImageBase<_Tp>::export_raw() const
5268  {
5269  return (*data_);
5270  }
5271 
5272  template<typename _Tp> template<typename _Tp2> inline
5273  std::vector<_Tp2>& ImageBase<_Tp>::export_raw(std::vector<_Tp2>& out) const
5274  {
5275  out.resize(rows_ * cols_ * channels_);
5276  auto p = out.begin();
5277  for (auto i = (*data_).begin(); i != (*data_).end(); ++i, ++p)
5278  {
5279  *p = saturate_cast<_Tp2>(*i);
5280  }
5281  return out;
5282  }
5283 
5284  template<typename _Tp> inline
5285  void ImageBase<_Tp>::crop(int r0, int c0, int r1, int c1)
5286  {
5287  assert(r0 >= 0 && c0 >= 0 && r1 >= 0 && c1 >= 0 && "crop region should be positive!");
5288  assert(r0 < rows_ && r1 < rows_ && c0 < cols_ && c1 < cols_ && "crop point should in image!");
5289  assert(r0 != r1 && (c0 != c1) && "need a rectangle region!");
5290 
5291  int width = std::abs(c0 - c1);
5292  int height = std::abs(r0 - r1);
5293  int i0 = (std::min)(r0, r1);
5294  int i1 = (std::max)(r0, r1);
5295  int j0 = (std::min)(c0, c1);
5296  int j1 = (std::max)(c0, c1);
5297  detach();
5298  ImageBase<_Tp> tmp(height, width, channels_);
5299 
5300  // temporary solution, not optimized
5301  _Tp* pOld = ptr(i0, j0, 0);
5302  _Tp* pNew = tmp.ptr(0);
5303  int step = cols_ * channels_;
5304  int bulkSize = width * channels_;
5305  for (auto r = 0; r < height; ++r)
5306  {
5307  // copy entire row
5308  std::memcpy(pNew, pOld, sizeof(_Tp)* bulkSize);
5309  pOld += step;
5310  pNew += bulkSize;
5311  }
5312  std::swap(*this, tmp);
5313  }
5314 
5315  template<typename _Tp> inline
5316  void ImageBase<_Tp>::crop(Point p0, Point p1)
5317  {
5318  crop(p0.y, p0.x, p1.y, p1.x);
5319  }
5320 
5321  template<typename _Tp> inline
5322  void ImageBase<_Tp>::crop(Rect rect)
5323  {
5324  crop(rect.y, rect.x, rect.y + rect.height, rect.y + rect.width);
5325  }
5326 
5327  template<typename _Tp> inline
5328  void ImageBase<_Tp>::detach()
5329  {
5330  if (data_.use_count() < 2) return;
5331  // detach the current resource from shared
5332  std::shared_ptr<std::vector<_Tp>> tmp = std::make_shared<std::vector<_Tp>>();
5333  *tmp = *data_; // deep copy
5334  data_ = tmp;
5335  }
5336  } // namespace zz::detail
5337 
5338  // \endcond
5339 
5340 } // namespace zz
5341 
5342 #endif //END _ZUPPLY_ZUPPLY_HPP_
5343 
5344 
Size_< _Tp > size() const
Get size of rectangle.
void detach_all_sinks()
Detach all sinks from this logger.
Definition: zupply.cpp:13514
Definition: zupply.hpp:1115
void load(const char *filename)
load Load image from disk file, HDR image(*.hdr) supported.
Definition: zupply.cpp:13848
void from_normal(const Image &from, float range=1.0f)
from_normal Convert from an 8-bit image.
Definition: zupply.cpp:13882
void to_utc_time()
Convert to UTC time zone.
Definition: zupply.cpp:11208
Directory(std::string root, bool recursive=false)
Directory constructor.
Definition: zupply.cpp:10821
std::u16string utf8_to_utf16(std::string u8str)
C++ 11 UTF-8 string to UTF-16 string.
Definition: zupply.cpp:10673
int log_level_mask()
Get default log level mask.
Definition: zupply.cpp:13435
void resume()
Resume timer.
Definition: zupply.cpp:11264
static void set_default_datetime_format(std::string dateFormat)
Set default datetime format for all future loggers.
Definition: zupply.cpp:13410
int round(double value)
fast round utilizing hardware acceleration features
Definition: zupply.hpp:951
std::string endl()
Gets the OS dependent line end characters.
Definition: zupply.cpp:11766
std::size_t size() const
Return number of contained directories or files.
Definition: zupply.hpp:2205
const_iterator cbegin() const
Return const begin iterator.
Definition: zupply.hpp:2193
Rect_< double > Rect2d
Rect2d Double version.
Definition: zupply.hpp:543
Exception for signalling memory errors.
Definition: zupply.hpp:244
ArgParser()
ArgParser default constructor.
Definition: zupply.cpp:12502
std::string next_line(bool trimWhiteSpaces=false)
Get next line.
Definition: zupply.cpp:11112
const_iterator cend() const
Return const end iterator.
Definition: zupply.hpp:2199
void replace_all_with_escape(std::string &str, const std::string &replaceWhat, const std::string &replaceWith)
Replace every occurance of one string with specified another string. Replace in-place.
Definition: zupply.cpp:10605
void add_opt_version(char shortKey, std::string longKey, std::string version, std::string help="print version and exit")
Add a special option used to display version information for argument parser. When triggered...
Definition: zupply.cpp:12586
void replace_sequential_with_escape(std::string &str, const std::string &replaceWhat, const std::vector< std::string > &replaceWith)
Replace every occurance of one string with specified list of strings sequentially. Replace in-place.
Definition: zupply.cpp:10623
Value operator[](const std::string &name)
Overloaded operator [] for config values.
Definition: zupply.hpp:2959
Exception for signalling unsuccessful cast operations.
Definition: zupply.hpp:220
bool operator!=(const Size_ &other)
Compare operator.
bool movefile(std::string src, std::string dst, bool replaceDst)
Move file, support unicode filename/path.
Definition: zupply.cpp:11614
int goto_line(int n)
Count number of lines in text file If reached end of file, will return the number of lines...
Definition: zupply.cpp:11134
std::string version() const
Return version info.
Definition: zupply.hpp:3202
bool create_directory_recursive(std::string path)
Create directory recursively if not exist.
Definition: zupply.cpp:11984
Definition: zupply.hpp:1265
A simple spin lock utilizing c++11 atomic_flag.
Definition: zupply.hpp:1062
bool open(std::string filename, bool truncateOrNot=false, int retryTimes=consts::kDefaultFileOpenRetryTimes, int retryInterval=consts::kDefaultFileOpenRetryInterval)
Open file.
Definition: zupply.cpp:10999
bool is_file(std::string path)
Check if path is file and exists.
Definition: zupply.cpp:11849
ArgOption & require(bool require=true)
Set this option to required or not. After parsing arguments, if this set to required but not found...
Definition: zupply.cpp:12364
void add_opt_help(char shortKey, std::string longKey, std::string help="print this help and exit")
Add a special option used to display help information for argument parser. When triggered, program will print help info and exit.
Definition: zupply.cpp:12575
void unlock_loggers()
Unlock all loggers. When locked, loggers cannot be modified.
Definition: zupply.cpp:13696
std::string path_split_extension(std::string path)
Split extension if any.
Definition: zupply.cpp:11531
std::string elapsed_us_str()
Return string of elapsed time quantized in microsecond.
Definition: zupply.cpp:11288
A null mutex, no cost.
Definition: zupply.hpp:1049
SinkPtr new_rotate_file_sink(std::string filename, std::size_t maxSizeInByte, bool backupOld)
Create new rotate file sink.
Definition: zupply.cpp:13660
ImageHdr()
ImageHdr Default(empty) constructor.
Definition: zupply.hpp:831
std::pair< std::string, std::string > split_first_occurance(const std::string s, char delim)
Split string in two parts with specified delim.
Definition: zupply.cpp:10522
The 2D size class The class represents the size of a 2D rectangle, image size, matrix size etc...
Definition: zupply.hpp:268
bool create_directory(std::string path)
Create directory if not exist.
Definition: zupply.cpp:11965
Value(const char *cstr)
Value constructor from raw string.
Definition: zupply.hpp:2804
CfgParser(std::string filename)
CfgParser constructor from filename.
Definition: zupply.cpp:12230
T load()
Template for load function with no input.
Definition: zupply.hpp:2889
void save(const char *filename, int quality=80) const
save Save image to file.
Definition: zupply.cpp:13787
void resize(Size sz)
resize Resize image given new size
Definition: zupply.cpp:13833
The ArgOption class for ArgParser.
Definition: zupply.hpp:2985
double ddot(const Point_ &pt) const
dot product computed in double-precision arithmetics
Namespace for zupply.
Definition: zupply.cpp:103
double cross(const Point_ &pt) const
cross-product
int count(char shortKey)
Count the occurance of the option by short key.
Definition: zupply.cpp:12887
std::string lskip(std::string str, std::string delim)
Skip from left until delimiter string found.
Definition: zupply.cpp:10427
std::string utf32_to_utf8(std::u32string u32str)
C++ 11 UTF-32 string to UTF-8 string.
Definition: zupply.cpp:10716
CfgParser(std::istream &s)
CfgParser constructor from stream.
Definition: zupply.hpp:2946
std::vector< std::string > list_directory(std::string root)
List directory contents.
Definition: zupply.cpp:12005
std::string store(T t)
Store value from template type T Support type that can << to a stringstream.
Definition: zupply.hpp:3288
std::string abs_path() const
Return Absolute path.
Definition: zupply.cpp:10762
bool remove_all(std::string path)
Remove path, whatever file or directory. Dangerous! Cannot revert.
Definition: zupply.cpp:11623
bool operator==(const Value &other)
Overloaded operator == for comparison.
Definition: zupply.hpp:2840
std::string filename() const
FileReader move constructor.
Definition: zupply.hpp:2402
void attach_console()
Attach stdout and stderr to the logger. Special case of attach_sink()
Definition: zupply.cpp:13602
static LogConfig & instance()
Get instance of LogConfig class. LogConfig is a singleton class, so use this to get the instance...
Definition: zupply.cpp:13399
Point_< double > Point2d
Point2d Double version.
Definition: zupply.hpp:428
void release()
release Destroy memory storage
std::string str() const
Return stored string.
Definition: zupply.hpp:2822
Definition: zupply.hpp:1089
void set_log_level_mask(int newMask)
Set default log level mask.
Definition: zupply.cpp:13440
std::size_t count_error()
Get error count generated during parsing.
Definition: zupply.hpp:3216
Exception for signalling argument errors.
Definition: zupply.hpp:196
ArgOption & call(std::function< void()> todo)
Set callback function when this option is triggered. One can use lambda function as callback...
Definition: zupply.cpp:12345
std::string name() const
Get name of the logger.
Definition: zupply.hpp:3792
static DateTime utc_time()
Static function to return in utc_time.
Definition: zupply.cpp:11237
std::string ltrim(std::string str)
Left trim whitespace.
Definition: zupply.cpp:10390
std::string to_string(const char *format="%y-%m-%d %H:%M:%S.%frac")
Convert date to user friendly string. Support various formats.
Definition: zupply.cpp:11213
_Tp at(int row, int col, int channel=0) const
at Access pixel, immutable version. This is guanranteed to be faster than () operator if you don't ne...
LoggerPtr get_logger(std::string name, bool createIfNotExists)
Get logger by name.
Definition: zupply.cpp:13580
bool empty() const
Check if path is empty.
Definition: zupply.cpp:10741
Point_< int > Point2i
Point2i Int version.
Definition: zupply.hpp:418
std::string absolute_path(std::string reletivePath)
Convert reletive path to absolute path.
Definition: zupply.cpp:11896
void drop_all_loggers()
Delete all loggers.
Definition: zupply.cpp:13706
_Tp & operator()(int row, int col, int channel=0)
operator () Access pixel element
std::vector< std::string > sink_list()
Get default sink list.
Definition: zupply.cpp:13425
void set_sink_list(std::vector< std::string > &list)
Set default sink list.
Definition: zupply.cpp:13430
void dump_loggers(std::ostream &out)
Dump all loggers info.
Definition: zupply.cpp:13629
void step(unsigned size=1)
Step forward for the progress.
Definition: zupply.cpp:12945
void sleep(int milliseconds)
Sleep for specified milliseconds.
Definition: zupply.hpp:2053
Exception for signalling logic errors.
Definition: zupply.hpp:184
ArgOption & set_max(int maxCount)
Set maximum number of argument this option take. If maximum number not satisfied, ArgParser will gene...
Definition: zupply.cpp:12388
bool starts_with(const std::string &str, const std::string &start)
Check if string starts with specified sub-string.
Definition: zupply.cpp:10560
SinkPtr get_sink(std::string name)
Get the sink pointer from name provided. Return nullptr if sink does not exist.
Definition: zupply.cpp:13614
std::string datetime_format()
Get default datetime format.
Definition: zupply.cpp:13455
The Path class to resolve filesystem path.
Definition: zupply.hpp:2078
bool is_directory(std::string path)
Check if path is directory and exists.
Definition: zupply.cpp:11867
CfgLevel & root()
Get root section of configuration.
Definition: zupply.hpp:2952
detail::LineLogger error()
Error level overloaded with stream style message.
Definition: zupply.cpp:13482
ProgBar(unsigned range=100, std::string info="")
Constructor of ProgBar.
Definition: zupply.cpp:12929
bool is_file() const
Check if path is a file and exist.
Definition: zupply.cpp:10752
Definition: zupply.hpp:1233
void drop_sink(std::string name)
Delete the sink, detach it from every logger.
Definition: zupply.cpp:13711
void attach_sink(SinkPtr sink)
Attach a sink to this logger.
Definition: zupply.cpp:13501
void clear()
Clear stored string.
Definition: zupply.hpp:2833
Rect_< int > Rect2i
Rect2i Int version.
Definition: zupply.hpp:533
std::string wstring_to_utf8(std::wstring &wstr)
Convert wstring to UTF-8.
Definition: zupply.cpp:11470
void fstream_open(std::fstream &stream, std::string filename, std::ios::openmode openmode)
Open fstream using UTF-8 string This is a wrapper function because Windows will require wstring to pr...
Definition: zupply.cpp:11570
SinkPtr new_stdout_sink()
Get the sink pointer to stdout.
Definition: zupply.cpp:13592
std::vector< std::string > path_split(std::string path)
Split path into hierachical sub-folders.
Definition: zupply.cpp:11483
An exception with customized prefix information.
Definition: zupply.hpp:161
std::size_t elapsed_ms()
Return elapsed time quantized in millisecond.
Definition: zupply.cpp:11293
bool exist() const
Check path existance, whatever file/dir/device...
Definition: zupply.cpp:10746
bool ends_with(const std::string &str, const std::string &end)
Check if string ends with specified sub-string.
Definition: zupply.cpp:10565
bool path_exists(std::string path, bool considerFile)
Check if path exist in filesystem.
Definition: zupply.cpp:11833
Exception for signalling warning errors when strict warning is enabled.
Definition: zupply.hpp:256
static void set_default_format(std::string format)
Set default format for all future loggers.
Definition: zupply.cpp:13405
The general functor Callback class.
Definition: zupply.hpp:1022
The ImageHdr class. Image container specifically good for HDR images which uses 32bit float precison...
Definition: zupply.hpp:825
The FileEditor class to modify file This class is derived from UnCopyable, so no copy operation...
Definition: zupply.hpp:2261
bool copyfile(std::string src, std::string dst, bool replaceDst)
Copy file, support unicode filename/path.
Definition: zupply.cpp:11599
Logger(std::string name)
Logger default constructor.
Definition: zupply.hpp:3623
Value(const Value &other)
Value copy constructor.
Definition: zupply.hpp:2816
SinkPtr new_stderr_sink()
Get the sink pointer to stderr.
Definition: zupply.cpp:13597
void config_from_stringstream(std::stringstream &ss)
Config loggers from a stringstream.
Definition: zupply.cpp:13757
void format_string(std::string &fmt, const Arg &last)
Format function to replace each {} with templated type variable.
Definition: zupply.hpp:2758
int is_atty()
Check if stdout is associated with console.
Definition: zupply.cpp:11402
std::string utf16_to_utf8(std::u16string u16str)
C++ 11 UTF-16 string to UTF-8 string.
Definition: zupply.cpp:10687
detail::LineLogger fatal()
Fatal level overloaded with stream style message.
Definition: zupply.cpp:13486
bool inside(const Rect_< _Tp > &r) const
checks whether the point is inside the specified rectangle
Point_< float > Point2f
Point2f Float version.
Definition: zupply.hpp:423
SinkPtr new_simple_file_sink(std::string filename, bool truncate)
Create new simple file sink withe filename provided.
Definition: zupply.cpp:13650
void add_info(std::string info)
Add info to parser.
Definition: zupply.cpp:12508
std::string filename() const
Return filename.
Definition: zupply.hpp:2301
Image()
Image Default(empty) constructor.
Definition: zupply.hpp:772
void reset()
Reset timer to record new process.
Definition: zupply.cpp:11249
std::string to_upper_ascii(std::string mixed)
Convert string to upper case. Support ASCII characters only. Unicode string will trigger undefined be...
Definition: zupply.cpp:10667
std::string elapsed_ns_str()
Return string of elapsed time quantized in nanosecond.
Definition: zupply.cpp:11278
bool is_dir() const
Check if path is a directory and exist.
Definition: zupply.cpp:10757
Logger(std::string name, int levelMask)
Logger constructor with name and mask.
Definition: zupply.hpp:3633
void parse(int argc, char **argv, bool ignoreUnknown=false)
Start parsing arguments.
Definition: zupply.cpp:12708
ArgOption(char shortKey, std::string longKey)
ArgOption constructor with short key and long key.
Definition: zupply.cpp:12332
ArgOption & add_opt(char shortKey, std::string longKey)
Add option. Use -1 for shortkey if you don't want to specify short key. Use "" for longkey if you don...
Definition: zupply.cpp:12560
bool is_recursive() const
Check if directory is resursively searched.
Definition: zupply.cpp:10848
Rect_()
Default constructor.
std::string path_split_filename(std::string path)
Split filename from path.
Definition: zupply.cpp:11502
The Directory class for filesystem directory operations.
Definition: zupply.hpp:2140
int cols() const
cols Get number of columns(width, x...)
Value(std::string str)
Value constrctor from string.
Definition: zupply.hpp:2810
std::string lstrip(std::string str, std::string what)
Strip specified sub-string from left. The strip will do strict check from left, even whitespace...
Definition: zupply.cpp:10407
A not movable/copyable base class, should be inheritated privately.
Definition: zupply.hpp:142
bool is_valid() const
Check if valid filename is set.
Definition: zupply.hpp:2414
ArgOption & set_once(bool onlyOnce=true)
Set this option to allow option be called only once. This is set to disable accidentally set a variab...
Definition: zupply.cpp:12370
A calendar date class.
Definition: zupply.hpp:1910
The Logger class Logger is the object to be called to log some message. Each logger may links to seve...
Definition: zupply.hpp:3616
static DateTime local_time()
Static function to return in local_time.
Definition: zupply.cpp:11231
static void set_default_level_mask(int levelMask)
Set default level mask for all future loggers. Level mask is an int. Each bit control if correspondin...
Definition: zupply.cpp:13420
void create(int rows, int cols, int channels)
create Create storage with specified size
int rows() const
rows Get number of rows(height, y...)
bool str_equals(const char *s1, const char *s2)
Compare c style raw string Will take care of string not ends with '\0'(ignore it), which is unsafe using strcmp().
Definition: zupply.cpp:10643
_Tp dot(const Point_ &pt) const
dot product
std::string get_help()
Get help information of entire parser.
Definition: zupply.cpp:12816
std::size_t elapsed_ns()
Return elapsed time quantized in nanosecond.
Definition: zupply.cpp:11271
Size_()
Default ctor.
bool rename(std::string oldName, std::string newName)
Rename file, support unicode filename/path.
Definition: zupply.cpp:11590
bool contains(const Point_< _Tp > &pt) const
Checks whether the rectangle contains the point.
std::string elapsed_ms_str()
Return string of elapsed time quantized in millisecond.
Definition: zupply.cpp:11298
bool operator==(const Size_ &other)
Compare operator.
_Tp y
the point coordinates
Definition: zupply.hpp:412
Value get_value()
Return the stored value.
Definition: zupply.cpp:12395
SinkPtr get_sink(std::string name)
Get pointer to a sink by name.
Definition: zupply.cpp:13491
detail::LineLogger trace()
Trace level overloaded with stream style message.
Definition: zupply.cpp:13466
std::string to_string(const char *format="[%ms ms]")
Convert timer to user friendly string. Support various formats.
Definition: zupply.cpp:11318
std::size_t elapsed_sec()
Return elapsed time quantized in second.
Definition: zupply.cpp:11303
Exception for signalling unexpected runtime errors.
Definition: zupply.hpp:208
_Tp * ptr(int offset=0) const
ptr Data pointer given specifed position. Use with cautious. This is provided for performance conside...
std::string rtrim(std::string str)
Right trim whitespace.
Definition: zupply.cpp:10396
Point2i Point
Point By default using Point2i.
Definition: zupply.hpp:433
Point_()
Default constructor.
std::vector< std::string > split(const std::string s, char delim)
Split string into parts with specified single char delimiter.
Definition: zupply.cpp:10468
void ifstream_open(std::ifstream &stream, std::string filename, std::ios::openmode openmode)
Open ifstream using UTF-8 string This is a wrapper function because Windows will require wstring to p...
Definition: zupply.cpp:11581
std::string last_error()
Retrieve the last error in errno.
Definition: zupply.cpp:11733
~ProgBar()
Destructor will stop background thread.
Definition: zupply.cpp:12940
std::string trim(std::string str)
Left and right trim whitespace.
Definition: zupply.cpp:10402
void detach_console()
Detach stdout and stderr from the logger if exist. Special case of detach_sink()
Definition: zupply.cpp:13608
_Tp height
the top-left corner, as well as width and height of the rectangle
Definition: zupply.hpp:527
The Value class for store/load various type to/from string.
Definition: zupply.hpp:2792
void attach_sink_list(std::vector< std::string > &sinkList)
Attach the entire vector of sinks to the logger.
Definition: zupply.cpp:13670
void to_local_time()
Convert to local time zone.
Definition: zupply.cpp:11203
std::string int_to_zero_pad_str(int num, int length)
Convert int to left zero padded string.
Definition: zupply.hpp:2494
std::vector< std::string > split_multi_delims(const std::string s, std::string delims)
Split string into parts with multiple single char delimiter.
Definition: zupply.cpp:10495
std::size_t count_lines()
Count number of lines in text file.
Definition: zupply.cpp:11077
_Tp area() const
Get area of rectagle.
std::u32string utf8_to_utf32(std::string u8str)
C++ 11 UTF-8 string to UTF-32 string.
Definition: zupply.cpp:10702
std::string join(std::vector< std::string > elems, char delim)
Concatenates a std::vector of strings into a string with delimiters.
Definition: zupply.cpp:10546
std::vector< std::string > split_whitespace(const std::string s)
Special case to split_multi_delims(), split all whitespace.
Definition: zupply.cpp:10510
void close()
Close file handler.
Definition: zupply.hpp:2419
ArgOption & add_opt_flag(char shortKey, std::string longKey, std::string help="", bool *dst=nullptr)
Add an toggle option. When this option found, dst = true, otherwise dst = false.
Definition: zupply.cpp:12598
bool is_digit(char c)
Check if is digit.
Definition: zupply.cpp:10361
bool empty() const
Check if stored string is empty.
Definition: zupply.hpp:2828
std::string elapsed_sec_str()
Return string of elapsed time quantized in second.
Definition: zupply.cpp:11308
_Tp area() const
area Calculate area
std::string path_delim()
Gets the OS dependent path delim.
Definition: zupply.cpp:11775
std::string path_split_basename(std::string path)
Split basename.
Definition: zupply.cpp:11542
void pause()
Pause recording timelapse.
Definition: zupply.cpp:11256
iterator end()
Return end iterator.
Definition: zupply.hpp:2187
bool should_log(LogLevels msgLevel) const
Check if a specific level should be logged in this logger.
Definition: zupply.hpp:3783
std::tm gmtime(std::time_t t)
Thread-safe version of gmtime.
Definition: zupply.cpp:11443
std::string rskip_all(std::string str, std::string delim)
Skip from right, remove all stuff right to left-most delim.
Definition: zupply.cpp:10455
Definition: zupply.hpp:1148
bool is_open() const
Check if is opened.
Definition: zupply.hpp:2408
std::size_t get_file_size(std::string filename)
Get file size in byte.
Definition: zupply.cpp:11167
std::string relative_path() const
Return relative path to current working directory.
Definition: zupply.cpp:10767
Size console_size()
Return the Size of console window.
Definition: zupply.cpp:11412
static void set_default_sink_list(std::vector< std::string > list)
Set default sink list for all future loggers.
Definition: zupply.cpp:13415
double elapsed_sec_double()
Return elapsed time in second, no quantization.
Definition: zupply.cpp:11313
detail::LineLogger info()
Info level overloaded with stream style message.
Definition: zupply.cpp:13474
std::size_t elapsed_us()
Return elapsed time quantized in microsecond.
Definition: zupply.cpp:11283
void config_from_file(std::string cfgFilename)
Config loggers from a config file.
Definition: zupply.cpp:13751
std::string root() const
Return root of directory.
Definition: zupply.cpp:10853
ImageHdr(int rows, int cols, int channels)
ImageHdr Constructor given specific size.
Definition: zupply.hpp:839
std::string rstrip(std::string str, std::string what)
Strip specified sub-string from right. The strip will do strict check from right, even whitespace...
Definition: zupply.cpp:10417
void detach_sink(SinkPtr sink)
Detach a sink from this logger.
Definition: zupply.cpp:13509
const T clip(const T &value, const T &low, const T &high)
Clip values in-between low and high values.
Definition: zupply.hpp:920
std::vector< std::string > & erase_empty(std::vector< std::string > &vec)
Go through vector and erase empty ones. Erase in-place in vector.
Definition: zupply.cpp:10530
Rect_ & operator=(const Rect_ &r)
Copy operator.
Base image storage class This defines the storage and pixel-wise access to a image like 3-D matrix...
Definition: zupply.hpp:556
Template meta programming for pow(a, b) where a, b must be natural numbers Use Pow::result = a^b, which is computed in compilation rather than runtime.
Definition: zupply.hpp:933
ImageBase & operator=(const ImageBase &other)
operator = Copy operator, again, shallow copy
Value & operator=(const Value &other)
Overloaded operator = for copy.
Definition: zupply.hpp:2847
void set_datetime_format(std::string newDatetimeFormat)
Set default datetime format.
Definition: zupply.cpp:13460
Point_< _Tp > br() const
Get bottom right corner point.
detail::LineLogger debug()
Debug level overloaded with stream style message.
Definition: zupply.cpp:13470
Definition: zupply.hpp:1350
std::wstring utf8_to_wstring(std::string &u8str)
Convert UTF-8 string to wstring.
Definition: zupply.cpp:11457
void set_level_mask(int levelMask)
Set level mask to this logger.
Definition: zupply.hpp:3773
std::string to_lower_ascii(std::string mixed)
Convert string to lower case. Support ASCII characters only. Unicode string will trigger undefined be...
Definition: zupply.cpp:10661
FileEditor & operator<<(T what)
Overload << operator just like a stream.
Definition: zupply.hpp:2295
SinkPtr new_ostream_sink(std::ostream &stream, std::string name, bool forceFlush)
Create new ostream sink from existing ostream.
Definition: zupply.cpp:13640
int get_count()
Return the count.
Definition: zupply.cpp:12400
std::vector< Point > Vecpts
Vecpts 1-D vector of points.
Definition: zupply.hpp:438
bool empty() const
empty Check empty or not
ArgOption & set_type(std::string type)
Set option variable type. Optional. Let user know what type this option take, INT, FLOAT, STRING...
Definition: zupply.cpp:12376
The Progress bar class. For simple progress bar.
Definition: zupply.hpp:3399
std::vector< Path > to_list() const
Return the entire list.
Definition: zupply.cpp:10858
std::string filename() const
Return filename if is file and exist. Will return empty string if path is not a file.
Definition: zupply.cpp:10815
Definition: zupply.hpp:2480
bool reopen(bool truncateOrNot=true)
Reopen current file.
Definition: zupply.cpp:11008
bool wild_card_match(const char *str, const char *pattern)
Match string with wildcard. Match string with wildcard pattern, '*' and '?' supported.
Definition: zupply.cpp:10366
The FileReader class for read-only operations. This class is derived from UnCopyable, so no copy operation. Move operation is allowed by std::move();.
Definition: zupply.hpp:2378
The 2D up-right rectangle class The class represents a 2D rectangle with coordinates of the specified...
Definition: zupply.hpp:344
Point_< _Tp > tl() const
Get top left corner point.
The Image class. Image container for 8-bit image manipulation including read/write. Image is based on detail::ImageBase.
Definition: zupply.hpp:766
void lock_loggers()
Lock all loggers. When locked, loggers cannot be modified.
Definition: zupply.cpp:13691
void drop_logger(std::string name)
Delete a logger with the name given.
Definition: zupply.cpp:13701
void flush()
Flush file stream.
Definition: zupply.hpp:2361
ArgOption & set_help(std::string helpInfo)
Set help info for this option. Use this to add description for this option.
Definition: zupply.cpp:12358
std::string path_append_basename(std::string origPath, std::string whatToAppend)
Append string to basename directly, rather than append to extension This is more practically useful b...
Definition: zupply.cpp:11557
A timer class.
Definition: zupply.hpp:1959
bool is_valid() const
Check whether current file handler is set.
Definition: zupply.hpp:2350
std::string & replace_all(std::string &str, char replaceWhat, char replaceWith)
Replace all from one to another sub-string, char version.
Definition: zupply.cpp:10570
bool path_identical(std::string first, std::string second, bool forceCaseSensitve)
Compare identical path according to OS. By default, windows paths are case-INsensitive.
Definition: zupply.cpp:11883
void load(const char *filename)
load Load image from file.
Definition: zupply.cpp:13770
std::tm localtime(std::time_t t)
Thread-safe version of localtime.
Definition: zupply.cpp:11429
Exception for signalling unexpected IO errors.
Definition: zupply.hpp:232
Value operator[](const std::string &longKey)
Overloaded operator [] to retrieve the value by long key.
Definition: zupply.cpp:12899
void save_hdr(const char *filename) const
save_hdr Save to HDR image
Definition: zupply.cpp:13865
ArgOption & add_opt_value(char shortKey, std::string longKey, T &dst, T defaultValue, std::string help="", std::string type="", int min=1, int max=1)
Template function for an option take a value. This will store the value from argument to dst...
Definition: zupply.hpp:3342
Point_ & operator=(const Point_ &pt)
Copy operator.
int channels() const
channels Get number of channels
Value()
Value default constructor.
Definition: zupply.hpp:2798
void crop(int r0, int c0, int r1, int c1)
crop Crop image given coordinates.
std::string get_error()
Get all errors generated during parsing.
Definition: zupply.cpp:12876
std::string current_working_directory()
Get current working directory.
Definition: zupply.cpp:11784
void replace_first_with_escape(std::string &str, const std::string &replaceWhat, const std::string &replaceWith)
Replace first occurance of one string with specified another string. Replace in-place.
Definition: zupply.cpp:10587
The CfgLevel struct, internal struct for cfgParser. Tree structure for config sections.
Definition: zupply.hpp:2899
The ArgParser class. For parsing command line arguments.
Definition: zupply.hpp:3113
ArgOption & set_min(int minCount)
Set minimum number of argument this option take. If minimum number not satisfied, ArgParser will gene...
Definition: zupply.cpp:12382
Rect_< float > Rect2f
Rect2f Float version.
Definition: zupply.hpp:538
std::string format()
Get default logger format.
Definition: zupply.cpp:13445
The LogConfig class. For get/set logging configurations.
Definition: zupply.hpp:3518
void unused(const T &)
Suppress warning for unused variables, do nothing actually.
Definition: zupply.hpp:995
The CfgParser class for INI/CFG file parsing.
Definition: zupply.hpp:2933
void close()
Close current file.
Definition: zupply.cpp:11014
void set_format(std::string newFormat)
Set default logger format.
Definition: zupply.cpp:13450
Size_ & operator=(const Size_ &sz)
Copy operator.
bool remove_file(std::string path)
Remove file. Dangerous! Cannot revert.
Definition: zupply.cpp:11723
void resize(Size sz)
resize Resize image given new size
Definition: zupply.cpp:13914
Image to_normal(float range=1.0f) const
to_normal Convert to 8-bit image(lose precision)
Definition: zupply.cpp:13870
bool remove_dir(std::string path, bool recursive)
Remove directory and all sub-directories and files if set recursive to true. If recursive set to fals...
Definition: zupply.cpp:11644
void filter(const std::string pattern)
Filter directory with specified pattern.
Definition: zupply.cpp:10895
template 2D point class. The class defines a point in 2D space. Data type of the point coordinates is...
Definition: zupply.hpp:351
std::vector< Value > arguments() const
Return all input arguments that does not belong to any option.
Definition: zupply.cpp:12513
Image(int rows, int cols, int channels)
Image Constructor with specified size.
Definition: zupply.hpp:780
Rect2i Rect
Rect By default use Rect2i, int version.
Definition: zupply.hpp:548
bool is_open() const
Check if file is opened.
Definition: zupply.hpp:2356
int system(const char *const command, const char *const moduleName)
Execute sub-process using system call.
Definition: zupply.cpp:11343
std::string path_join(std::vector< std::string > elems)
Join path from sub-folders This function will handle system dependent path formats such as '/' for un...
Definition: zupply.cpp:11493
ImageBase()
ImageBase Default(empty) constructor.
std::size_t thread_id()
Get thread id.
Definition: zupply.cpp:11380
std::string to_string()
Get user friendly information about this logger. Get informations such as log levels, sink list, etc...
Definition: zupply.cpp:13528
void reset()
Clear filter pattern, redo search in directory.
Definition: zupply.cpp:10952
A not copyable base class, should be inheritated privately.
Definition: zupply.hpp:127
void stop()
Stop the progress bar. Don't call this manully unless you know what u r doing. This will automaticall...
Definition: zupply.cpp:13004
std::size_t file_size()
Get file size in byte, member function.
Definition: zupply.cpp:11064
iterator begin()
Return begin iterator.
Definition: zupply.hpp:2181
detail::LineLogger warn()
Warn level overloaded with stream style message.
Definition: zupply.cpp:13478
std::string rskip(std::string str, std::string delim)
Skip from right until delimiter string found.
Definition: zupply.cpp:10441
std::string path_split_directory(std::string path)
Split the deepest directory.
Definition: zupply.cpp:11517
CfgLevel & operator()(const std::string &name)
Overloaded operator () for config sections.
Definition: zupply.hpp:2966