1 // ******************** FlopCpp ********************************************** 2 // File: MP_utilities.hpp 3 // $Id$ 4 // Author: Tim Helge Hultberg (thh@mat.ua.pt) 5 // Copyright (C) 2003 Tim Helge Hultberg 6 // All Rights Reserved. 7 // **************************************************************************** 8 9 #ifndef _MP_utilities_hpp_ 10 #define _MP_utilities_hpp_ 11 12 #include <string> 13 #include <vector> 14 15 namespace flopc { 16 17 /** @file This file contains several different useful utilities which are 18 used to simplify use of FlopC++. 19 @ingroup PublicInterface 20 */ 21 22 /** @brief Function object. Often used 23 @ingroup INTERNAL_USE 24 @note is the base class for passing a fucntion object around. 25 */ 26 class Functor { 27 public: 28 virtual void operator()() const = 0; 29 protected: Functor()30 Functor() {} ~Functor()31 virtual ~Functor() {} 32 private: 33 Functor(const Functor&); 34 Functor& operator=(const Functor&); 35 }; 36 37 /** This template makes a vector of appropriate size out of the 38 variable number of arguments. 39 @ingroup INTERNAL_USE 40 */ 41 template<int nbr, class T> makeVector(T i1,T i2=0,T i3=0,T i4=0,T i5=0)42 std::vector<T> makeVector(T i1, T i2=0, T i3=0, T i4=0, T i5=0) { 43 std::vector<T> S(nbr); 44 S[0] = i1; 45 if (nbr==1) return S; 46 S[1] = i2; 47 if (nbr==2) return S; 48 S[2] = i3; 49 if (nbr==3) return S; 50 S[3] = i4; 51 if (nbr==4) return S; 52 S[4] = i5; 53 return S; 54 } 55 56 /// return the strictly positive modulus of two integers mod(int a,int b)57 inline int mod(int a, int b) { 58 int t = a % b; 59 return (t>=0) ? t : t+b; 60 } 61 62 /// Distinct return value on conditions where an index goes out of bounds. 63 const int outOfBound = -2; 64 65 /** Utility class to flatten multidimensional information into single 66 dimentional offset information. 67 @ingroup INTERNAL_USE 68 */ 69 class RowMajor { 70 public: size() const71 int size() const { return size_; } 72 protected: RowMajor(int s1,int s2,int s3,int s4,int s5)73 RowMajor(int s1, int s2, int s3, int s4, int s5) : 74 size1(s1), size2(s2), size3(s3), size4(s4), size5(s5), 75 size_(s1*s2*s3*s4*s5) {} f(int i1=0,int i2=0,int i3=0,int i4=0,int i5=0) const76 int f(int i1=0, int i2=0, int i3=0, int i4=0, int i5=0) const { 77 if ( i1==outOfBound || i2==outOfBound || i3==outOfBound || 78 i4==outOfBound || i5==outOfBound ) { 79 return outOfBound; 80 } else { 81 int i = i1; 82 i *= size2; i += i2; i *= size3; i += i3; 83 i *= size4; i += i4; i *= size5; i += i5; 84 return i; 85 } 86 } 87 int size1,size2,size3,size4,size5,size_; 88 }; 89 90 /** @brief Utility interface class for adding a string name onto a 91 structure. 92 @ingroup INTERNAL_USE 93 */ 94 class Named { 95 public: getName() const96 std::string getName() const { return name; } setName(const std::string & n)97 void setName(const std::string& n) { name = n; } 98 private: 99 std::string name; 100 }; 101 102 /** @brief Utility for doing reference counted pointers. 103 @ingroup INTERNAL_USE 104 */ 105 template<class T> class Handle { 106 public: operator ->() const107 const T &operator->() const { 108 return root; 109 } Handle(const T & r)110 Handle(const T &r) : root(r) { 111 increment(); 112 } Handle(const Handle & h)113 Handle(const Handle& h) : root(h.root) { 114 increment(); 115 } operator =(const Handle & h)116 const Handle& operator=(const Handle& h) { 117 if (root != h.root) { 118 decrement(); 119 root = h.root; 120 increment(); 121 } 122 return *this; 123 } ~Handle()124 ~Handle() { 125 decrement(); 126 } 127 protected: increment()128 void increment() { 129 if(root != 0) { 130 (root->count)++; 131 } 132 } decrement()133 void decrement() { 134 if(root != 0) { 135 if(root->count == 1) { 136 delete root; 137 root = 0; 138 } else { 139 ///if(root->count != 0) { 140 --(root->count); 141 ///} 142 } 143 } 144 } 145 private: Handle()146 Handle() : root(0) {} 147 T root; 148 }; 149 150 } // End of namespace flopc 151 #endif 152