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_