Writing about PIFS and convergence.
[fic.git] / util.h
blob6acf644c1cccc564b009eee72ebec509b9299403
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 if (value<high)
51 return value;
52 else
53 return high;
54 else
55 return low;
58 /** Struct for conversion between [0..1] Real and 0..(2^power-1) integer */
59 template<int power=8,class R=MTypes::Real> struct Float2int {
60 static R convert(int i)
61 { return std::ldexp( i+R(0.5), -power ); }
63 static int convert(R r)
64 { return (int)trunc(std::ldexp( r, power )); }
65 static int convertCheck(R r)
66 { return checkBoundsFunc( 0, convert(r), powers[power]-1 ); }
69 /** Counts the number of '\n' characters in a C-string */
70 inline int countEOLs(const char *s) {
71 int result= 0;
72 for (; *s; ++s)
73 if (*s=='\n')
74 ++result;
75 return result;
78 template<class T> inline std::string toString(const T &what) {
79 std::stringstream stream;
80 stream << what;
81 std::string result;
82 stream >> result;
83 return result;
86 /** Automatic version of const_cast for pointers */
87 template <class T> inline T* constCast(const T* toCast) { return const_cast<T*>(toCast); }
88 /** Automatic version of const_cast for references */
89 template <class T> inline T& constCast(const T& toCast) { return const_cast<T&>(toCast); }
91 /** Automatic helper cast from "T**" to "const T**" */
92 template <class T> inline const T** bogoCast(T** toCast)
93 { return const_cast<const T**>(toCast); }
95 /** Checking a condition - throws an exception if false */
96 inline void checkThrow(bool check) { if (!check) throw std::exception(); }
99 /* Auto-release pointer template altered to work more like an ordinary pointer *//*
100 template<class T> class Auto_ptr: public std::auto_ptr<T> {
101 public:
102 Auto_ptr(T *t=0): std::auto_ptr<T>(t) {}
103 operator T*() const
104 { return this->get(); }
105 Auto_ptr& operator=(T *t) {
106 reset(t);
107 return *this;
113 /** Template object for automated deletion of pointers (useful in for_each) */
114 template <class T> struct SingleDeleter {
115 void operator()(T *toDelete) { delete toDelete; }
117 /** Template object for automated deletion of field pointers (useful in for_each) */
118 template <class T> struct MultiDeleter {
119 void operator()(T *toDelete) { delete[] toDelete; }
122 #ifndef __ICC
123 /** Deletes all pointers in a container (it has to support \c begin and \c end methods) */
124 template < class T, template<class> class C > inline
125 void clearContainer(const C<T*> &container)
126 { for_each( container.begin(), container.end(), SingleDeleter<T>() ); }
128 #else
129 #define clearContainer(cont_) \
130 do { \
131 typedef typeof(cont_) contType_; \
132 const contType_ &c_= cont_; \
133 for (contType_::const_iterator it_=c_.begin(); it_!=c_.end(); ++it_) \
134 delete *it_; \
135 } while (false)
136 #endif
138 template <class T,int bulkKb=64>
139 class BulkAllocator {
140 enum { bulkCount=(bulkKb*1024)/sizeof(T) };
142 std::vector<T*> pools;
143 size_t nextIndex;
145 public:
146 BulkAllocator()
147 : nextIndex(bulkCount) {}
148 BulkAllocator(const BulkAllocator &DEBUG_ONLY(copy))
149 { nextIndex=bulkCount; assert(copy.pools.empty()); }
150 ~BulkAllocator()
151 { for_each( pools.begin(), pools.end(), MultiDeleter<T>() ); }
153 T* make() {
154 // check for errors
155 assert(nextIndex<=bulkCount);
156 // allocate a new bulk if needed
157 if (nextIndex==bulkCount) {
158 nextIndex= 0;
159 pools.push_back( new T[bulkCount] );
161 return & (pools.back()[nextIndex++]);
163 T* makeField(size_t count) {
164 // check for errors
165 assert(nextIndex<=bulkCount);
167 if (count>bulkCount/2) {
168 T *result=new T[count];
169 if (pools.empty())
170 pools.push_back(result);
171 else {
172 pools.push_back(pools.back());
173 *(pools.end()-2)=result;
175 return result;
178 if (nextIndex+count>bulkCount) {
179 // some space will be wasted
180 nextIndex=0;
181 pools.push_back(new T[bulkCount]);
183 T *result=&pools.back()[nextIndex];
184 nextIndex+=count;
185 return result;
189 struct UpdateInfo {
190 typedef void (*IncInt)(int increment);
192 volatile const bool *terminate;
193 IncInt incMaxProgress, incProgress;
195 static void emptyFunction(int) {}
196 static const bool noTerminate= false; ///< defined in modules.cpp
198 UpdateInfo( const bool &terminate_= noTerminate, IncInt incMaxProgress_=&emptyFunction
199 , IncInt incProgress_=&emptyFunction )
200 : terminate(&terminate_), incMaxProgress(incMaxProgress_), incProgress(incProgress_) {}
203 #endif // UTIL_HEADER_