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
00042 #ifndef WIN32
00043 #define __FUNCSIG__ __PRETTY_FUNCTION__
00044 #endif
00045
00046
00047 #ifdef WIN32
00048 #include <tchar.h>
00049 #include <wchar.h>
00051 typedef TCHAR tchar;
00052 #else
00053 #define _T(x) (x)
00054 typedef char tchar;
00055 #endif
00056
00057 #ifdef _UNICODE
00059 typedef std::wstring tstring;
00061 #define TCHAR_TO_INT(c) ( (int)(c) )
00063 #define INT_TO_TCHAR(i) ( (wchar_t)(i) )
00064 #else
00065 typedef std::string tstring;
00066 #define TCHAR_TO_INT(c) ( (int)(uint1)(c) )
00067 #define INT_TO_TCHAR(i) ( (char)(uint1)(i) )
00068 #endif
00069
00071 #define __TFILE__ _T(__FILE__)
00073 #define __TFUNCSIG__ _T(__FUNCSIG__)
00075 #define __TFUNCTION__ _T(__FUNCTION__)
00076
00079 #ifdef WIN32
00081 typedef unsigned __int32 uint;
00083 typedef __int8 int1;
00085 typedef unsigned __int8 uint1;
00087 typedef __int16 int2;
00089 typedef unsigned __int16 uint2;
00091 typedef __int32 int4;
00093 typedef unsigned __int32 uint4;
00095 typedef __int64 int8;
00097 typedef unsigned __int64 uint8;
00098 #else
00099 typedef unsigned int uint;
00100 typedef char int1;
00101 typedef unsigned char uint1;
00102 typedef short int2;
00103 typedef unsigned short uint2;
00104 typedef int int4;
00105 typedef unsigned int uint4;
00106 typedef long long int8;
00107 typedef unsigned long long uint8;
00108 #endif
00109
00110
00111 #ifdef WIN32
00112 #define common_memzero(buf,bufSize) { ZeroMemory(buf,bufSize); }
00113 #else
00114 #define common_memzero(buf,bufSize) { memset(buf,0,bufSize); }
00115 #endif
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 #ifdef _MSC_VER
00127 #define common_sprintf(buf,bufSize,fmt,...) ( _stprintf_s(buf,bufSize,fmt,__VA_ARGS__) )
00128 #define common_memcpy(dst,src,count) { memcpy_s(dst,count,src,count); }
00129 #define common_memmove(dst,src,count) { memmove_s(dst,count,src,count); }
00130 #define common_strcat(dst,dstSize,src) { _tcscat_s(dst,dstSize,src); }
00131 #define common_strncat(dst,dstSize,src,count) { _tcsncat_s(dst,dstSize,src,count); }
00132 #define common_strchr(str,c) ( _tcschr(str,c) )
00133 #define common_strrchr(str,c) ( _tcsrchr(str,c) )
00134 #define common_strcmp(s1,s2) ( _tcscmp(s1,s2) )
00135 #define common_strncmp(s1,s2,count) ( _tcsncmp(s1,s2,count) )
00136 #define common_stricmp(s1,s2) ( _tcsicmp(s1,s2) )
00137 #define common_strnicmp(s1,s2,count) ( _tcsnicmp(s1,s2,count) )
00138 #define common_strcoll(s1,s2) ( _tcscoll(s) )
00139 #define common_strcpy(dst,dstSize,src) { _tcscpy_s(dst,dstSize,src); }
00140 #define common_strncpy(dst,dstSize,src,count) { _tcsncpy(dst,dstSize,src,count); }
00141 #define common_strlen(str) ( _tcslen(str) )
00142 #define common_strspn(str,charset) ( _tcsspn(str,charset) )
00143 #define common_strcspn(str,charset) ( _tcscspn(str,charset) )
00144 #define common_strpbrk(str,charset) ( _tcspbrk(str,charset) )
00145 #define common_strstr(str,strSearch) ( _tcsstr(str,strSearch) )
00146 #define common_strxfrm(dst,str,count) ( _tcsxfrm(dst,str,count) )
00147
00148 #else
00149 #define common_sprintf(buf,bufSize,fmt,...) ( sprintf(buf,fmt,##__VA_ARGS__) )
00150 #define common_memcpy(dst,src,count) { memcpy(dst,src,count); }
00151 #define common_memmove(dst,src,count) { memmove(dst,src,count); }
00152 #define common_strcat(dst,dstSize,src) { strcat(dst,src); }
00153 #define common_strncat(dst,dstSize,src,count) { strncat(dst,src,count); }
00154 #define common_strchr(str,c) ( strchr(str,c) )
00155 #define common_strrchr(str,c) ( strrchr(str,c) )
00156 #define common_strcmp(s1,s2) ( strcmp(s1,s2) )
00157 #define common_strncmp(s1,s2,count) ( strncmp(s1,s2,count) )
00158 #define common_stricmp(s1,s2) ( stricmp(s1,s2) )
00159 #define common_strnicmp(s1,s2,count) ( strnicmp(s1,s2,count) )
00160 #define common_strcoll(s1,s2) ( strcoll(s) )
00161 #define common_strcpy(dst,dstSize,src) { strcpy(dst,src); }
00162 #define common_strncpy(dst,dstSize,src,count) { strncpy(dst,src,count); }
00163 #define common_strlen(str) ( strlen(str) )
00164 #define common_strspn(str,charset) ( strspn(str,charset) )
00165 #define common_strcspn(str,charset) ( strcspn(str,charset) )
00166 #define common_strpbrk(str,charset) ( strpbrk(str,charset) )
00167 #define common_strstr(str,strSearch) ( strstr(str,strSearch) )
00168 #define common_strxfrm(dst,str,count) ( strxfrm(dst,str,count) )
00169
00170 #endif
00171
00173 typedef std::vector<tstring> STRING_VECTOR;
00174
00176 #define SAFE_DELETE(x) { delete (x); (x) = 0; }
00178 #define SAFE_DELARR(x) { delete [] (x); (x) = 0; }
00180 #define SAFE_RELEASE(x) { if (x) { (x)->Release(); (x) = 0; } }
00181
00182 #ifdef WIN32
00184 #define ASSERT_INT3(x) if ((x) == 0) { __asm { int 3 } }
00186 #ifdef _DEBUG
00187 #define ASSERT_INT3_DEBUG(x) if ((x) == 0) { __asm { int 3 } }
00188 #else
00189 #define ASSERT_INT3_DEBUG(x) { }
00190 #endif
00191 #endif
00192
00194
00195 #ifdef _MSC_VER
00196 #define PACKED __declspec(align(1))
00197 #else
00198 #define PACKED __attribute__((packed))
00199 #endif
00200
00202
00203
00204 #define DECLARE_NO_COPY_CLASS(ClassName) \
00205 private: \
00206 ClassName(const ClassName&); \
00207 ClassName& operator=(const ClassName&);
00208
00210 #define STATIC_ASSERT(x) { const char temp[ (((x) == 0) ? 0 : 1) ] = {'\0'}; }
00211
00213 template <typename destT, typename srcT>
00214 destT &absolute_cast(srcT &v)
00215 {
00216 return reinterpret_cast<destT&>(v);
00217 }
00218 template <typename destT, typename srcT>
00219 const destT &absolute_cast(const srcT &v)
00220 {
00221 return reinterpret_cast<const destT&>(v);
00222 }
00223
00224 #define REF_COUNTED_FIELDS \
00225 uint m_RefCount;
00226 #define REF_COUNTED_METHODS \
00227 void AddRef() { m_RefCount++; } \
00228 void Release() { assert(m_RefCount > 0); if (--m_RefCount == 0) delete this; }
00229 #define REF_COUNTED_CTOR \
00230 { m_RefCount = 1; }
00231
00233
00234
00236 namespace common
00237 {
00238
00241
00242
00245
00246 #ifndef _countof
00248 template <typename _CountofType, size_t _SizeOfArray>
00249 char (*__countof_helper(_CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
00251
00252 #define _countof(_Array) sizeof(*__countof_helper(_Array))
00253 #endif
00254
00256 enum ORIENTATION
00257 {
00258 O_NONE,
00259 O_VERT,
00260 O_HORIZ,
00261 };
00262
00264 template <typename T>
00265 T **new_2d(size_t cx, size_t cy)
00266 {
00267 T **a = new T*[cx];
00268 for (size_t x = 0; x < cx; x++)
00269 a[x] = new T[cy];
00270 return a;
00271 }
00272
00274 template <typename T>
00275 void delete_2d(T **a, size_t cx)
00276 {
00277 for (size_t x = 0; x < cx; x++)
00278 delete[] a[x];
00279 delete[] a;
00280 }
00281
00283
00286 inline void strcpy0(tchar* dest, const tstring &src)
00287 {
00288 for (size_t i = 0; i < src.length(); i++)
00289 dest[i] = src[i];
00290 dest[src.length()] = '\0';
00291 }
00292
00294
00307 template <typename T>
00308 class Singleton
00309 {
00310 public:
00312 static T & GetInstance()
00313 {
00314 static T Instance;
00315 return Instance;
00316 }
00317 };
00318
00320 template<class Iterator>
00321 void InsertionSort(Iterator b, Iterator e)
00322 {
00323 if (b == e) return;
00324 for (Iterator j = b + 1; j < e; j++)
00325 {
00326 typename std::iterator_traits<Iterator>::value_type key;
00327 key = *j;
00328 Iterator i = j;
00329 while (i > b && key < *(i-1))
00330 {
00331 *i = *(i-1);
00332 i--;
00333 }
00334 *i = key;
00335 }
00336 }
00337
00339 template<class Iterator, typename Compare>
00340 void InsertionSort(Iterator b, Iterator e, Compare Comp)
00341 {
00342 if (b == e) return;
00343 for (Iterator j = b + 1; j < e; j++)
00344 {
00345 typename std::iterator_traits<Iterator>::value_type key;
00346 key = *j;
00347 Iterator i = j;
00348 while (i > b && Comp(key, *(i-1)))
00349 {
00350 *i = *(i-1);
00351 i--;
00352 }
00353 *i = key;
00354 }
00355 }
00356
00357 template <typename IterT, typename KeyT, typename CmpT>
00358 IterT FirstNotLessIndex(IterT beg, IterT end, const KeyT &key, CmpT cmp)
00359 {
00360 unsigned down=0, up=(end-beg);
00361 while(down<up)
00362 {
00363 unsigned mid=(down+up)/2;
00364 int res=cmp(key,*(beg+mid));
00365 if(res>0)
00366 down=mid+1;
00367 else
00368 up=mid;
00369 }
00370 return beg+down;
00371 }
00372
00374
00378 template <typename IterT, typename KeyT, typename CmpT>
00379 IterT BinarySearch(IterT beg, IterT end, const KeyT &key, CmpT cmp)
00380 {
00381 IterT it = FirstNotLessIndex<IterT, KeyT, CmpT>(beg, end, key, cmp);
00382 if (it == end || cmp(key, *it) != 0)
00383 return end;
00384 return it;
00385 }
00386
00388 inline void SwapEndian16(void *p)
00389 {
00390 uint2 &u = *(uint2*)p;
00391 u = (u << 8) | (u >> 8);
00392 }
00394 inline void SwapEndian32(void *p)
00395 {
00396 uint4 &u = *(uint4*)p;
00397 u = (u << 24) | ((u & 0x0000ff00u) << 8) | ((u & 0x00ff0000u) >> 8) | (u >> 24);
00398 }
00400 inline void SwapEndian64(void *p)
00401 {
00402 uint8 &u = *(uint8*)p;
00403 u = (u << 56) | (u >> 56) |
00404 ((u & 0x000000000000ff00ull) << 40) | ((u & 0x00ff000000000000ull) >> 40) |
00405 ((u & 0x0000000000ff0000ull) << 24) | ((u & 0x0000ff0000000000ull) >> 24) |
00406 ((u & 0x00000000ff000000ull) << 8) | ((u & 0x000000ff00000000ull) >> 8);
00407 }
00408
00409 void SwapEndian16_Array(void *p, uint count);
00410 void SwapEndian32_Array(void *p, uint count);
00411 void SwapEndian64_Array(void *p, uint count);
00412
00413 void SwapEndian16_Data(void *p, uint count, int stepBytes);
00414 void SwapEndian32_Data(void *p, uint count, int stepBytes);
00415 void SwapEndian64_Data(void *p, uint count, int stepBytes);
00416
00417 inline void SwapEndian(bool &v) { }
00418 inline void SwapEndian(uint1 &v) { }
00419 inline void SwapEndian(int1 &v) { }
00420 inline void SwapEndian(uint2 &v) { SwapEndian16(&v); }
00421 inline void SwapEndian(int2 &v) { SwapEndian16(&v); }
00422 inline void SwapEndian(uint4 &v) { SwapEndian32(&v); }
00423 inline void SwapEndian(int4 &v) { SwapEndian32(&v); }
00424 inline void SwapEndian(uint8 &v) { SwapEndian64(&v); }
00425 inline void SwapEndian(int8 &v) { SwapEndian64(&v); }
00426 inline void SwapEndian(float &v) { SwapEndian32(&v); }
00427 inline void SwapEndian(double &v) { SwapEndian64(&v); }
00428
00430
00432 void Wait(uint4 Miliseconds);
00433
00434 template <typename T>
00435 inline int UniversalCmp(const T &a, const T &b)
00436 {
00437 if (a < b) return -1;
00438 if (b < a) return 1;
00439 return 0;
00440 }
00441
00443
00444
00447
00449 class DeletePolicy
00450 {
00451 public:
00452 template <typename T>
00453 static void Destroy(T *p)
00454 {
00455
00456 typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
00457 (void) sizeof(type_must_be_complete);
00458 delete p;
00459 }
00460 };
00462 class DeleteArrayPolicy
00463 {
00464 public:
00465 template <typename T>
00466 static void Destroy(T *p)
00467 {
00468
00469 typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
00470 (void) sizeof(type_must_be_complete);
00471 delete [] p;
00472 }
00473 };
00475 class ReleasePolicy
00476 {
00477 public:
00478 template <typename T>
00479 static void Destroy(T *p)
00480 {
00481 if (p) p->Release();
00482 }
00483 };
00484
00486
00489 template <typename T, typename PolicyT = DeletePolicy>
00490 class scoped_ptr
00491 {
00492 template<typename Y, typename PolicyY> friend class scoped_ptr;
00493
00494 private:
00495 T *m_Ptr;
00496
00497 scoped_ptr(const scoped_ptr &);
00498 scoped_ptr & operator = (const scoped_ptr &);
00499
00500 public:
00501 typedef T value_type;
00502 typedef T *ptr_type;
00503
00504 explicit scoped_ptr(T *p = NULL) : m_Ptr(p) { }
00505 ~scoped_ptr() { PolicyT::template Destroy<T>(m_Ptr); }
00506
00507 T & operator * () const { assert(m_Ptr != NULL); return *m_Ptr; }
00508 T * operator -> () const { assert(m_Ptr != NULL); return m_Ptr; }
00509 T & operator [] (uint i) const { return m_Ptr[i]; }
00510
00511 inline friend bool operator == (const scoped_ptr &lhs, const T *rhs) { return lhs.m_Ptr == rhs; }
00512 inline friend bool operator == (const T *lhs, const scoped_ptr &rhs) { return lhs == rhs.m_Ptr; }
00513 inline friend bool operator != (const scoped_ptr &lhs, const T *rhs) { return lhs.m_Ptr != rhs; }
00514 inline friend bool operator != (const T *lhs, const scoped_ptr &rhs) { return lhs != rhs.m_Ptr; }
00515
00516 T * get() const { return m_Ptr; }
00517 void swap(scoped_ptr<T, PolicyT> &b) { T *tmp = b.m_Ptr; b.m_Ptr = m_Ptr; m_Ptr = tmp; }
00518 void reset(T *p = NULL) { assert(p == NULL || p != m_Ptr); scoped_ptr<T, PolicyT>(p).swap(*this); }
00519 bool is_null() { return m_Ptr == NULL; }
00520 };
00521
00523
00526 template <typename T, typename PolicyT = DeletePolicy>
00527 class shared_ptr
00528 {
00529 template<typename Y, typename PolicyY> friend class shared_ptr;
00530
00531 private:
00532 T *m_Ptr;
00533 unsigned *m_Counter;
00534
00535 public:
00536 typedef T value_type;
00537 typedef T *ptr_type;
00538
00539 explicit shared_ptr(T *p = NULL) : m_Ptr(p), m_Counter(p ? new unsigned(1) : NULL) { }
00540 ~shared_ptr() { if (m_Ptr && --(*m_Counter) == 0) { delete m_Counter; PolicyT::template Destroy<T>(m_Ptr); } }
00541
00542 shared_ptr(const shared_ptr &p) : m_Ptr(p.m_Ptr), m_Counter(p.m_Counter) { if (m_Ptr) (*m_Counter)++; }
00543 shared_ptr & operator = (const shared_ptr &p) { reset<T>(p); return *this; }
00544 template <typename U, typename PolicyU> explicit shared_ptr(const shared_ptr<U, PolicyU> &p) : m_Ptr(p.m_Ptr), m_Counter(p.m_Counter) { if (m_Ptr) (*m_Counter)++; }
00545 template <typename U, typename PolicyU> shared_ptr & operator = (const shared_ptr<U, PolicyU> &p) { reset<U, PolicyU>(p); return *this; }
00546
00547 T & operator * () const { assert(m_Ptr != NULL); return *m_Ptr; }
00548 T * operator -> () const { assert(m_Ptr != NULL); return m_Ptr; }
00549 T & operator [] (uint i) const { return m_Ptr[i]; }
00550
00551 inline friend bool operator == (const shared_ptr &lhs, const T *rhs) { return lhs.m_Ptr == rhs; }
00552 inline friend bool operator == (const T *lhs, const shared_ptr &rhs) { return lhs == rhs.m_Ptr; }
00553 inline friend bool operator != (const shared_ptr &lhs, const T *rhs) { return lhs.m_Ptr != rhs; }
00554 inline friend bool operator != (const T *lhs, const shared_ptr &rhs) { return lhs != rhs.m_Ptr; }
00555 template <typename U, typename PolicyU> bool operator == (const shared_ptr<U, PolicyU> &rhs) const { return m_Ptr == rhs.m_Ptr; }
00556 template <typename U, typename PolicyU> bool operator != (const shared_ptr<U, PolicyU> &rhs) const { return m_Ptr != rhs.m_Ptr; }
00557
00558 T * get() const { return m_Ptr; }
00559 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; }
00560 void reset(T *p = NULL) { if (p == m_Ptr) return; shared_ptr<T, PolicyT>(p).swap(*this); }
00561 template <typename U, typename PolicyU> void reset(const shared_ptr<U, PolicyU> &p) { shared_ptr<U, PolicyU>(p).swap(*this); }
00562 bool unique() const { return m_Counter == NULL || *m_Counter == 1; }
00563 bool is_null() { return m_Ptr == NULL; }
00564 };
00565
00566 #ifdef WIN32
00568 class CloseHandlePolicy { public: template <typename T> static void Destroy(T p) { if (p != NULL) CloseHandle(p); } };
00570 class DeleteObjectPolicy { public: template <typename T> static void Destroy(T p) { if (p != NULL) DeleteObject(p); } };
00571 #endif
00572
00574 template <typename T, typename PolicyT>
00575 class scoped_handle
00576 {
00577 template<typename Y, typename PolicyY> friend class scoped_handle;
00578
00579 private:
00580 T m_Ptr;
00581
00582 scoped_handle(const scoped_handle &);
00583 scoped_handle & operator = (const scoped_handle &);
00584
00585 public:
00586 typedef T value_type;
00587
00588 explicit scoped_handle(T p) : m_Ptr(p) { }
00589 ~scoped_handle() { PolicyT::template Destroy<T>(m_Ptr); }
00590
00591 inline friend bool operator == (const scoped_handle &lhs, const T &rhs) { return lhs.m_Ptr == rhs; }
00592 inline friend bool operator == (const T &lhs, const scoped_handle &rhs) { return lhs == rhs.m_Ptr; }
00593 inline friend bool operator != (const scoped_handle &lhs, const T &rhs) { return lhs.m_Ptr != rhs; }
00594 inline friend bool operator != (const T &lhs, const scoped_handle &rhs) { return lhs != rhs.m_Ptr; }
00595
00596 const T & get() const { return m_Ptr; }
00597 void swap(scoped_handle<T, PolicyT> &b) { T tmp = b.m_Ptr; b.m_Ptr = m_Ptr; m_Ptr = tmp; }
00598 void reset(T p) { scoped_handle<T, PolicyT>(p).swap(*this); }
00599 };
00600
00602 template <typename T, typename PolicyT>
00603 class shared_handle
00604 {
00605 template<typename Y, typename PolicyY> friend class shared_handle;
00606
00607 private:
00608 T m_Ptr;
00609 unsigned *m_Counter;
00610
00611 public:
00612 typedef T value_type;
00613
00614 explicit shared_handle(T p) : m_Ptr(p), m_Counter(new unsigned(1)) { }
00615 ~shared_handle() { if (--(*m_Counter) == 0) { delete m_Counter; PolicyT::template Destroy<T>(m_Ptr); } }
00616
00617 shared_handle(const shared_handle &p) : m_Ptr(p.m_Ptr), m_Counter(p.m_Counter) { (*m_Counter)++; }
00618 shared_handle & operator = (const shared_handle &p) { reset<T>(p); return *this; }
00619 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)++; }
00620 template <typename U, typename PolicyU> shared_handle & operator = (const shared_handle<U, PolicyU> &p) { reset<U, PolicyU>(p); return *this; }
00621
00622 inline friend bool operator == (const shared_handle &lhs, const T &rhs) { return lhs.m_Ptr == rhs; }
00623 inline friend bool operator == (const T &lhs, const shared_handle &rhs) { return lhs == rhs.m_Ptr; }
00624 inline friend bool operator != (const shared_handle &lhs, const T &rhs) { return lhs.m_Ptr != rhs; }
00625 inline friend bool operator != (const T &lhs, const shared_handle &rhs) { return lhs != rhs.m_Ptr; }
00626 template <typename U, typename PolicyU> bool operator == (const shared_handle<U, PolicyU> &rhs) const { return m_Ptr == rhs.m_Ptr; }
00627 template <typename U, typename PolicyU> bool operator != (const shared_handle<U, PolicyU> &rhs) const { return m_Ptr != rhs.m_Ptr; }
00628
00629 const T & get() const { return m_Ptr; }
00630 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; }
00631 void reset(T p) { if (p == m_Ptr) return; shared_handle<T, PolicyT>(p).swap(*this); }
00632 template <typename U, typename PolicyU> void reset(const shared_handle<U, PolicyU> &p) { shared_handle<U, PolicyU>(p).swap(*this); }
00633 bool unique() const { return *m_Counter == 1; }
00634 };
00635
00636 template <typename T, typename PolicyT> void swap(scoped_ptr<T, PolicyT> &a, scoped_ptr<T, PolicyT> &b) { a.swap(b); }
00637 template <typename T, typename PolicyT> void swap(shared_ptr<T, PolicyT> &a, shared_ptr<T, PolicyT> &b) { a.swap(b); }
00638 template <typename T, typename PolicyT> void swap(scoped_handle<T, PolicyT> &a, scoped_handle<T, PolicyT> &b) { a.swap(b); }
00639 template <typename T, typename PolicyT> void swap(shared_handle<T, PolicyT> &a, shared_handle<T, PolicyT> &b) { a.swap(b); }
00640
00642
00643
00644
00650
00654 const int1 MININT1 = std::numeric_limits<int1>::min();
00655 const int1 MAXINT1 = std::numeric_limits<int1>::max();
00656 const int2 MININT2 = std::numeric_limits<int2>::min();
00657 const int2 MAXINT2 = std::numeric_limits<int2>::max();
00658 const int4 MININT4 = std::numeric_limits<int4>::min();
00659 const int4 MAXINT4 = std::numeric_limits<int4>::max();
00660 const int8 MININT8 = std::numeric_limits<int8>::min();
00661 const int8 MAXINT8 = std::numeric_limits<int8>::max();
00662 const uint1 MAXUINT1 = std::numeric_limits<uint1>::max();
00663 const uint2 MAXUINT2 = std::numeric_limits<uint2>::max();
00664 const uint4 MAXUINT4 = std::numeric_limits<uint4>::max();
00665 const uint8 MAXUINT8 = std::numeric_limits<uint8>::max();
00666 const float MINFLOAT = std::numeric_limits<float>::min();
00667 const float MAXFLOAT = std::numeric_limits<float>::max();
00669
00671
00673 #define FLOAT_ALMOST_ZERO(F) ((absolute_cast<uint4>(F) & 0x7f800000L) == 0)
00674
00678 const float E = 2.71828182845904523536f;
00679 const float LOG2E = 1.44269504088896340736f;
00680 const float LOG10E = 0.434294481903251827651f;
00681 const float LN2 = 0.693147180559945309417f;
00682 const float LN10 = 2.30258509299404568402f;
00683 const float PI = 3.14159265358979323846264338327950288419716939937510582f;
00684 const float PI_2 = 1.57079632679489661923f;
00685 const float PI_4 = 0.785398163397448309616f;
00686 const float PI_X_2 = 6.28318530717958647692f;
00687 const float _1_PI = 0.318309886183790671538f;
00688 const float _2_PI = 0.636619772367581343076f;
00689 const float _2_SQRTPI = 1.12837916709551257390f;
00690 const float SQRT2 = 1.41421356237309504880f;
00691 const float SQRT3 = 1.7320508075688772935274463415059f;
00692 const float SQRT1_2 = 0.707106781186547524401f;
00693
00694
00695
00696 #ifdef WIN32
00698 bool is_finite(float x);
00700 bool is_finite(double x);
00702 bool is_nan(float x);
00704 bool is_nan(double x);
00705
00706 #else
00707 inline bool is_finite(float x) { return (finitef(x) != 0); }
00708 inline bool is_finite(double x) { return (finite(x) != 0); }
00709 inline bool is_nan(float x) { return (isnanf(x) != 0); }
00710 inline bool is_nan(double x) { return (isnan(x) != 0); }
00711 #endif
00712
00714
00716 template <typename T>
00717 T safe_add(T a, T b)
00718 {
00719 T R = a + b;
00720 if (R < std::max(a, b)) return std::numeric_limits<T>::max();
00721 else return R;
00722 }
00723
00725
00727 template <typename T>
00728 T safe_sub(T a, T b)
00729 {
00730 if (b > a) return T();
00731 else return a - b;
00732 }
00733
00735
00737 template <typename T>
00738 T safe_mul(T a, T b)
00739 {
00740 if (b == T()) return T();
00741 T R = a * b;
00742 if (R / b != a) return std::numeric_limits<T>::max();
00743 else return R;
00744 }
00745
00747 inline float safe_acos(float x)
00748 {
00749 if (x <= -1.0f) return PI;
00750 if (x >= 1.0f) return 0.0f;
00751 return acosf(x);
00752 }
00753
00755
00756 inline int round(float x)
00757 {
00758 return static_cast<int>(floorf(x+0.5f));
00759 }
00760 inline int round(double x)
00761 {
00762 return static_cast<int>(floor(x+0.5));
00763 }
00764
00766
00770 template <typename T>
00771 inline T ceil_div(T x, T y)
00772 {
00773 return (x+y-1) / y;
00774 }
00775
00777 template <typename T>
00778 inline T AlignUp(T val, T align)
00779 {
00780 return (val + align - 1) / align * align;
00781 }
00783 template <typename T>
00784 inline T AlignDown(T val, T align)
00785 {
00786 return (val / align) * align;
00787 }
00788
00790 template <typename T>
00791 inline T round_div(T x, T y)
00792 {
00793 return (x + (y / 2)) / y;
00794 }
00795
00797 inline bool around(float x, float epsilon)
00798 {
00799 return (fabsf(x) <= epsilon);
00800 }
00801 inline bool around(double x, double epsilon)
00802 {
00803 return (fabs(x) <= epsilon);
00804 }
00805
00807 inline bool around(float x, float y, float epsilon)
00808 {
00809 return (fabsf(x-y) <= epsilon);
00810 }
00811 inline bool around(double x, double y, double epsilon)
00812 {
00813 return (fabs(x-y) <= epsilon);
00814 }
00815
00817
00819 inline bool float_equal(float x, float y)
00820 {
00821 float epsilon = (fabsf(x)+fabsf(y)) * 1e-4f;
00822
00823 return (fabsf(x-y) <= epsilon);
00824 }
00825 inline bool double_equal(double x, double y)
00826 {
00827 double epsilon = (fabs(x)+fabs(y)) * 1e-13;
00828
00829 return (fabs(x-y) <= epsilon);
00830 }
00831
00833
00835 template <typename T> inline T sqr(T v) { return v * v; }
00836
00838
00839 template <typename T> inline T sign(T v) { return (v > 0) - (v < 0); }
00840
00842 template <typename T> inline T MergeBits(T a, T b, T Mask) { return a ^ ((a ^ b) & Mask); }
00843
00845 template <typename T> inline uint CountBitsSet(T v) { uint c; for (c = 0; v; c++) v &= v - 1; return c; }
00846
00847
00848 template<> inline uint CountBitsSet<uint>(unsigned v)
00849 {
00850 uint c;
00851 static const int S[] = {1, 2, 4, 8, 16};
00852 static const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
00853
00854 c = v - ((v >> 1) & B[0]);
00855 c = ((c >> S[1]) & B[1]) + (c & B[1]);
00856 c = ((c >> S[2]) + c) & B[2];
00857 c = ((c >> S[3]) + c) & B[3];
00858 c = ((c >> S[4]) + c) & B[4];
00859 return c;
00860 }
00861
00863 inline uint CalcParity(uint v) {
00864 v ^= v >> 1; v ^= v >> 2; v = (v & 0x11111111U) * 0x11111111U; return (v >> 28) & 1;
00865 }
00867 inline uint8 CalcParity(uint8 v) {
00868 v ^= v >> 1; v ^= v >> 2; v = (v & 0x1111111111111111ULL) * 0x1111111111111111ULL; return (v >> 60) & 1;
00869 }
00870
00872 template <typename T> inline T SwapBitSequences(T v, uint SrcBit, uint DstBit, uint NumBits)
00873 {
00874 int x = ((v >> SrcBit) ^ (v >> DstBit)) & ((1 << NumBits) - 1);
00875 return v ^ ((x << SrcBit) | (x << DstBit));
00876 }
00877
00879
00881 template <typename T> inline bool IsPow2(T x) { return (x & (x-1)) == 0; }
00882
00884
00885 uint4 GetBitMask(uint4 n);
00886
00888
00890 uint log2u(uint v);
00892
00893 uint log10u(uint v);
00894
00896
00898 inline uint next_pow2(uint v) {
00899 v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v;
00900 }
00901
00903 uint InterleaveBits(uint a, uint b);
00904
00905
00906
00907 uint Extend10BitsBy2Zeros(uint n);
00908
00909
00910
00911 uint Extend16BitsBy1Zero(uint n);
00912
00913
00915
00917 template <typename T>
00918 T powi(T a, uint4 b)
00919 {
00920 T r = (T)1;
00921 T p = a;
00922 while (b)
00923 {
00924 if (b & 1)
00925 r *= p;
00926 p *= p;
00927 b >>= 1;
00928 }
00929 return r;
00930 }
00931
00932 template <typename T, typename Predicate>
00933 void Sort2(T &v1, T &v2, Predicate comp)
00934 {
00935 if (comp(v2, v1))
00936 std::swap<T>(v1, v2);
00937 }
00938 template <typename T>
00939 void Sort2(T &v1, T &v2)
00940 {
00941 Sort2(v1, v2, std::less<T>());
00942 }
00943
00944 template <typename T, typename Predicate>
00945 void Sort3(T &v1, T &v2, T &v3, Predicate comp)
00946 {
00947 Sort2<T, Precicate>(v1, v3, comp);
00948 Sort2<T, Precicate>(v1, v2, comp);
00949 Sort2<T, Precicate>(v2, v3, comp);
00950 }
00951 template <typename T>
00952 void Sort3(T &v1, T &v2, T &v3)
00953 {
00954 Sort2<T>(v1, v3);
00955 Sort2<T>(v1, v2);
00956 Sort2<T>(v2, v3);
00957 }
00958
00960 template <typename T>
00961 inline T max3(const T &a, const T &b, const T &c)
00962 {
00963 return std::max(a, std::max(b, c));
00964 }
00965
00967 template <typename T>
00968 inline T min3(const T &a, const T &b, const T &c)
00969 {
00970 return std::min(a, std::min(b, c));
00971 }
00972
00974 template <typename T>
00975 inline T minmax(const T &a, const T &x, const T &b)
00976 {
00977 if (x < a) return a; else if (x > b) return b; else return x;
00978
00979 }
00980 inline float saturate(float x) { return minmax<float>(0.f, x, 1.f); }
00981 inline double saturate(double x) { return minmax<double>(0., x, 1.); }
00982
00984
00985 inline float trunc(float x)
00986 {
00987 return (x < 0.0f) ? ceilf(x) : floorf(x);
00988 }
00989 inline double trunc(double x)
00990 {
00991 return (x < 0.0) ? ceil(x) : floor(x);
00992 }
00993
00995
00996 inline float frac(float x)
00997 {
00998 return x - floorf(x);
00999 }
01000 inline double frac(double x)
01001 {
01002 return x - floor(x);
01003 }
01004
01006 void sincos(float angle, float *sine, float *cosine);
01007
01009 inline float Lerp(float x, float y, float t)
01010 {
01011 return x + t*(y-x);
01012 }
01013 inline void Lerp(float *out, float x, float y, float t)
01014 {
01015 *out = x + t*(y-x);
01016 }
01018 inline float SafeLerp(float x, float y, float t)
01019 {
01020 return Lerp(x, y, minmax(0.0f, t, 1.0f));
01021 }
01022
01024
01025 inline float Lerp2D(float x11, float x21, float x12, float x22, float tx, float ty)
01026 {
01027 return Lerp(Lerp(x11, x21, tx), Lerp(x12, x22, tx), ty);
01028 }
01029
01031 inline float NormalizeAngle(float angle)
01032 {
01033 angle /= PI_X_2;
01034 angle = frac(angle);
01035 if (angle < 0.0f)
01036 angle += 1.0f;
01037 else if (angle >= 1.0f)
01038 angle -= 1.0f;
01039 return angle * PI_X_2;
01040 }
01041
01043 inline float NormalizeAngle2(float Angle)
01044 {
01045 Angle += PI;
01046 Angle -= floorf(Angle * (1.0f/PI_X_2)) * PI_X_2;
01047 Angle -= PI;
01048 return Angle;
01049 }
01050
01052 inline float DegToRad(float Angle)
01053 {
01054
01055 return Angle * 0.017453292519943295769222222222222f;
01056 }
01058 inline float RadToDeg(float Angle)
01059 {
01060
01061 return Angle * 57.295779513082320876846364344191f;
01062 }
01063
01065
01066 inline float AngleDiff(float A, float B)
01067 {
01068 float R1 = B - A;
01069 float R2 = B - PI_X_2 - A;
01070 float R3 = B + PI_X_2 - A;
01071
01072 float R1a = fabsf(R1);
01073 float R2a = fabsf(R2);
01074 float R3a = fabsf(R3);
01075
01076 if (R1a < R2a && R1a < R3a)
01077 return R1;
01078 else if (R2a < R3a)
01079 return R2;
01080 else
01081 return R3;
01082 }
01083
01085 inline float EaseCurve(float x)
01086 {
01087 return x * x * (3.0f - 2.0f * x);
01088 }
01089
01091 inline float EaseCurve2(float x)
01092 {
01093 return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f);
01094 }
01095
01097
01099 inline float smoothstep(float min, float max, float x)
01100 {
01101 if(x <= min) return 0.0f;
01102 if(x >= max) return 1.0f;
01103 x = (x - min) / (max - min);
01104 return x * x * (3.0f - 2.0f * x);
01105 }
01106
01108
01116 void SmoothCD(float *InOutPos, float Dest, float *InOutVel, float SmoothTime, float TimeDelta);
01117 void SmoothCD(float *InOutPos, float Dest, float *InOutVel, float SmoothTime, float TimeDelta, float MaxSpeed);
01118
01120
01129 inline float Trapezoidal(float x, float a, float b, float c, float d)
01130 {
01131 if (x < a)
01132 return 0.f;
01133 else if (x < b)
01134 return (x-a)/(b-a);
01135 else if (x < c)
01136 return 1.f;
01137 else if (x < d)
01138 return 1.f - (x-c)/(d-c);
01139 else
01140 return 0.f;
01141 }
01143 inline float Trapezoidal(float x, float a, float b, float c, float d, float min, float max)
01144 {
01145 return Trapezoidal(x, a, b, c, d) * (max-min) + min;
01146 }
01147
01149
01153 int QuadraticEquation(float a, float b, float c, float *Out_x1, float *Out_x2);
01154
01156
01158 void CalcMeanAndVariance(const float Numbers[], size_t NumberCount, float *OutMean, float *OutVariance = NULL, bool VarianceBiased = true);
01159 void CalcMeanAndVariance(const void *NumberData, size_t NumberCount, int NumberStride, float *OutMean, float *OutVariance = NULL, bool VarianceBiased = true);
01160
01162 uint MurmurHash(const void *Data, uint DataLen, uint Seed);
01163
01165
01169 uint SuperFastHash(const void *DataBytes, size_t DataLen);
01170
01172
01176 inline uint WangMix(uint key)
01177 {
01178 key += ~(key << 15);
01179 key ^= (key >> 10);
01180 key += (key << 3);
01181 key ^= (key >> 6);
01182 key += ~(key << 11);
01183 key ^= (key >> 16);
01184 return key;
01185 }
01186
01188
01195 template <typename T>
01196 class RoundInterpolator
01197 {
01198 public:
01199 struct ITEM
01200 {
01201 float t;
01202 T Value;
01203
01204 ITEM() { }
01205 ITEM(float t, const T &Value) : t(t), Value(Value) { }
01206 };
01207
01208 std::vector<ITEM> Items;
01209
01210 RoundInterpolator() : m_LastUsedIndex(0) { }
01211 void Calc(T *Out, float t) const;
01212
01213 private:
01214 mutable uint m_LastUsedIndex;
01215 };
01216
01217 template <typename T>
01218 void RoundInterpolator<T>::Calc(T *Out, float t) const
01219 {
01220 assert(t >= 0.0f && t <= 1.0f);
01221
01222 if (Items.empty())
01223 {
01224 *Out = T();
01225 return;
01226 }
01227
01228
01229
01230
01231 uint Index = m_LastUsedIndex;
01232
01233 if (Index >= Items.size())
01234 Index = 0;
01235
01236 if (Items[Index].t > t)
01237 Index = 0;
01238
01239
01240 while (Index < Items.size()-1 && Items[Index+1].t < t)
01241 Index++;
01242
01243
01244 m_LastUsedIndex = Index;
01245
01246 if (Index < Items.size()-1)
01247 {
01248 float my_t = (t - Items[Index].t) / (Items[Index+1].t - Items[Index].t);
01249 RoundInterpolatorLerp(Out, Items[Index].Value, Items[Index+1].Value, my_t);
01250 }
01251 else
01252 {
01253 float my_t = (t - Items[Index].t) / (Items[0].t + 1.0f - Items[Index].t);
01254 RoundInterpolatorLerp(Out, Items[Index].Value, Items[0].Value, my_t);
01255 }
01256 }
01257
01266 float PerlinNoise1(float x);
01267 float PerlinNoise2(float x, float y);
01268 float PerlinNoise3(float x, float y, float z);
01269 float BrownianNoise1(float x, uint i, float Persistence);
01270 float BrownianNoise2(float x, float y, uint i, float Persistence);
01271 float BrownianNoise3(float x, float y, float z, uint i, float Persistence);
01273
01280
01281 inline uint MakeDEC3(uint x, uint y, uint z)
01282 {
01283 return (x & 0x03FF) | ((y & 0x03FF) << 10) | ((z & 0x03FF) << 20);
01284 }
01285 inline uint MakeDEC3(uint x, uint y, uint z, uint w)
01286 {
01287 return (x & 0x03FF) | ((y & 0x03FF) << 10) | ((z & 0x03FF) << 20) | ((w & 0x03) << 30);
01288 }
01289 inline uint GetXFromDEC3(uint dec3) { return (dec3 ) & 0x03FF; }
01290 inline uint GetYFromDEC3(uint dec3) { return (dec3 >> 10) & 0x03FF; }
01291 inline uint GetZFromDEC3(uint dec3) { return (dec3 >> 20) & 0x03FF; }
01292 inline uint GetWFromDEC3(uint dec3) { return (dec3 >> 30); }
01293
01295
01297
01298 template <typename T>
01299 bool CalcLinearFactors(
01300 T &outA, T &outB,
01301 float x1, float x2,
01302 const T &y1, const T &y2)
01303 {
01304 float d = x2-x1;
01305 if (FLOAT_ALMOST_ZERO(d))
01306 return false;
01307 outA = (y2 - y1) / d;
01308 outB = (y1*x2 - y2*x1) / d;
01309 return true;
01310 }
01311
01313
01314 template <typename T>
01315 bool CalcQuadraticFactors(
01316 T &outA, T &outB, T &outC,
01317 float x1, float x2, float x3,
01318 const T &y1, const T &y2, const T &y3)
01319 {
01320 float x1_sq = x1 * x1;
01321 float x2_sq = x2 * x2;
01322 float x3_sq = x3 * x3;
01323 float w = x1_sq*(x2-x3) + x2_sq*(x3-x1) + x3_sq*(x1+x2);
01324 if (FLOAT_ALMOST_ZERO(w))
01325 return false;
01326 outA = ( y1*(x2-x3) + y2*(x3-x1) + y3*(x1+x2) ) / w;
01327 outB = ( y1*(x3_sq-x2_sq) + y2*(x1_sq-x3_sq) + y3*(x2_sq-x1_sq) ) / w;
01328 outC = ( y1*(x2_sq*x3-x3_sq*x2) + y2*(x3_sq*x1-x1_sq*x3) + y3*(x1_sq*x1-x2_sq*x1) ) / w;
01329 return true;
01330 }
01331
01333
01334
01335
01338
01340 enum EOLMODE
01341 {
01342 EOL_NONE,
01343 EOL_CRLF,
01344 EOL_LF,
01345 EOL_CR
01346 };
01347
01349 extern const tstring EMPTY_STRING;
01351 extern const tchar * const EOL;
01352
01354 enum CHARSET
01355 {
01356 CHARSET_NONE = 0,
01357 CHARSET_WINDOWS,
01358 CHARSET_ISO,
01359 CHARSET_IBM,
01360 CHARSET_UTF8,
01361 };
01362
01364 bool CharIsAlphaNumeric(tchar ch);
01366 bool CharIsAlpha(tchar ch);
01368 inline bool CharIsDigit(tchar ch) { return (ch >= _T('0') && ch <= _T('9')); }
01370
01371 inline bool CharIsHexDigit(tchar ch) { return (ch >= _T('0') && ch <= _T('9')) || (ch >= _T('A') && ch <= _T('F')) || (ch >= _T('a') && ch <= _T('f')); }
01373 bool CharIsLower(tchar ch);
01375 bool CharIsUpper(tchar ch);
01377
01378 bool CharIsWhitespace(char ch);
01379 #ifdef WIN32
01380 bool CharIsWhitespace(wchar_t ch);
01381 #endif
01383
01389 inline bool CharIsWhitespace_f(tchar ch)
01390 {
01391 return (ch == _T(' ') || ch == _T('\n') || ch == _T('\r') || ch == _T('\t') || ch == _T('\v'));
01392 }
01393
01395
01397 size_t StrStrI(const tstring &Str, const tstring &SubStr, size_t Count = 0xffffffff);
01398 const tchar * StrStrI(const tchar *Str, const tchar *SubStr, size_t Count = 0xffffffff);
01400 void ReverseString(tstring *s);
01402 void Trim(tstring *s);
01404 void Trim(tstring *Out, const tstring &s);
01405
01406
01407
01408
01409
01411
01412 tchar CharToLower(tchar ch);
01414
01415 tchar CharToUpper(tchar ch);
01417
01418 void LowerCase(tstring *s);
01419 inline void LowerCase(tstring *Out, const tstring &s) { *Out = s; LowerCase(Out); }
01421
01422 void UpperCase(tstring *s);
01423 inline void UpperCase(tstring *Out, const tstring &s) { *Out = s; UpperCase(Out); }
01424
01426
01429 bool Charset_WindowsSpecialChar(char a_c, string *a_s);
01431
01433 char Charset_Convert_Char(char a_c, CHARSET a_Charset1, CHARSET a_Charset2);
01435
01436 void Charset_Convert(string *out, const string &s, CHARSET Charset1, CHARSET Charset2);
01437
01439 void Rot13(tstring *InOut);
01440 inline void Rot13(tstring *Out, const tstring &In) { *Out = In; Rot13(Out); }
01441
01443 void EolModeToStr(tstring *Out, EOLMODE EolMode);
01444
01446
01447 void Replace(tstring *result, const tstring &s, const tstring &s1, const tstring &s2);
01449 void Replace(tstring *Out, const tstring &s, tchar Ch1, tchar Ch2);
01451 void Replace(tstring *InOut, tchar Ch1, tchar Ch2);
01452
01454 void ReplaceEOL(tstring *result, const tstring &s, EOLMODE EOLMode);
01455
01457 void NormalizeWhitespace(tstring *result, const tstring &s);
01458
01460 void DuplicateString(tstring *Out, const tstring &s, size_t count);
01461
01463 void RightStr(tstring *Out, const tstring &s, size_t Length);
01464
01466 size_t SubstringCount(const tstring &str, const tstring &substr);
01467
01469
01470 int StrCmpI(const tstring &s1, const tstring &s2, size_t Count = 0xffffffff);
01471 int StrCmpI(const tchar *s1, const tchar *s2, size_t Count = 0xffffffff);
01473 int SubStrCmp(const tstring &s1, size_t off1, const tstring &s2, size_t off2, size_t length);
01475 int SubStrCmpI(const tstring &s1, size_t off1, const tstring &s2, size_t off2, size_t length);
01476
01478 bool ContainsEOL(const tstring &s);
01479
01481 bool StrBegins(const tstring &s, const tstring &sub, size_t Begin = 0);
01483 bool StrBeginsI(const tstring &s, const tstring &sub, size_t Begin = 0);
01485 bool StrEnds(const tstring &s, const tstring &Sub);
01487 bool StrEndsI(const tstring &s, const tstring &Sub);
01488
01490
01492 bool Split(const tstring &s, const tstring &delimiter, tstring *out, size_t *index);
01494 bool SplitFirstOf(const tstring &s, const tstring &delimiters, tstring *out, size_t *index);
01496 void Split(STRING_VECTOR *Out, const tstring &s, const tstring &Delimiter);
01498 bool SplitEOL(const tstring &s, tstring *out, size_t *index);
01500 bool SplitQuery(const tstring &s, tstring *out, size_t *index);
01502
01503 bool ValidateWildcard(const tstring &Mask, const tstring &S, bool CaseSensitive = true, size_t MaskOff = 0, size_t SOff = 0);
01505
01512 float FineSearch(const tstring &SubStr, const tstring &Str);
01514
01516 size_t LevenshteinDistance(const tstring &s1, const tstring &s2);
01518
01520 size_t LevenshteinDistanceI(const tstring &s1, const tstring &s2);
01521
01525
01527 class StringNaturalCompare
01528 {
01529 private:
01530 bool m_CaseInsensitive;
01531
01532 int CompareNumbers(const tstring &s1, size_t i1, const tstring &s2, size_t i2);
01533
01534 public:
01535 StringNaturalCompare(bool CaseInsensitive) : m_CaseInsensitive(CaseInsensitive) { }
01536 int Compare(const tstring &s1, const tstring &s2);
01537 };
01538
01540
01546 class StringNaturalLess : public StringNaturalCompare
01547 {
01548 public:
01549 StringNaturalLess(bool CaseInsensitive = true) : StringNaturalCompare(CaseInsensitive) { }
01550 bool operator () (const tstring &s1, const tstring &s2) { return (Compare(s1, s2) < 0); }
01551 };
01552
01554 class StringNaturalGreater : public StringNaturalCompare
01555 {
01556 public:
01557 StringNaturalGreater(bool CaseInsensitive = true) : StringNaturalCompare(CaseInsensitive) { }
01558 bool operator () (const tstring &s1, const tstring &s2) { return (Compare(s1, s2) > 0); }
01559 };
01560
01562
01564 class StrLessI
01565 {
01566 public:
01567 bool operator () (const tstring &s1, const tstring &s2) { return StrCmpI(s1, s2) < 0; }
01568 };
01570 class StrGreaterI
01571 {
01572 public:
01573 bool operator () (const tstring &s1, const tstring &s2) { return StrCmpI(s1, s2) > 0; }
01574 };
01575
01578
01580 inline bool StrIsEmpty(const char *s) { return s == NULL || *s == '\0'; }
01582 inline void ClearStr(char *s) { assert(s); *s = '\0'; }
01583
01584 #ifdef WIN32
01585 inline bool StrIsEmpty(const wchar_t *s) { return s == NULL || *s == L'\0'; }
01586 inline void ClearStr(wchar_t *s) { assert(s); *s = L'\0'; }
01587 #endif
01588
01590
01592 const tchar * strnistr(const tchar *str, const tchar *substr, size_t count = MAXUINT4);
01593
01594 bool StrBegins(const tchar *str, const tchar *substr, bool caseSensitive);
01596 bool StrEnds(const tchar *str, const tchar *substr, bool caseSensitive);
01598 void StrErase(tchar *str, size_t off, size_t count = MAXUINT4);
01600 void StrInsert(tchar *str, size_t strCapacity, const tchar *newStr, size_t off, size_t count);
01601 void StrInsert(tchar *str, size_t strCapacity, const tchar *newStr, size_t off);
01603 void Trim(tchar *s);
01605 unsigned StrReplace(tchar *str, tchar from, tchar to);
01606
01608
01609
01610
01614
01615 #ifdef WIN32
01616
01628
01629 bool ConvertUnicodeToChars(string *Out, const wstring &S, unsigned CodePage);
01630 bool ConvertUnicodeToChars(string *Out, const wchar_t *S, unsigned NumChars, unsigned CodePage);
01631
01632 bool ConvertCharsToUnicode(wstring *Out, const string &S, unsigned CodePage);
01633 bool ConvertCharsToUnicode(wstring *Out, const char *S, unsigned NumChars, unsigned CodePage);
01634
01636
01637 bool UnicodeToChars_CalcBufLen(size_t &outLen, const wchar_t *wcs, unsigned CodePage);
01638 bool UnicodeToChars_CalcBufLen(size_t &outLen, const wchar_t *wcs, size_t wcsLen, unsigned CodePage);
01639 bool CharsToUnicode_CalcBufLen(size_t &outLen, const char *str, unsigned CodePage);
01640 bool CharsToUnicode_CalcBufLen(size_t &outLen, const char *str, size_t strLen, unsigned CodePage);
01641
01643
01644 bool ConvertUnicodeToChars(char *outBuf, size_t bufLen, const wchar_t *wcs, unsigned CodePage);
01645 bool ConvertUnicodeToChars(char *outBuf, size_t bufLen, const wchar_t *wcs, size_t wcsLen, unsigned CodePage);
01646 bool ConvertCharsToUnicode(wchar_t *outBuf, size_t bufLen, const char *str, unsigned CodePage);
01647 bool ConvertCharsToUnicode(wchar_t *outBuf, size_t bufLen, const char *str, size_t strLen, unsigned CodePage);
01648
01650
01655 extern const char * const BOM_UTF8;
01656 extern const char * const BOM_UTF16_LE;
01657 extern const char * const BOM_UTF16_BE;
01659
01660 #endif
01661
01665 #ifdef _UNICODE
01666 bool TstringToString(string *Out, const tstring &S);
01667 bool StringToTstring(tstring *Out, const string &S);
01668 inline bool TstringToWstring(wstring *Out, const tstring &S) { *Out = S; return true; }
01669 inline bool WstringToTstring(tstring *Out, const wstring &S) { *Out = S; return true; }
01670
01671 inline string TstringToStringR(const tstring &S) { string R; if (!TstringToString(&R, S)) return string(); return R; }
01672 inline tstring StringToTstringR(const string &S) { tstring R; if (!StringToTstring(&R, S)) return tstring(); return R; }
01673 inline wstring TstringToWstring(const tstring &S) { return S; }
01674 inline tstring WstringToTstring(const wstring &S) { return S; }
01675 #else
01676 inline bool TstringToString(string *Out, const tstring &S) { *Out = S; return true; }
01677 inline bool StringToTstring(tstring *Out, const string &S) { *Out = S; return true; }
01678 inline string TstringToStringR(const tstring &S) { return S; }
01679 inline tstring StringToTstringR(const string &S) { return S; }
01680 #ifdef WIN32
01681 bool TstringToWstring(wstring *Out, const tstring &S);
01682 bool WstringToTstring(tstring *Out, const wstring &S);
01683 inline wstring TstringToWstringR(const tstring &S) { wstring R; if (!TstringToWstring(&R, S)) return wstring(); return R; }
01684 inline tstring WstringToTstringR(const wstring &S) { tstring R; if (!WstringToTstring(&R, S)) return tstring(); return R; }
01685 #endif
01686 #endif
01687
01688
01689
01691
01692
01694
01695
01696
01699
01700 #ifdef WIN32
01702 const tchar DIR_SEP = _T('\\');
01703 #else
01704 const tchar DIR_SEP = _T('/');
01705 #endif
01706
01708 bool PathIsAbsolute(const tstring &s);
01710 void IncludeTrailingPathDelimiter(tstring *InOutPath);
01712 void IncludeTrailingPathDelimiter(tstring *OutPath, const tstring &InPath);
01714 void ExcludeTrailingPathDelimiter(tstring *InOutPath);
01716 void ExcludeTrailingPathDelimiter(tstring *OutPath, const tstring &InPath);
01718
01719 void ExtractPathPrefix(tstring *OutPrefix, const tstring &s);
01721 void ExtractFilePath(tstring *OutPath, const tstring &s);
01723 void ExtractFileName(tstring *OutFileName, const tstring &s);
01725 void ExtractFileExt(tstring *OutExt, const tstring &s);
01727
01729 void ChangeFileExt(tstring *Out, const tstring &FileName, const tstring &Ext);
01731
01732 void NormalizePath(tstring *OutPath, const tstring &s);
01734
01735 void RelativeToAbsolutePath(tstring *Out, const tstring &Base, const tstring &Path);
01737
01739 void AbsoluteToRelativePath(tstring *Out, const tstring &Base, const tstring &Target);
01740
01742
01743
01744
01745
01755
01757 extern const tchar _DIGITS_L[];
01759 extern const tchar _DIGITS_U[];
01760
01762
01765 inline int HexDigitToNumber(char Ch)
01766 {
01767 if (Ch >= '0' && Ch <= '9') return (int)(uint1)(Ch - '0');
01768 else if (Ch >= 'A' && Ch <= 'F') return (int)(uint1)(Ch - ('A' - 10));
01769 else if (Ch >= 'a' && Ch <= 'f') return (int)(uint1)(Ch - ('a' - 10));
01770 else return 0xFF;
01771 }
01772 #ifdef WIN32
01773 inline int HexDigitToNumber(wchar_t Ch)
01774 {
01775 if (Ch >= L'0' && Ch <= L'9') return (int)(Ch - L'0');
01776 else if (Ch >= L'A' && Ch <= L'F') return (int)(Ch - (L'A' - 10));
01777 else if (Ch >= L'a' && Ch <= L'f') return (int)(Ch - (L'a' - 10));
01778 else return 0xFF;
01779 }
01780 #endif
01781
01783
01784 template <typename T>
01785 void UintToStr(tstring *Out, T x, uint4 Base = 10, bool UpperCase = true)
01786 {
01787 if (x == 0)
01788 {
01789 Out->assign(_T("0"));
01790 return;
01791 }
01792
01793 Out->clear();
01794 Out->reserve(8);
01795
01796
01797 if (IsPow2<uint4>(Base))
01798 {
01799
01800 uint4 Bits = log2u(Base);
01801
01802 uint4 BitMask = GetBitMask(Bits);
01803
01804 if (UpperCase)
01805 {
01806 while (x != 0)
01807 {
01808 *Out += _DIGITS_U[x & BitMask];
01809 x = x >> Bits;
01810 }
01811 }
01812 else
01813 {
01814 while (x != 0)
01815 {
01816 *Out += _DIGITS_L[x & BitMask];
01817 x = x >> Bits;
01818 }
01819 }
01820 }
01821
01822 else
01823 {
01824 if (UpperCase)
01825 {
01826 while (x != 0)
01827 {
01828 *Out += _DIGITS_U[x % Base];
01829 x /= Base;
01830 }
01831 }
01832 else
01833 {
01834 while (x != 0)
01835 {
01836 *Out += _DIGITS_L[x % Base];
01837 x /= Base;
01838 }
01839 }
01840 }
01841
01842 ReverseString(Out);
01843 }
01844
01845 template <typename T>
01846 void IntToStr(tstring *Out, T x, uint4 Base = 10, bool UpperCase = true)
01847 {
01848 if (x == 0)
01849 {
01850 Out->assign(_T("0"));
01851 return;
01852 }
01853
01854 Out->clear();
01855 Out->reserve(8);
01856
01857
01858 if (x > 0)
01859 {
01860
01861 if (IsPow2<uint4>(Base))
01862 {
01863
01864 uint4 Bits = log2u(Base);
01865
01866 uint4 BitMask = GetBitMask(Bits);
01867
01868 if (UpperCase)
01869 {
01870 while (x != 0)
01871 {
01872 *Out += _DIGITS_U[x & BitMask];
01873 x = x >> Bits;
01874 }
01875 }
01876 else
01877 {
01878 while (x != 0)
01879 {
01880 *Out += _DIGITS_L[x & BitMask];
01881 x = x >> Bits;
01882 }
01883 }
01884 }
01885
01886 else
01887 {
01888 if (UpperCase)
01889 {
01890 while (x != 0)
01891 {
01892 *Out += _DIGITS_U[x % Base];
01893 x /= Base;
01894 }
01895 }
01896 else
01897 {
01898 while (x != 0)
01899 {
01900 *Out += _DIGITS_L[x % Base];
01901 x /= Base;
01902 }
01903 }
01904 }
01905 }
01906
01907
01908 else
01909 {
01910 T x_div_base;
01911 if (UpperCase)
01912 {
01913 while (x != 0)
01914 {
01915 x_div_base = x/(T)Base;
01916 *Out += _DIGITS_U[- (x - x_div_base*(T)Base)];
01917 x = x_div_base;
01918 }
01919 }
01920 else
01921 {
01922 while (x != 0)
01923 {
01924 x_div_base = x/(T)Base;
01925 *Out += _DIGITS_L[- (x - x_div_base*(T)Base)];
01926 x = x_div_base;
01927 }
01928 }
01929 *Out += '-';
01930 }
01931
01932 ReverseString(Out);
01933 }
01934
01936
01937 template <typename T>
01938 bool _CharToDigit(T *Digit, tchar ch)
01939 {
01940 if (ch >= _T('0') && ch <= _T('9'))
01941 *Digit = static_cast<T>(ch-_T('0'));
01942 else if (ch >= _T('A') && ch <= _T('Z'))
01943 *Digit = static_cast<T>(ch-_T('A')+10);
01944 else if (ch >= _T('a') && ch <= _T('z'))
01945 *Digit = static_cast<T>(ch-_T('a')+10);
01946 else
01947 return false;
01948 return true;
01949 }
01950
01952
01956 template <typename T>
01957 int StrToUint(T *Number, const tstring &str, unsigned Base = 10)
01958 {
01959 T BaseT = static_cast<T>(Base);
01960 if (str.empty()) return -1;
01961 *Number = 0;
01962 T Digit, LastNumber = 0, Limit = std::numeric_limits<T>::max()/BaseT;
01963 for (size_t i = 0; i < str.length(); ++i) {
01964 if (!_CharToDigit(&Digit, str[i])) return -1;
01965 if (Digit >= BaseT) return -1;
01966 if (*Number > Limit) return -2;
01967 *Number = *Number * BaseT + Digit;
01968 if (*Number < LastNumber) return -2;
01969 LastNumber = *Number;
01970 }
01971 return 0;
01972 }
01973
01974 template <typename T>
01975 int StrToInt(T *Number, const tstring &str, unsigned Base = 10)
01976 {
01977 T BaseT = static_cast<T>(Base);
01978 if (str.empty()) return -1;
01979 *Number = 0;
01980 size_t i = 0;
01981 int Sign = +1;
01982 if (str[0] == '+') i = 1;
01983 else if (str[0] == '-') { Sign = -1; i = 1; }
01984 T Digit, LastNumber = 0, Limit;
01985 if (Sign > 0) Limit = std::numeric_limits<T>::max()/BaseT;
01986 else Limit = std::numeric_limits<T>::min()/BaseT;
01987 for (; i < str.length(); ++i) {
01988 if (!_CharToDigit(&Digit, str[i])) return -1;
01989 if (Digit >= BaseT) return -1;
01990 if (Sign > 0) { if (*Number > Limit) return -2; }
01991 else { if (*Number < Limit) return -2; }
01992 *Number = *Number * BaseT + Digit * Sign;
01993 if (Sign > 0) { if (*Number < LastNumber) return -2; }
01994 else { if (*Number > LastNumber) return -2; }
01995 LastNumber = *Number;
01996 }
01997 return 0;
01998 }
01999
02000 template <typename T> inline tstring IntToStrR (T x, int base = 10, bool UpperCase = true) { tstring r; IntToStr<T> (&r, x, base, UpperCase); return r; }
02001 template <typename T> inline tstring UintToStrR(T x, int base = 10, bool UpperCase = true) { tstring r; UintToStr<T>(&r, x, base, UpperCase); return r; }
02002
02003 inline void Size_tToStr(tstring *Out, size_t x, size_t Base = 10, bool UpperCase = true) { UintToStr(Out, (uint4)x, Base, UpperCase); }
02004 inline tstring Size_tToStrR(size_t x, size_t Base = 10, bool UpperCase = true) { tstring R; Size_tToStr(&R, x, Base, UpperCase); return R; }
02005
02007
02008 template <typename T>
02009 void UintToStr2(tstring *Out, T x, unsigned Length, int base = 10)
02010 {
02011 tstring Tmp;
02012 UintToStr(&Tmp, x, base);
02013 if (Tmp.length() >= Length)
02014 *Out = Tmp;
02015 else
02016 {
02017 Out->clear();
02018 Out->reserve(std::max(Tmp.length(), Length));
02019 for (size_t Left = Length - Tmp.length(); Left > 0; Left--)
02020 *Out += _T('0');
02021 *Out += Tmp;
02022 }
02023 }
02024 template <typename T>
02025 void IntToStr2(tstring *Out, T x, unsigned Length, int base = 10)
02026 {
02027 tstring Tmp;
02028 IntToStr<T>(&Tmp, x, base);
02029 if (Tmp.length() >= Length)
02030 *Out = Tmp;
02031 else
02032 {
02033 Out->clear();
02034 Out->reserve(std::max(Tmp.length(), Length));
02035 assert(!Tmp.empty());
02036 if (Tmp[0] == _T('-'))
02037 {
02038 *Out += _T('-');
02039 for (size_t Left = Length - Tmp.length(); Left > 0; Left--)
02040 *Out += _T('0');
02041 Out->append(Tmp.begin()+1, Tmp.end());
02042 }
02043 else
02044 {
02045 for (size_t Left = Length - Tmp.length(); Left > 0; Left--)
02046 *Out += _T('0');
02047 *Out += Tmp;
02048 }
02049 }
02050 }
02051
02052 template <typename T> tstring UintToStr2R(T x, unsigned Length, int Base = 10) { tstring R; UintToStr2<T>(&R, x, Length, Base); return R; }
02053 template <typename T> tstring IntToStr2R (T x, unsigned Length, int Base = 10) { tstring R; IntToStr2<T> (&R, x, Length, Base); return R; }
02054
02056 inline void CharToStr(tstring *Out, tchar ch) { Out->clear(); *Out += ch; }
02057 inline tstring CharToStrR(tchar ch) { tstring s; s += ch; return s; }
02058
02060
02067 void DoubleToStr(tstring *Out, double x, char Mode = 'g', int Precision = 6);
02068 void FloatToStr(tstring *Out, float x, char Mode = 'g', int Precision = 6);
02069
02070 inline tstring DoubleToStrR(double x, char Mode = 'g', int Precision = 6) { tstring R; DoubleToStr(&R, x, Mode, Precision); return R; }
02071 inline tstring FloatToStrR (float x, char Mode = 'g', int Precision = 6) { tstring R; FloatToStr (&R, x, Mode, Precision); return R; }
02072
02074
02077 int StrToDouble(double *out, const tstring &s);
02078 int StrToFloat (float *out, const tstring &s);
02079
02081
02088 void BoolToStr(tstring *Out, bool x, char mode = 'f');
02089 inline tstring BoolToStrR(bool x, char mode = 'f') { tstring R; BoolToStr(&R, x, mode); return R; }
02091
02094 bool StrToBool(bool *result, const tstring &s);
02095
02097 void PtrToStr(tstring *Out, const void* p);
02098 inline tstring PtrToStrR(const void *p) { tstring R; PtrToStr(&R, p); return R; }
02099
02101
02104 template <typename T>
02105 void SizeToStr(tstring *str, T size, bool Space, int Precision)
02106 {
02107 double size2 = (double)size;
02108 if (size2 >= 1024.0*1024.0*1024.0*1024.0)
02109 {
02110 DoubleToStr( str, size2/(1024.0*1024.0*1024.0*1024.0), 'f', Precision );
02111 str->append(Space ? _T(" TB") : _T("TB"));
02112 }
02113 else if (size2 >= 1024.0*1024.0*1024.0)
02114 {
02115 DoubleToStr( str, size2/(1024.0*1024.0*1024.0), 'f', Precision );
02116 str->append(Space ? _T(" GB") : _T("GB"));
02117 }
02118 else if (size2 >= 1024.0*1024.0)
02119 {
02120 DoubleToStr( str, size2/(1024.0*1024.0), 'f', Precision );
02121 str->append(Space ? _T(" MB") : _T("MB"));
02122 }
02123 else if (size2 >= 1024.0)
02124 {
02125 DoubleToStr( str, size2/1024.0, 'f', Precision );
02126 str->append(Space ? _T(" KB") : _T("KB"));
02127 }
02128 else
02129 {
02130 UintToStr( str, size );
02131 str->append(Space ? _T(" B") : _T("B"));
02132 }
02133 }
02134 template <typename T> tstring SizeToStrR(T Size, bool Space, int Precision) { tstring r; SizeToStr<T>(&r, Size, Space, Precision); return r; }
02135
02137
02138
02139
02140
02143
02144
02145
02146
02147
02148
02149
02150
02151
02153 inline float WaveformSine(float x, float Base, float Amplitude, float Frequency, float Phase)
02154 {
02155 return Base + (sinf((x + Phase) * Frequency * PI_X_2)+1.0f)*0.5f * Amplitude;
02156 }
02157 inline float WaveformSine(float x)
02158 {
02159 return (sinf(x * PI_X_2)+1.0f)*0.5f;
02160 }
02161
02163 inline float WaveformTriangle(float x, float Base, float Amplitude, float Frequency, float Phase)
02164 {
02165 float Input = frac((x + Phase) * Frequency);
02166 float Output;
02167 if (Input < 0.25f)
02168 Output = Input * 4.0f;
02169 else if (Input < 0.75f)
02170 Output = 1.0f - ((Input - 0.25f) * 4.0f);
02171 else
02172 Output = ((Input - 0.75f) * 4.0f) - 1.0f;
02173 return Base + (Output+1.0f)*0.5f * Amplitude;
02174 }
02175 inline float WaveformTriangle(float x)
02176 {
02177 float Input = frac(x);
02178 float Output;
02179 if (Input < 0.25f)
02180 Output = Input * 4.0f;
02181 else if (Input < 0.75f)
02182 Output = 1.0f - ((Input - 0.25f) * 4.0f);
02183 else
02184 Output = ((Input - 0.75f) * 4.0f) - 1.0f;
02185 return (Output+1.0f)*0.5f;
02186 }
02187
02189 inline float WaveformSquare(float x, float Base, float Amplitude, float Frequency, float Phase)
02190 {
02191 return Base + (frac((x + Phase) * Frequency) <= 0.5f ? 1.0f : 0.0f) * Amplitude;
02192 }
02193 inline float WaveformSquare(float x)
02194 {
02195 return frac(x) <= 0.5f ? 1.0f : 0.0f;
02196 }
02197
02199 inline float WaveformSawtooth(float x, float Base, float Amplitude, float Frequency, float Phase)
02200 {
02201 return Base + frac((x + Phase) * Frequency) * Amplitude;
02202 }
02203 inline float WaveformSawtooth(float x)
02204 {
02205 return frac(x);
02206 }
02207
02209 inline float WaveformInvSawtooth(float x, float Base, float Amplitude, float Frequency, float Phase)
02210 {
02211 return Base + (1.0f - frac((x + Phase) * Frequency)) * Amplitude;
02212 }
02213 inline float WaveformInvSawtooth(float x)
02214 {
02215 return 1.0f - frac(x);
02216 }
02217
02219
02221 inline float WaveformPWM(float x, float DutyCycle, float Base, float Amplitude, float Frequency, float Phase)
02222 {
02223 return Base + (frac((x + Phase) * Frequency) <= DutyCycle ? 1.0f : 0.0f) * Amplitude;
02224 }
02225 inline float WaveformPWM(float x, float DutyCycle)
02226 {
02227 return (frac(x) <= DutyCycle ? 1.0f : 0.0f);
02228 }
02229
02231
02232
02233
02234
02238
02240
02243 class RandomGenerator
02244 {
02245 private:
02246
02247 uint4 m_Seed;
02248 float m_NextNormalNumber; bool m_NextNormalNumberIs;
02249
02250 public:
02252 RandomGenerator();
02254 RandomGenerator(uint4 seed) : m_Seed(seed), m_NextNormalNumberIs(false) { }
02255
02257 void Seed(uint4 a_Seed)
02258 {
02259 m_Seed = a_Seed;
02260 }
02261
02263
02265 uint4 RandUint_Fast()
02266 {
02267 return ( m_Seed = (m_Seed * 196314165 + 907633515) );
02268 }
02270 uint4 RandUint()
02271 {
02272 return
02273 (RandUint_Fast() & 0xFF000000) |
02274 (RandUint_Fast() & 0xFF000000) >> 8 |
02275 (RandUint_Fast() & 0xFF000000) >> 16 |
02276 (RandUint_Fast() & 0xFF000000) >> 24;
02277 }
02279 uint4 RandUint(uint4 max)
02280 {
02281 return RandUint() % max;
02282 }
02284 uint4 RandUint(uint4 min, uint4 max)
02285 {
02286 return RandUint() % (max-min) + min;
02287 }
02288
02290 uint1 RandByte()
02291 {
02292 return (RandUint_Fast() & 0xFF000000) >> 24;
02293 }
02294
02296
02297 float RandFloat()
02298 {
02299 return absolute_cast<float>(RandUint() & 0x007FFFFF | 0x3F800000) - 1.0f;
02300 }
02302 float RandFloat(float max)
02303 {
02304 return RandFloat() * max;
02305 }
02307 float RandFloat(float min, float max)
02308 {
02309 return RandFloat() * (max - min) + min;
02310 }
02312
02313 float RandFloat2()
02314 {
02315 uint a = (RandUint() & 0x007fffff) | 0x40000000;
02316 return( *((float*)&a) - 3.0f );
02317 }
02318
02320 bool RandBool()
02321 {
02322 return (RandUint() >= 0x7FFFFFFF);
02323 }
02324
02326 int RandInt(int Min, int Max)
02327 {
02328 if (Max > Min)
02329 return static_cast<int>(RandUint(Max-Min)) + Min;
02330 else
02331 return static_cast<int>(RandUint(Min-Max)) + Max;
02332 }
02333
02335
02336 void RandData(void *OutData, size_t DataLength);
02337
02339
02343 float RandNormal(float sigma);
02344 };
02345
02347 extern RandomGenerator g_Rand;
02348
02350
02354 class MersenneTwister
02355 {
02356 public:
02358 MersenneTwister();
02360 MersenneTwister(uint Seed);
02362 MersenneTwister(uint InitKeys[], int KeyCount);
02363
02365 uint NextUint();
02367 int NextInt31();
02369 double NextReal1();
02371 double NextReal2();
02373 double NextReal3();
02375 double NextReal_Res53();
02376
02377 private:
02378 uint m_State[624];
02379 int m_Left;
02380 uint *m_Next;
02381
02382 void Init(uint Seed);
02383 void NextState();
02384 };
02385
02387 class UniqueGenerator
02388 {
02389 private:
02390 uint4 m_Next;
02391
02392 public:
02394 UniqueGenerator();
02396 UniqueGenerator(uint4 First);
02397
02399 uint4 GetUint() { return m_Next++; }
02401 void GetString(tstring *Out);
02402 tstring GetString() { tstring R; GetString(&R); return R; }
02404 void GetString(tstring *Out, const tstring &Prefix);
02406 tstring GetString(const tstring &Prefix) { tstring R; GetString(&R, Prefix); return R; }
02407 };
02408
02410
02411
02412
02413
02414
02416 class CmdLineParser_pimpl;
02417
02419 class CmdLineParser
02420 {
02421 private:
02422 scoped_ptr<CmdLineParser_pimpl> pimpl;
02423
02424 public:
02426 enum RESULT
02427 {
02428 RESULT_OPT,
02429 RESULT_PARAMETER,
02430 RESULT_END,
02431 RESULT_ERROR,
02432 };
02433
02435 CmdLineParser(int argc, tchar **argv);
02437 CmdLineParser(const tchar *CmdLine);
02438
02439 ~CmdLineParser();
02440
02442
02443 void RegisterOpt(uint Id, tchar Opt, bool Parameter);
02445
02446 void RegisterOpt(uint Id, const tstring &Opt, bool Parameter);
02447
02449 RESULT ReadNext();
02450
02452
02453 uint GetOptId();
02455
02456 const tstring & GetParameter();
02457 };
02458
02460 class CommonGUID
02461 {
02462 public:
02463 static const CommonGUID NIL;
02464
02465 static int Cmp(const CommonGUID &v1, const CommonGUID &v2);
02466
02468 CommonGUID() { }
02469 CommonGUID(uint1 v0, uint1 v1, uint1 v2, uint1 v3, uint1 v4, uint1 v5, uint1 v6, uint1 v7, uint1 v8, uint1 v9, uint1 v10, uint1 v11, uint1 v12, uint1 v13, uint1 v14, uint1 v15);
02470
02471 const uint1 * AccessData() const { return Data; }
02472 uint1 * AccessData() { return Data; }
02473
02474 const uint1 & operator [] (uint i) const { return Data[i]; }
02475 uint1 & operator [] (uint i) { return Data[i]; }
02476
02477 bool operator == (const CommonGUID &v) const { return Cmp(*this, v) == 0; }
02478 bool operator != (const CommonGUID &v) const { return Cmp(*this, v) != 0; }
02479 bool operator < (const CommonGUID &v) const { return Cmp(*this, v) < 0; }
02480 bool operator > (const CommonGUID &v) const { return Cmp(*this, v) > 0; }
02481 bool operator <= (const CommonGUID &v) const { return Cmp(*this, v) <= 0; }
02482 bool operator >= (const CommonGUID &v) const { return Cmp(*this, v) >= 0; }
02483
02484 void ToString(tchar *out) const;
02485 void ToString(tstring &out) const;
02486 bool FromString(const tchar *s);
02487 bool FromString(const tstring &s);
02488
02490 void GenerateVersion4();
02491
02492 private:
02494 uint1 Data[16];
02495 };
02496
02498
02499
02500 }
02501
02502
02503
02507
02508 template <typename T>
02509 struct SthToStr_obj
02510 {
02511 void operator () (tstring *Str, const T &Sth)
02512 {
02513
02514 assert(0 && "SthToStr: Unsupported type.");
02515
02516
02517 #ifdef WIN32
02518 int y = UnsupportedTypeInSthToStr;
02519 #endif
02520 }
02521 static inline bool IsSupported() { return false; }
02522 };
02523
02524 template <typename T>
02525 inline void SthToStr(tstring *Str, const T &Sth)
02526 {
02527 SthToStr_obj<T>()(Str, Sth);
02528 }
02529
02530 template <typename T>
02531 struct StrToSth_obj
02532 {
02533 bool operator () (const tstring &Str, T *Sth)
02534 {
02535
02536 assert(0 && "StrToSth: Unsupported type.");
02537
02538
02539 #ifdef WIN32
02540 int y = UnsupportedTypeInSthToStr;
02541 #endif
02542 return false;
02543 }
02544 static inline bool IsSupported() { return false; }
02545 };
02546
02547 template <typename T>
02548 inline bool StrToSth(T *Sth, const tstring &Str)
02549 {
02550 return StrToSth_obj<T>()(Sth, Str);
02551 }
02552
02554
02555 namespace common
02556 {
02557
02560
02562 class Format_pimpl
02563 {
02564 friend class Format;
02565
02566 private:
02567 tstring m_String;
02568 char m_Sep;
02569 size_t m_Index;
02570
02571 Format_pimpl(const tstring &Fmt, char Sep) : m_String(Fmt), m_Sep(Sep), m_Index(0) { }
02572 };
02573
02575
02582 class Format
02583 {
02584 private:
02585 shared_ptr<Format_pimpl> pimpl;
02586
02587 public:
02588 Format(const tstring &Fmt, char Sep = '#') : pimpl(new Format_pimpl(Fmt, Sep)) { }
02590
02596 Format(const Format &f, const tstring &Element);
02598 Format(const Format &f, const tchar *Element);
02599
02600 operator tstring () const { return pimpl->m_String; }
02602 tstring str() const { return pimpl->m_String; }
02603 };
02604
02605 template <typename T>
02606 const Format operator % (const Format &fmt, const T &x)
02607 {
02608 tstring s;
02609 SthToStr<T>(&s, x);
02610 return Format(fmt, s);
02611 }
02612
02613 inline const Format operator % (const Format &fmt, const tchar *x)
02614 {
02615 return Format(fmt, x);
02616 }
02617
02619
02620 }
02621
02622
02625
02626
02627
02628
02629 template <>
02630 struct SthToStr_obj<bool>
02631 {
02632 void operator () (tstring *Str, const bool &Sth)
02633 {
02634 common::BoolToStr(Str, Sth, 'f');
02635 }
02636 static inline bool IsSupported() { return true; }
02637 };
02638
02639 template <>
02640 struct SthToStr_obj<tchar>
02641 {
02642 void operator () (tstring *Str, const tchar &Sth)
02643 {
02644 common::CharToStr(Str, Sth);
02645 }
02646 static inline bool IsSupported() { return true; }
02647 };
02648
02649 template <>
02650 struct SthToStr_obj<int2>
02651 {
02652 void operator () (tstring *Str, const int2 &Sth)
02653 {
02654 common::IntToStr<int2>(Str, Sth);
02655 }
02656 static inline bool IsSupported() { return true; }
02657 };
02658
02659 template <>
02660 struct SthToStr_obj<int4>
02661 {
02662 void operator () (tstring *Str, const int4 &Sth)
02663 {
02664 common::IntToStr<int4>(Str, Sth);
02665 }
02666 static inline bool IsSupported() { return true; }
02667 };
02668 template <>
02669 struct SthToStr_obj<long>
02670 {
02671 void operator () (tstring *Str, const long &Sth)
02672 {
02673 common::IntToStr<int4>(Str, Sth);
02674 }
02675 static inline bool IsSupported() { return true; }
02676 };
02677
02678 template <>
02679 struct SthToStr_obj<int8>
02680 {
02681 void operator () (tstring *Str, const int8 &Sth)
02682 {
02683 common::IntToStr<int8>(Str, Sth);
02684 }
02685 static inline bool IsSupported() { return true; }
02686 };
02687
02688 template <>
02689 struct SthToStr_obj<uint1>
02690 {
02691 void operator () (tstring *Str, const uint1 &Sth)
02692 {
02693 common::UintToStr<uint1>(Str, Sth);
02694 }
02695 static inline bool IsSupported() { return true; }
02696 };
02697
02698 template <>
02699 struct SthToStr_obj<uint2>
02700 {
02701 void operator () (tstring *Str, const uint2 &Sth)
02702 {
02703 common::UintToStr<uint2>(Str, Sth);
02704 }
02705 static inline bool IsSupported() { return true; }
02706 };
02707
02708 template <>
02709 struct SthToStr_obj<uint4>
02710 {
02711 void operator () (tstring *Str, const uint4 &Sth)
02712 {
02713 common::UintToStr<uint4>(Str, Sth);
02714 }
02715 static inline bool IsSupported() { return true; }
02716 };
02717 template <>
02718 struct SthToStr_obj<unsigned long>
02719 {
02720 void operator () (tstring *Str, const unsigned long &Sth)
02721 {
02722 common::UintToStr<uint4>(Str, (uint4)Sth);
02723 }
02724 static inline bool IsSupported() { return true; }
02725 };
02726
02727 template <>
02728 struct SthToStr_obj<uint8>
02729 {
02730 void operator () (tstring *Str, const uint8 &Sth)
02731 {
02732 common::UintToStr<uint8>(Str, Sth);
02733 }
02734 static inline bool IsSupported() { return true; }
02735 };
02736
02737 template <>
02738 struct SthToStr_obj<float>
02739 {
02740 void operator () (tstring *Str, const float &Sth)
02741 {
02742 common::FloatToStr(Str, Sth);
02743 }
02744 static inline bool IsSupported() { return true; }
02745 };
02746
02747 template <>
02748 struct SthToStr_obj<double>
02749 {
02750 void operator () (tstring *Str, const double &Sth)
02751 {
02752 common::DoubleToStr(Str, Sth);
02753 }
02754 static inline bool IsSupported() { return true; }
02755 };
02756
02757 template <>
02758 struct SthToStr_obj<tstring>
02759 {
02760 void operator () (tstring *Str, const tstring &Sth)
02761 {
02762 *Str = Sth;
02763 }
02764 static inline bool IsSupported() { return true; }
02765 };
02766
02767 template <typename T>
02768 struct SthToStr_obj< std::vector<T> >
02769 {
02770 void operator () (tstring *Str, const std::vector<T> &Sth)
02771 {
02772 Str->clear();
02773 tstring Element;
02774 for (typename std::vector<T>::const_iterator it = Sth.begin(); it != Sth.end(); ++it)
02775 {
02776 if (!Str->empty())
02777 *Str += ',';
02778 SthToStr<T>(&Element, *it);
02779 *Str += Element;
02780 }
02781 }
02782 static inline bool IsSupported() { return true; }
02783 };
02784
02785 template <>
02786 struct SthToStr_obj<char *>
02787 {
02788 void operator () (tstring *Str, tchar *Sth)
02789 {
02790 *Str = Sth;
02791 }
02792 static inline bool IsSupported() { return true; }
02793 };
02794
02795 template <>
02796 struct SthToStr_obj<const tchar *>
02797 {
02798 void operator () (tstring *Str, const tchar *Sth)
02799 {
02800 *Str = Sth;
02801 }
02802 static inline bool IsSupported() { return true; }
02803 };
02804
02805 template <>
02806 struct SthToStr_obj<void *>
02807 {
02808 void operator () (tstring *Str, void *Sth)
02809 {
02810 common::PtrToStr(Str, Sth);
02811 }
02812 static inline bool IsSupported() { return true; }
02813 };
02814
02815 template <>
02816 struct SthToStr_obj<const void *>
02817 {
02818 void operator () (tstring *Str, const void *Sth)
02819 {
02820 common::PtrToStr(Str, Sth);
02821 }
02822 static inline bool IsSupported() { return true; }
02823 };
02824
02825
02826
02827
02828 template <>
02829 struct StrToSth_obj<bool>
02830 {
02831 bool operator () (bool *Sth, const tstring &Str)
02832 {
02833 return common::StrToBool(Sth, Str);
02834 }
02835 static inline bool IsSupported() { return true; }
02836 };
02837
02838 template <>
02839 struct StrToSth_obj<tchar>
02840 {
02841 bool operator () (tchar *Sth, const tstring &Str)
02842 {
02843 if (Str.length() != 1) return false;
02844 *Sth = Str[0];
02845 return true;
02846 }
02847 static inline bool IsSupported() { return true; }
02848 };
02849
02850 template <>
02851 struct StrToSth_obj<int2>
02852 {
02853 bool operator () (int2 *Sth, const tstring &Str)
02854 {
02855 return common::StrToInt<int2>(Sth, Str) == 0;
02856 }
02857 static inline bool IsSupported() { return true; }
02858 };
02859
02860 template <>
02861 struct StrToSth_obj<int4>
02862 {
02863 bool operator () (int4 *Sth, const tstring &Str)
02864 {
02865 return common::StrToInt<int4>(Sth, Str) == 0;
02866 }
02867 static inline bool IsSupported() { return true; }
02868 };
02869 template <>
02870 struct StrToSth_obj<long>
02871 {
02872 bool operator () (long *Sth, const tstring &Str)
02873 {
02874 return common::StrToInt<int4>((int4*)Sth, Str) == 0;
02875 }
02876 static inline bool IsSupported() { return true; }
02877 };
02878
02879 template <>
02880 struct StrToSth_obj<int8>
02881 {
02882 bool operator () (int8 *Sth, const tstring &Str)
02883 {
02884 return common::StrToInt<int8>(Sth, Str) == 0;
02885 }
02886 static inline bool IsSupported() { return true; }
02887 };
02888
02889 template <>
02890 struct StrToSth_obj<uint1>
02891 {
02892 bool operator () (uint1 *Sth, const tstring &Str)
02893 {
02894 return common::StrToUint<uint1>(Sth, Str) == 0;
02895 }
02896 static inline bool IsSupported() { return true; }
02897 };
02898
02899 template <>
02900 struct StrToSth_obj<uint2>
02901 {
02902 bool operator () (uint2 *Sth, const tstring &Str)
02903 {
02904 return common::StrToUint<uint2>(Sth, Str) == 0;
02905 }
02906 static inline bool IsSupported() { return true; }
02907 };
02908
02909 template <>
02910 struct StrToSth_obj<uint4>
02911 {
02912 bool operator () (uint4 *Sth, const tstring &Str)
02913 {
02914 return common::StrToUint<uint4>(Sth, Str) == 0;
02915 }
02916 static inline bool IsSupported() { return true; }
02917 };
02918 template <>
02919 struct StrToSth_obj<unsigned long>
02920 {
02921 bool operator () (unsigned long *Sth, const tstring &Str)
02922 {
02923 return common::StrToUint<uint4>((uint4*)Sth, Str) == 0;
02924 }
02925 static inline bool IsSupported() { return true; }
02926 };
02927
02928 template <>
02929 struct StrToSth_obj<uint8>
02930 {
02931 bool operator () (uint8 *Sth, const tstring &Str)
02932 {
02933 return common::StrToUint<uint8>(Sth, Str) == 0;
02934 }
02935 static inline bool IsSupported() { return true; }
02936 };
02937
02938 template <>
02939 struct StrToSth_obj<float>
02940 {
02941 bool operator () (float *Sth, const tstring &Str)
02942 {
02943 return common::StrToFloat(Sth, Str) == 0;
02944 }
02945 static inline bool IsSupported() { return true; }
02946 };
02947
02948 template <>
02949 struct StrToSth_obj<double>
02950 {
02951 bool operator () (double *Sth, const tstring &Str)
02952 {
02953 return common::StrToDouble(Sth, Str) == 0;
02954 }
02955 static inline bool IsSupported() { return true; }
02956 };
02957
02958 template <>
02959 struct StrToSth_obj<tstring>
02960 {
02961 bool operator () (tstring *Sth, const tstring &Str)
02962 {
02963 *Sth = Str;
02964 return true;
02965 }
02966 static inline bool IsSupported() { return true; }
02967 };
02968
02969 template <typename T>
02970 struct StrToSth_obj< std::vector<T> >
02971 {
02972 bool operator () (std::vector<T> *Sth, const tstring &Str)
02973 {
02974 Sth->clear();
02975 uint4 Index = 0;
02976 tstring Element;
02977 T Val;
02978 while (common::Split(Str, _T(","), &Element, &Index))
02979 {
02980 if (!StrToSth<T>(&Val, Element)) return false;
02981 Sth->push_back(Val);
02982 }
02983 return true;
02984 }
02985 static inline bool IsSupported() { return true; }
02986 };
02987
02989
02990
02991 #endif