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