You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
455 lines
10 KiB
C
455 lines
10 KiB
C
|
5 years ago
|
/*! \file StdUtils.h
|
||
|
|
\brief useful functions working with std functions.
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
Created: 2015/06/22, author: Jin Bingwen.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef __StdUtils_h_
|
||
|
|
#define __StdUtils_h_
|
||
|
|
|
||
|
|
#if (defined(_MSC_VER) && _MSC_VER <= 1600)
|
||
|
|
#define LITTLE_CPP11 1
|
||
|
|
#else
|
||
|
|
#include <thread>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if (defined _WINDOWS) || (defined WIN32)
|
||
|
|
#define USE_WIN_API 1
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
#include <vector>
|
||
|
|
#include <string>
|
||
|
|
#include <sstream>
|
||
|
|
#include <memory>
|
||
|
|
#include <map>
|
||
|
|
#include <fstream>
|
||
|
|
#include <algorithm>
|
||
|
|
|
||
|
|
using std::string;
|
||
|
|
using std::vector;
|
||
|
|
using std::stringstream;
|
||
|
|
|
||
|
|
#if defined(LITTLE_CPP11)
|
||
|
|
#define GET_SIGN(x) (x < 0 ? true : false)
|
||
|
|
#else
|
||
|
|
#define GET_SIGN(x) std::signbit(x)
|
||
|
|
#endif
|
||
|
|
|
||
|
|
template<typename T, typename _Iter>
|
||
|
|
T sum(_Iter s, _Iter e)
|
||
|
|
{
|
||
|
|
if (s == e)
|
||
|
|
{
|
||
|
|
return T();
|
||
|
|
}
|
||
|
|
T ret = *s;
|
||
|
|
s++;
|
||
|
|
while (s != e)
|
||
|
|
{
|
||
|
|
ret += *s;
|
||
|
|
s++;
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T, typename _Iter>
|
||
|
|
_Iter findTopNPercentEle(_Iter s, _Iter e, float nPersent)
|
||
|
|
{
|
||
|
|
auto maxVal = std::max_element(s, e);
|
||
|
|
T threVal = (*maxVal)*(1.0f - nPersent);
|
||
|
|
while (s != e)
|
||
|
|
{
|
||
|
|
if (*s < threVal)
|
||
|
|
{
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
++s;
|
||
|
|
}
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T, typename _Iter>
|
||
|
|
_Iter findSumTopNPercentEle(_Iter s, _Iter e, float nPersent)
|
||
|
|
{
|
||
|
|
T sumVal = sum<T, _Iter>(s, e);
|
||
|
|
T threVal = sumVal*nPersent;
|
||
|
|
sumVal = 0;
|
||
|
|
while (s != e)
|
||
|
|
{
|
||
|
|
sumVal += *s;
|
||
|
|
if (sumVal > threVal)
|
||
|
|
{
|
||
|
|
s++;
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
s++;
|
||
|
|
}
|
||
|
|
return e;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
void clearAndResetVec(vector<T>* vec, int n)
|
||
|
|
{
|
||
|
|
if (vec) {
|
||
|
|
vec->clear();
|
||
|
|
vec->reserve(n);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
void genIncVec(vector<T>& vec, T start, int count, T step)
|
||
|
|
{
|
||
|
|
for (int i = 0; i < count; ++i)
|
||
|
|
{
|
||
|
|
vec.push_back(start);
|
||
|
|
start += step;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
class SortEle
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
SortEle() : mSortVal(0), pEle(NULL) {}
|
||
|
|
SortEle(double val, const void* pData) : mSortVal(val), pEle(pData) {}
|
||
|
|
double mSortVal;
|
||
|
|
const void* pEle;
|
||
|
|
bool operator< (const SortEle& i)
|
||
|
|
{
|
||
|
|
return mSortVal < i.mSortVal;
|
||
|
|
}
|
||
|
|
bool operator>(const SortEle& i)
|
||
|
|
{
|
||
|
|
return mSortVal > i.mSortVal;
|
||
|
|
}
|
||
|
|
SortEle operator+ (const SortEle& i)
|
||
|
|
{
|
||
|
|
return SortEle(mSortVal + i.mSortVal, pEle);
|
||
|
|
}
|
||
|
|
void operator+= (const SortEle& i)
|
||
|
|
{
|
||
|
|
mSortVal += i.mSortVal;
|
||
|
|
}
|
||
|
|
SortEle operator- (const SortEle& i)
|
||
|
|
{
|
||
|
|
return SortEle(mSortVal - i.mSortVal, pEle);
|
||
|
|
}
|
||
|
|
operator float()
|
||
|
|
{
|
||
|
|
return (float)mSortVal;
|
||
|
|
}
|
||
|
|
operator double()
|
||
|
|
{
|
||
|
|
return mSortVal;
|
||
|
|
}
|
||
|
|
SortEle operator* (float f)
|
||
|
|
{
|
||
|
|
return SortEle(mSortVal*f, pEle);
|
||
|
|
}
|
||
|
|
void operator= (float f)
|
||
|
|
{
|
||
|
|
mSortVal = f;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
template<typename _It, typename _Ty>
|
||
|
|
_It findRange(_It s, _It e, const _Ty& val)
|
||
|
|
{
|
||
|
|
if (s == e)
|
||
|
|
{
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
_It mi = (e - s) / 2 + s;
|
||
|
|
if (val < *mi)
|
||
|
|
{
|
||
|
|
return findRange(s, mi, val);
|
||
|
|
}
|
||
|
|
else if (val > *mi)
|
||
|
|
{
|
||
|
|
return findRange(mi + 1, e, val);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return mi;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename _Ty, typename _It>
|
||
|
|
void add(_It s, _It e, const _Ty& val)
|
||
|
|
{
|
||
|
|
while (s != e)
|
||
|
|
{
|
||
|
|
*s += val;
|
||
|
|
s++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename _Ty, typename _It>
|
||
|
|
bool allInRange(_It s, _It e, _Ty minVal, _Ty maxVal)
|
||
|
|
{
|
||
|
|
while (s != e)
|
||
|
|
{
|
||
|
|
if (*s < minVal || *s > maxVal)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
++s;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename _Ty, typename _It>
|
||
|
|
bool anyInRange(_It s, _It e, _Ty minVal, _Ty maxVal)
|
||
|
|
{
|
||
|
|
while (s != e)
|
||
|
|
{
|
||
|
|
if (*s >= minVal && *s <= maxVal)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
++s;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename _Ty, typename _It>
|
||
|
|
bool anyIn(_It s, _It e, _Ty v)
|
||
|
|
{
|
||
|
|
while (s != e)
|
||
|
|
{
|
||
|
|
if (*s == v)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
++s;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename _T>
|
||
|
|
bool loadAValueFromFile(string filePath, _T& ret)
|
||
|
|
{
|
||
|
|
std::fstream fs;
|
||
|
|
fs.open(filePath, std::fstream::in);
|
||
|
|
if (!fs.is_open())
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
fs >> ret;
|
||
|
|
fs.close();
|
||
|
|
}
|
||
|
|
|
||
|
|
// search range is [si, ei), not include ei
|
||
|
|
template<typename _PairIter>
|
||
|
|
_PairIter max_first_element(_PairIter si, _PairIter ei)
|
||
|
|
{
|
||
|
|
if (si == ei)
|
||
|
|
{
|
||
|
|
return ei;
|
||
|
|
}
|
||
|
|
|
||
|
|
// exclude ei
|
||
|
|
_PairIter ret = --ei;
|
||
|
|
ei++;
|
||
|
|
|
||
|
|
auto maxVal = si->first;
|
||
|
|
si++;
|
||
|
|
|
||
|
|
while (si != ei)
|
||
|
|
{
|
||
|
|
if (maxVal < si->first)
|
||
|
|
{
|
||
|
|
maxVal = si->first;
|
||
|
|
ret = si;
|
||
|
|
}
|
||
|
|
++si;
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<typename _Ty0, typename _Ty1>
|
||
|
|
string joinStr(_Ty0 s0, _Ty1 s1)
|
||
|
|
{
|
||
|
|
stringstream ss;
|
||
|
|
ss << s0 << s1;
|
||
|
|
return ss.str();
|
||
|
|
}
|
||
|
|
template<typename _Ty0, typename _Ty1, typename _Ty2>
|
||
|
|
string joinStr(_Ty0 s0, _Ty1 s1, _Ty2 s2)
|
||
|
|
{
|
||
|
|
stringstream ss;
|
||
|
|
ss << s0 << s1 << s2;
|
||
|
|
return ss.str();
|
||
|
|
}
|
||
|
|
template<typename _Ty0, typename _Ty1, typename _Ty2, typename _Ty3>
|
||
|
|
string joinStr(_Ty0 s0, _Ty1 s1, _Ty2 s2, _Ty3 s3)
|
||
|
|
{
|
||
|
|
stringstream ss;
|
||
|
|
ss << s0 << s1 << s2 << s3;
|
||
|
|
return ss.str();
|
||
|
|
}
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
protected:\
|
||
|
|
type m##name;
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_GETFUN(type, name)\
|
||
|
|
public:\
|
||
|
|
type get##name() const { return m##name; }
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_SETFUN(type, name)\
|
||
|
|
public:\
|
||
|
|
void set##name(type val) { m##name = val; }
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_SETFUN2(type, name, val1, val2)\
|
||
|
|
public:\
|
||
|
|
void set##name(type val) {\
|
||
|
|
assert(val >= val1 && val <= val2);\
|
||
|
|
if (val >= val1 && val <= val2) m##name = val; }
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_SETENUM(type, name)\
|
||
|
|
public:\
|
||
|
|
void set##name(type val) { m##name = val; }\
|
||
|
|
void set##name(int val) {\
|
||
|
|
set##name(static_cast<type>(val)); }
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_SETENUM2(type, name, val1, val2)\
|
||
|
|
public:\
|
||
|
|
void set##name(type val) {\
|
||
|
|
assert(val >= val1 && val <= val2);\
|
||
|
|
if (val >= val1 && val <= val2) m##name = val; }\
|
||
|
|
void set##name(int val) {\
|
||
|
|
set##name(static_cast<type>(val)); }
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_SETPAIR(type, name)\
|
||
|
|
public:\
|
||
|
|
void set##name(type val1, type val2) {\
|
||
|
|
if (val1 > val2) { m##name##Start = val2; m##name##End = val1; }\
|
||
|
|
else { m##name##Start = val1; m##name##End = val2; }\
|
||
|
|
}
|
||
|
|
|
||
|
|
#define _DECLARE_PARAMETER_SETPAIR2(type, name, val1, val2)\
|
||
|
|
public:\
|
||
|
|
void set##name(type value1, type value2) {\
|
||
|
|
assert(value1 >= val1 && value1 <= val2 && value2 >= val1 && value2 <= val2);\
|
||
|
|
if (value1 >= val1 && value1 <= val2 && value2 >= val1 && value2 <= val2) {\
|
||
|
|
if (value1 > value2) { m##name##Start = value2; m##name##End = value1; }\
|
||
|
|
else { m##name##Start = value1; m##name##End = value2; }\
|
||
|
|
}\
|
||
|
|
}
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER(type, name)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name)\
|
||
|
|
_DECLARE_PARAMETER_SETFUN(type, name)
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER2(type, name, val1, val2)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name)\
|
||
|
|
_DECLARE_PARAMETER_SETFUN2(type, name, val1 , val2)
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER_SET(type, name)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_SETFUN(type, name)
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER_SET2(type, name, val1, val2)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_SETFUN2(type, name, val1, val2)
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER_GET(type, name)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name)
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER_ENUM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name)\
|
||
|
|
_DECLARE_PARAMETER_SETENUM(type, name)
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER_ENUM2(type, name, val1, val2)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name)\
|
||
|
|
_DECLARE_PARAMETER_SETENUM2(type, name, val1, val2)
|
||
|
|
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER_PAIR(type, name)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name##Start)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name##End)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name##Start)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name##End)\
|
||
|
|
_DECLARE_PARAMETER_SETPAIR(type, name)
|
||
|
|
|
||
|
|
#define DECLARE_PARAMETER_PAIR2(type, name, val1, val2)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name##Start)\
|
||
|
|
_DECLARE_PARAMETER_MEM(type, name##End)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name##Start)\
|
||
|
|
_DECLARE_PARAMETER_GETFUN(type, name##End)\
|
||
|
|
_DECLARE_PARAMETER_SETPAIR2(type, name, val1, val2)
|
||
|
|
|
||
|
|
|
||
|
|
// Declare the provide class as a singleton.
|
||
|
|
// Get instance via Class::getInstance().
|
||
|
|
//
|
||
|
|
// Note: according to C++11 standard, static object initialization will
|
||
|
|
// be made only by one thread, other threads will wait till it complete.
|
||
|
|
// start from VS2014, this macro is thread-safe.
|
||
|
|
#define DECLARE_SINGLETON(type, ...)\
|
||
|
|
public:\
|
||
|
|
static type& getInstance() {\
|
||
|
|
static type inst(__VA_ARGS__);\
|
||
|
|
return inst;\
|
||
|
|
}
|
||
|
|
|
||
|
|
// Declare the provide class as a singleton.
|
||
|
|
// Get instance via Class::getInstance().
|
||
|
|
//
|
||
|
|
// Note: according to C++11 standard, static object initialization will
|
||
|
|
// be made only by one thread, other threads will wait till it complete.
|
||
|
|
// start from VS2014, this macro is thread-safe.
|
||
|
|
#define DECLARE_SINGLETON_NOPARA(type)\
|
||
|
|
public:\
|
||
|
|
static type& getInstance() {\
|
||
|
|
static type inst;\
|
||
|
|
return inst;\
|
||
|
|
}
|
||
|
|
|
||
|
|
// A simple version of object factory that use object name as key and hold object instances.
|
||
|
|
// It's thread-safe.
|
||
|
|
// Note: factory own the object instance, aka. own the object instance's memory, which means it will
|
||
|
|
// deallocate the memory when it self is destroyed (when the who application is shutdown).
|
||
|
|
// You don't need to delete the object instance yourself, and even worse, it will cause the double-delete crash.
|
||
|
|
template<typename T, typename TPtr,
|
||
|
|
typename std::enable_if<std::is_base_of<std::shared_ptr<T>, TPtr>::value>::type* = nullptr>
|
||
|
|
class ObjectFactory
|
||
|
|
{
|
||
|
|
DECLARE_SINGLETON_NOPARA(ObjectFactory)
|
||
|
|
|
||
|
|
public:
|
||
|
|
~ObjectFactory() {}
|
||
|
|
TPtr getObject(const char* name)
|
||
|
|
{
|
||
|
|
//CyclopsLockGuard guard(&mLock);
|
||
|
|
auto it = mLookupTable.find(name);
|
||
|
|
if (it == mLookupTable.end()) {
|
||
|
|
// create new
|
||
|
|
TPtr ptr = std::make_shared<T>();
|
||
|
|
it = mLookupTable.insert(std::make_pair(name, ptr)).first;
|
||
|
|
}
|
||
|
|
return it->second;
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
ObjectFactory() {}
|
||
|
|
std::map<string, TPtr> mLookupTable;
|
||
|
|
//CyclopsLock mLock;
|
||
|
|
};
|
||
|
|
|
||
|
|
template<typename T>
|
||
|
|
inline T minMax(T val, T minVal, T maxVal) {
|
||
|
|
return std::min<T>(maxVal, std::max<T>(minVal, val));
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif // __StdUtils_h_
|
||
|
|
|