Last active
July 8, 2021 03:07
-
-
Save neur1n/d482577b9c5d7e5adae75acc8f7a12dd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /****************************************************************************** | |
| 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 |
Author
Author
2021-06-28
- Move position of
NRelease - Add
NMutexThread
Author
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
2021-03-31