Added czech translation and some support for it.
[fic.git] / util.h
blob75aa143636f35efa2caa63bccef659360b1d5d2e
1 #ifndef UTIL_HEADER_
2 #define UTIL_HEADER_
4 /// \file
6 /** Field containing 2^i on i-th position, defined in modules.cpp */
7 extern const int powers[31];
9 /** Helper template function computing the square of a number */
10 template<typename T> inline T sqr(T i)
11 { return i*i; }
12 /** Helper template function computing the cube of a number */
13 template<typename T> inline T cube(T i)
14 { return i*i*i; }
16 /** Returns i*2^bits */
17 template<typename T> inline T lShift(T i,T bits)
18 { ASSERT(bits>=0); return i<<bits; }
20 /** Returns i/2^bits */
21 template<typename T> inline T rShift(T i,T bits)
22 { ASSERT(bits>=0 && i>=0); return i>>bits; }
24 /** Returns ceil(log2(i)) */
25 inline int log2ceil(int i) {
26 ASSERT(i>0);
27 --i;
28 int result= 0;
29 while (i) {
30 i/= 2;
31 ++result;
33 return result;
36 /** A wrapper around isnan() because of compiler support */
37 template<class T> inline bool isNaN(T num) {
38 #ifndef __ICC
39 return isnan(num);
40 #else
41 return num!=num;
42 #endif
45 /** How many short intervals (shifted by density) can fit into a long interval (discrete) */
46 inline int getCountForDensity(int longLength,int density,int shortLength)
47 { return (longLength-shortLength)/density +1; }
49 /** The same as above, but in 2D for squares fitting into a rectangle */
50 inline int getCountForDensity2D(int width,int height,int density,int sideSize) {
51 return getCountForDensity(width,density,sideSize)
52 * getCountForDensity(height,density,sideSize);
55 /** General bounds-checking template routine - returns max(low,min(value,high)) */
56 template<class T> inline T checkBoundsFunc(T low,T value,T high) {
57 if (value<low)
58 return low;
59 if (value>high)
60 return high;
61 return value;
64 /** Struct for conversion between 0-1 Real and 0-(2^power-1) integer */
65 template<int power,class R> struct Float2int {
66 static R convert(int i)
67 { return std::ldexp( i+R(0.5), -power ); }
69 static int convert(R r)
70 { return (int)trunc(std::ldexp( r, power )); }
71 static int convertCheck(R r)
72 { return checkBoundsFunc( 0, convert(r), powers[power]-1 ); }
75 template<class C,class F> inline F for_each(C &container,F functor)
76 { return for_each( container.begin(), container.end(), functor ); }
78 /** Counts the number of '\n' characters in a C-string */
79 inline int countEOLs(const char *s) {
80 int result= 0;
81 for (; *s; ++s)
82 if (*s=='\n')
83 ++result;
84 return result;
87 /** Type convertor - NonConstType<T>::Result is a non-const variant of T or T itself if N/A */
88 template<class T> struct NonConstType { typedef T Result; };
89 template<class T> struct NonConstType<const T> { typedef T Result; };
91 /** Automatic version of const_cast for pointers */
92 template <class T> inline T* constCast(const T* toCast) { return const_cast<T*>(toCast); }
93 /** Automatic version of const_cast for references */
94 template <class T> inline T& constCast(const T& toCast) { return const_cast<T&>(toCast); }
96 /** Checking a condition - throws std::exception if false */
97 inline void checkThrow(bool check) { if (!check) throw std::exception(); }
100 /** Template object for automated deletion of pointers (useful in for_each) */
101 struct SingleDeleter {
102 template <class T> void operator()(T *toDelete) const { delete toDelete; }
104 /** Template object for automated deletion of field pointers (useful in for_each) */
105 struct MultiDeleter {
106 template <class T> void operator()(T *toDelete) const { delete[] toDelete; }
110 /** Deletes all pointers in a container (it has to support \c begin and \c end methods) */
111 template<class C> inline void clearContainer(const C &container)
112 { for_each( container, SingleDeleter() ); }
113 /** Clears a QList of pointers (and deletes the pointers) */
114 template<class C> inline void clearQtContainer(C container)
115 { while (!container.isEmpty()) delete container.takeFirst(); }
117 template <class T,int bulkKb=64>
118 class BulkAllocator {
119 enum { bulkCount=(bulkKb*1024)/sizeof(T) };
121 std::vector<T*> pools;
122 PtrInt nextIndex;
124 public:
125 BulkAllocator()
126 : nextIndex(bulkCount) {}
127 BulkAllocator(const BulkAllocator &DEBUG_ONLY(copy))
128 { nextIndex=bulkCount; ASSERT(copy.pools.empty()); }
129 ~BulkAllocator()
130 { for_each( pools, MultiDeleter() ); }
132 T* make() {
133 // check for errors
134 ASSERT(nextIndex<=bulkCount);
135 // allocate a new bulk if needed
136 if (nextIndex==bulkCount) {
137 nextIndex= 0;
138 pools.push_back( new T[bulkCount] );
140 return & (pools.back()[nextIndex++]);
142 T* makeField(PtrInt count) {
143 // check for errors
144 ASSERT(nextIndex<=bulkCount);
146 if (count>bulkCount/2) {
147 T *result= new T[count];
148 if (pools.empty())
149 pools.push_back(result);
150 else {
151 pools.push_back(pools.back());
152 *(pools.end()-2)= result;
154 return result;
157 if (nextIndex+count>bulkCount) {
158 // some space will be wasted
159 nextIndex=0;
160 pools.push_back(new T[bulkCount]);
162 T *result=&pools.back()[nextIndex];
163 nextIndex+=count;
164 return result;
166 }; // BulkAllocator class
168 /** Structure providing support for progress update and interruption (used for encoding) */
169 struct UpdateInfo {
170 typedef void (*IncInt)(int increment); ///< Type for used functions -> more readable code
172 static void emptyFunction(int) {} ///< does nothing, default for IncInt functions
173 static const bool noTerminate= false; ///< default for #terminate, defined in modules.cpp
174 static const UpdateInfo none; ///< empty UpdateInfo instance, in modules.cpp
176 volatile const bool *terminate; ///< true if the action should be terminated
177 IncInt incMaxProgress /// function for increasing the maximum progress (100%)
178 , incProgress; ///< function for increasing the current progress
180 /** Initializes the structure from supplied parametres */
181 UpdateInfo( const bool &terminate_, IncInt incMaxProgress_, IncInt incProgress_ )
182 : terminate(&terminate_), incMaxProgress(incMaxProgress_), incProgress(incProgress_)
183 { ASSERT(isValid()); }
185 bool isValid() const { return terminate && incMaxProgress && incProgress; }
188 #endif // UTIL_HEADER_