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.
wheeldetect/molunCar/StdUtils.h

458 lines
10 KiB
C++

/*! \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 "CyclopsLock.h"
#include <vector>
#include <string>
#include <sstream>
#include <memory>
#include <map>
#include <fstream>
#include <algorithm>
#include "Asserte.h"
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_