/** \file helpers.hpp * * Declaration of some auxiliary functions for memory dis-/allocation and so on */ #ifndef HELPERS_HPP_ #define HELPERS_HPP_ using namespace std; /*********************************************** includes ***********************************/ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include "defs.hpp" #include "Helpers/Log.hpp" /********************************************** definitions *********************************/ /********************************************** helpful functions *********************************/ // taken out of TREMOLO /*@-namechecks@*/ #ifndef __GNUC__ # undef __attribute__ # define __attribute__(x) #endif /*@=namechecks@*/ /* Behandelt aufgetretene Fehler. error ist der Fehlertyp(enum Errors) void *SpecialData ist ein untypisierter Zeiger auf Spezielle Daten zur Fehlerbehandlung. Man koennte auch noch einen Zeiger auf eine Funktion uebergeben */ extern void /*@exits@*/ debug(const char *output); //__attribute__ ((__return__)); #define debug(data) debug_in((data), __FILE__, __LINE__) extern void /*@exits@*/ debug_in(const char *output, const char *file, const int line); //__attribute__ ((__return__)); double ask_value(const char *text); bool check_bounds(double *x, double *cell_size); void bound(double *b, double lower_bound, double upper_bound); int CountLinesinFile(ifstream &InputFile); char *FixedDigitNumber(const int FragmentNumber, const int digits); bool IsValidNumber( const char *string); int CompareDoubles (const void * a, const void * b); void performCriticalExit(); /********************************************** helpful template functions *********************************/ /** returns greater of the two values. * \param x first value * \param y second value * \return greater of the two (by operator>()) */ template T Max(T x, T y) { if (x > y) return x; else return y; }; /** returns smaller of the two values. * \param x first value * \param y second value * \return smaller of the two (by operator<()) */ template T Min(T x, T y) { if (x < y) return x; else return y; }; /** Creates a lookup table for true father's Atom::Nr -> atom ptr. * \param *start begin of chain list * \paran *end end of chain list * \param **Lookuptable pointer to return allocated lookup table (should be NULL on start) * \param count optional predetermined size for table (otherwise we set the count to highest true father id) * \return true - success, false - failure */ template bool CreateFatherLookupTable(T *start, T *end, T **&LookupTable, int count = 0) { bool status = true; T *Walker = NULL; int AtomNo; if (LookupTable != NULL) { DoeLog(0) && (eLog() << Verbose(0) << "Pointer for Lookup table is not NULL! Aborting ..." <next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron Walker = Walker->next; count = (count < Walker->GetTrueFather()->nr) ? Walker->GetTrueFather()->nr : count; } } if (count <= 0) { DoeLog(1) && (eLog() << Verbose(1) << "Count of lookup list is 0 or less." << endl); return false; } // allocate and fill LookupTable = new T*[count]; if (LookupTable == NULL) { DoeLog(0) && (eLog()<< Verbose(0) << "LookupTable memory allocation failed!" << endl); performCriticalExit(); status = false; } else { Walker = start; while (Walker->next != end) { // create a lookup table (Atom::nr -> atom) used as a marker table lateron Walker = Walker->next; AtomNo = Walker->GetTrueFather()->nr; if ((AtomNo >= 0) && (AtomNo < count)) { //*out << "Setting LookupTable[" << AtomNo << "] to " << *Walker << endl; LookupTable[AtomNo] = Walker; } else { DoeLog(2) && (eLog() << Verbose(2) << "Walker " << *Walker << " exceeded range of nuclear ids [0, " << count << ")." << endl); status = false; break; } } } return status; }; /** Frees a two-dimensional array. * \param *ptr pointer to array * \param dim first dim of array */ template void Free2DArray(X **ptr, int dim) { int i; if (ptr != NULL) { for(i=dim;i--;) if (ptr[i] != NULL) free(ptr[i]); free(ptr); } }; template void Increment(T *value, T *inc) { *value += *inc; }; template void AbsoluteValue(T *value, T *abs) { *value = *abs; }; template void IncrementalAbsoluteValue(T *value, T *abs) { *value = *abs; (*abs) += 1; }; #define PLURAL_S(v) (((v)==1)?"":"s") // this is to allow different modes of access for // maps and sets template struct _take{ Res get(T value) const; }; // if we have a set,vector etc we can directly access the result template struct _take{ static inline Res get(Res value){ return value; } }; // if we have a map we have to access the second part of // the pair template struct _take >{ static inline Res get(std::pair value){ return value.second; } }; /************ struct to contain simple enumerations ***************/ template struct enumeration{ enumeration() : max(0) {} enumeration(unsigned int i) : max(i) {} enumeration(const enumeration &src) : there(src.there), back(src.back), max(src.max) {} enumeration &operator=(const enumeration &src){ /* no self-assignment check needed */ there = src.there; back = src.back; max = src.max; return *this; } void add(const C &value){ if(!there.count(value)){ there[value]=max; back[max++]=value; } } unsigned int getMax() const{ return max; } map there; map back; private: unsigned int max; }; /***** A counter to generate sequential numbers *******************/ struct counter{ inline counter() : count(0){}; inline counter(int i) : count(i){}; inline unsigned int operator()(){ return count++; } private: unsigned int count; }; template enumeration enumerate(ForwardIterator first,ForwardIterator last){ enumeration res; for_each(first,last,bind1st(mem_fun(&enumeration::add),&res)); return res; } #endif /*HELPERS_HPP_*/