#pragma once #include #include #include #include #include #include #include #include #include "ScopeExit.h" #include "InterfaceDefs.h" /** * Compile time message */ #define STRING2(n) #n #define STRING1(n) STRING2(n) #define __MESSAGE(m) __pragma(message(__FILE__ "(" STRING1(__LINE__) ")" m)) #define WARNING(m) __MESSAGE(" : Warning: " #m) #define TODO(m) __MESSAGE(" : TODO: " #m) #define MESSAGE(m) __MESSAGE(" : " #m) /** * macro for enum & string */ #define ENUM_ELE(e) e #define STRING_ELE(e) std::string(#e) /** * Size of Array */ template inline constexpr size_t sizeof_array(T(&array)[N]) { return N; } /** * helper for simplifying to free */ #define xFREE(p) __free((void **)&p) inline void __free(void** p) { if (*p) { ::free(*p); *p = nullptr; } } /** * helper for simplifying to delete */ #define xDELETE(heapObj) __delete(&heapObj) template void __delete(T** heapObj) { if (*heapObj) { delete *heapObj; *heapObj = nullptr; } } /** * Floating Point Value Comparison */ template static typename std::enable_if::is_integer, bool>::type fpv_equal(T x, T y, int ulp = 2) { auto ad = std::abs(x - y); return ad < std::numeric_limits::epsilon() * std::abs(x + y) * ulp || ad < (std::numeric_limits::min)(); // to prevent conflict with // min() macro in windef.h } /** * usage : char const* jsonData = STRING_AS( { "JobDispatherRule": { "NumberOfDuplication": 1 } } ); */ #define STRING_AS(...) #__VA_ARGS__ /** * shortcut for error check */ #ifdef FUNC_LOGE #define __LOG__(fmt, ...) FUNC_LOGE(fmt, ##__VA_ARGS__) #else #define __LOG__(fmt, ...) \ do { \ fprintf(stderr, "%s() " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \ } while (false) #endif #define IF_ERR_RETURN(s) \ do { \ int err = (s); \ if (err) { \ __LOG__("ERROR(%d): %s", err, #s); \ return; \ } \ } while (false) #define IF_ERR_RETURN_ERR(s) \ do { \ int err = (s); \ if (err) { \ __LOG__("ERROR(%d): %s", err, #s); \ return err; \ } \ } while (false) #define IF_EQ_RETURN(val1, val2) \ do { \ if ((val1) == (val2)) { \ __LOG__("ERROR: %s == %s", #val2, #val2); \ return; \ } \ } while (false) #define IF_EQ_RETURN_ERR(val1, val2, err) \ do { \ if ((val1) == (val2)) { \ __LOG__("ERROR: %s == %s", #val1, #val2); \ return err; \ } \ } while (false) #define IF_NE_RETURN(val1, val2) \ do { \ if ((val1) != (val2)) { \ __LOG__("ERROR: %s != %s", #val1, #val2); \ return; \ } \ } while (false) #define IF_NE_RETURN_ERR(val1, val2, err) \ do { \ if ((val1) != (val2)) { \ __LOG__("ERROR: %s != %s", #val1, #val2); \ return err; \ } \ } while (false) #define IF_TRUE_RETURN(val) \ IF_EQ_RETURN(true, val) #define IF_TRUE_RETURN_ERR(val, err) \ IF_EQ_RETURN_ERR(true, val, err) #define IF_FALSE_RETURN(val) \ IF_EQ_RETURN(false, val) #define IF_FALSE_RETURN_ERR(val, err) \ IF_EQ_RETURN_ERR(false, val, err) #define IF_NULL_RETURN(val) \ IF_EQ_RETURN(nullptr, val) #define IF_NULL_RETURN_ERR(val, err) \ IF_EQ_RETURN_ERR(nullptr, val, err) /** * compare for C string (char*) */ class CStringComparer { public: bool operator()(const char *c1, const char *c2) const { return strcmp(c1, c2) < 0; } }; /** * guarded thread * join when thread termination */ struct guarded_thread : public std::thread { using thread::thread; ~guarded_thread() { if (joinable()) join(); } };