00001
00011 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00012 #pragma once
00013 #endif
00014 #ifndef COMMON_BASE_H_
00015 #define COMMON_BASE_H_
00016
00021
00022
00023 #include <cassert>
00024 #include <string>
00025 #include <vector>
00026
00027
00028 #include <limits>
00029 #include <cmath>
00030
00031 #ifdef WIN32
00033 #define NOMINMAX
00034 #endif
00035
00036
00037 using std::string;
00038 using std::wstring;
00039
00040
00041 #ifndef WIN32
00042 #define __FUNCSIG__ __PRETTY_FUNCTION__
00043 #endif
00044
00045
00046 #ifdef WIN32
00047 #include <tchar.h>
00048 #include <wchar.h>
00050 typedef TCHAR tchar;
00051 #else
00052 #define _T(x) (x)
00053 typedef char tchar;
00054 #endif
00055
00056 #ifdef _UNICODE
00058 typedef std::wstring tstring;
00060 #define TCHAR_TO_INT(c) ( (int)(c) )
00062 #define INT_TO_TCHAR(i) ( (wchar_t)(i) )
00063 #else
00064 typedef std::string tstring;
00065 #define TCHAR_TO_INT(c) ( (int)(uint1)(c) )
00066 #define INT_TO_TCHAR(i) ( (char)(uint1)(i) )
00067 #endif
00068
00070 #define __TFILE__ _T(__FILE__)
00072 #define __TFUNCSIG__ _T(__FUNCSIG__)
00073
00074
00075 #ifdef WIN32
00076
00077 #pragma warning(disable: 4267)
00078
00079 #pragma warning(disable: 4996)
00080 #endif
00081
00084 #ifdef WIN32
00086 typedef unsigned __int32 uint;
00088 typedef __int8 int1;
00090 typedef unsigned __int8 uint1;
00092 typedef __int16 int2;
00094 typedef unsigned __int16 uint2;
00096 typedef __int32 int4;
00098 typedef unsigned __int32 uint4;
00100 typedef __int64 int8;
00102 typedef unsigned __int64 uint8;
00103 #else
00104 typedef unsigned int uint;
00105 typedef char int1;
00106 typedef unsigned char uint1;
00107 typedef short int2;
00108 typedef unsigned short uint2;
00109 typedef int int4;
00110 typedef unsigned int uint4;
00111 typedef long long int8;
00112 typedef unsigned long long uint8;
00113 #endif
00114
00115
00117 typedef std::vector<tstring> STRING_VECTOR;
00118
00120 #define SAFE_DELETE(x) { delete (x); (x) = 0; }
00122 #define SAFE_DELARR(x) { delete [] (x); (x) = 0; }
00124 #define SAFE_RELEASE(x) { if (x) { (x)->Release(); (x) = 0; } }
00125
00127
00128 #ifdef _MSC_VER
00129 #define PACKED __declspec(align(1))
00130 #else
00131 #define PACKED __attribute__((packed))
00132 #endif
00133
00135
00136
00137 #define DECLARE_NO_COPY_CLASS(ClassName) \
00138 private: \
00139 ClassName(const ClassName&); \
00140 ClassName& operator=(const ClassName&);
00141
00143 template <typename destT, typename srcT>
00144 destT &absolute_cast(srcT &v)
00145 {
00146 return reinterpret_cast<destT&>(v);
00147 }
00148 template <typename destT, typename srcT>
00149 const destT &absolute_cast(const srcT &v)
00150 {
00151 return reinterpret_cast<const destT&>(v);
00152 }
00153
00155
00156
00158 namespace common
00159 {
00160
00163
00164
00167
00169 enum ORIENTATION
00170 {
00171 O_NONE,
00172 O_VERT,
00173 O_HORIZ,
00174 };
00175
00177
00179 template <typename T>
00180 inline bool IsPow2(T x)
00181 {
00182 return (x & (x-1)) == 0;
00183 }
00184
00186
00188 uint4 log2u(uint4 x);
00190
00191 uint4 GetBitMask(uint4 n);
00192
00194 template <typename T>
00195 T **new_2d(size_t cx, size_t cy)
00196 {
00197 T **a = new T*[cx];
00198 for (size_t x = 0; x < cx; x++)
00199 a[x] = new T[cy];
00200 return a;
00201 }
00202
00204 template <typename T>
00205 void delete_2d(T **a, size_t cx)
00206 {
00207 for (size_t x = 0; x < cx; x++)
00208 delete[] a[x];
00209 delete[] a;
00210 }
00211
00213
00216 inline void strcpy0(tchar* dest, const tstring &src)
00217 {
00218 for (size_t i = 0; i < src.length(); i++)
00219 dest[i] = src[i];
00220 dest[src.length()] = '\0';
00221 }
00222
00224
00237 template <typename T>
00238 class Singleton
00239 {
00240 public:
00242 static T & GetInstance()
00243 {
00244 static T Instance;
00245 return Instance;
00246 }
00247 };
00248
00250 void ZeroMem(void *Data, size_t NumBytes);
00252 void CopyMem(void *Out, const void *In, size_t NumBytes);
00254 bool CompareMem(const void *Data1, const void *Data2, size_t NumBytes);
00256 void FillMem(void *Data, size_t NumBytes, uint1 Byte);
00257
00259 template<class Iterator>
00260 void InsertionSort(Iterator b, Iterator e)
00261 {
00262 if (b == e) return;
00263 for (Iterator j = b + 1; j < e; j++)
00264 {
00265 typename std::iterator_traits<Iterator>::value_type key;
00266 key = *j;
00267 Iterator i = j;
00268 while (i > b && key < *(i-1))
00269 {
00270 *i = *(i-1);
00271 i--;
00272 }
00273 *i = key;
00274 }
00275 }
00276
00278 template<class Iterator, typename Compare>
00279 void InsertionSort(Iterator b, Iterator e, Compare Comp)
00280 {
00281 if (b == e) return;
00282 for (Iterator j = b + 1; j < e; j++)
00283 {
00284 typename std::iterator_traits<Iterator>::value_type key;
00285 key = *j;
00286 Iterator i = j;
00287 while (i > b && Comp(key, *(i-1)))
00288 {
00289 *i = *(i-1);
00290 i--;
00291 }
00292 *i = key;
00293 }
00294 }
00296
00297
00300
00302 class DeletePolicy
00303 {
00304 public:
00305 template <typename T>
00306 static void Destroy(T *p)
00307 {
00308
00309 typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
00310 (void) sizeof(type_must_be_complete);
00311 delete p;
00312 }
00313 };
00315 class DeleteArrayPolicy
00316 {
00317 public:
00318 template <typename T>
00319 static void Destroy(T *p)
00320 {
00321
00322 typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
00323 (void) sizeof(type_must_be_complete);
00324 delete [] p;
00325 }
00326 };
00328 class ReleasePolicy
00329 {
00330 public:
00331 template <typename T>
00332 static void Destroy(T *p)
00333 {
00334 if (p) p->Release();
00335 }
00336 };
00337
00339
00342 template <typename T, typename PolicyT = DeletePolicy>
00343 class scoped_ptr
00344 {
00345 template<typename Y, typename PolicyY> friend class scoped_ptr;
00346
00347 private:
00348 T *m_Ptr;
00349
00350 scoped_ptr(const scoped_ptr &);
00351 scoped_ptr & operator = (const scoped_ptr &);
00352
00353 public:
00354 typedef T value_type;
00355 typedef T *ptr_type;
00356
00357 explicit scoped_ptr(T *p = NULL) : m_Ptr(p) { }
00358 ~scoped_ptr() { PolicyT::template Destroy<T>(m_Ptr); }
00359
00360 T & operator * () const { assert(m_Ptr != NULL); return *m_Ptr; }
00361 T * operator -> () const { assert(m_Ptr != NULL); return m_Ptr; }
00362 T & operator [] (uint i) const { return m_Ptr[i]; }
00363
00364 inline friend bool operator == (const scoped_ptr &lhs, const T *rhs) { return lhs.m_Ptr == rhs; }
00365 inline friend bool operator == (const T *lhs, const scoped_ptr &rhs) { return lhs == rhs.m_Ptr; }
00366 inline friend bool operator != (const scoped_ptr &lhs, const T *rhs) { return lhs.m_Ptr != rhs; }
00367 inline friend bool operator != (const T *lhs, const scoped_ptr &rhs) { return lhs != rhs.m_Ptr; }
00368
00369 T * get() const { return m_Ptr; }
00370 void swap(scoped_ptr<T, PolicyT> &b) { T *tmp = b.m_Ptr; b.m_Ptr = m_Ptr; m_Ptr = tmp; }
00371 void reset(T *p = NULL) { assert(p == NULL || p != m_Ptr); scoped_ptr<T, PolicyT>(p).swap(*this); }
00372 };
00373
00375
00378 template <typename T, typename PolicyT = DeletePolicy>
00379 class shared_ptr
00380 {
00381 template<typename Y, typename PolicyY> friend class shared_ptr;
00382
00383 private:
00384 T *m_Ptr;
00385 unsigned *m_Counter;
00386
00387 public:
00388 typedef T value_type;
00389 typedef T *ptr_type;
00390
00391 explicit shared_ptr(T *p = NULL) : m_Ptr(p), m_Counter(new unsigned(1)) { }
00392 ~shared_ptr() { if (--(*m_Counter) == 0) { delete m_Counter; PolicyT::template Destroy<T>(m_Ptr); } }
00393
00394 shared_ptr(const shared_ptr &p) : m_Ptr(p.m_Ptr), m_Counter(p.m_Counter) { (*m_Counter)++; }
00395 shared_ptr & operator = (const shared_ptr &p) { reset<T>(p); return *this; }
00396 template <typename U, typename PolicyU> explicit shared_ptr(const shared_ptr<U, PolicyU> &p) : m_Ptr(p.m_Ptr), m_Counter(p.m_Counter) { (*m_Counter)++; }
00397 template <typename U, typename PolicyU> shared_ptr & operator = (const shared_ptr<U, PolicyU> &p) { reset<U, PolicyU>(p); return *this; }
00398
00399 T & operator * () const { assert(m_Ptr != NULL); return *m_Ptr; }
00400 T * operator -> () const { assert(m_Ptr != NULL); return m_Ptr; }
00401 T & operator [] (uint i) const { return m_Ptr[i]; }
00402
00403 inline friend bool operator == (const shared_ptr &lhs, const T *rhs) { return lhs.m_Ptr == rhs; }
00404 inline friend bool operator == (const T *lhs, const shared_ptr &rhs) { return lhs == rhs.m_Ptr; }
00405 inline friend bool operator != (const shared_ptr &lhs, const T *rhs) { return lhs.m_Ptr != rhs; }
00406 inline friend bool operator != (const T *lhs, const shared_ptr &rhs) { return lhs != rhs.m_Ptr; }
00407 template <typename U, typename PolicyU> bool operator == (const shared_ptr<U, PolicyU> &rhs) const { return m_Ptr == rhs.m_Ptr; }
00408 template <typename U, typename PolicyU> bool operator != (const shared_ptr<U, PolicyU> &rhs) const { return m_Ptr != rhs.m_Ptr; }
00409
00410 T * get() const { return m_Ptr; }
00411 void swap(shared_ptr<T, PolicyT> &b) { T *tmp = b.m_Ptr; b.m_Ptr = m_Ptr; m_Ptr = tmp; unsigned *tmpc = b.m_Counter; b.m_Counter = m_Counter; m_Counter = tmpc; }
00412 void reset(T *p = NULL) { if (p == m_Ptr) return; shared_ptr<T, PolicyT>(p).swap(*this); }
00413 template <typename U, typename PolicyU> void reset(const shared_ptr<U, PolicyU> &p) { shared_ptr<U, PolicyU>(p).swap(*this); }
00414 bool unique() const { return *m_Counter == 1; }
00415 };
00416
00417 #ifdef WIN32
00419 class CloseHandlePolicy { public: template <typename T> static void Destroy(T p) { if (p != NULL) CloseHandle(p); } };
00421 class DeleteObjectPolicy { public: template <typename T> static void Destroy(T p) { if (p != NULL) DeleteObject(p); } };
00422 #endif
00423
00425 template <typename T, typename PolicyT>
00426 class scoped_handle
00427 {
00428 template<typename Y, typename PolicyY> friend class scoped_handle;
00429
00430 private:
00431 T m_Ptr;
00432
00433 scoped_handle(const scoped_handle &);
00434 scoped_handle & operator = (const scoped_handle &);
00435
00436 public:
00437 typedef T value_type;
00438
00439 explicit scoped_handle(T p) : m_Ptr(p) { }
00440 ~scoped_handle() { PolicyT::template Destroy<T>(m_Ptr); }
00441
00442 inline friend bool operator == (const scoped_handle &lhs, const T &rhs) { return lhs.m_Ptr == rhs; }
00443 inline friend bool operator == (const T &lhs, const scoped_handle &rhs) { return lhs == rhs.m_Ptr; }
00444 inline friend bool operator != (const scoped_handle &lhs, const T &rhs) { return lhs.m_Ptr != rhs; }
00445 inline friend bool operator != (const T &lhs, const scoped_handle &rhs) { return lhs != rhs.m_Ptr; }
00446
00447 const T & get() const { return m_Ptr; }
00448 void swap(scoped_handle<T, PolicyT> &b) { T tmp = b.m_Ptr; b.m_Ptr = m_Ptr; m_Ptr = tmp; }
00449 void reset(T p) { scoped_handle<T, PolicyT>(p).swap(*this); }
00450 };
00451
00453 template <typename T, typename PolicyT>
00454 class shared_handle
00455 {
00456 template<typename Y, typename PolicyY> friend class shared_handle;
00457
00458 private:
00459 T m_Ptr;
00460 unsigned *m_Counter;
00461
00462 public:
00463 typedef T value_type;
00464
00465 explicit shared_handle(T p) : m_Ptr(p), m_Counter(new unsigned(1)) { }
00466 ~shared_handle() { if (--(*m_Counter) == 0) { delete m_Counter; PolicyT::template Destroy<T>(m_Ptr); } }
00467
00468 shared_handle(const shared_handle &p) : m_Ptr(p.m_Ptr), m_Counter(p.m_Counter) { (*m_Counter)++; }
00469 shared_handle & operator = (const shared_handle &p) { reset<T>(p); return *this; }
00470 template <typename U, typename PolicyU> explicit shared_handle(const shared_handle<U, PolicyU> &p) : m_Ptr(p.m_Ptr), m_Counter(p.m_Counter) { (*m_Counter)++; }
00471 template <typename U, typename PolicyU> shared_handle & operator = (const shared_handle<U, PolicyU> &p) { reset<U, PolicyU>(p); return *this; }
00472
00473 inline friend bool operator == (const shared_handle &lhs, const T &rhs) { return lhs.m_Ptr == rhs; }
00474 inline friend bool operator == (const T &lhs, const shared_handle &rhs) { return lhs == rhs.m_Ptr; }
00475 inline friend bool operator != (const shared_handle &lhs, const T &rhs) { return lhs.m_Ptr != rhs; }
00476 inline friend bool operator != (const T &lhs, const shared_handle &rhs) { return lhs != rhs.m_Ptr; }
00477 template <typename U, typename PolicyU> bool operator == (const shared_handle<U, PolicyU> &rhs) const { return m_Ptr == rhs.m_Ptr; }
00478 template <typename U, typename PolicyU> bool operator != (const shared_handle<U, PolicyU> &rhs) const { return m_Ptr != rhs.m_Ptr; }
00479
00480 const T & get() const { return m_Ptr; }
00481 void swap(shared_handle<T, PolicyT> &b) { T tmp = b.m_Ptr; b.m_Ptr = m_Ptr; m_Ptr = tmp; unsigned *tmpc = b.m_Counter; b.m_Counter = m_Counter; m_Counter = tmpc; }
00482 void reset(T p) { if (p == m_Ptr) return; shared_handle<T, PolicyT>(p).swap(*this); }
00483 template <typename U, typename PolicyU> void reset(const shared_handle<U, PolicyU> &p) { shared_handle<U, PolicyU>(p).swap(*this); }
00484 bool unique() const { return *m_Counter == 1; }
00485 };
00486
00487 template <typename T, typename PolicyT> void swap(scoped_ptr<T, PolicyT> &a, scoped_ptr<T, PolicyT> &b) { a.swap(b); }
00488 template <typename T, typename PolicyT> void swap(shared_ptr<T, PolicyT> &a, shared_ptr<T, PolicyT> &b) { a.swap(b); }
00489 template <typename T, typename PolicyT> void swap(scoped_handle<T, PolicyT> &a, scoped_handle<T, PolicyT> &b) { a.swap(b); }
00490 template <typename T, typename PolicyT> void swap(shared_handle<T, PolicyT> &a, shared_handle<T, PolicyT> &b) { a.swap(b); }
00491
00493
00494
00497
00499 enum EOLMODE
00500 {
00501 EOL_NONE,
00502 EOL_CRLF,
00503 EOL_LF,
00504 EOL_CR
00505 };
00506
00508 extern const tstring EMPTY_STRING;
00510 extern const tchar * const EOL;
00511
00513 enum CHARSET
00514 {
00515 CHARSET_NONE = 0,
00516 CHARSET_WINDOWS,
00517 CHARSET_ISO,
00518 CHARSET_IBM,
00519 CHARSET_UTF8,
00520 };
00521
00523 bool CharIsAlphaNumeric(tchar ch);
00525 bool CharIsAlpha(tchar ch);
00527 inline bool CharIsDigit(tchar ch) { return (ch >= _T('0') && ch <= _T('9')); }
00529
00530 inline bool CharIsHexDigit(tchar ch) { return (ch >= _T('0') && ch <= _T('9')) || (ch >= _T('A') && ch <= _T('F')) || (ch >= _T('a') && ch <= _T('f')); }
00532 bool CharIsLower(tchar ch);
00534 bool CharIsUpper(tchar ch);
00536
00537 bool CharIsWhitespace(char ch);
00538 #ifdef WIN32
00539 bool CharIsWhitespace(wchar_t ch);
00540 #endif
00542
00548 inline bool CharIsWhitespace_f(tchar ch)
00549 {
00550 return (ch == _T(' ') || ch == _T('\n') || ch == _T('\r') || ch == _T('\t') || ch == _T('\v'));
00551 }
00552
00554 void ReverseString(tstring *s);
00556 void Trim(tstring *s);
00558 void Trim(tstring *Out, const tstring &s);
00559
00560
00561
00562
00563
00565
00566 tchar CharToLower(tchar ch);
00568
00569 tchar CharToUpper(tchar ch);
00571
00572 void LowerCase(tstring *s);
00573 inline void LowerCase(tstring *Out, const tstring &s) { *Out = s; LowerCase(Out); }
00575
00576 void UpperCase(tstring *s);
00577 inline void UpperCase(tstring *Out, const tstring &s) { *Out = s; UpperCase(Out); }
00578
00580
00583 bool Charset_WindowsSpecialChar(char a_c, string *a_s);
00585
00587 char Charset_Convert_Char(char a_c, CHARSET a_Charset1, CHARSET a_Charset2);
00589
00590 void Charset_Convert(string *out, const string &s, CHARSET Charset1, CHARSET Charset2);
00591
00593 void Rot13(tstring *InOut);
00594 inline void Rot13(tstring *Out, const tstring &In) { *Out = In; Rot13(Out); }
00595
00597 void EolModeToStr(tstring *Out, EOLMODE EolMode);
00598
00600
00601 void Replace(tstring *result, const tstring &s, const tstring &s1, const tstring &s2);
00603 void Replace(tstring *Out, const tstring &s, tchar Ch1, tchar Ch2);
00605 void Replace(tstring *InOut, tchar Ch1, tchar Ch2);
00606
00608 void ReplaceEOL(tstring *result, const tstring &s, EOLMODE EOLMode);
00609
00611 void NormalizeWhitespace(tstring *result, const tstring &s);
00612
00614 void DupeString(tstring *Out, const tstring &s, size_t count);
00615
00617 void RightStr(tstring *Out, const tstring &s, size_t Length);
00618
00620 size_t SubstringCount(const tstring &str, const tstring &substr);
00621
00623 bool StrEqualI(const tstring &s1, const tstring &s2);
00625 bool SubStrEqual(const tstring &s1, size_t off1, const tstring &s2, size_t off2, size_t length);
00627 bool SubStrEqualI(const tstring &s1, size_t off1, const tstring &s2, size_t off2, size_t length);
00628
00630 bool ContainsEOL(const tstring &s);
00631
00633 bool StrBegins(const tstring &s, const tstring &sub, size_t Begin = 0);
00635 bool StrEnds(const tstring &s, const tstring &Sub);
00636
00638
00640 bool Split(const tstring &s, const tstring &delimiter, tstring *out, size_t *index);
00642 bool SplitFirstOf(const tstring &s, const tstring &delimiters, tstring *out, size_t *index);
00644 void Split(STRING_VECTOR *Out, const tstring &s, const tstring &Delimiter);
00646 bool SplitEOL(const tstring &s, tstring *out, size_t *index);
00648 bool SplitQuery(const tstring &s, tstring *out, size_t *index);
00650
00651 bool ValidateWildcard(const tstring &Mask, const tstring &S, bool CaseSensitive = true, size_t MaskOff = 0, size_t SOff = 0);
00653
00660 float FineSearch(const tstring &SubStr, const tstring &Str);
00662
00664 size_t LevenshteinDistance(const tstring &s1, const tstring &s2);
00666
00668 size_t LevenshteinDistanceI(const tstring &s1, const tstring &s2);
00669
00673
00675 class StringNaturalCompare
00676 {
00677 private:
00678 bool m_CaseInsensitive;
00679
00680 int CompareNumbers(const tstring &s1, size_t i1, const tstring &s2, size_t i2);
00681
00682 public:
00683 StringNaturalCompare(bool CaseInsensitive) : m_CaseInsensitive(CaseInsensitive) { }
00684 int Compare(const tstring &s1, const tstring &s2);
00685 };
00686
00688
00694 class StringNaturalLess : public StringNaturalCompare
00695 {
00696 public:
00697 StringNaturalLess(bool CaseInsensitive = true) : StringNaturalCompare(CaseInsensitive) { }
00698 bool operator () (const tstring &s1, const tstring &s2) { return (Compare(s1, s2) < 0); }
00699 };
00700
00702 class StringNaturalGreater : public StringNaturalCompare
00703 {
00704 public:
00705 StringNaturalGreater(bool CaseInsensitive = true) : StringNaturalCompare(CaseInsensitive) { }
00706 bool operator () (const tstring &s1, const tstring &s2) { return (Compare(s1, s2) > 0); }
00707 };
00708
00710
00712 class StrLessCi
00713 {
00714 public:
00715 bool operator () (const tstring &s1, const tstring &s2)
00716 {
00717 tstring u1 = s1, u2 = s2;
00718 UpperCase(&u1);
00719 UpperCase(&u2);
00720 return u1 < u2;
00721 }
00722 };
00724 class StrGreaterCi
00725 {
00726 public:
00727 bool operator () (const tstring &s1, const tstring &s2)
00728 {
00729 tstring u1 = s1, u2 = s2;
00730 UpperCase(&u1);
00731 UpperCase(&u2);
00732 return u1 > u2;
00733 }
00734 };
00735
00739
00740 #ifdef WIN32
00741
00753
00754 bool ConvertUnicodeToChars(string *Out, const wstring &S, unsigned CodePage);
00755 bool ConvertUnicodeToChars(string *Out, const wchar_t *S, unsigned NumChars, unsigned CodePage);
00756
00757 bool ConvertCharsToUnicode(wstring *Out, const string &S, unsigned CodePage);
00758 bool ConvertCharsToUnicode(wstring *Out, const char *S, unsigned NumChars, unsigned CodePage);
00759
00761
00766 extern const char * const BOM_UTF8;
00767 extern const char * const BOM_UTF16_LE;
00768 extern const char * const BOM_UTF16_BE;
00770
00771 #endif
00772
00776 #ifdef _UNICODE
00777 bool TstringToString(string *Out, const tstring &S);
00778 bool StringToTstring(tstring *Out, const string &S);
00779 inline bool TstringToWstring(wstring *Out, const tstring &S) { *Out = S; return true; }
00780 inline bool WstringToTstring(tstring *Out, const wstring &S) { *Out = S; return true; }
00781
00782 inline string TstringToStringR(const tstring &S) { string R; if (!TstringToString(&R, S)) return string(); return R; }
00783 inline tstring StringToTstringR(const string &S) { tstring R; if (!StringToTstring(&R, S)) return tstring(); return R; }
00784 inline wstring TstringToWstring(const tstring &S) { return S; }
00785 inline tstring WstringToTstring(const wstring &S) { return S; }
00786 #else
00787 inline bool TstringToString(string *Out, const tstring &S) { *Out = S; return true; }
00788 inline bool StringToTstring(tstring *Out, const string &S) { *Out = S; return true; }
00789 inline string TstringToStringR(const tstring &S) { return S; }
00790 inline tstring StringToTstringR(const string &S) { return S; }
00791 #ifdef WIN32
00792 bool TstringToWstring(wstring *Out, const tstring &S);
00793 bool WstringToTstring(tstring *Out, const wstring &S);
00794 inline wstring TstringToWstringR(const tstring &S) { wstring R; if (!TstringToWstring(&R, S)) return wstring(); return R; }
00795 inline tstring WstringToTstringR(const wstring &S) { tstring R; if (!WstringToTstring(&R, S)) return tstring(); return R; }
00796 #endif
00797 #endif
00798
00799
00800
00802
00803
00805
00806
00807
00810
00811 #ifdef WIN32
00813 const tchar DIR_SEP = _T('\\');
00814 #else
00815 const tchar DIR_SEP = _T('/');
00816 #endif
00817
00819 bool PathIsAbsolute(const tstring &s);
00821 void IncludeTrailingPathDelimiter(tstring *InOutPath);
00823 void IncludeTrailingPathDelimiter(tstring *OutPath, const tstring &InPath);
00825 void ExcludeTrailingPathDelimiter(tstring *InOutPath);
00827 void ExcludeTrailingPathDelimiter(tstring *OutPath, const tstring &InPath);
00829
00830 void ExtractPathPrefix(tstring *OutPrefix, const tstring &s);
00832 void ExtractFilePath(tstring *OutPath, const tstring &s);
00834 void ExtractFileName(tstring *OutFileName, const tstring &s);
00836 void ExtractFileExt(tstring *OutExt, const tstring &s);
00838
00840 void ChangeFileExt(tstring *Out, const tstring &FileName, const tstring &Ext);
00842
00843 void NormalizePath(tstring *OutPath, const tstring &s);
00845
00846 void RelativeToAbsolutePath(tstring *Out, const tstring &Base, const tstring &Path);
00848
00850 void AbsoluteToRelativePath(tstring *Out, const tstring &Base, const tstring &Target);
00851
00853
00854
00855
00856
00866
00868 extern const tchar _DIGITS_L[];
00870 extern const tchar _DIGITS_U[];
00871
00873
00876 inline int HexDigitToNumber(char Ch)
00877 {
00878 if (Ch >= '0' && Ch <= '9') return (int)(uint1)(Ch - '0');
00879 else if (Ch >= 'A' && Ch <= 'F') return (int)(uint1)(Ch - ('A' - 10));
00880 else if (Ch >= 'a' && Ch <= 'f') return (int)(uint1)(Ch - ('a' - 10));
00881 else return 0xFF;
00882 }
00883 #ifdef WIN32
00884 inline int HexDigitToNumber(wchar_t Ch)
00885 {
00886 if (Ch >= L'0' && Ch <= L'9') return (int)(Ch - L'0');
00887 else if (Ch >= L'A' && Ch <= L'F') return (int)(Ch - (L'A' - 10));
00888 else if (Ch >= L'a' && Ch <= L'f') return (int)(Ch - (L'a' - 10));
00889 else return 0xFF;
00890 }
00891 #endif
00892
00894
00895 template <typename T>
00896 void UintToStr(tstring *Out, T x, uint4 Base = 10, bool UpperCase = true)
00897 {
00898 if (x == 0)
00899 {
00900 Out->assign(_T("0"));
00901 return;
00902 }
00903
00904 Out->clear();
00905 Out->reserve(8);
00906
00907
00908 if (IsPow2<uint4>(Base))
00909 {
00910
00911 uint4 Bits = log2u(Base);
00912
00913 uint4 BitMask = GetBitMask(Bits);
00914
00915 if (UpperCase)
00916 {
00917 while (x != 0)
00918 {
00919 *Out += _DIGITS_U[x & BitMask];
00920 x = x >> Bits;
00921 }
00922 }
00923 else
00924 {
00925 while (x != 0)
00926 {
00927 *Out += _DIGITS_L[x & BitMask];
00928 x = x >> Bits;
00929 }
00930 }
00931 }
00932
00933 else
00934 {
00935 if (UpperCase)
00936 {
00937 while (x != 0)
00938 {
00939 *Out += _DIGITS_U[x % Base];
00940 x /= Base;
00941 }
00942 }
00943 else
00944 {
00945 while (x != 0)
00946 {
00947 *Out += _DIGITS_L[x % Base];
00948 x /= Base;
00949 }
00950 }
00951 }
00952
00953 ReverseString(Out);
00954 }
00955
00956 template <typename T>
00957 void IntToStr(tstring *Out, T x, uint4 Base = 10, bool UpperCase = true)
00958 {
00959 if (x == 0)
00960 {
00961 Out->assign(_T("0"));
00962 return;
00963 }
00964
00965 Out->clear();
00966 Out->reserve(8);
00967
00968
00969 if (x > 0)
00970 {
00971
00972 if (IsPow2<uint4>(Base))
00973 {
00974
00975 uint4 Bits = log2u(Base);
00976
00977 uint4 BitMask = GetBitMask(Bits);
00978
00979 if (UpperCase)
00980 {
00981 while (x != 0)
00982 {
00983 *Out += _DIGITS_U[x & BitMask];
00984 x = x >> Bits;
00985 }
00986 }
00987 else
00988 {
00989 while (x != 0)
00990 {
00991 *Out += _DIGITS_L[x & BitMask];
00992 x = x >> Bits;
00993 }
00994 }
00995 }
00996
00997 else
00998 {
00999 if (UpperCase)
01000 {
01001 while (x != 0)
01002 {
01003 *Out += _DIGITS_U[x % Base];
01004 x /= Base;
01005 }
01006 }
01007 else
01008 {
01009 while (x != 0)
01010 {
01011 *Out += _DIGITS_L[x % Base];
01012 x /= Base;
01013 }
01014 }
01015 }
01016 }
01017
01018
01019 else
01020 {
01021 T x_div_base;
01022 if (UpperCase)
01023 {
01024 while (x != 0)
01025 {
01026 x_div_base = x/(T)Base;
01027 *Out += _DIGITS_U[- (x - x_div_base*(T)Base)];
01028 x = x_div_base;
01029 }
01030 }
01031 else
01032 {
01033 while (x != 0)
01034 {
01035 x_div_base = x/(T)Base;
01036 *Out += _DIGITS_L[- (x - x_div_base*(T)Base)];
01037 x = x_div_base;
01038 }
01039 }
01040 *Out += '-';
01041 }
01042
01043 ReverseString(Out);
01044 }
01045
01047
01048 template <typename T>
01049 bool _CharToDigit(T *Digit, tchar ch)
01050 {
01051 if (ch >= _T('0') && ch <= _T('9'))
01052 *Digit = static_cast<T>(ch-_T('0'));
01053 else if (ch >= _T('A') && ch <= _T('Z'))
01054 *Digit = static_cast<T>(ch-_T('A')+10);
01055 else if (ch >= _T('a') && ch <= _T('z'))
01056 *Digit = static_cast<T>(ch-_T('a')+10);
01057 else
01058 return false;
01059 return true;
01060 }
01061
01063
01067 template <typename T>
01068 int StrToUint(T *Number, const tstring &str, unsigned Base = 10)
01069 {
01070 T BaseT = static_cast<T>(Base);
01071 if (str.empty()) return -1;
01072 *Number = 0;
01073 T Digit, LastNumber = 0, Limit = std::numeric_limits<T>::max()/BaseT;
01074 for (size_t i = 0; i < str.length(); ++i) {
01075 if (!_CharToDigit(&Digit, str[i])) return -1;
01076 if (Digit >= BaseT) return -1;
01077 if (*Number > Limit) return -2;
01078 *Number = *Number * BaseT + Digit;
01079 if (*Number < LastNumber) return -2;
01080 LastNumber = *Number;
01081 }
01082 return 0;
01083 }
01084
01085 template <typename T>
01086 int StrToInt(T *Number, const tstring &str, unsigned Base = 10)
01087 {
01088 T BaseT = static_cast<T>(Base);
01089 if (str.empty()) return -1;
01090 *Number = 0;
01091 size_t i = 0;
01092 int Sign = +1;
01093 if (str[0] == '+') i = 1;
01094 else if (str[0] == '-') { Sign = -1; i = 1; }
01095 T Digit, LastNumber = 0, Limit;
01096 if (Sign > 0) Limit = std::numeric_limits<T>::max()/BaseT;
01097 else Limit = std::numeric_limits<T>::min()/BaseT;
01098 for (; i < str.length(); ++i) {
01099 if (!_CharToDigit(&Digit, str[i])) return -1;
01100 if (Digit >= BaseT) return -1;
01101 if (Sign > 0) { if (*Number > Limit) return -2; }
01102 else { if (*Number < Limit) return -2; }
01103 *Number = *Number * BaseT + Digit * Sign;
01104 if (Sign > 0) { if (*Number < LastNumber) return -2; }
01105 else { if (*Number > LastNumber) return -2; }
01106 LastNumber = *Number;
01107 }
01108 return 0;
01109 }
01110
01111 template <typename T> inline tstring IntToStrR (T x, int base = 10, bool UpperCase = true) { tstring r; IntToStr<T> (&r, x, base, UpperCase); return r; }
01112 template <typename T> inline tstring UintToStrR(T x, int base = 10, bool UpperCase = true) { tstring r; UintToStr<T>(&r, x, base, UpperCase); return r; }
01113
01114 inline void Size_tToStr(tstring *Out, size_t x, size_t Base = 10, bool UpperCase = true) { UintToStr(Out, (uint4)x, Base, UpperCase); }
01115 inline tstring Size_tToStrR(size_t x, size_t Base = 10, bool UpperCase = true) { tstring R; Size_tToStr(&R, x, Base, UpperCase); return R; }
01116
01118
01119 template <typename T>
01120 void UintToStr2(tstring *Out, T x, unsigned Length, int base = 10)
01121 {
01122 tstring Tmp;
01123 UintToStr(&Tmp, x, base);
01124 if (Tmp.length() >= Length)
01125 *Out = Tmp;
01126 else
01127 {
01128 Out->clear();
01129 Out->reserve(std::max(Tmp.length(), Length));
01130 for (size_t Left = Length - Tmp.length(); Left > 0; Left--)
01131 *Out += _T('0');
01132 *Out += Tmp;
01133 }
01134 }
01135 template <typename T>
01136 void IntToStr2(tstring *Out, T x, unsigned Length, int base = 10)
01137 {
01138 tstring Tmp;
01139 IntToStr<T>(&Tmp, x, base);
01140 if (Tmp.length() >= Length)
01141 *Out = Tmp;
01142 else
01143 {
01144 Out->clear();
01145 Out->reserve(std::max(Tmp.length(), Length));
01146 assert(!Tmp.empty());
01147 if (Tmp[0] == _T('-'))
01148 {
01149 *Out += _T('-');
01150 for (size_t Left = Length - Tmp.length(); Left > 0; Left--)
01151 *Out += _T('0');
01152 Out->append(Tmp.begin()+1, Tmp.end());
01153 }
01154 else
01155 {
01156 for (size_t Left = Length - Tmp.length(); Left > 0; Left--)
01157 *Out += _T('0');
01158 *Out += Tmp;
01159 }
01160 }
01161 }
01162
01163 template <typename T> tstring UintToStr2R(T x, unsigned Length, int Base = 10) { tstring R; UintToStr2<T>(&R, x, Length, Base); return R; }
01164 template <typename T> tstring IntToStr2R (T x, unsigned Length, int Base = 10) { tstring R; IntToStr2<T> (&R, x, Length, Base); return R; }
01165
01167 inline void CharToStr(tstring *Out, tchar ch) { Out->clear(); *Out += ch; }
01168 inline tstring CharToStrR(tchar ch) { tstring s; s += ch; return s; }
01169
01171
01178 void DoubleToStr(tstring *Out, double x, char Mode = 'g', int Precision = 6);
01179 void FloatToStr(tstring *Out, float x, char Mode = 'g', int Precision = 6);
01180
01181 inline tstring DoubleToStrR(double x, char Mode = 'g', int Precision = 6) { tstring R; DoubleToStr(&R, x, Mode, Precision); return R; }
01182 inline tstring FloatToStrR (float x, char Mode = 'g', int Precision = 6) { tstring R; FloatToStr (&R, x, Mode, Precision); return R; }
01183
01185
01188 int StrToDouble(double *out, const tstring &s);
01189 int StrToFloat (float *out, const tstring &s);
01190
01192
01199 void BoolToStr(tstring *Out, bool x, char mode = 'f');
01200 inline tstring BoolToStrR(bool x, char mode = 'f') { tstring R; BoolToStr(&R, x, mode); return R; }
01202
01205 bool StrToBool(bool *result, const tstring &s);
01206
01208 void PtrToStr(tstring *Out, const void* p);
01209 inline tstring PtrToStrR(const void *p) { tstring R; PtrToStr(&R, p); return R; }
01210
01212
01215 template <typename T>
01216 void SizeToStr(tstring *str, T size, bool Space, int Precision)
01217 {
01218 double size2 = (double)size;
01219 if (size2 >= 1024.0*1024.0*1024.0*1024.0)
01220 {
01221 DoubleToStr( str, size2/(1024.0*1024.0*1024.0*1024.0), 'f', Precision );
01222 str->append(Space ? _T(" TB") : _T("TB"));
01223 }
01224 else if (size2 >= 1024.0*1024.0*1024.0)
01225 {
01226 DoubleToStr( str, size2/(1024.0*1024.0*1024.0), 'f', Precision );
01227 str->append(Space ? _T(" GB") : _T("GB"));
01228 }
01229 else if (size2 >= 1024.0*1024.0)
01230 {
01231 DoubleToStr( str, size2/(1024.0*1024.0), 'f', Precision );
01232 str->append(Space ? _T(" MB") : _T("MB"));
01233 }
01234 else if (size2 >= 1024.0)
01235 {
01236 DoubleToStr( str, size2/1024.0, 'f', Precision );
01237 str->append(Space ? _T(" KB") : _T("KB"));
01238 }
01239 else
01240 {
01241 UintToStr( str, size );
01242 str->append(Space ? _T(" B") : _T("B"));
01243 }
01244 }
01245 template <typename T> tstring SizeToStrR(T Size, bool Space, int Precision) { tstring r; SizeToStr<T>(&r, Size, Space, Precision); return r; }
01246
01248
01249
01250
01251
01254
01256 class TimeMeasurer
01257 {
01258 private:
01259 #ifdef WIN32
01260 bool m_QPF_Using;
01261 int8 m_QPF_TicksPerSec;
01262 int8 m_QPF_Start;
01263 uint4 m_Start;
01264 #else
01265
01266 int8 m_Start;
01267 #endif
01268
01269 public:
01270 TimeMeasurer();
01271
01273 double GetTimeD();
01275 float GetTimeF();
01276 };
01277
01279 extern TimeMeasurer g_Timer;
01280
01282
01284 void Wait(uint4 Miliseconds);
01285
01287
01288
01289
01290
01293
01297 const int1 MININT1 = std::numeric_limits<int1>::min();
01298 const int1 MAXINT1 = std::numeric_limits<int1>::max();
01299 const int2 MININT2 = std::numeric_limits<int2>::min();
01300 const int2 MAXINT2 = std::numeric_limits<int2>::max();
01301 const int4 MININT4 = std::numeric_limits<int4>::min();
01302 const int4 MAXINT4 = std::numeric_limits<int4>::max();
01303 const int8 MININT8 = std::numeric_limits<int8>::min();
01304 const int8 MAXINT8 = std::numeric_limits<int8>::max();
01305 const uint1 MAXUINT1 = std::numeric_limits<uint1>::max();
01306 const uint2 MAXUINT2 = std::numeric_limits<uint2>::max();
01307 const uint4 MAXUINT4 = std::numeric_limits<uint4>::max();
01308 const uint8 MAXUINT8 = std::numeric_limits<uint8>::max();
01309 const float MINFLOAT = std::numeric_limits<float>::min();
01310 const float MAXFLOAT = std::numeric_limits<float>::max();
01312
01314
01316 #define FLOAT_ALMOST_ZERO(F) ((absolute_cast<uint4>(F) & 0x7f800000L) == 0)
01317
01321 const float E = 2.71828182845904523536f;
01322 const float LOG2E = 1.44269504088896340736f;
01323 const float LOG10E = 0.434294481903251827651f;
01324 const float LN2 = 0.693147180559945309417f;
01325 const float LN10 = 2.30258509299404568402f;
01326 const float PI = 3.14159265358979323846264338327950288419716939937510582f;
01327 const float PI_2 = 1.57079632679489661923f;
01328 const float PI_4 = 0.785398163397448309616f;
01329 const float PI_X_2 = 6.28318530717958647692f;
01330 const float _1_PI = 0.318309886183790671538f;
01331 const float _2_PI = 0.636619772367581343076f;
01332 const float _2_SQRTPI = 1.12837916709551257390f;
01333 const float SQRT2 = 1.41421356237309504880f;
01334 const float SQRT3 = 1.7320508075688772935274463415059f;
01335 const float SQRT1_2 = 0.707106781186547524401f;
01336
01337
01338
01339 #ifdef WIN32
01341 bool is_finite(float x);
01343 bool is_finite(double x);
01345 bool is_nan(float x);
01347 bool is_nan(double x);
01348
01349 #else
01350 inline bool is_finite(float x) { return (finitef(x) != 0); }
01351 inline bool is_finite(double x) { return (finite(x) != 0); }
01352 inline bool is_nan(float x) { return (isnanf(x) != 0); }
01353 inline bool is_nan(double x) { return (isnan(x) != 0); }
01354 #endif
01355
01357
01359 template <typename T>
01360 T safe_add(T a, T b)
01361 {
01362 T R = a + b;
01363 if (R < std::max(a, b)) return std::numeric_limits<T>::max();
01364 else return R;
01365 }
01366
01368
01370 template <typename T>
01371 T safe_sub(T a, T b)
01372 {
01373 if (b > a) return T();
01374 else return a - b;
01375 }
01376
01378
01380 template <typename T>
01381 T safe_mul(T a, T b)
01382 {
01383 if (b == T()) return T();
01384 T R = a * b;
01385 if (R / b != a) return std::numeric_limits<T>::max();
01386 else return R;
01387 }
01388
01390 inline float safe_acos(float x)
01391 {
01392 if (x <= -1.0f) return PI;
01393 if (x >= 1.0f) return 0.0f;
01394 return acosf(x);
01395 }
01396
01398
01399 inline int round(float x)
01400 {
01401 return static_cast<int>(floorf(x+0.5f));
01402 }
01403 inline int round(double x)
01404 {
01405 return static_cast<int>(floor(x+0.5));
01406 }
01407
01409
01413 template <typename T>
01414 inline T ceil_div(T x, T y)
01415 {
01416 return (x+y-1) / y;
01417 }
01418
01420 inline bool around(float x, float epsilon)
01421 {
01422 return (fabsf(x) <= epsilon);
01423 }
01424 inline bool around(double x, double epsilon)
01425 {
01426 return (fabs(x) <= epsilon);
01427 }
01428
01430 inline bool around(float x, float y, float epsilon)
01431 {
01432 return (fabsf(x-y) <= epsilon);
01433 }
01434 inline bool around(double x, double y, double epsilon)
01435 {
01436 return (fabs(x-y) <= epsilon);
01437 }
01438
01440
01442 inline bool float_equal(float x, float y)
01443 {
01444 float epsilon = (fabsf(x)+fabsf(y)) * 1e-4f;
01445
01446 return (fabsf(x-y) <= epsilon);
01447 }
01448 inline bool double_equal(double x, double y)
01449 {
01450 double epsilon = (fabs(x)+fabs(y)) * 1e-13;
01451
01452 return (fabs(x-y) <= epsilon);
01453 }
01454
01456
01457 inline uint4 greater_power_of_2(uint4 x)
01458 {
01459
01460 if (!(x & (x-1))) return x;
01461 int R[16]={0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4};
01462 uint4 r=0;
01463 if (x&0xFFFF0000) {r|=16;x>>=16;}
01464 if (x&0xFF00) {r|=8;x>>=8;}
01465 if (x&0xF0) {r|=4;x>>=4;}
01466 return 1<<(r+R[x]);
01467 }
01468
01470
01472 template <typename T>
01473 T powi(T a, uint4 b)
01474 {
01475 T r = (T)1;
01476 T p = a;
01477 while (b)
01478 {
01479 if (b & 1)
01480 r *= p;
01481 p *= p;
01482 b >>= 1;
01483 }
01484 return r;
01485 }
01486
01488 template <typename T>
01489 inline T max3(const T &a, const T &b, const T &c)
01490 {
01491 return std::max(a, std::max(b, c));
01492 }
01493
01495 template <typename T>
01496 inline T min3(const T &a, const T &b, const T &c)
01497 {
01498 return std::min(a, std::min(b, c));
01499 }
01500
01502 template <typename T>
01503 inline T minmax(const T &a, const T &x, const T &b)
01504 {
01505 if (x < a) return a; else if (x > b) return b; else return x;
01506
01507 }
01508
01510
01511 inline float trunc(float x)
01512 {
01513 return (x < 0.0f) ? ceilf(x) : floorf(x);
01514 }
01515 inline double trunc(double x)
01516 {
01517 return (x < 0.0) ? ceil(x) : floor(x);
01518 }
01519
01521
01522 inline float frac(float x)
01523 {
01524 return x - trunc(x);
01525 }
01526 inline double frac(double x)
01527 {
01528 return x - trunc(x);
01529 }
01530
01532 inline float Lerp(float x, float y, float t)
01533 {
01534 return x + t*(y-x);
01535 }
01537 inline float SafeLerp(float x, float y, float t)
01538 {
01539 return Lerp(x, y, minmax(0.0f, t, 1.0f));
01540 }
01541
01543
01544 inline float Lerp2D(float x11, float x21, float x12, float x22, float tx, float ty)
01545 {
01546 return Lerp(Lerp(x11, x21, tx), Lerp(x12, x22, tx), ty);
01547 }
01548
01550 inline float NormalizeAngle(float angle)
01551 {
01552 angle /= PI_X_2;
01553 angle = frac(angle);
01554 if (angle < 0.0f)
01555 angle += 1.0f;
01556 else if (angle >= 1.0f)
01557 angle -= 1.0f;
01558 return angle * PI_X_2;
01559 }
01560
01562 inline float NormalizeAngle2(float Angle)
01563 {
01564 Angle += PI;
01565 Angle -= floorf(Angle * (1.0f/PI_X_2)) * PI_X_2;
01566 Angle -= PI;
01567 return Angle;
01568 }
01569
01571 inline float DegToRad(float Angle)
01572 {
01573
01574 return Angle * 0.017453292519943295769222222222222f;
01575 }
01577 inline float RadToDeg(float Angle)
01578 {
01579
01580 return Angle * 57.295779513082320876846364344191f;
01581 }
01582
01584
01585 inline float AngleDiff(float A, float B)
01586 {
01587 float R1 = B - A;
01588 float R2 = B - PI_X_2 - A;
01589 float R3 = B + PI_X_2 - A;
01590
01591 float R1a = fabsf(R1);
01592 float R2a = fabsf(R2);
01593 float R3a = fabsf(R3);
01594
01595 if (R1a < R2a && R1a < R3a)
01596 return R1;
01597 else if (R2a < R3a)
01598 return R2;
01599 else
01600 return R3;
01601 }
01602
01604
01612 void SmoothCD(float *InOutPos, float Dest, float *InOutVel, float SmoothTime, float TimeDelta);
01613 void SmoothCD(float *InOutPos, float Dest, float *InOutVel, float SmoothTime, float TimeDelta, float MaxSpeed);
01614
01616
01625 inline float Trapezoidal(float x, float a, float b, float c, float d)
01626 {
01627 if (x < a)
01628 return 0.f;
01629 else if (x < b)
01630 return (x-a)/(b-a);
01631 else if (x < c)
01632 return 1.f;
01633 else if (x < d)
01634 return 1.f - (x-c)/(d-c);
01635 else
01636 return 0.f;
01637 }
01639 inline float Trapezoidal(float x, float a, float b, float c, float d, float min, float max)
01640 {
01641 return Trapezoidal(x, a, b, c, d) * (max-min) + min;
01642 }
01643
01645
01649 int QuadraticEquation(float a, float b, float c, float *Out_x1, float *Out_x2);
01650
01659 float PerlinNoise1(float x);
01660 float PerlinNoise2(float x, float y);
01661 float PerlinNoise3(float x, float y, float z);
01662 float BrownianNoise1(float x, uint i, float Persistence);
01663 float BrownianNoise2(float x, float y, uint i, float Persistence);
01664 float BrownianNoise3(float x, float y, float z, uint i, float Persistence);
01666
01667
01668
01671
01672
01673
01674
01675
01676
01677
01678
01679
01681 inline float WaveformSine(float x, float Base, float Amplitude, float Frequency, float Phase)
01682 {
01683 return Base + (sinf((x + Phase) * Frequency * PI_X_2)+1.0f)*0.5f * Amplitude;
01684 }
01685 inline float WaveformSine(float x)
01686 {
01687 return (sinf(x * PI_X_2)+1.0f)*0.5f;
01688 }
01689
01691 inline float WaveformTriangle(float x, float Base, float Amplitude, float Frequency, float Phase)
01692 {
01693 float Input = frac((x + Phase) * Frequency);
01694 float Output;
01695 if (Input < 0.25f)
01696 Output = Input * 4.0f;
01697 else if (Input < 0.75f)
01698 Output = 1.0f - ((Input - 0.25f) * 4.0f);
01699 else
01700 Output = ((Input - 0.75f) * 4.0f) - 1.0f;
01701 return Base + (Output+1.0f)*0.5f * Amplitude;
01702 }
01703 inline float WaveformTriangle(float x)
01704 {
01705 float Input = frac(x);
01706 float Output;
01707 if (Input < 0.25f)
01708 Output = Input * 4.0f;
01709 else if (Input < 0.75f)
01710 Output = 1.0f - ((Input - 0.25f) * 4.0f);
01711 else
01712 Output = ((Input - 0.75f) * 4.0f) - 1.0f;
01713 return (Output+1.0f)*0.5f;
01714 }
01715
01717 inline float WaveformSquare(float x, float Base, float Amplitude, float Frequency, float Phase)
01718 {
01719 return Base + (frac((x + Phase) * Frequency) <= 0.5f ? 1.0f : 0.0f) * Amplitude;
01720 }
01721 inline float WaveformSquare(float x)
01722 {
01723 return frac(x) <= 0.5f ? 1.0f : 0.0f;
01724 }
01725
01727 inline float WaveformSawtooth(float x, float Base, float Amplitude, float Frequency, float Phase)
01728 {
01729 return Base + frac((x + Phase) * Frequency) * Amplitude;
01730 }
01731 inline float WaveformSawtooth(float x)
01732 {
01733 return frac(x);
01734 }
01735
01737 inline float WaveformInvSawtooth(float x, float Base, float Amplitude, float Frequency, float Phase)
01738 {
01739 return Base + (1.0f - frac((x + Phase) * Frequency)) * Amplitude;
01740 }
01741 inline float WaveformInvSawtooth(float x)
01742 {
01743 return 1.0f - frac(x);
01744 }
01745
01747
01749 inline float WaveformPWM(float x, float DutyCycle, float Base, float Amplitude, float Frequency, float Phase)
01750 {
01751 return Base + (frac((x + Phase) * Frequency) <= DutyCycle ? 1.0f : 0.0f) * Amplitude;
01752 }
01753 inline float WaveformPWM(float x, float DutyCycle)
01754 {
01755 return (frac(x) <= DutyCycle ? 1.0f : 0.0f);
01756 }
01757
01759
01760
01761
01762
01768
01770 class RandomGenerator
01771 {
01772 private:
01773
01774 uint4 m_Seed;
01775
01776 public:
01778 RandomGenerator();
01780 RandomGenerator(uint4 seed) : m_Seed(seed) { }
01781
01783 void Seed(uint4 a_Seed)
01784 {
01785 m_Seed = a_Seed;
01786 }
01787
01789
01790 uint4 RandUint()
01791 {
01792 return ( m_Seed = (m_Seed * 196314165 + 907633515) );
01793 }
01795
01796 uint4 RandUint(uint4 max)
01797 {
01798 return RandUint() % max;
01799 }
01801 uint4 RandUint(uint4 min, uint4 max)
01802 {
01803 return RandUint() % (max-min) + min;
01804 }
01805
01807
01808 uint1 RandByte()
01809 {
01810 uint4 u = RandUint();
01811 return (u >> 13) ^ u;
01812 }
01813
01815
01816 float RandFloat()
01817 {
01818 return absolute_cast<float>(RandUint() & 0x007FFFFF | 0x3F800000) - 1.0f;
01819 }
01821 float RandFloat(float max)
01822 {
01823 return RandFloat() * max;
01824 }
01826 float RandFloat(float min, float max)
01827 {
01828 return RandFloat() * (max - min) + min;
01829 }
01830
01832 bool RandBool()
01833 {
01834 return (RandUint() >= 0x7FFFFFFF);
01835 }
01836
01838 int RandInt(int Min, int Max)
01839 {
01840 if (Max > Min)
01841 return static_cast<int>(RandUint(Max-Min)) + Min;
01842 else
01843 return static_cast<int>(RandUint(Min-Max)) + Max;
01844 }
01845
01847
01848 void RandData(void *OutData, size_t DataLength);
01849
01851
01855 float RandNormal(float sigma);
01856 };
01857
01859 extern RandomGenerator g_Rand;
01860
01862 class UniqueGenerator
01863 {
01864 private:
01865 uint4 m_Next;
01866
01867 public:
01869 UniqueGenerator();
01871 UniqueGenerator(uint4 First);
01872
01874 uint4 GetUint() { return m_Next++; }
01876 void GetString(tstring *Out);
01877 tstring GetString() { tstring R; GetString(&R); return R; }
01879 void GetString(tstring *Out, const tstring &Prefix);
01881 tstring GetString(const tstring &Prefix) { tstring R; GetString(&R, Prefix); return R; }
01882 };
01883
01885 extern UniqueGenerator g_Unique;
01886
01888
01890
01891
01892
01893
01894
01895
01897 class CmdLineParser_pimpl;
01898
01900 class CmdLineParser
01901 {
01902 private:
01903 scoped_ptr<CmdLineParser_pimpl> pimpl;
01904
01905 public:
01907 enum RESULT
01908 {
01909 RESULT_OPT,
01910 RESULT_PARAMETER,
01911 RESULT_END,
01912 RESULT_ERROR,
01913 };
01914
01916 CmdLineParser(int argc, tchar **argv);
01918 CmdLineParser(const tchar *CmdLine);
01919
01920 ~CmdLineParser();
01921
01923
01924 void RegisterOpt(uint Id, tchar Opt, bool Parameter);
01926
01927 void RegisterOpt(uint Id, const tstring &Opt, bool Parameter);
01928
01930 RESULT ReadNext();
01931
01933
01934 uint GetOptId();
01936
01937 const tstring & GetParameter();
01938 };
01939
01941
01942
01943 }
01944
01945
01946
01950
01951 template <typename T>
01952 struct SthToStr_obj
01953 {
01954 void operator () (tstring *Str, const T &Sth)
01955 {
01956
01957 assert(0 && "SthToStr: Unsupported type.");
01958
01959
01960 #ifdef WIN32
01961 int y = UnsupportedTypeInSthToStr;
01962 #endif
01963 }
01964 static inline bool IsSupported() { return false; }
01965 };
01966
01967 template <typename T>
01968 inline void SthToStr(tstring *Str, const T &Sth)
01969 {
01970 SthToStr_obj<T>()(Str, Sth);
01971 }
01972
01973 template <typename T>
01974 struct StrToSth_obj
01975 {
01976 bool operator () (const tstring &Str, T *Sth)
01977 {
01978
01979 assert(0 && "StrToSth: Unsupported type.");
01980
01981
01982 #ifdef WIN32
01983 int y = UnsupportedTypeInSthToStr;
01984 #endif
01985 return false;
01986 }
01987 static inline bool IsSupported() { return false; }
01988 };
01989
01990 template <typename T>
01991 inline bool StrToSth(T *Sth, const tstring &Str)
01992 {
01993 return StrToSth_obj<T>()(Sth, Str);
01994 }
01995
01997
01998 namespace common
01999 {
02000
02003
02005 class Format_pimpl
02006 {
02007 friend class Format;
02008
02009 private:
02010 tstring m_String;
02011 char m_Sep;
02012 size_t m_Index;
02013
02014 Format_pimpl(const tstring &Fmt, char Sep) : m_String(Fmt), m_Sep(Sep), m_Index(0) { }
02015 };
02016
02018
02025 class Format
02026 {
02027 private:
02028 shared_ptr<Format_pimpl> pimpl;
02029
02030 public:
02031 Format(const tstring &Fmt, char Sep = '#') : pimpl(new Format_pimpl(Fmt, Sep)) { }
02033
02039 Format(const Format &f, const tstring &Element);
02041 Format(const Format &f, const tchar *Element);
02042
02043 operator tstring () const { return pimpl->m_String; }
02045 tstring str() const { return pimpl->m_String; }
02046 };
02047
02048 template <typename T>
02049 const Format operator % (const Format &fmt, const T &x)
02050 {
02051 tstring s;
02052 SthToStr<T>(&s, x);
02053 return Format(fmt, s);
02054 }
02055
02056 inline const Format operator % (const Format &fmt, const tchar *x)
02057 {
02058 return Format(fmt, x);
02059 }
02060
02062
02063 }
02064
02065
02068
02069
02070
02071
02072 template <>
02073 struct SthToStr_obj<bool>
02074 {
02075 void operator () (tstring *Str, const bool &Sth)
02076 {
02077 common::BoolToStr(Str, Sth, 'f');
02078 }
02079 static inline bool IsSupported() { return true; }
02080 };
02081
02082 template <>
02083 struct SthToStr_obj<tchar>
02084 {
02085 void operator () (tstring *Str, const tchar &Sth)
02086 {
02087 common::CharToStr(Str, Sth);
02088 }
02089 static inline bool IsSupported() { return true; }
02090 };
02091
02092 template <>
02093 struct SthToStr_obj<int2>
02094 {
02095 void operator () (tstring *Str, const int2 &Sth)
02096 {
02097 common::IntToStr<int2>(Str, Sth);
02098 }
02099 static inline bool IsSupported() { return true; }
02100 };
02101
02102 template <>
02103 struct SthToStr_obj<int4>
02104 {
02105 void operator () (tstring *Str, const int4 &Sth)
02106 {
02107 common::IntToStr<int4>(Str, Sth);
02108 }
02109 static inline bool IsSupported() { return true; }
02110 };
02111 template <>
02112 struct SthToStr_obj<long>
02113 {
02114 void operator () (tstring *Str, const long &Sth)
02115 {
02116 common::IntToStr<int4>(Str, Sth);
02117 }
02118 static inline bool IsSupported() { return true; }
02119 };
02120
02121 template <>
02122 struct SthToStr_obj<int8>
02123 {
02124 void operator () (tstring *Str, const int8 &Sth)
02125 {
02126 common::IntToStr<int8>(Str, Sth);
02127 }
02128 static inline bool IsSupported() { return true; }
02129 };
02130
02131 template <>
02132 struct SthToStr_obj<uint1>
02133 {
02134 void operator () (tstring *Str, const uint1 &Sth)
02135 {
02136 common::UintToStr<uint1>(Str, Sth);
02137 }
02138 static inline bool IsSupported() { return true; }
02139 };
02140
02141 template <>
02142 struct SthToStr_obj<uint2>
02143 {
02144 void operator () (tstring *Str, const uint2 &Sth)
02145 {
02146 common::UintToStr<uint2>(Str, Sth);
02147 }
02148 static inline bool IsSupported() { return true; }
02149 };
02150
02151 template <>
02152 struct SthToStr_obj<uint4>
02153 {
02154 void operator () (tstring *Str, const uint4 &Sth)
02155 {
02156 common::UintToStr<uint4>(Str, Sth);
02157 }
02158 static inline bool IsSupported() { return true; }
02159 };
02160 template <>
02161 struct SthToStr_obj<unsigned long>
02162 {
02163 void operator () (tstring *Str, const unsigned long &Sth)
02164 {
02165 common::UintToStr<uint4>(Str, (uint4)Sth);
02166 }
02167 static inline bool IsSupported() { return true; }
02168 };
02169
02170 template <>
02171 struct SthToStr_obj<uint8>
02172 {
02173 void operator () (tstring *Str, const uint8 &Sth)
02174 {
02175 common::UintToStr<uint8>(Str, Sth);
02176 }
02177 static inline bool IsSupported() { return true; }
02178 };
02179
02180 template <>
02181 struct SthToStr_obj<float>
02182 {
02183 void operator () (tstring *Str, const float &Sth)
02184 {
02185 common::FloatToStr(Str, Sth);
02186 }
02187 static inline bool IsSupported() { return true; }
02188 };
02189
02190 template <>
02191 struct SthToStr_obj<double>
02192 {
02193 void operator () (tstring *Str, const double &Sth)
02194 {
02195 common::DoubleToStr(Str, Sth);
02196 }
02197 static inline bool IsSupported() { return true; }
02198 };
02199
02200 template <>
02201 struct SthToStr_obj<tstring>
02202 {
02203 void operator () (tstring *Str, const tstring &Sth)
02204 {
02205 *Str = Sth;
02206 }
02207 static inline bool IsSupported() { return true; }
02208 };
02209
02210 template <typename T>
02211 struct SthToStr_obj< std::vector<T> >
02212 {
02213 void operator () (tstring *Str, const std::vector<T> &Sth)
02214 {
02215 Str->clear();
02216 tstring Element;
02217 for (typename std::vector<T>::const_iterator it = Sth.begin(); it != Sth.end(); ++it)
02218 {
02219 if (!Str->empty())
02220 *Str += ',';
02221 SthToStr<T>(&Element, *it);
02222 *Str += Element;
02223 }
02224 }
02225 static inline bool IsSupported() { return true; }
02226 };
02227
02228 template <>
02229 struct SthToStr_obj<char *>
02230 {
02231 void operator () (tstring *Str, tchar *Sth)
02232 {
02233 *Str = Sth;
02234 }
02235 static inline bool IsSupported() { return true; }
02236 };
02237
02238 template <>
02239 struct SthToStr_obj<const tchar *>
02240 {
02241 void operator () (tstring *Str, const tchar *Sth)
02242 {
02243 *Str = Sth;
02244 }
02245 static inline bool IsSupported() { return true; }
02246 };
02247
02248 template <>
02249 struct SthToStr_obj<void *>
02250 {
02251 void operator () (tstring *Str, void *Sth)
02252 {
02253 common::PtrToStr(Str, Sth);
02254 }
02255 static inline bool IsSupported() { return true; }
02256 };
02257
02258 template <>
02259 struct SthToStr_obj<const void *>
02260 {
02261 void operator () (tstring *Str, const void *Sth)
02262 {
02263 common::PtrToStr(Str, Sth);
02264 }
02265 static inline bool IsSupported() { return true; }
02266 };
02267
02268
02269
02270
02271 template <>
02272 struct StrToSth_obj<bool>
02273 {
02274 bool operator () (bool *Sth, const tstring &Str)
02275 {
02276 return common::StrToBool(Sth, Str);
02277 }
02278 static inline bool IsSupported() { return true; }
02279 };
02280
02281 template <>
02282 struct StrToSth_obj<tchar>
02283 {
02284 bool operator () (tchar *Sth, const tstring &Str)
02285 {
02286 if (Str.length() != 1) return false;
02287 *Sth = Str[0];
02288 return true;
02289 }
02290 static inline bool IsSupported() { return true; }
02291 };
02292
02293 template <>
02294 struct StrToSth_obj<int2>
02295 {
02296 bool operator () (int2 *Sth, const tstring &Str)
02297 {
02298 return common::StrToInt<int2>(Sth, Str) == 0;
02299 }
02300 static inline bool IsSupported() { return true; }
02301 };
02302
02303 template <>
02304 struct StrToSth_obj<int4>
02305 {
02306 bool operator () (int4 *Sth, const tstring &Str)
02307 {
02308 return common::StrToInt<int4>(Sth, Str) == 0;
02309 }
02310 static inline bool IsSupported() { return true; }
02311 };
02312 template <>
02313 struct StrToSth_obj<long>
02314 {
02315 bool operator () (long *Sth, const tstring &Str)
02316 {
02317 return common::StrToInt<int4>((int4*)Sth, Str) == 0;
02318 }
02319 static inline bool IsSupported() { return true; }
02320 };
02321
02322 template <>
02323 struct StrToSth_obj<int8>
02324 {
02325 bool operator () (int8 *Sth, const tstring &Str)
02326 {
02327 return common::StrToInt<int8>(Sth, Str) == 0;
02328 }
02329 static inline bool IsSupported() { return true; }
02330 };
02331
02332 template <>
02333 struct StrToSth_obj<uint1>
02334 {
02335 bool operator () (uint1 *Sth, const tstring &Str)
02336 {
02337 return common::StrToUint<uint1>(Sth, Str) == 0;
02338 }
02339 static inline bool IsSupported() { return true; }
02340 };
02341
02342 template <>
02343 struct StrToSth_obj<uint2>
02344 {
02345 bool operator () (uint2 *Sth, const tstring &Str)
02346 {
02347 return common::StrToUint<uint2>(Sth, Str) == 0;
02348 }
02349 static inline bool IsSupported() { return true; }
02350 };
02351
02352 template <>
02353 struct StrToSth_obj<uint4>
02354 {
02355 bool operator () (uint4 *Sth, const tstring &Str)
02356 {
02357 return common::StrToUint<uint4>(Sth, Str) == 0;
02358 }
02359 static inline bool IsSupported() { return true; }
02360 };
02361 template <>
02362 struct StrToSth_obj<unsigned long>
02363 {
02364 bool operator () (unsigned long *Sth, const tstring &Str)
02365 {
02366 return common::StrToUint<uint4>((uint4*)Sth, Str) == 0;
02367 }
02368 static inline bool IsSupported() { return true; }
02369 };
02370
02371 template <>
02372 struct StrToSth_obj<uint8>
02373 {
02374 bool operator () (uint8 *Sth, const tstring &Str)
02375 {
02376 return common::StrToUint<uint8>(Sth, Str) == 0;
02377 }
02378 static inline bool IsSupported() { return true; }
02379 };
02380
02381 template <>
02382 struct StrToSth_obj<float>
02383 {
02384 bool operator () (float *Sth, const tstring &Str)
02385 {
02386 return common::StrToFloat(Sth, Str) == 0;
02387 }
02388 static inline bool IsSupported() { return true; }
02389 };
02390
02391 template <>
02392 struct StrToSth_obj<double>
02393 {
02394 bool operator () (double *Sth, const tstring &Str)
02395 {
02396 return common::StrToDouble(Sth, Str) == 0;
02397 }
02398 static inline bool IsSupported() { return true; }
02399 };
02400
02401 template <>
02402 struct StrToSth_obj<tstring>
02403 {
02404 bool operator () (tstring *Sth, const tstring &Str)
02405 {
02406 *Sth = Str;
02407 return true;
02408 }
02409 static inline bool IsSupported() { return true; }
02410 };
02411
02412 template <typename T>
02413 struct StrToSth_obj< std::vector<T> >
02414 {
02415 bool operator () (std::vector<T> *Sth, const tstring &Str)
02416 {
02417 Sth->clear();
02418 uint4 Index = 0;
02419 tstring Element;
02420 T Val;
02421 while (common::Split(Str, _T(","), &Element, &Index))
02422 {
02423 if (!StrToSth<T>(&Val, Element)) return false;
02424 Sth->push_back(Val);
02425 }
02426 return true;
02427 }
02428 static inline bool IsSupported() { return true; }
02429 };
02430
02432
02433
02434 #endif