Skip to content

Instantly share code, notes, and snippets.

@neur1n
Last active July 8, 2021 03:07
Show Gist options
  • Select an option

  • Save neur1n/d482577b9c5d7e5adae75acc8f7a12dd to your computer and use it in GitHub Desktop.

Select an option

Save neur1n/d482577b9c5d7e5adae75acc8f7a12dd to your computer and use it in GitHub Desktop.
/******************************************************************************
Author: Jihang Li (Jihang.Li_AT_outlook.com)
Last update: 2021-06-28 19:09
******************************************************************************/
#ifndef NEU_H
#define NEU_H
#include <stdio.h>
#include <stdlib.h>
#include <condition_variable>
#include <chrono>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
//******************************************************************** Handy{{{
#ifdef _WIN32
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#else
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
#ifdef NEU_DEBUG
#define NInfo(fmt, ...) printf("\033[0;32m[%s] " fmt "\n\033[0m", __FILENAME__, ##__VA_ARGS__)
#define NHint(fmt, ...) printf("\033[0;34m[%s > %d] " fmt "\n\033[0m", __FILENAME__, __LINE__, ##__VA_ARGS__)
#define NErr(fmt, ...) printf("\033[0;31m[%s > %s > %d] " fmt "\n\033[0m", __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define NOneLine(fmt, ...) printf("\r[%s] " fmt, __FILENAME__, ##__VA_ARGS__); fflush(stdout); // Print on one line.
#else
#define NInfo(fmt, ...)
#define NHint(fmt, ...)
#define NErr(fmt, ...)
#define NOneLine(fmt, ...)
#endif
#ifndef NArraySize
#define NArraySize(a) ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
#endif
#ifndef NBit
#define NBit(b) (1 << b)
#endif
#ifndef NClamp
#if defined(_MSC_VER)
#define NClamp(x, l, u) \
[&](){ \
decltype(x) _x = (x); \
decltype(l) _l = (l); \
decltype(u) _u = (u); \
return _x <= _l ? _l : (_x <= _u ? _x : _u); \
}()
#elif defined(__GNUC__) || defined(__GNUG__)
#define NClamp(x, l, u) \
({ \
__typeof__(x) _x = (x); \
__typeof__(l) _l = (l); \
__typeof__(u) _u = (u); \
_x <= _l ? _l : (_x <= _u ? _x : _u); \
})
#endif
#endif
#ifndef NMax
#if defined(_MSC_VER)
#define NMax(x, y) \
[&](){ \
decltype(x) _x = (x); \
decltype(y) _y = (y); \
return _x >= _y ? _x : _y; \
}()
#elif defined(__GNUC__) || defined(__GNUG__)
#define NMax(x, y) \
({ \
__typeof__(x) _x = (x); \
__typeof__(y) _y = (y); \
_x >= _y ? _x : _y; \
})
#endif
#endif
#ifndef NMin
#if defined(_MSC_VER)
#define NMin(x, y) \
[&](){ \
decltype(x) _x = (x); \
decltype(y) _y = (y); \
return _x <= _y ? _x : _y; \
}()
#elif defined(__GNUC__) || defined(__GNUG__)
#define NMin(x, y) \
({ \
__typeof__(x) _x = (x); \
__typeof__(y) _y = (y); \
_x <= _y ? _x : _y; \
})
#endif
#endif
#define NRelease(o) \
if ((o) != nullptr) \
{ \
delete (o); \
(o) = nullptr; \
}
inline long long NDuration(
const std::chrono::system_clock::time_point &start,
const std::chrono::system_clock::time_point &end,
const std::string &unit = "ms")
{
if (unit.compare("s") == 0)
{
return std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
}
else if (unit.compare("us") == 0)
{
return std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
}
else // if (unit.compare("ms") == 0) // Milliseconds by default
{
return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}
}
inline bool NIsStringEmpty(const char *str)
{
return (str == nullptr || str[0] == '\0');
}
inline void NSleep(const int &ms)
{
#ifdef _WIN32
Sleep(ms);
#else
usleep(ms * 1000);
#endif
}
template<class T>
T NEnumAnd(const T &x, const T &y)
{
return static_cast<T>(static_cast<int>(x) & static_cast<int>(y));
}
template<class T>
T NEnumNot(T x)
{
return static_cast<T>(~static_cast<int>(x));
}
template<class T>
T NEnumOr(const T &x, const T &y)
{
return static_cast<T>(static_cast<int>(x) | static_cast<int>(y));
}
template<class T>
T NEnumSubtract(const T &x, const T &y)
{
return static_cast<T>(static_cast<int>(x) - static_cast<int>(y));
}
//******************************************************************** Handy}}}
//*************************************************************** Error Code{{{
typedef enum
{
N_OK = 0,
N_FAIL = -1,
N_DATA_INVALID = -2,
N_DATA_NOT_READY = -3,
N_DATA_REPEATED = -4,
N_INPUT_INVALID = -5,
N_OPERATION_ABORTED = -6,
} NRESULT;
typedef struct _NRESULTMSG_
{
NRESULT nr;
const char *msg;
} NRESULTMSG;
static const NRESULTMSG nr_msgs[] =
{
{N_OK, "Succeeded"},
{N_FAIL, "Failed"},
{N_DATA_INVALID, "Data are invalid"},
{N_DATA_NOT_READY, "Data are not ready"},
{N_DATA_REPEATED, "Data are repeated"},
{N_INPUT_INVALID, "Input is invalid"},
{N_OPERATION_ABORTED, "Operation aborted"},
};
inline const char* NRMsg(NRESULT nr)
{
for (size_t i = 0; i < NArraySize(nr_msgs); ++i)
{
if (nr_msgs[i].nr == nr)
{
return nr_msgs[i].msg;
}
}
return "Unknown error";
}
#define NSucc(nr) (((NRESULT)(nr)) >= 0)
#define NFail(nr) (((NRESULT)(nr)) < 0)
//*************************************************************** Error Code}}}
//*********************************************************** Class & Struct{{{
class NMutexThread
{
public:
template<class Fn, class... Args>
NMutexThread(Fn&& function, Args&&... arguments)
{
this->m_lock = std::unique_lock<std::mutex>(this->m_mutex);
this->m_thread = std::thread(function, arguments...);
}
~NMutexThread()
{
if (this->m_thread.joinable())
{
this->m_thread.detach();
}
}
void Block(bool should_block)
{
while (should_block)
{
this->m_controller.wait(this->m_lock);
break;
}
}
void Unblock()
{
this->m_controller.notify_one();
}
private:
std::condition_variable_any m_controller;
std::unique_lock<std::mutex> m_lock;
std::mutex m_mutex;
std::thread m_thread;
}; // class NMutexThread
/* Numeric vector, only works with numeric data. */
template<class T>
class NNVector
{
public:
NNVector()
{
this->m_sum = (T)0;
}
~NNVector()
{
}
void Erase(const int &index)
{
this->m_sum -= this->m_data[index];
if (index >= 0)
{
this->m_data.erase(this->m_data.begin() + index);
}
else
{
this->m_data.erase(this->m_data.end() + index);
}
}
T Mean()
{
if (this->m_data.size() <= 0)
{
return (T)0;
}
return this->m_sum / this->m_data.size();
}
void Push(const T &data)
{
this->m_data.push_back(data);
this->m_sum += data;
}
size_t Size()
{
return this->m_data.size();
}
private:
std::vector<T> m_data;
T m_sum;
}; // class NNVector
//*********************************************************** Class & Struct}}}
//********************************************************************* Keys{{{
#define NK_ESC 0x1B
#define NK_Q 0x51
//********************************************************************* Keys}}}
#endif // NEU_H
@neur1n
Copy link
Author

neur1n commented Mar 31, 2021

2021-03-31

  1. Add colors to NInfo, NHint, NErr.

@neur1n
Copy link
Author

neur1n commented Jun 28, 2021

2021-06-28

  1. Move position of NRelease
  2. Add NMutexThread

@neur1n
Copy link
Author

neur1n commented Jul 8, 2021

2021-07-08
Move to Neur1n/neu.h for better version controlling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment