Some code cleanup and changes due to GCC upgrade to 4.3.*.
[fic.git] / util.h
blob0e9963e4a3ae13fc2abed24ddf3e10141e1b9b85
1 #ifndef UTIL_HEADER_
2 #define UTIL_HEADER_
4 #include "headers.h"
5 #include "debug.h"
7 /** Field containing 2^i on i-th position, defined in modules.cpp */
8 extern const int powers[31];
10 /** Helper template function computing the square of a number */
11 template<typename T> inline T sqr(T i)
12 { return i*i; }
13 /** Helper template function computing the cube of a number */
14 template<typename T> inline T cube(T i)
15 { return i*i*i; }
17 /** Returns i*2^bits */
18 template<typename T> inline T lShift(T i,T bits)
19 { ASSERT(bits>=0); return i<<bits; }
21 /** Returns i/2^bits */
22 template<typename T> inline T rShift(T i,T bits)
23 { ASSERT(bits>=0 && i>=0); return i>>bits; }
25 /** Returns ceil(log2(i)) */
26 inline int log2ceil(int i) {
27 ASSERT(i>0);
28 --i;
29 int result= 0;
30 while (i) {
31 i/= 2;
32 ++result;
34 return result;
37 /** How many short intervals (shifted by density) can fit into a long interval (discrete) */
38 inline int getCountForDensity(int longLength,int density,int shortLength)
39 { return (longLength-shortLength)/density +1; }
41 /** The same as above, but in 2D for squares fitting into a rectangle */
42 inline int getCountForDensity2D(int width,int height,int density,int sideSize) {
43 return getCountForDensity(width,density,sideSize)
44 * getCountForDensity(height,density,sideSize);
47 /** General bounds-checking template routine - returns max(low,min(value,high)) */
48 template<class T> inline T checkBoundsFunc(T low,T value,T high) {
49 if (value<low)
50 return low;
51 if (value>high)
52 return high;
53 return value;
56 /** Struct for conversion between [0..1] Real and 0..(2^power-1) integer */
57 template<int power,class R> struct Float2int {
58 static R convert(int i)
59 { return std::ldexp( i+R(0.5), -power ); }
61 static int convert(R r)
62 { return (int)trunc(std::ldexp( r, power )); }
63 static int convertCheck(R r)
64 { return checkBoundsFunc( 0, convert(r), powers[power]-1 ); }
67 /** Counts the number of '\n' characters in a C-string */
68 inline int countEOLs(const char *s) {
69 int result= 0;
70 for (; *s; ++s)
71 if (*s=='\n')
72 ++result;
73 return result;
76 /** Converts any type to std::string via std::stringstream */
77 template<class T> inline std::string toString(const T &what) {
78 std::stringstream stream;
79 stream << what;
80 std::string result;
81 stream >> result;
82 return result;
85 /** Type convertor - NonConstType<T>::Result is a non-const variant of T or T itself if N/A */
86 template<class T> struct NonConstType { typedef T Result; };
87 template<class T> struct NonConstType<const T> { typedef T Result; };
89 /** Automatic version of const_cast for pointers */
90 template <class T> inline T* constCast(const T* toCast) { return const_cast<T*>(toCast); }
91 /** Automatic version of const_cast for references */
92 template <class T> inline T& constCast(const T& toCast) { return const_cast<T&>(toCast); }
94 /** Checking a condition - throws an exception if false */
95 inline void checkThrow(bool check) { if (!check) throw std::exception(); }
98 /** Template object for automated deletion of pointers (useful in for_each) */
99 struct SingleDeleter {
100 template <class T> void operator()(T *toDelete) const { delete toDelete; }
102 /** Template object for automated deletion of field pointers (useful in for_each) */
103 struct MultiDeleter {
104 template <class T> void operator()(T *toDelete) const { delete[] toDelete; }
108 /** Deletes all pointers in a container (it has to support \c begin and \c end methods) */
109 template<class C> void clearContainer(const C &container)
110 { for_each( container.begin(), container.end(), SingleDeleter() ); }
113 template <class T,int bulkKb=64>
114 class BulkAllocator {
115 enum { bulkCount=(bulkKb*1024)/sizeof(T) };
117 std::vector<T*> pools;
118 size_t nextIndex;
120 public:
121 BulkAllocator()
122 : nextIndex(bulkCount) {}
123 BulkAllocator(const BulkAllocator &DEBUG_ONLY(copy))
124 { nextIndex=bulkCount; ASSERT(copy.pools.empty()); }
125 ~BulkAllocator()
126 { for_each( pools.begin(), pools.end(), MultiDeleter() ); }
128 T* make() {
129 // check for errors
130 ASSERT(nextIndex<=bulkCount);
131 // allocate a new bulk if needed
132 if (nextIndex==bulkCount) {
133 nextIndex= 0;
134 pools.push_back( new T[bulkCount] );
136 return & (pools.back()[nextIndex++]);
138 T* makeField(size_t count) {
139 // check for errors
140 ASSERT(nextIndex<=bulkCount);
142 if (count>bulkCount/2) {
143 T *result=new T[count];
144 if (pools.empty())
145 pools.push_back(result);
146 else {
147 pools.push_back(pools.back());
148 *(pools.end()-2)=result;
150 return result;
153 if (nextIndex+count>bulkCount) {
154 // some space will be wasted
155 nextIndex=0;
156 pools.push_back(new T[bulkCount]);
158 T *result=&pools.back()[nextIndex];
159 nextIndex+=count;
160 return result;
164 /** Structure providing support for progress update and interruption (used for encoding) */
165 struct UpdateInfo {
166 typedef void (*IncInt)(int increment); ///< Type for used functions -> more readable code
168 volatile const bool *terminate; ///< true if the action should be terminated
169 IncInt incMaxProgress /// function for increasing the maximum progress (100%)
170 , incProgress; ///< function for increasing the current progress
172 static void emptyFunction(int) {} ///< does nothing, default for IncInt functions
173 static const bool noTerminate= false; ///< default for #terminate, defined in modules.cpp
175 /** Initializes the structure from supplied parametres */
176 UpdateInfo( const bool &terminate_= noTerminate, IncInt incMaxProgress_= &emptyFunction
177 , IncInt incProgress_= &emptyFunction )
178 : terminate(&terminate_), incMaxProgress(incMaxProgress_), incProgress(incProgress_) {}
181 #endif // UTIL_HEADER_