00001 #ifndef UTIL_HEADER_
00002 #define UTIL_HEADER_
00003
00005
00007 extern const int powers[31];
00008
00010 template<typename T> inline T sqr(T i)
00011 { return i*i; }
00013 template<typename T> inline T cube(T i)
00014 { return i*i*i; }
00015
00017 template<typename T> inline T lShift(T i,T bits)
00018 { ASSERT(bits>=0); return i<<bits; }
00019
00021 template<typename T> inline T rShift(T i,T bits)
00022 { ASSERT(bits>=0 && i>=0); return i>>bits; }
00023
00025 template<typename T> inline T exp10(T val)
00026 { return exp2( val*log2(T(10)) ); }
00027
00029 inline int log2ceil(int i) {
00030 ASSERT(i>0);
00031 --i;
00032 int result= 0;
00033 while (i) {
00034 i/= 2;
00035 ++result;
00036 }
00037 return result;
00038 }
00039
00041 template<class T> inline bool isNaN(T num) {
00042 #ifndef __ICC
00043 return isnan(num);
00044 #else
00045 return num!=num;
00046 #endif
00047 }
00048
00050 inline int getCountForDensity(int longLength,int density,int shortLength)
00051 { return (longLength-shortLength)/density +1; }
00052
00054 inline int getCountForDensity2D(int width,int height,int density,int sideSize) {
00055 return getCountForDensity(width,density,sideSize)
00056 * getCountForDensity(height,density,sideSize);
00057 }
00058
00060 template<class T> inline T checkBoundsFunc(T low,T value,T high) {
00061 if (value<low)
00062 return low;
00063 if (value>high)
00064 return high;
00065 return value;
00066 }
00067
00069 template<int power,class R> struct Float2int {
00070 static R convert(int i)
00071 { return std::ldexp( i+R(0.5), -power ); }
00072
00073 static int convert(R r)
00074 { return (int)trunc(std::ldexp( r, power )); }
00075 static int convertCheck(R r)
00076 { return checkBoundsFunc( 0, convert(r), powers[power]-1 ); }
00077 };
00078
00079 template<class C,class F> inline F for_each(C &container,F functor)
00080 { return for_each( container.begin(), container.end(), functor ); }
00081
00083 inline int countEOLs(const char *s) {
00084 int result= 0;
00085 for (; *s; ++s)
00086 if (*s=='\n')
00087 ++result;
00088 return result;
00089 }
00090
00092 template<class T> struct NonConstType { typedef T Result; };
00093 template<class T> struct NonConstType<const T> { typedef T Result; };
00094
00096 template <class T> inline T* constCast(const T* toCast) { return const_cast<T*>(toCast); }
00098 template <class T> inline T& constCast(const T& toCast) { return const_cast<T&>(toCast); }
00099
00101 inline void checkThrow(bool check) { if (!check) throw std::exception(); }
00102
00103
00105 struct SingleDeleter {
00106 template <class T> void operator()(T *toDelete) const { delete toDelete; }
00107 };
00109 struct MultiDeleter {
00110 template <class T> void operator()(T *toDelete) const { delete[] toDelete; }
00111 };
00112
00113
00115 template<class C> inline void clearContainer(const C &container)
00116 { for_each( container, SingleDeleter() ); }
00118 template<class C> inline void clearQtContainer(C container)
00119 { while (!container.isEmpty()) delete container.takeFirst(); }
00120
00121 template <class T,int bulkKb=64>
00122 class BulkAllocator {
00123 enum { bulkCount=(bulkKb*1024)/sizeof(T) };
00124
00125 std::vector<T*> pools;
00126 PtrInt nextIndex;
00127
00128 public:
00129 BulkAllocator()
00130 : nextIndex(bulkCount) {}
00131 BulkAllocator(const BulkAllocator &DEBUG_ONLY(copy))
00132 { nextIndex=bulkCount; ASSERT(copy.pools.empty()); }
00133 ~BulkAllocator()
00134 { for_each( pools, MultiDeleter() ); }
00135
00136 T* make() {
00137
00138 ASSERT(nextIndex<=bulkCount);
00139
00140 if (nextIndex==bulkCount) {
00141 nextIndex= 0;
00142 pools.push_back( new T[bulkCount] );
00143 }
00144 return & (pools.back()[nextIndex++]);
00145 }
00146 T* makeField(PtrInt count) {
00147
00148 ASSERT(nextIndex<=bulkCount);
00149
00150 if (count>bulkCount/2) {
00151 T *result= new T[count];
00152 if (pools.empty())
00153 pools.push_back(result);
00154 else {
00155 pools.push_back(pools.back());
00156 *(pools.end()-2)= result;
00157 }
00158 return result;
00159 }
00160
00161 if (nextIndex+count>bulkCount) {
00162
00163 nextIndex=0;
00164 pools.push_back(new T[bulkCount]);
00165 }
00166 T *result=&pools.back()[nextIndex];
00167 nextIndex+=count;
00168 return result;
00169 }
00170 };
00171
00173 struct UpdateInfo {
00174 typedef void (*IncInt)(int increment);
00175
00176 static void emptyFunction(int) {}
00177 static const bool noTerminate= false;
00178 static const UpdateInfo none;
00179
00180 volatile const bool *terminate;
00181 IncInt incMaxProgress
00182 , incProgress;
00183
00185 UpdateInfo( const bool &terminate_, IncInt incMaxProgress_, IncInt incProgress_ )
00186 : terminate(&terminate_), incMaxProgress(incMaxProgress_), incProgress(incProgress_)
00187 { ASSERT(isValid()); }
00188
00189 bool isValid() const { return terminate && incMaxProgress && incProgress; }
00190 };
00191
00192 #endif // UTIL_HEADER_