2026-06-05 13:44:39 +09:00

196 lines
5.7 KiB
C++

#pragma once
#include <cstdio>
#include <cstdint>
#include <cmath>
#include <limits>
#include <string>
#include <thread>
#include <type_traits>
#include <cstring>
#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 <typename T, size_t N>
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<typename T>
void __delete(T** heapObj)
{
if (*heapObj) {
delete *heapObj;
*heapObj = nullptr;
}
}
/**
* Floating Point Value Comparison
*/
template<typename T>
static
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
fpv_equal(T x, T y, int ulp = 2)
{
auto ad = std::abs(x - y);
return ad < std::numeric_limits<T>::epsilon() * std::abs(x + y) * ulp
|| ad < (std::numeric_limits<T>::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(); }
};